Bootstrap FreeKB - OpenShift - Getting Started with Keycloak
OpenShift - Getting Started with Keycloak

Updated:   |  OpenShift articles

The oc new-project command can be used to create an isolated project/namespace for keycloak.

oc new-project keycloak

 

Let's create a YAML file that contains the following. To be able to access the Keycloak admin console (more on that in a moment), I had to include the KC_PROXY_HEADERS xfowarded variable. It's also import to recongize that in this example, I'm using the quay.io/keycloak/keycloak:26.0.0 image, meaning I'm deploying Keycloak version 26. This YAML may be slightly different for different versions of Keycloak.

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: keycloak
  name: keycloak
  namespace: keycloak
spec:
  replicas: 1
  selector:
    matchLabels:
      app: keycloak
  template:
    metadata:
      labels:
        app: keycloak
      name: keycloak
    spec:
      containers:
      - args:
        - start-dev
        env:
        - name: KC_BOOTSTRAP_ADMIN_USERNAME
          value: admin
        - name: KC_BOOTSTRAP_ADMIN_PASSWORD
          value: itsasecret
        - name: KC_PROXY_HEADERS
          value: xforwarded
        image: quay.io/keycloak/keycloak:26.0.0
        name: keycloak
        ports:
        - containerPort: 8080
          protocol: TCP
        volumeMounts:
        - mountPath: /opt/keycloak/data
          name: empty
      volumes:
      - emptyDir: {}
        name: empty

 

Or you could create a deployment config instead of a deployment, but deployment configs are deprecated.

apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
  labels:
    app: keycloak
  name: keycloak
  namespace: keycloak
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    deploymentConfig: keycloak
  strategy:
    activeDeadlineSeconds: 21600
    recreateParams:
      timeoutSeconds: 600
    resources: {}
    type: Recreate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: keycloak
        deploymentConfig: keycloak
      name: keycloak
    spec:
      containers:
      - args:
        - start-dev
        env:
        - name: KC_BOOTSTRAP_ADMIN_USERNAME
          value: admin
        - name: KC_BOOTSTRAP_ADMIN_PASSWORD
          value: itsasecret
        - name: KC_PROXY_HEADERS
          value: xforwarded
        image: quay.io/keycloak/keycloak:26.0.0
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 100
          httpGet:
            path: /
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: keycloak
        ports:
        - containerPort: 8080
          protocol: TCP
        readinessProbe:
          failureThreshold: 300
          httpGet:
            path: /
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        securityContext:
          privileged: false
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /opt/keycloak/data
          name: empty
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - emptyDir: {}
        name: empty
  test: false
  triggers:
  - type: ConfigChange

 

And then the oc apply command can be used to create the deployment config, replica set, and pods. Or if you create a deployment config, this will instead create a deployment config, replication controller, and pods.

oc apply --filename deployment.yaml

 

And then the oc get all command can be used to see the resource that have been created.

~]$ oc get all --namespace keycloak
NAME                          READY   STATUS    RESTARTS   AGE
pod/keycloak-c857bfb4-nhkbv   1/1     Running   0          10m

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/keycloak   1/1     1            1           10m

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/keycloak-c857bfb4   1         1         1       10m

 

The pod logs should return something like this.

~]$ oc logs keycloak-c857bfb4-nhkbv --namespace keycloak
2024-10-23 01:50:09,998 INFO  [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 3325ms
2024-10-23 01:50:11,878 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Starting Infinispan embedded cache manager
2024-10-23 01:50:11,952 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Persistent user sessions enabled and no memory limit found in configuration. Setting max entries for sessions to 10000 entries.
2024-10-23 01:50:11,952 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Persistent user sessions enabled and no memory limit found in configuration. Setting max entries for clientSessions to 10000 entries.
2024-10-23 01:50:11,952 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Persistent user sessions enabled and no memory limit found in configuration. Setting max entries for offlineSessions to 10000 entries.
2024-10-23 01:50:11,953 INFO  [org.keycloak.quarkus.runtime.storage.infinispan.CacheManagerFactory] (main) Persistent user sessions enabled and no memory limit found in configuration. Setting max entries for offlineClientSessions to 10000 entries.
2024-10-23 01:50:12,158 INFO  [org.infinispan.CONTAINER] (ForkJoinPool.commonPool-worker-1) ISPN000556: Starting user marshaller 'org.infinispan.commons.marshall.ImmutableProtoStreamMarshaller'
2024-10-23 01:50:12,584 INFO  [org.keycloak.connections.infinispan.DefaultInfinispanConnectionProviderFactory] (main) Node name: node_355364, Site name: null
2024-10-23 01:50:13,040 INFO  [org.keycloak.quarkus.runtime.storage.database.liquibase.QuarkusJpaUpdaterProvider] (main) Initializing database schema. Using changelog META-INF/jpa-changelog-master.xml

UPDATE SUMMARY
Run:                        144
Previously run:               0
Filtered out:                 0
-------------------------------
Total change sets:          144

2024-10-23 01:50:14,395 WARN  [io.agroal.pool] (main) Datasource '<default>': JDBC resources leaked: 1 ResultSet(s) and 0 Statement(s)
2024-10-23 01:50:14,673 INFO  [org.keycloak.broker.provider.AbstractIdentityProviderMapper] (main) Registering class org.keycloak.broker.provider.mappersync.ConfigSyncEventListener
2024-10-23 01:50:14,726 INFO  [org.keycloak.services] (main) KC-SERVICES0050: Initializing master realm
2024-10-23 01:50:15,746 INFO  [org.keycloak.services] (main) KC-SERVICES0077: Created temporary admin user with username admin
2024-10-23 01:50:15,765 WARN  [io.agroal.pool] (main) Datasource '<default>': JDBC resources leaked: 1 ResultSet(s) and 0 Statement(s)
2024-10-23 01:50:15,836 INFO  [io.quarkus] (main) Keycloak 26.0.0 on JVM (powered by Quarkus 3.15.1) started in 5.722s. Listening on: http://0.0.0.0:8080
2024-10-23 01:50:15,837 INFO  [io.quarkus] (main) Profile dev activated.
2024-10-23 01:50:15,837 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, hibernate-orm, jdbc-h2, keycloak, narayana-jta, opentelemetry, reactive-routes, rest, rest-jackson, smallrye-context-propagation, vertx]
2024-10-23 01:50:15,841 WARN  [org.keycloak.quarkus.runtime.KeycloakMain] (main) Running the server in development mode. DO NOT use this configuration in production.

 

The env or printenv command can then be run in the pod to ensure the pod contains the KC_BOOTSTRAP_ADMIN_USERNAME and KC_BOOTSTRAP_ADMIN_PASSWORD variables.

[c065234@DLOCPLJ-1-0001 ~]$ oc exec pod/keycloak-c857bfb4-nhkbv --namespace keycloak -- env
KC_BOOTSTRAP_ADMIN_USERNAME=admin
KC_BOOTSTRAP_ADMIN_PASSWORD=itsasecret
KC_PROXY_HEADERS=xforwarded

 

Keycloak Service

Next let's create a file named keycloak_service.yml that contains the following YAML.

apiVersion: v1
kind: Service
metadata:
  name: keycloak
  namespace: keycloak
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: keycloak
  sessionAffinity: None
  type: ClusterIP  

 

And then the oc apply command can be used to create the service.

oc apply --filename service.yaml

 

And the oc describe command should show that the service Endpoint is pointing to the IP address and port of the keycloak pod.

~]$ oc describe service --namespace keycloak
Name:              keycloak
Namespace:         keycloak
Labels:            <none>
Annotations:       <none>
Selector:          app=keycloak
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                172.30.245.108
IPs:               172.30.245.108
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         10.128.3.72:8080
Session Affinity:  None
Events:            <none>

 

Keycloak Route

Next let's create a file named keycloak_route.yml that contains the following YAML, replacing "keycloak.apps.openshift.example.com" with the URL you want to use for your keycloak route.

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: keycloak
    route-type: internal
  name: keycloak
  namespace: keycloak
spec:
  host: keycloak.apps.openshift.example.com
  tls:
    termination: edge
  to:
    kind: Service
    name: keycloak
    weight: 100
  wildcardPolicy: None

 

And then the oc apply command can be used to create the route.

oc apply --filename route.yaml

 

And the oc describe command should show that the route is exposed on one of the OpenShift routes and is forwarding onto the keycloak service, which is turns forwards onto the keycloak pod. Notice in this example that the route HOST/PORT is keycloak-keycloak.apps.openshift.example.com.

~]$ oc describe route keycloak --namespace keycloak
Name:                   keycloak
Namespace:              keycloak
Created:                7 days ago
Labels:                 app=keycloak
                        route-type=default
Description:            Route for application's service.
Annotations:            openshift.io/host.generated=true
Requested Host:         keycloak.apps.openshift.example.com
                           exposed on router default-router (host router-default-router.apps.openshift.example.com) 1 minute ago
Path:                   <none>
TLS Termination:        edge
Insecure Policy:        <none>
Endpoint Port:          <all endpoint ports>

Service:        keycloak
Weight:         100 (100%)
Endpoints:      <none>

 

Now you can go to the URL of your route and if all goes according to plan, you should be presented with the admin console sign in page. Awesome! You should be able to sign into the console using the admin username and password, which is admin and itsasecret in this example.

 

Once signed into the console, you should see something like this.

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter e2697a in the box below so that we can be sure you are a human.