keycloak-scim/server_installation/topics/operator/external-database.adoc
2021-12-01 16:46:30 +01:00

159 lines
5.8 KiB
Text

[[_external_database]]
=== Connecting to an external database
You can use the Operator to connect to an external PostgreSQL database by creating a `keycloak-db-secret` YAML file and setting Keycloak CR externalDatabase property to enabled. Note that values are Base64 encoded.
.Example YAML file for `keycloak-db-secret`
```yaml
apiVersion: v1
kind: Secret
metadata:
name: keycloak-db-secret
namespace: keycloak
stringData:
POSTGRES_DATABASE: <Database Name>
POSTGRES_EXTERNAL_ADDRESS: <External Database IP or URL (resolvable by K8s)>
POSTGRES_EXTERNAL_PORT: <External Database Port>
POSTGRES_PASSWORD: <Database Password>
# Required for AWS Backup functionality
POSTGRES_SUPERUSER: "true"
POSTGRES_USERNAME: <Database Username>
SSLMODE: <TLS configuration for the Database connection>
type: Opaque
```
The following properties set the hostname or IP address and port of the database.
* `POSTGRES_EXTERNAL_ADDRESS` - an IP address or a hostname of the external database.
ifeval::[{project_community}==true]
This address needs be resolvable in a Kubernetes cluster.
endif::[]
* `POSTGRES_EXTERNAL_PORT` - (Optional) A database port.
The other properties work in the same way for a hosted or external database. Set them as follows:
* `POSTGRES_DATABASE` - Database name to be used.
* `POSTGRES_USERNAME` - Database username
* `POSTGRES_PASSWORD` - Database password
* `POSTGRES_SUPERUSER` - Indicates whether backups should run as super user. Typically `true`.
* `SSL_MODE` - Indicates whether to use TLS on the connection to the external PostgreSQL database. Check the possible https://www.postgresql.org/docs/current/libpq-ssl.html[values]
When `SSL_MODE` is enabled, the operator searches for a secret called `keycloak-db-ssl-cert-secret` containing the `root.crt` that has been used by the PostgreSQL database. Creating the secret is optional and the secret is used only when you want to verify the Database's certificate (for example `SSLMODE: verify-ca`). Here is an example :
.Example YAML file for `TLS Secret` to be used by the operator.
```yaml
apiVersion: v1
kind: Secret
metadata:
name: keycloak-db-ssl-cert-secret
namespace: keycloak
type: Opaque
data:
root.crt: {root.crt base64}
```
The Operator will create a Service named `keycloak-postgresql`. This Service is configured by the Operator to expose the external database based on the content of `POSTGRES_EXTERNAL_ADDRESS`. {project_name} uses this Service to connect to the Database, which means it does not connect to the Database directly but rather through this Service.
The Keycloak custom resource requires updates to enable external database support.
.Example YAML file for `Keycloak` custom resource that supports an external database
```yaml
apiVersion: keycloak.org/v1alpha1
kind: Keycloak
metadata:
labels:
ifeval::[{project_community}==true]
app: example-keycloak
endif::[]
ifeval::[{project_product}==true]
app: sso
endif::[]
name: example-keycloak
namespace: keycloak
spec:
externalDatabase:
enabled: true
instances: 1
```
.Prerequisites
* You have a YAML file for `keycloak-db-secret`.
* You have modified the Keycloak custom resource to set `externalDatabase` to `true`.
* You have cluster-admin permission or an equivalent level of permissions granted by an administrator.
.Procedure
. Locate the secret for your PostgreSQL database: `{create_cmd_brief} get secret <secret_for_db> -o yaml`. For example:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get secret keycloak-db-secret -o yaml
apiVersion: v1
data
POSTGRES_DATABASE: cm9vdA==
POSTGRES_EXTERNAL_ADDRESS: MTcyLjE3LjAuMw==
POSTGRES_EXTERNAL_PORT: NTQzMg==
----
+
The `POSTGRES_EXTERNAL_ADDRESS` is in Base64 format.
. Decode the value for the secret: `echo "<encoded_secret>" | base64 -decode`. For example:
+
[source,bash,subs=+attributes]
----
$ echo "MTcyLjE3LjAuMw==" | base64 -decode
192.0.2.3
----
. Confirm that the decoded value matches the IP address for your database:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get pods -o wide
NAME READY STATUS RESTARTS AGE IP
keycloak-0 1/1 Running 0 13m 192.0.2.0
keycloak-postgresql-c8vv27m 1/1 Running 0 24m 192.0.2.3
----
. Confirm that `keycloak-postgresql` appears in a list of running services:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
keycloak ClusterIP 203.0.113.0 <none> 8443/TCP 27m
keycloak-discovery ClusterIP None <none> 8080/TCP 27m
keycloak-postgresql ClusterIP 203.0.113.1 <none> 5432/TCP 27m
----
+
The `keycloak-postgresql` service sends requests to a set of IP addresses in the backend. These IP addresses are called endpoints.
. View the endpoints used by the `keycloak-postgresql` service to confirm that they use the IP addresses for your database:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get endpoints keycloak-postgresql
NAME ENDPOINTS AGE
keycloak-postgresql 192.0.2.3.5432 27m
----
. Confirm that {project_name} is running with the external database. This example shows that everything is running:
+
[source,bash,subs=+attributes]
----
$ {create_cmd_brief} get pods
NAME READY STATUS RESTARTS AGE IP
keycloak-0 1/1 Running 0 26m 192.0.2.0
keycloak-postgresql-c8vv27m 1/1 Running 0 36m 192.0.2.3
----
ifeval::[{project_community}==true]
.Additional Resources
* To back up your database using custom resources, see xref:_backup-cr[Scheduling database backups].
* For more information on Base64 encoding, see the https://kubernetes.io/docs/concepts/configuration/secret/[Kubernetes Secrets manual].
endif::[]