Bitnami Helm部署3副本高可用Keycloak集群登录失败故障
基础环境信息
使用Bitnami提供的Keycloak Helm Chart,基于DNS ping机制部署3副本高可用集群,相关版本如下:
Chart version: 5.2.8 Image version: 15.1.1-debian-10-r10 Helm repo: https://charts.bitnami.com/bitnami -> bitnami/keycloak
部署使用的values配置
global: image: registry: docker.io repository: bitnami/keycloak tag: 15.1.1-debian-10-r10 pullPolicy: IfNotPresent pullSecrets: [] debug: true proxyAddressForwarding: true serviceDiscovery: enabled: true protocol: dns.DNS_PING properties: - dns_query=keycloak.identity.svc.cluster.local transportStack: tcp cache: ownersCount: 3 authOwnersCount: 3 replicaCount: 3 ingress: enabled: true hostname: my-keycloak.keycloak.example.com apiVersion: "" ingressClassName: "nginx" path: / pathType: ImplementationSpecific annotations: {} tls: false extraHosts: [] extraTls: [] secrets: [] existingSecret: "" servicePort: http
故障现象
部署完成后访问Keycloak UI执行登录操作,输入用户名密码后无法完成登录,直接跳转回登录页面。初始排查时参考社区建议开启proxyAddressForwarding: true,故障未解决;尝试更换其他版本Helm Chart部署,会出现UI加载异常、返回页面不存在的问题。
不同Service对接场景的报错
- Ingress对接Headless Service时,Pod日志出现如下授权码错误:
0:07:05,251 WARN [org.keycloak.events] (default task-1) type=CODE_TO_TOKEN_ERROR, realmId=master, clientId=security-admin-console, userId=null, ipAddress=10.244.5.46, error=invalid_code, grant_type=authorization_code, code_id=157e0483-67fa-4ea4-a964-387f3884cbc9, client_auth_method=client-secret
- Ingress对接ClusterIP类型Service时,Pod日志出现如下会话过期错误:
06:43:37,587 WARN [org.keycloak.events] (default task-6) type=LOGIN_ERROR, realmId=master, clientId=null, userId=null, ipAddress=10.122.0.26, error=expired_code, restart_after_timeout=true, authSessionParentId=453870cd-5580-495d-8f03-f73498cd3ace, authSessionTabId=1d17vpIoysE
关键启动日志
所有Keycloak Pod启动时都会打印如下INFO级别日志:
05:27:10,437 INFO [org.jgroups.protocols.pbcast.GMS] (ServerService Thread Pool -- 58) my-keycloak-0: no members discovered after 3006 ms: creating cluster as coordinator
从日志可确认:3个副本节点未完成节点发现流程,没有成功组建可用的Keycloak集群。
故障根因
核心问题是DNS_PING的查询域名配置错误:
配置中填写的dns_query=keycloak.identity.svc.cluster.local和Helm Chart实际创建的Headless Service域名不匹配。Bitnami Keycloak Helm Chart默认会创建名称为{Release-Name}-headless的Headless Service用于集群发现,本次部署Release名称为my-keycloak,命名空间为identity,正确的Headless Service完整域名应为my-keycloak-headless.identity.svc.cluster.local。
错误的DNS查询导致每个Pod只能解析到自身IP,无法发现其他副本节点,最终每个Pod都独立组建了单节点集群。用户登录请求被负载均衡转发到不同节点时,授权码、登录会话只存在于处理首个请求的节点本地缓存中,其他节点无法读取对应数据,就会抛出无效code、会话过期的错误,最终导致登录跳转失败。
修复步骤
- 修正serviceDiscovery配置中的DNS查询地址,指向实际存在的Headless Service域名:
serviceDiscovery: enabled: true protocol: dns.DNS_PING properties: - dns_query=my-keycloak-headless.identity.svc.cluster.local transportStack: tcp
- 验证Headless Service状态:
执行kubectl get svc -n identity,确认存在名为my-keycloak-headless、ClusterIP为None的Service;再执行kubectl get endpoints my-keycloak-headless -n identity,确认后端关联了3个Keycloak Pod的IP地址。 - 滚动重启所有Keycloak Pod,重启后查看Pod日志,出现
view size is 3、received new cluster view类的日志即代表集群组建成功。 - 补充Ingress转发头配置,避免代理场景下的会话异常,在ingress.annotations中添加如下配置:
annotations: nginx.ingress.kubernetes.io/configuration-snippet: | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host;
配置生效后重新访问Keycloak UI即可正常完成登录。
内容的提问来源于stack exchange,提问作者rakesh kotian

