K8s环境Keycloak双节点集群部署Helm Chart配置修改方法
问题根因
CODE_TO_TOKEN_ERROR的直接原因是两个Keycloak Pod未组建统一的Infinispan分布式缓存集群:
- 日志中
no members discovered after 2002 ms: creating cluster as coordinator说明Infinispan默认节点发现协议在K8s环境下不生效,两个Pod各自作为独立协调节点启动,会话、授权码数据仅在单Pod内存中存储,当登录流程的token交换请求被负载均衡到另一节点时,找不到对应授权码就会抛出错误。 Unable to persist Infinispan internal caches as no global state enabled是缓存未做集群适配时的伴随警告,配置正确的缓存存储路径即可修复。
Helm Chart配置修改方案
以下配置适配Keycloak 17.0.1 Quarkus版本,直接修改自定义values.yaml对应字段即可:
1. 基础集群配置
replicaCount: 2 # 核心缓存与集群发现环境变量 extraEnv: # 指定使用K8s适配的Infinispan缓存栈 - name: KC_CACHE value: ispn - name: KC_CACHE_STACK value: kubernetes # 替换默认发现协议为DNS_PING,不依赖K8s API权限,稳定性更高 - name: JGROUPS_DISCOVERY_PROTOCOL value: dns.DNS_PING # 指向无头Service的DNS地址,替换为你实际的部署命名空间、Helm Release名称 - name: JGROUPS_DNS_QUERY value: <你的Helm Release名称>-headless.<部署命名空间>.svc.cluster.local # 指定Infinispan全局状态存储路径,解决持久化警告 - name: KC_CACHE_GLOBAL_STATE_DIR value: /tmp/ispn-state # 挂载临时存储用于Infinispan全局状态持久化 extraVolumes: - name: ispn-state emptyDir: {} extraVolumeMounts: - name: ispn-state mountPath: /tmp/ispn-state # 启用无头Service,供DNS_PING做节点发现 service: headless: enabled: true port: 7800 # JGroups集群通信默认端口
2. 可选优化配置(避免偶发登录异常)
在Ingress层开启会话亲和性,短时间内将同一客户端的请求转发到同一Pod,降低缓存同步延迟带来的偶发错误:
ingress: enabled: true annotations: # Nginx Ingress示例,其他Ingress控制器可替换为对应亲和性配置 nginx.ingress.kubernetes.io/affinity: "cookie" nginx.ingress.kubernetes.io/session-cookie-name: "KC_ROUTE" nginx.ingress.kubernetes.io/session-cookie-max-age: "180"
部署后验证
执行helm upgrade更新部署后,进入任意Keycloak Pod执行以下命令验证集群状态:
curl -s http://127.0.0.1:8080/metrics | grep vendor_infinispan_cluster_size
返回结果数值为2即代表双节点缓存集群组建成功,此时Pod日志中不会再出现节点发现失败、全局状态未启用的报错,登录流程可正常执行。
内容的提问来源于stack exchange,提问作者Hoorooroo
相关产品推荐
相关产品推荐

