In this blog, we will se how we can deploy Keycloak with Postgres database on kubernetes here, Postgres database is to persist keycloak data. Without Postgres Keycloak will use it’s internal embedded databse H2.
Keycloak is an open-source Identity and Access management application. It can be used for authentication applications and it has many providers like google to provide sign-in from your google account. It has many security services like SSO, Social logins, Identity brokering, LDAP & active directory, and much more.
Read more about Keycloak from here.
Scope – Keycloak with Postgres
We will deploy Keycloak with the Postgresql database to persist data. We will deploy all workloads on Google Kubernetes Engine.
Prerequisites – Keycloak with Postgres
- GCP project with enabled billing
- Kubernetes cluster
- Basic Knowledge of Postgresql Learn about Postgres from here
- Basic Knowledge of Keycloak Learn about Keycloak from here
Deploy Postgresql YAMLs
Create 2 directories postgres/ & keycloak/ and place yaml files in these directories then deploy the workloads on cluster.
1. Create storageclass for dynamic storage provisioning
postgres/storageclass.yml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: postgres-sc
parameters:
type: pd-standard
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
2. Create secrets for postgres database
postgres/postgres-secrets.yml
apiVersion: v1
kind: Secret
metadata:
name: postgres-sec
type: Opaque
data:
POSTGRES_PASSWORD: YWRtaW4K
POSTGRES_USER: YWRtaW4K
3. Create statefulset and service for postgres database
postgres/postgres-statefulset.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: postgres
name: postgres
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: postgres
serviceName: postgres-svc
template:
metadata:
labels:
app: postgres
spec:
containers:
- env:
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
key: POSTGRES_USER
name: postgres-sec
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
key: POSTGRES_PASSWORD
name: postgres-sec
- name: POSTGRES_DB
value: keycloak
image: postgres:12.4-alpine
imagePullPolicy: IfNotPresent
name: postgres
ports:
- containerPort: 5432
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-pvc
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
updateStrategy:
rollingUpdate:
partition: 0
type: RollingUpdate
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
labels:
app: postgres
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: postgres-sc
---
apiVersion: v1
kind: Service
metadata:
name: postgres-svc
spec:
ports:
- port: 5432
protocol: TCP
targetPort: 5432
selector:
app: postgres
4. Deploy on GKE
Check directory structure
tree postgres
output will look like this.
postgres/
├── postgres-secrets.yml
├── postgres-statefulset.yml
└── storageclass.yml
0 directories, 3 files
Deploy all yaml files
kubectl apply -f storageclass.yml
kubectl apply -f postgres-secrets.yml
kubectl apply -f postgres-statefulset.yml
Deploy Keycloak YAMLs
1. Create secrets for Keycloak
keycloak/keycloak-secrets.yml
apiVersion: v1
kind: Secret
metadata:
name: keycloak-secrets
type: Opaque
data:
KEYCLOAK_ADMIN: YWRtaW4K
KEYCLOAK_ADMIN_PASSWORD: YWRtaW4K
2. Create statefulset and service for Keycloak
keycloak/keycloak-statefulset.yml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: keyclaok
name: keycloak
spec:
podManagementPolicy: Parallel
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: keycloak
serviceName: keycloak-headless
template:
metadata:
labels:
app: keycloak
spec:
containers:
- env:
- name: KEYCLOAK_ADMIN
valueFrom:
secretKeyRef:
key: KEYCLOAK_ADMIN
name: keycloak-secrets
- name: KEYCLOAK_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
key: KEYCLOAK_ADMIN_PASSWORD
name: keycloak-secrets
- name: DB_VENDOR
value: postgres
- name: DB_ADDR
value: postgres-svc
- name: DB_PORT
value: "5432"
- name: DB_DATABASE
value: keycloak
- name: DB_SCHEMA
value: public
- name: DB_USER
valueFrom:
secretKeyRef:
key: POSTGRES_USER
name: postgres-sec
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
key: POSTGRES_PASSWORD
name: postgres-sec
image: quay.io/keycloak/keycloak:17.0.0
args: ["start-dev"]
imagePullPolicy: IfNotPresent
name: keycloak
ports:
- containerPort: 8080
name: http
protocol: TCP
- containerPort: 8443
name: https
protocol: TCP
resources: {}
securityContext:
runAsNonRoot: true
runAsUser: 1000
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
terminationGracePeriodSeconds: 60
updateStrategy:
type: RollingUpdate
---
apiVersion: v1
kind: Service
metadata:
name: keycloak
labels:
app: keycloak
spec:
ports:
- name: http
port: 8080
targetPort: 8080
selector:
app: keycloak
type: LoadBalancer
3. Deploy Keycloak on Kubernetes
Check directory structure
tree keycloak/
Output will look like this.
├── keycloak-sec.yml
├── keycloak-service.yml
└── keycloak-statefulset.yml
0 directories, 3 files
Deploy the workloads on kubernetes
kubectl apply -f keycloak-sec.yml
kubectl apply -f keycloak-service.yml
kubectl apply -f keycloak-statefulset.yml
4. Keycloak URL
Run the below command to see external-IP of Keycloak
echo "Keycloak_URL http://$(kubectl get svc keycloak -o go-template='{{(index .status.loadBalancer.ingress 0).ip}}'):8080"
conclusion
So we successfully deployed Keycloak on kubernetes. If you want to migrate form H2 database to postgres database to persist all data.
Refer this blog link.