apiVersion: v1 kind: Service metadata: name: keycloak-headless labels: app: keycloak spec: clusterIP: None # Headless service for DNS discovery (returns pod IPs) selector: app: keycloak ports: - name: jgroups port: 7600 targetPort: 7600 protocol: TCP --- apiVersion: v1 kind: Service metadata: name: keycloak labels: app: keycloak spec: type: ClusterIP # Internal service for Keycloak (ingress will use this) selector: app: keycloak ports: - name: http port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: keycloak namespace: keycloak labels: app: keycloak spec: replicas: 3 selector: matchLabels: app: keycloak template: metadata: labels: app: keycloak spec: containers: - name: keycloak image: quay.io/keycloak/keycloak:26.1.4 args: - "start" - "--cache=ispn" # Enable distributed Infinispan cache (HA mode) [oai_citation_attribution:0‡keycloak.org](https://www.keycloak.org/server/caching#:~:text=When%20you%20start%20Keycloak%20in,in%20your%20network%20are%20discovered) - "--cache-stack=kubernetes" # Use built-in Kubernetes stack for clustering (DNS_PING) - "--hostname=https://sso.panic.haus" # External URL for Keycloak (use HTTPS for TLS offload) - "--http-enabled=true" # Allow Keycloak to listen on HTTP (for edge TLS termination) [oai_citation_attribution:1‡keycloak.org](https://www.keycloak.org/server/hostname#:~:text=provides%20the%20flexibility%20for%20users,start%20the%20server%20as%20follows) - "-Djgroups.dns.query=keycloak-headless" env: - name: KEYCLOAK_ADMIN value: "admin" - name: KEYCLOAK_ADMIN_PASSWORD value: "admin" # - name: KC_PROXY_HEADERS # value: "xforwarded" - name: KC_HOSTNAME value: "sso.panic.haus" - name: KC_HTTP_ENABLED value: "true" - name: KC_HEALTH_ENABLED value: "true" - name: KC_DB value: "postgres" - name: KC_DB_URL value: "jdbc:postgresql://postgres-base-rw.postgres:5432/keycloakdb" - name: KC_DB_USERNAME valueFrom: secretKeyRef: name: keycloak-db-secret key: username - name: KC_DB_PASSWORD valueFrom: secretKeyRef: name: keycloak-db-secret key: password # --- Clustering and caching settings --- - name: KC_CACHE_STACK value: "kubernetes" - name: CACHE_OWNERS_COUNT value: "2" - name: CACHE_OWNERS_AUTH_SESSIONS_COUNT value: "2" # Enable proxy address forwarding since Keycloak is behind an NGINX proxy - name: PROXY_ADDRESS_FORWARDING value: "true" # Trust X-Forwarded-* headers [oai_citation_attribution:3‡github.com](https://github.com/codecentric/helm-charts/issues/325#:~:text=extraEnv%3A%20%7C%20,name%3A%20CACHE_OWNERS_AUTH_SESSIONS_COUNT) # - name: KC_PROXY # value: "edge" # Keycloak is behind an edge (TLS termination) proxy - name: KC_HOSTNAME_STRICT value: "false" # Disable strict host check (allow internal/external host differences) # (Optional) Enable health and metrics endpoints for monitoring: - name: KC_HEALTH_ENABLED value: "true" - name: KC_METRICS_ENABLED value: "true" ports: - name: http containerPort: 8080 - name: jgroups containerPort: 7600 protocol: TCP - name: management containerPort: 9000 # Expose management (health) port livenessProbe: httpGet: path: /health/live port: 9000 # Use management port for liveness initialDelaySeconds: 60 periodSeconds: 30 readinessProbe: httpGet: path: /health/ready port: 9000 # Use management port for readiness initialDelaySeconds: 30 periodSeconds: 15 affinity: # Spread pods across different nodes for higher availability podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: topologyKey: "kubernetes.io/hostname" labelSelector: matchLabels: app: keycloak