2022-03-31 11:55:45 +00:00
<#import "/templates/guide.adoc" as tmpl>
<#import "/templates/kc.adoc" as kc>
<#import "/templates/options.adoc" as opts>
<#import "/templates/links.adoc" as links>
<@tmpl.guide
2023-03-01 15:24:36 +00:00
title="Basic Keycloak deployment"
2022-04-20 08:24:40 +00:00
priority=20
2022-03-31 11:55:45 +00:00
summary="How to install Keycloak using the Operator on Kubernetes or OpenShift">
2023-03-01 15:24:36 +00:00
== Performing a basic Keycloak deployment
2023-05-04 09:04:44 +00:00
This {section} describes how to perform a basic Keycloak Deployment on Kubernetes or OpenShift using the Operator.
2022-03-31 11:55:45 +00:00
2023-03-01 15:24:36 +00:00
=== Preparing for deployment
Once the Keycloak Operator is installed and running in the cluster namespace, you can set up the other deployment prerequisites.
2022-03-31 11:55:45 +00:00
* Database
* Hostname
* TLS Certificate and associated keys
==== Database
2023-03-01 15:24:36 +00:00
A database should be available and accessible from the cluster namespace where Keycloak is installed.
For a list of supported databases, see <@links.server id="db"/>.
The Keycloak Operator does not manage the database and you need to provision it yourself. Consider verifying your cloud provider offering or using a database operator such as https://access.crunchydata.com/documentation/postgres-operator/latest/[Crunchy].
2022-03-31 11:55:45 +00:00
2023-05-17 15:34:32 +00:00
For development purposes, you can use an ephemeral PostgreSQL pod installation. To provision it, follow the approach below:
2022-03-31 11:55:45 +00:00
2023-05-17 15:34:32 +00:00
Create YAML file `example-postgres.yaml`:
[source,yaml]
2022-03-31 11:55:45 +00:00
----
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: postgresql-db
spec:
serviceName: postgresql-db-service
selector:
matchLabels:
app: postgresql-db
replicas: 1
template:
metadata:
labels:
app: postgresql-db
spec:
containers:
- name: postgresql-db
image: postgres:latest
2023-04-21 12:36:41 +00:00
volumeMounts:
- mountPath: /data
name: cache-volume
2022-03-31 11:55:45 +00:00
env:
- name: POSTGRES_PASSWORD
value: testpassword
- name: PGDATA
value: /data/pgdata
- name: POSTGRES_DB
value: keycloak
2023-04-21 12:36:41 +00:00
volumes:
- name: cache-volume
emptyDir: {}
2022-03-31 11:55:45 +00:00
---
apiVersion: v1
kind: Service
metadata:
name: postgres-db
spec:
selector:
app: postgresql-db
type: LoadBalancer
ports:
- port: 5432
targetPort: 5432
2023-05-17 15:34:32 +00:00
----
Apply the changes:
[source,bash]
----
2022-04-13 10:50:25 +00:00
kubectl apply -f example-postgres.yaml
2022-03-31 11:55:45 +00:00
----
==== Hostname
2023-03-01 15:24:36 +00:00
For a production ready installation, you need a hostname that can be used to contact Keycloak.
See <@links.server id="hostname"/> for the available configurations.
2022-03-31 11:55:45 +00:00
2023-05-04 09:04:44 +00:00
For development purposes, this {section} will use `test.keycloak.org`.
2022-03-31 11:55:45 +00:00
==== TLS Certificate and key
2023-03-01 15:24:36 +00:00
See your Certification Authority to obtain the certificate and the key.
2022-03-31 11:55:45 +00:00
2023-03-01 15:24:36 +00:00
For development purposes, you can enter this command to obtain a self-signed certificate:
2022-03-31 11:55:45 +00:00
[source,bash]
----
openssl req -subj '/CN=test.keycloak.org/O=Test Keycloak./C=US' -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
----
2023-03-01 15:24:36 +00:00
You should install it in the cluster namespace as a Secret by entering this command:
2022-03-31 11:55:45 +00:00
[source,bash]
----
kubectl create secret tls example-tls-secret --cert certificate.pem --key key.pem
----
=== Deploying Keycloak
2023-03-01 15:24:36 +00:00
To deploy Keycloak, you create a Custom Resource (CR) based on the Keycloak Custom Resource Definition (CRD).
2022-03-31 11:55:45 +00:00
2023-03-01 15:24:36 +00:00
Consider storing the Database credentials in a separate Secret. Enter the following commands:
2022-03-31 11:55:45 +00:00
[source,bash]
----
kubectl create secret generic keycloak-db-secret \
--from-literal=username=[your_database_username] \
--from-literal=password=[your_database_password]
----
2023-05-17 15:34:32 +00:00
You can customize several fields using the Keycloak CRD. For a basic deployment, you can stick to the following approach:
2022-03-31 11:55:45 +00:00
2023-05-17 15:34:32 +00:00
Create YAML file `example-kc.yaml`:
[source,yaml]
2022-03-31 11:55:45 +00:00
----
2022-04-11 12:48:21 +00:00
apiVersion: k8s.keycloak.org/v2alpha1
2022-03-31 11:55:45 +00:00
kind: Keycloak
metadata:
name: example-kc
spec:
instances: 1
2022-10-21 14:42:42 +00:00
db:
vendor: postgres
host: postgres-db
usernameSecret:
name: keycloak-db-secret
key: username
passwordSecret:
name: keycloak-db-secret
key: password
http:
tlsSecret: example-tls-secret
hostname:
hostname: test.keycloak.org
2023-05-17 15:34:32 +00:00
----
Apply the changes:
[source,bash]
----
2022-04-13 10:50:25 +00:00
kubectl apply -f example-kc.yaml
2022-03-31 11:55:45 +00:00
----
2023-03-01 15:24:36 +00:00
To check that the Keycloak instance has been provisioned in the cluster, check the status of the created CR by entering the following command:
2022-03-31 11:55:45 +00:00
[source,bash]
----
kubectl get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}'
----
2023-03-01 15:24:36 +00:00
When the deployment is ready, look for output similar to the following:
2022-03-31 11:55:45 +00:00
[source,bash]
----
CONDITION: Ready
STATUS: true
2023-03-01 15:24:36 +00:00
MESSAGE:
2022-03-31 11:55:45 +00:00
CONDITION: HasErrors
STATUS: false
2023-03-01 15:24:36 +00:00
MESSAGE:
2022-03-31 11:55:45 +00:00
CONDITION: RollingUpdate
STATUS: false
MESSAGE:
----
2023-03-01 15:24:36 +00:00
=== Accessing the Keycloak deployment
2022-03-31 11:55:45 +00:00
2023-06-05 21:10:39 +00:00
The Keycloak deployment is exposed through a basic Ingress and is accessible through the provided hostname. On installations with multiple default IngressClass instances
or when running on OpenShift 4.12+ you should provide an ingressClassName by setting `ingress` spec with `className` property to the desired class name:
Edit YAML file `example-kc.yaml`:
[source,yaml]
----
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
ingress:
className: openshift-default
----
2023-03-01 15:24:36 +00:00
If the default ingress does not fit your use case, disable it by setting `ingress` spec with `enabled` property to `false` value:
2022-04-27 08:54:33 +00:00
2023-05-17 15:34:32 +00:00
Edit YAML file `example-kc.yaml`:
[source,yaml]
2022-04-27 08:54:33 +00:00
----
apiVersion: k8s.keycloak.org/v2alpha1
kind: Keycloak
metadata:
name: example-kc
spec:
...
2022-10-15 19:14:58 +00:00
ingress:
enabled: false
2023-05-17 15:34:32 +00:00
----
Apply the changes:
[source,bash]
----
2022-04-27 08:54:33 +00:00
kubectl apply -f example-kc.yaml
----
2023-03-01 15:24:36 +00:00
You can provide an alternative ingress resource pointing to the service `<keycloak-cr-name>-service`.
2022-03-31 11:55:45 +00:00
2023-03-01 15:24:36 +00:00
For debugging and development purposes, consider directly connecting to the Keycloak service using a port forward. For example, enter this command:
2022-03-31 11:55:45 +00:00
[source,bash]
----
kubectl port-forward service/example-kc-service 8443:8443
----
2023-03-01 15:24:36 +00:00
=== Accessing the Admin Console
2022-04-08 09:57:22 +00:00
When deploying Keycloak, the operator generates an arbitrary initial admin `username` and `password` and stores those credentials as a Kubernetes basic-auth Secret in the same namespace as the CR.
2023-03-01 15:24:36 +00:00
[WARNING]
====
2022-04-08 09:57:22 +00:00
Change the default admin credentials and enable MFA in Keycloak before going to production.
2023-03-01 15:24:36 +00:00
====
2022-04-08 09:57:22 +00:00
2023-03-01 15:24:36 +00:00
To fetch the initial admin credentials, you have to read and decode a Kubernetes Secret.
2022-04-08 09:57:22 +00:00
The Secret name is derived from the Keycloak CR name plus the fixed suffix `-initial-admin`.
2023-03-01 15:24:36 +00:00
To get the username and password for the `example-kc` CR, enter the following commands:
2022-04-08 09:57:22 +00:00
[source,bash]
----
kubectl get secret example-kc-initial-admin -o jsonpath='{.data.username}' | base64 --decode
kubectl get secret example-kc-initial-admin -o jsonpath='{.data.password}' | base64 --decode
----
You can use those credentials to access the Admin Console or the Admin REST API.
2022-03-31 11:55:45 +00:00
</@tmpl.guide>