<#import "/templates/guide.adoc" as tmpl> <#import "/templates/kc.adoc" as kc> <#import "/templates/options.adoc" as opts> <#import "/templates/links.adoc" as links> <#import "/templates/profile.adoc" as profile> <@tmpl.guide title="Basic Keycloak deployment" priority=20 summary="How to install Keycloak using the Operator"> == Performing a basic Keycloak deployment This {section} describes how to perform a basic Keycloak Deployment on <@profile.ifCommunity> Kubernetes or OpenShift using the Operator. === Preparing for deployment Once the Keycloak Operator is installed and running in the cluster namespace, you can set up the other deployment prerequisites. * Database * Hostname * TLS Certificate and associated keys ==== Database 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]. For development purposes, you can use an ephemeral PostgreSQL pod installation. To provision it, follow the approach below: Create YAML file `example-postgres.yaml`: [source,yaml] ---- 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 volumeMounts: - mountPath: /data name: cache-volume env: - name: POSTGRES_PASSWORD value: testpassword - name: PGDATA value: /data/pgdata - name: POSTGRES_DB value: keycloak volumes: - name: cache-volume emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: postgres-db spec: selector: app: postgresql-db type: LoadBalancer ports: - port: 5432 targetPort: 5432 ---- Apply the changes: [source,bash] ---- kubectl apply -f example-postgres.yaml ---- ==== Hostname 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. For development purposes, this {section} will use `test.keycloak.org`. When running on OpenShift, with ingress enabled, and with the spec.ingress.classname set to openshift-default, you may leave the spec.hostname.hostname unpopulated in the Keycloak CR. The operator will assign a default hostname to the stored version of the CR similar to what would be created by an OpenShift Route without an explicit host - that is ingress-namespace.appsDomain If the appsDomain changes, or should you need a different hostname for any reason, then update the Keycloak CR. ==== TLS Certificate and key See your Certification Authority to obtain the certificate and the key. For development purposes, you can enter this command to obtain a self-signed certificate: [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 ---- You should install it in the cluster namespace as a Secret by entering this command: [source,bash] ---- kubectl create secret tls example-tls-secret --cert certificate.pem --key key.pem ---- === Deploying Keycloak To deploy Keycloak, you create a Custom Resource (CR) based on the Keycloak Custom Resource Definition (CRD). Consider storing the Database credentials in a separate Secret. Enter the following commands: [source,bash] ---- kubectl create secret generic keycloak-db-secret \ --from-literal=username=[your_database_username] \ --from-literal=password=[your_database_password] ---- You can customize several fields using the Keycloak CRD. For a basic deployment, you can stick to the following approach: Create YAML file `example-kc.yaml`: [source,yaml] ---- apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: instances: 1 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 ---- Apply the changes: [source,bash] ---- kubectl apply -f example-kc.yaml ---- To check that the Keycloak instance has been provisioned in the cluster, check the status of the created CR by entering the following command: [source,bash] ---- kubectl get keycloaks/example-kc -o go-template='{{range .status.conditions}}CONDITION: {{.type}}{{"\n"}} STATUS: {{.status}}{{"\n"}} MESSAGE: {{.message}}{{"\n"}}{{end}}' ---- When the deployment is ready, look for output similar to the following: [source,bash] ---- CONDITION: Ready STATUS: true MESSAGE: CONDITION: HasErrors STATUS: false MESSAGE: CONDITION: RollingUpdate STATUS: false MESSAGE: ---- === Accessing the Keycloak deployment 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 ---- If the default ingress does not fit your use case, disable it by setting `ingress` spec with `enabled` property to `false` value: Edit YAML file `example-kc.yaml`: [source,yaml] ---- apiVersion: k8s.keycloak.org/v2alpha1 kind: Keycloak metadata: name: example-kc spec: ... ingress: enabled: false ---- Apply the changes: [source,bash] ---- kubectl apply -f example-kc.yaml ---- You can provide an alternative ingress resource pointing to the service `-service`. For debugging and development purposes, consider directly connecting to the Keycloak service using a port forward. For example, enter this command: [source,bash] ---- kubectl port-forward service/example-kc-service 8443:8443 ---- === Accessing the Admin Console When deploying Keycloak, the operator generates an arbitrary initial admin `username` and `password` and stores those credentials as a basic-auth Secret object in the same namespace as the CR. [WARNING] ==== Change the default admin credentials and enable MFA in Keycloak before going to production. ==== To fetch the initial admin credentials, you have to read and decode the Secret. The Secret name is derived from the Keycloak CR name plus the fixed suffix `-initial-admin`. To get the username and password for the `example-kc` CR, enter the following commands: [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.