Files
infra-keycloak/k8s/keycloak/deployment.yaml
T
Stéphane Tailland 01d2082f3b Send traces to Tempo and expose metrics to Prometheus
Point the OTel Java agent at Tempo instead of Jaeger, so Keycloak's traces
land in the same backend as the rest of the stack and correlate with the
Loki logs of the same requests.

Annotate the pod for scraping. KC_METRICS_ENABLED already served /metrics
on the management port, so this only makes Prometheus discover it — on
port 9000, never on the application port.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 07:27:14 +02:00

170 lines
5.5 KiB
YAML

apiVersion: apps/v1
kind: Deployment
metadata:
name: keycloak
namespace: keycloak
labels:
app.kubernetes.io/name: keycloak
app.kubernetes.io/component: idp
app.kubernetes.io/part-of: keycloak
spec:
replicas: 1
selector:
matchLabels:
app: keycloak
template:
metadata:
labels:
app: keycloak
app.kubernetes.io/name: keycloak
app.kubernetes.io/component: idp
app.kubernetes.io/part-of: keycloak
annotations:
# Discovered by the Prometheus in the observability namespace.
# Endpoint exposed by KC_METRICS_ENABLED=true, on the management
# port (9000), never on the application port.
prometheus.io/scrape: "true"
prometheus.io/port: "9000"
prometheus.io/path: "/metrics"
spec:
initContainers:
- name: download-otel-agent
image: curlimages/curl:8.10.0
command:
- "sh"
- "-c"
- "curl -sSL -o /otel/opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.31.0/opentelemetry-javaagent.jar"
volumeMounts:
- name: otel-agent
mountPath: /otel
containers:
- name: keycloak
image: quay.io/keycloak/keycloak:26.6.0
args:
- "start"
- "--import-realm"
ports:
- name: http
containerPort: 8080
- name: https
containerPort: 8443
- name: management
containerPort: 9000
env:
- name: KC_DB
value: "postgres"
- name: KC_DB_URL_HOST
value: "keycloak-postgresql"
- name: KC_DB_URL_PORT
value: "5432"
- name: KC_DB_URL_DATABASE
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: POSTGRES_DB
- name: KC_DB_USERNAME
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: KC_DB_USERNAME
- name: KC_DB_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: KC_DB_PASSWORD
- name: KC_BOOTSTRAP_ADMIN_USERNAME
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: KC_BOOTSTRAP_ADMIN_USERNAME
- name: KC_BOOTSTRAP_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: KC_BOOTSTRAP_ADMIN_PASSWORD
- name: KEYCLOAK_ADMIN
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: KEYCLOAK_ADMIN
- name: KEYCLOAK_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
name: keycloak-secrets
key: KEYCLOAK_ADMIN_PASSWORD
- name: KC_HTTP_ENABLED
value: "true"
- name: KC_PROXY_HEADERS
value: "xforwarded"
- name: KC_HOSTNAME
value: "https://keycloak.sttlab.local"
- name: KC_HOSTNAME_STRICT
value: "false"
- name: KC_HOSTNAME_BACKCHANNEL_DYNAMIC
value: "false"
- name: KC_FEATURES
value: "token-exchange,admin-fine-grained-authz,log-mdc"
- name: JAVA_OPTS_APPEND
value: "-javaagent:/otel/opentelemetry-javaagent.jar"
- name: OTEL_SERVICE_NAME
value: "keycloak"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://tempo.observability.svc.cluster.local:4318"
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: "http/protobuf"
- name: OTEL_TRACES_EXPORTER
value: "otlp"
- name: OTEL_METRICS_EXPORTER
value: "none"
- name: OTEL_LOGS_EXPORTER
value: "none"
- name: KC_HTTP_ACCESS_LOG_ENABLED
value: "true"
- name: KC_LOG_LEVEL
value: "INFO,org.keycloak.events:DEBUG"
- name: KC_LOG_CONSOLE_OUTPUT
value: "json"
- name: KC_LOG_MDC_ENABLED
value: "true"
- name: KC_LOG_SERVICE_NAME
value: "keycloak"
- name: KC_LOG_SERVICE_ENVIRONMENT
value: "local"
- name: KC_HEALTH_ENABLED
value: "true"
- name: KC_METRICS_ENABLED
value: "true"
readinessProbe:
httpGet:
path: /health/ready
port: 9000
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 5
livenessProbe:
httpGet:
path: /health/live
port: 9000
initialDelaySeconds: 30
periodSeconds: 15
failureThreshold: 5
resources:
requests:
cpu: 500m
memory: 1024Mi
limits:
cpu: 2000m
memory: 2048Mi
volumeMounts:
- name: realm-import
mountPath: /opt/keycloak/data/import
readOnly: true
- name: otel-agent
mountPath: /otel
volumes:
- name: realm-import
configMap:
name: keycloak-realm-classic-models
- name: otel-agent
emptyDir: {}