Deploy Keycloak using Podman on Oracle Linux

1
0
Send lab feedback

Deploy Keycloak Using Podman

Introduction

Keycloak provides single sign-on functionality for web applications and RESTFUL web services. A primary goal of Keycloak is to provide security features that developers can easily use to secure applications and services within their organizations, for example Single-Sign-On authentication. Keycloak can also be integrated with existing LDAP and Active Directory servers.

Keycloak is based on standard protocols and provides support for User Federation, OpenID Connect, OAuth 2.0 and SAML and many more. Keycloak provides both administrators, and users, with management consoles. Users can update their passwords, profile details and setup two-factor authentication via the Account Managment Console. Likewise administrators can use the Admin Console to manage all aspects of Keycloak's functionality, it's authorization policies, applications and manage users (including user's permissions and sessions).

Objectives

This lab shows how to deploy Keycloak on Podman, configure it with a datastore using a Podman volume to store the data outside of Podman. Then demonstrate how to access Keycloak, create a new Realm then add a User to the newly created Keycloak Realm. Finally the newly created User will log on to the Keycloak server's newly created Realm to demonstrate where a User could manage the Single Sign-On details. The main steps are outlined below:

  • Install Podman
  • Configure a Podman network and volume
  • Deploy a Postgres database container
  • Deploy a Keycloak container using the Postgres container as a datastore
  • Create a new Keycloak Realm and User

Note: A production deployment would most likely use either Podman secrets, or Kubernetes secrets, to obfuscate any passwords. Neither of the scenarios are covered in this Lab.

What Do You Need?

  • A client system with Oracle Linux installed
  • Access to the Internet

For more information about Keycloak itself, see the upstream website .

Setup the Lab Environment

Note: When using the free lab environment, see Oracle Linux Lab Basics for connection and other usage instructions.

  1. Open a terminal and connect via ssh to the ol-server instance if not already connected.

    ssh oracle@<ip_address_of_instance>

Install the Container Tools

The Container Tools in Oracle Linux provide the latest fast and stable versions of Podman, Buildah, Skopeo, and associated dependencies.

  1. Install the Container Tools packages.

    sudo dnf install -y container-tools
  2. Check the version of Podman.

    podman --version

Create a Podman Network

Podman provides a default network environment wihch can be used to run any container available to it. However, there may be occasions where the business requires the ability to segregate some deployments from each other - this is where the podman network command helps. In this scenario Keycloak, along with it's database, will be deployed onto it's own podman network.

Whilst it is possible, as part of creating a Podman Network to define numerous other options at the same time, for example a different --subnet, --gateway or --ip-range, to be defined - this scenario will not demonstrate this. Please refer to the upstream documentation for more details. This scenario only shows a basic bridge network, using Podman's default settings, being created.

  1. Create the Podman network.

    podman network create keycloak-network
  2. Verify that the Podman network is created.

    Note: Podman creates a default Podman network (called podman) when Podman is installed, hence why two networks are displayed.

    podman network ls

    Example Output:

    [oracle@ol-server ~]$ podman network ls
    NETWORK ID    NAME              DRIVER
    ea439617652f  keycloak-network  bridge
    2f259bab93aa  podman            bridge
  3. Display the network configuration used by the newly created Podman keycloak-network. This can be used to confirm that the required/expected network settings for a deployment are active for the specified podman network.

    podman network inspect keycloak-network

    Example Output:

    [oracle@ol-server ~]$ podman network inspect keycloak-network
    [
         {
              "name": "keycloak-network",
              "id": "ea439617652ffdd8320503c4eb2723f5f5ca291ed1ed70f8efc05ec52980f9e3",
              "driver": "bridge",
              "network_interface": "podman1",
              "created": "2022-10-05T11:39:55.55110214Z",
              "subnets": [
                   {
                        "subnet": "10.89.0.0/24",
                        "gateway": "10.89.0.1"
                   }
              ],
              "ipv6_enabled": false,
              "internal": false,
              "dns_enabled": true,
              "ipam_options": {
                 "driver": "host-local"
              }
         }
    ]

Download Postgres

By default Keycloak uses a file-based H2 database to store any configuration changes made. However because this is stored within the deployed container, it means that any information is lost whenever the Keycloak container is stopped. However Keycloak has built-in support for multiple databases. So, this example uses a Postgres database configured to store it's data externally from the container to prevent any Keycloak configuration being lost when the Keycloak container is stopped (shutdown).

  1. Download the latest image of Postgress.

    podman pull docker.io/library/postgres:latest

    Example Output:

    [oracle@ol-server ~]$ podman pull docker.io/libraary/postgres
    ��� docker.io/library/postgres:latest
    Trying to pull docker.io/library/postgres:latest...
    Getting image source signatures
    Copying blob b955aac8d5e0 done  
    ...
    ...  
    Copying config e270a11b9c done  
    Writing manifest to image destination
    Storing signatures
    e270a11b9c8a719c4f501c34f1fccf7de89cda4d95e6e6ec9cadc73bdb1ae6d5
  2. Confirm the Postgres image is available.

    podman image ls

    Example Output:

    [oracle@ol-server ~]$ podman image ls
    REPOSITORY                  TAG         IMAGE ID      CREATED      SIZE
    docker.io/library/postgres  latest      e270a11b9c8a  4 hours ago  384 MB
  3. Create a Podman volume to store the data.

    podman volume create pgdata

    Example Output:

    [oracle@ol-server ~]$ podman volume create pgdata
    pgdata
  4. Verifiy the Podman volume has been created.

    podman volume inspect pgdata

    Note: The Podman volume's data is located in the $PATH indicated by the Mountpoint variable.

    Example Output:

    [oracle@ol-server ~]$ podman volume inspect pgdata
    [
         {
              "Name": "pgdata",
              "Driver": "local",
              "Mountpoint": "/home/oracle/.local/share/containers/storage/volumes/pgdata/_data",
              "CreatedAt": "2022-10-12T12:19:31.393134253Z",
              "Labels": {},
              "Scope": "local",
              "Options": {},
              "MountCount": 0,
              "NeedsCopyUp": true,
              "NeedsChown": true
         }
    ]
  5. Start the Postgres container.

    podman run -p 5432:5432 --name myPostgresDB -d --net keycloak-network -v pgdata:/var/lib/postresql/data -e POSTGRES_USER=pgresUser -e POSTGRES_PASSWORD=pgresPW -e POSTGRES_DB=keycloakDB postgres

    Example Output:

    [oracle@ol-server ~]$ podman run -p 5432:5432 --name  -d --net keycloak-network -v pgdata:/var/lib/postresql/data -e POSTGRES_USER=pgresUser -e POSTGRES_PASSWORD=pgresPW -e POSTGREs_DB=keycloakDB postgres
    8008a2b87bdca436fce22ad4420ae40caf456c4f3f77099b0e44584caca5984b

    Time to explain what just occurred.

    • podman run instructs Podman to create and run a container.
    • -p 5432:5432 is the port mapping being used by the running container. In this case the 5432 on the left maps to the local port, and 5432 on the right maps to the port internally within Podman.
    • --name myPostgresDB is the name chosen for the container being created.
    • -d indicates that Podman is to execute the container in detached mode (it runs in a background process)
    • --net keycloak-network instructs Podman to assign the Postgres container to the keycloak-network
    • -v pgdata:/var/lib/postresql/data starts Postgres using a Podman volume (the left hand value) to store the Postres data (the right hand value) externally from the Postgres container
    • Next set the required Postgres environment variables:
      • -e POSTGRES_DB=keycloakDB Sets the database's name
      • -e POSTGRES_USER=pgresUser Sets the administrator user's name
      • -e POSTGRES_PASSWORD=pgressPW Sets the administrator user's password
    • postgres is the name of the image Podman is to run.

  6. Confirm the Postgres container is running.

    Notice that the NAMES column listed is the same value as that passed to Podman using the --name switch.

    podman ps

    Example Output:

    [oracle@ol-server ~]$ podman ps
    CONTAINER ID  IMAGE                              COMMAND     CREATED         STATUS             PORTS                   NAMES
    8008a2b87bdc  docker.io/library/postgres:latest  postgres    11 minutes ago  Up 11 minutes ago  0.0.0.0:5432->5432/tcp  myPostgresDB
  7. (Optional) How to confirm the Postgres container's environment variables.

    This demonstrates how to inspect, or confirm, the environment variables for the running Postgres container.

    podman exec myPostgresDB env

    Example Output:

    [oracle@ol-server ~]$ podman exec myPostgresDB env
    LANG=en_US.utf8
    PG_MAJOR=14
    PG_VERSION=14.5-1.pgdg110+1
    POSTGRES_PASSWORD=pgresPW
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/14/bin
    TERM=xterm
    container=podman
    GOSU_VERSION=1.14
    PGDATA=/var/lib/postgresql/data
    POSTGRES_USER=pgresUser
    POSTGREs_DB=keycloakDB
    HOME=/root

Download and start PGAdmin

Now that Postgres is running, either the command-line can be used to connect to the database, or use PGAdmin, a web-based GUI tool used to connect to Postgres servers. The following steps demonstrate how to get PGAdmin working in Podman.

Download PGAdmin

  1. Download the PGAdmin image.

    podman pull docker.io/dpage/pgadmin4:latest

    Example Output:

    [oracle@ol-server ~]$ podman pull docker.io/dpage/pgadmin4:latest
    Trying to pull docker.io/dpage/pgadmin4:latest...
    Getting image source signatures
    Copying blob 15719ca221da done  
    ...
    ...  
    Copying config 94c0924749 done  
    Writing manifest to image destination
    Storing signatures
    94c0924749b6efbd528467945d7c12370f5e8b98e4b873a0b50406aa25d4ca4b

    Important Note: If running Podman on Oracle Linux, the default container registry is set as: container-registry.oracle.com. However it requires a username/password to access, therefore if you do not already have this, or if using the Free Lab environment (and not using the Docker hub URI directly), please use the down arrow key on the keyboard to select the public repository: docker-io

    Example Output:

    [oracle@ol-server ~]$ podman pull dpage/pgadmin4:latest
    ? Please select an image: 
      ��� container-registry.oracle.com/dpage/pgadmin4:latest
        docker.io/dpage/pgadmin4:latest

Confirm the Server's IP address and Hostname

  1. Get the ip address of the server.

    sudo ip addr show

    Example Output:

    [oracle@ol-server ~]$ sudo ip addr show
    ...
    2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 02:00:17:09:3d:1f brd ff:ff:ff:ff:ff:ff
        altname enp0s3
        inet 10.0.0.150/24 brd 10.0.0.255 scope global dynamic noprefixroute ens3
           valid_lft 71828sec preferred_lft 71828sec
        inet6 fe80::17ff:fe09:3d1f/64 scope link noprefixroute 
           valid_lft forever preferred_lft forever

    The IPv4 address to use is on the line starting with inet

  2. Confirm the forward DNS configuration.

    host $(hostname -f)

    Example output:

    [oracle@ol-server ~]$ host $(hostname -f)
    ol-server.pub.linuxvirt.oraclevcn.com has address 10.0.0.150

Start PGAdmin

  1. Start PGAdmin

    podman run --name my-pgadmin -p 8082:80 --net keycloak-network -e PGADMIN_DEFAULT_EMAIL="pgresUser@example.com" -e PGADMIN_DEFAULT_PASSWORD="pgresPW" -d dpage/pgadmin4

    Important: use the email as specified.

    Again, time to explain what just occured.

    • podman run instructs Podman to create and run a container.
    • -p 8082:80 is the port mapping being used by the running container. In this case the 8082 maps to the local port, and 80 maps to the port internally within Podman. (Note: Ports lower than 1024 need to be started by root)
    • --name my-pgadmin is the name chosen for the container being created.
    • -d indicates that Podman is to execute the container in detached mode (it runs in a background process)
    • --net keycloak-network instructs Podman to assign the Postgres container to the keycloak-network
    • Sets the Postgres environment variables:
      • -e PGADMIN_DEFAULT_EMAIL="pgresUser@example.com" Sets the administrator user's email
      • -e PGADMIN_DEFAULT_PASSWORD="pgresPW" Sets the administrator user's password
    • dpage/pgadmin4 is the name of the image Podman is to run.

Access the PGAdmin Web Console

  1. Right-click on the Virtual Desktop and select Open Terminal Here.

  2. Configure an SSH tunnel.

    ssh -L 8082:localhost:8082 oracle@<hostname or ip address>
  3. Open a new browser session (on the Virtual Desktop) and enter the URL.

    http://localhost:8082

    Example Output:

    pgadmin-login

  4. Login to PGAdmin

    This requires using the same User Name and Password passed when starting the PGAdmin container. Enter the values shown below:

    Example Output:

    pgadmin-start

  5. Connect to the Postgres database

    • Click on the Add New Server icon, a new dialogue box appears.

    Example Output:

    pgadmin-register

    • Enter the name of the Postgres server to connect to which in the scenario is myPostgresDB

    Example Output:

    pgadmin-server-name

    • Click on the Connection tab within the dialogue box, and enter the following details in the relevant fields:

      Host name/Address - 10.0.0.150 Port - 5432 Username - pgresUser Password - pgresPW

      Click on the Save button to register the server.

    Example Output:

    pgadmin-detail

    • The connection to myPostgresDBis complete

    Example Output:

    pgadmin-connected

Download and Start Keycloak

The first step is to pull, and start, the Keycloak container.

  1. Pull and start Keycloak. The following step will start Keycloak using port 8080, and then create an initial administrator user admin and assign the password admin to that user. The last option start-dev initializes Keycloak to use:

    podman run -p 8080:8080 -d --name keycloak -d --net keycloak-network -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KC_DB=postgres -e KC_DB_URL_DATABASE=keycloakDB -e KC_DB_URL_HOST=10.0.0.150 -e KC_DB_URL_PORT=5432 -e KC_DB_USERNAME=pgresUser -e KC_DB_PASSWORD=pgresPW quay.io/keycloak/keycloak:latest start-dev

    Again, time to explain what command-line options describe.

    • podman run instructs Podman to create and run a container.
    • -p 8080:8080 is the port mapping being used by the running container. In this case the 8080 on the left hand side maps to the local port, and 8080 on the right hand side maps to the port internally within Podman. (Note: Ports lower than 1024 need to be started by root)
    • --name keycloak is the name chosen for the container being created.
    • -d indicates that Podman is to execute the container in detached mode (it runs in a background process)
    • --net keycloak-network instructs Podman to assign the Postgres container to the keycloak-network
    • -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin set the required Keycloak environment variables. In this instance the administrator user and password.
    • -e KC_DB=postgres -e KC_DB_URL_DATABASE=keycloakDB -e KC_DB_URL_HOST=10.0.0.150 -e KC_DB_URL_PORT=5432 -e KC_DB_USERNAME=pgresUser -e KC_DB_PASSWORD=pgresPW - set the required environment variables to enable Keycloak to store it's data in the Postgres database.
    • dquay.io/keycloak/keycloak:latest is the name of the image Podman is to run.
    • start-dev - Starts Keycloak in development mode (which is not using certificates & SSL). NOTE This is NOT suitable for production use.

    Example Output:

    [oracle@ol-server ~]$ podman run -p 8080:8080 -d --name keycloak -d --net keycloak-network -e KEYCLOAK_ADMIN=admin -e
    KEYCLOAK_ADMIN_PASSWORD=admin -e KC_DB=postgres -e KC_DB_URL_DATABASE=keycloakDB -e KC_DB_URL_HOST=10.0.0.150 -e KC_DB_URL_PORT=5432 -e
    KC_DB_USERNAME=pgresUser -e KC_DB_PASSWORD=pgresPW quay.io/keycloak/keycloak:latest start-dev
    Trying to pull quay.io/keycloak/keycloak:latest...
    Getting image source signatures
    Copying blob 0f8dfc4ae562 done  
    Copying blob 008dba906bf6 done  
    Copying blob d5d2e87c6892 done  
    Copying blob e89553497f29 done  
    Copying config fab433d55e done  
    Writing manifest to image destination
    Storing signatures
    0fead1b248b4118950b20e89ab8db485746adaa12db545e892b871959ce394b8

Access the Keycloak Console

  1. The next step is to open a second SSH Tunnel. Right-click on the Virtual Desktop and select Open Terminal Here.

  2. Configure the SSH tunnel.

    ssh -L 8080:localhost:8080 oracle@<hostname or ip address>

    Note: In this example, the <hostname or ip address> is the hostname or IP address of the system running Keycloak . If hostname is used, the host must be resolvable. If using the free lab environment this will be the IP address for ol-server

    Example Output:

    [luna.user@lunabox Desktop]$ ssh -L 8080:localhost:8080 oracle@130.162.241.27
    Activate the web console with: systemctl enable --now cockpit.socket
    
    Last login: Wed Sep 28 10:29:42 2022 from 147.154.151.58
    [oracle@ol-server ~]$ 
  3. Open a new browser session (on the Virtual Desktop) and enter the URL.

    http://localhost:8080

    Example Output:

    keycloak-welcome

Login to the Keycloak Administration Console

  1. Click on the called Administration Console

    Example Output:

    keycloak-admin-login

  2. Enter the Administrator user's credentials, and click the Sign In button.

    • User name = admin
    • Password = admin

    The main page for the Keycloak Master Realm is displayed.

    Example Output:

    keycloak-admin-signin

Create a new Realm

Keycloak defines Realms as a space where objects, users, applications, roles and groups are managed. The Realms within a Keycloak deployment are administered from within the Keycloak Admin Console. Once logged in to the Keycloak Admin Console there are two types of realms:

  • Master Realm - This realm is created as part of the initial Keycloak deployment and contains details of the Administrator user created during the initial login. It is important that the master realm is only used to create and manage the other realms defined on the system. So the administrator user logs onto the master realm, and manages other realms within their organization from there.
  • Other Realms - These realms are created by the administrator from within the master realm. The administrator uses these realms to manage, and delineate, the creation of users within an organization and the applications used/required by those users. The realms created are isolated from each other and can only manage the users and applications assigned to any individual realm.

Further information about using, creating and managing realms can be located in the upstream Keycloak documentation.

For now, this lab will demonstrate setting up an example Realm and adding a new User to that realm.

  1. Click on the hamburger menu, then click the drop-down listbox showing Master. Now click on the Create Realm button.

    Example Output:

    create-realm

  2. The Create realm screen is displayed. Enter the value test in the Realm Name field, the press the Create button.

    Example Output:

    new-realm

  3. The newly created Realm's "Welcome" page is diplayed.

    Example Output:

    realm-created

Create a new User in the new Realm

  1. Click on the hamburger menu, and select Users

    Example Output:

    new-realm-user

  2. The Users screen is displayed. Click on the Create new user button.

    Example Output:

    realm-users-list

  3. The Create User screen is displayed. Enter the following details into these fields:

    • Username - user01
    • First Name - Foo
    • Last Name - Bar

    Click on the Create button.

    Example Output:

    create-user

  4. The new user's details are displayed.

    Example Output:

    new-user

  5. Click on the Credentials tab

    Example Output:

    credentials

  6. Click on the Set Password button. A dialogue box is displayed, etner the following details:

    • Password - user01
    • Password confirmation - user01
    • Temporary - Click to set to Off

    Important Note: An insecure password is used for illustrative purposes only. Production deployment would define secure password requirements as part of Keycloak administration.

    Example Output:

    set-password

  7. Click on the Save button, a confirmation dialogue box is dsplayed. Click on the Save Password button.

    Example Output:

    save-password

  8. A confirmation screen is displayed, confirming a password has been set.

    Example Output:

    password-set

Verify the New User is Setup Correctly

The next step is to to verify that the newly created user's details are correctly configured by logging in to the account console using the new user's credentials.

  1. (On Luna Desktop) Login to the Keycloak Account Console. Open a new tab on the browser and enter the URL:

    http://localhost:8080/realms/test/account

    Example Output:

    test-user-acc

  2. Click the Sign In button (top right-hand side of browser).

    Example Output:

    new-user-signin

  3. Enter the credentials for user01 previously defined:

    Username - user01 Password - user01

    Click on the Sign In button.

    Example Output:

    new-user-login

  4. The Welcome to Keycloak account management page is displayed.

    Example Output:

    new-user-welcome

(Optional) Confirm the Keycloak repository is stored within Postgres.

It can be confirmed that Keycloak has indeed created a schema within the Postgres container by returning to the previously opened browser tab on the Virtual Desktop's environment used to connect to PGAdmin

  1. Connect to PGAdmin as previously detailed (or reuse the existing open browser tab).

  2. Expand the tree in the left-hand panel (called Browser) by clicking on the icon called Servers, followed by Databases, keycloakDB, Schemas, public, Tables. This shows all of the Keycloak schema's tables which are used to record any changes made within the Keycloak Admin console.

    Example Output:

    pgadmin-keycloak-schema

Summary

This completes the demonstration detailing how to configure Podman to run a Keycloak container that stores it's data in a Postgres container which is also running in Podman.

For More Information

See other related resources:

SSR