From 7b4a189fe4e4a5b080753d75efc4ae9c4848f3fb Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Tue, 2 Dec 2025 17:46:52 -0300 Subject: [PATCH] keycloak: add raw manifests backed by shared postgres --- services/keycloak/README.md | 27 +++++++++ services/keycloak/deployment.yaml | 89 ++++++++++++++++++++++++++++ services/keycloak/ingress.yaml | 24 ++++++++ services/keycloak/kustomization.yaml | 10 ++++ services/keycloak/namespace.yaml | 5 ++ services/keycloak/pvc.yaml | 12 ++++ services/keycloak/service.yaml | 15 +++++ 7 files changed, 182 insertions(+) create mode 100644 services/keycloak/README.md create mode 100644 services/keycloak/deployment.yaml create mode 100644 services/keycloak/ingress.yaml create mode 100644 services/keycloak/kustomization.yaml create mode 100644 services/keycloak/namespace.yaml create mode 100644 services/keycloak/pvc.yaml create mode 100644 services/keycloak/service.yaml diff --git a/services/keycloak/README.md b/services/keycloak/README.md new file mode 100644 index 0000000..bf7c21b --- /dev/null +++ b/services/keycloak/README.md @@ -0,0 +1,27 @@ +# services/keycloak + +Keycloak is deployed via raw manifests and backed by the shared Postgres (`postgres-service.postgres.svc.cluster.local:5432`). Create these secrets before applying: + +```bash +# DB creds (per-service DB/user in shared Postgres) +kubectl -n sso create secret generic keycloak-db \ + --from-literal=username=keycloak \ + --from-literal=password='' \ + --from-literal=database=keycloak + +# Admin console creds (maps to KC admin user) +kubectl -n sso create secret generic keycloak-admin \ + --from-literal=username=brad@bstein.dev \ + --from-literal=password='' +``` + +Apply: + +```bash +kubectl apply -k services/keycloak +``` + +Notes +- Service: `keycloak.sso.svc:80` (Ingress `sso.bstein.dev`, TLS via cert-manager). +- Uses Postgres schema `public`; DB/user should be provisioned in the shared Postgres instance. +- Health endpoints on :9000 are wired for probes. diff --git a/services/keycloak/deployment.yaml b/services/keycloak/deployment.yaml new file mode 100644 index 0000000..fb70b40 --- /dev/null +++ b/services/keycloak/deployment.yaml @@ -0,0 +1,89 @@ +# services/keycloak/deployment.yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: keycloak + namespace: sso + labels: + app: keycloak +spec: + replicas: 1 + selector: + matchLabels: + app: keycloak + template: + metadata: + labels: + app: keycloak + spec: + containers: + - name: keycloak + image: quay.io/keycloak/keycloak:26.0.7 + imagePullPolicy: IfNotPresent + args: + - start + - --optimized + env: + - name: KC_DB + value: postgres + - name: KC_DB_URL_HOST + value: postgres-service.postgres.svc.cluster.local + - name: KC_DB_URL_DATABASE + valueFrom: + secretKeyRef: + name: keycloak-db + key: database + - name: KC_DB_USERNAME + valueFrom: + secretKeyRef: + name: keycloak-db + key: username + - name: KC_DB_PASSWORD + valueFrom: + secretKeyRef: + name: keycloak-db + key: password + - name: KC_DB_SCHEMA + value: public + - name: KC_HOSTNAME + value: sso.bstein.dev + - name: KC_PROXY + value: edge + - name: KC_HTTP_ENABLED + value: "true" + - name: KEYCLOAK_ADMIN + valueFrom: + secretKeyRef: + name: keycloak-admin + key: username + - name: KEYCLOAK_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: keycloak-admin + key: password + ports: + - containerPort: 8080 + name: http + - containerPort: 9000 + name: metrics + readinessProbe: + httpGet: + path: /health/ready + port: 9000 + initialDelaySeconds: 15 + periodSeconds: 10 + failureThreshold: 6 + livenessProbe: + httpGet: + path: /health/live + port: 9000 + initialDelaySeconds: 60 + periodSeconds: 15 + failureThreshold: 6 + volumeMounts: + - name: data + mountPath: /opt/keycloak/data + volumes: + - name: data + persistentVolumeClaim: + claimName: keycloak-data diff --git a/services/keycloak/ingress.yaml b/services/keycloak/ingress.yaml new file mode 100644 index 0000000..39f6cb0 --- /dev/null +++ b/services/keycloak/ingress.yaml @@ -0,0 +1,24 @@ +# services/keycloak/ingress.yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: keycloak + namespace: sso + annotations: + cert-manager.io/cluster-issuer: letsencrypt +spec: + ingressClassName: traefik + rules: + - host: sso.bstein.dev + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: keycloak + port: + number: 80 + tls: + - hosts: [sso.bstein.dev] + secretName: keycloak-tls diff --git a/services/keycloak/kustomization.yaml b/services/keycloak/kustomization.yaml new file mode 100644 index 0000000..a65715c --- /dev/null +++ b/services/keycloak/kustomization.yaml @@ -0,0 +1,10 @@ +# services/keycloak/kustomization.yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: sso +resources: + - namespace.yaml + - pvc.yaml + - deployment.yaml + - service.yaml + - ingress.yaml diff --git a/services/keycloak/namespace.yaml b/services/keycloak/namespace.yaml new file mode 100644 index 0000000..b4c731d --- /dev/null +++ b/services/keycloak/namespace.yaml @@ -0,0 +1,5 @@ +# services/keycloak/namespace.yaml +apiVersion: v1 +kind: Namespace +metadata: + name: sso diff --git a/services/keycloak/pvc.yaml b/services/keycloak/pvc.yaml new file mode 100644 index 0000000..b57ec61 --- /dev/null +++ b/services/keycloak/pvc.yaml @@ -0,0 +1,12 @@ +# services/keycloak/pvc.yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: keycloak-data + namespace: sso +spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 10Gi + storageClassName: astreae diff --git a/services/keycloak/service.yaml b/services/keycloak/service.yaml new file mode 100644 index 0000000..5d93ef6 --- /dev/null +++ b/services/keycloak/service.yaml @@ -0,0 +1,15 @@ +# services/keycloak/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: keycloak + namespace: sso + labels: + app: keycloak +spec: + selector: + app: keycloak + ports: + - name: http + port: 80 + targetPort: http