Keycloak集群高可用需数据库、缓存、网络和配置四层协同:用PostgreSQL/MySQL共享存储配置;Infinispan+JDBC_PING实现会话同步;负载均衡透传X-Forwarded头;通过用户创建、API响应、session漂移验证集群生效。

部署 Keycloak 集群实现高可用,核心在于解决数据一致性和会话同步两个问题。单实例 Keycloak 无法应对节点宕机或流量突增,而集群必须确保所有节点看到相同的用户、角色、客户端配置,并能共享登录态(Session)。这不是简单起多个容器就能完成的,需要数据库、缓存、网络和配置四层协同。
用共享数据库统一存储配置与用户数据
Keycloak 默认使用内嵌 H2 数据库,仅适用于单机测试。生产集群必须替换为外部高可用数据库。
- 推荐 PostgreSQL 或 MySQL 主从集群,确保写操作有主库、读操作可分发到从库
- 每个 Keycloak 实例通过相同连接参数(JDBC URL、用户名、密码)访问同一套数据库
- 数据库需提前建库、授予权限,并启用连接池(如 HikariCP),避免连接耗尽
- 注意时区统一:数据库和服务端 JVM 均设为 UTC 或同地时区,防止 token 过期逻辑异常
配 Infinispan + JDBC_PING 实现会话自动发现与同步
Keycloak 使用 Infinispan 作为分布式缓存管理 Session、认证会话、离线会话等。多实例间必须形成集群才能同步这些状态。
- 禁用默认的 UDP 发现(不适用于云环境或容器网络),改用 JDBC_PING —— 所有节点通过查询数据库中的一张心跳表来发现彼此
- 需在启动参数中指定
KC_CACHE_STACK=jdbc-ping,并挂载自定义 JGroups 配置(如JDBC_PING.cli) - 确保所有实例使用相同的 cache container 名(如
keycloak)和一致的副本数(CACHE_OWNERS=2表示每个缓存项至少存两份) - 若用 Kubernetes,StatefulSet 比 Deployment 更合适,便于固定网络标识和持久卷绑定
通过负载均衡器对外暴露并正确透传请求头
用户请求不能直连某台 Keycloak 实例,必须经由负载均衡器统一分发,同时保证关键上下文不丢失。
- 使用 Kubernetes Service(type: LoadBalancer 或 NodePort)+ Ingress,或独立 Nginx/HAProxy
- 必须设置
KC_PROXY=edge(表示 Keycloak 处于边缘位置)或KC_PROXY=reencrypt(反向代理终结 TLS 后再转 HTTPS) - 确保 X-Forwarded-* 系列头(如
X-Forwarded-For、X-Forwarded-Proto)被真实传递,否则重定向地址或 Cookie Secure 标志会出错 - 健康检查路径建议用
/realms/master/protocol/openid-connect/certs,比根路径更轻量且反映服务真实就绪状态
验证集群是否真正生效
启动后不能只看页面能否打开,要验证底层状态同步是否正常。
- 登录任意节点创建一个用户,在另一节点后台管理界面刷新查看该用户是否立即可见
- 用 Postman 调用
/realms/{realm}/users接口,对比不同节点返回结果是否完全一致 - 登录后关闭当前节点 Pod,观察用户在其他节点上是否仍保持登录态(即 session 未丢失)
- 查日志关键词:
ISPN000078(成功加入集群)、KEYCLOAK_SESSIONcookie 是否带Path=/和Domain属性,且 HttpOnly/Secure 正确

















