Azure App Service多实例部署Keycloak v21的Infinispan集群问题
Keycloak v21多实例集群通信故障排查(Azure App Service环境)
环境与现象
- 部署环境:Azure App Service,已横向扩展为至少2个Keycloak v21实例
- 缓存配置:基于Azure缓存栈的Infinispan
- 附加资源:已配置可访问Azure存储账户
实例启动后,存储账户容器中生成包含IP和端口(如169.254.254.2:7800)的文件,但实例无法通过这些IP互相通信,容器日志报错如下:
2023-06-23T07:21:52.815593967Z 2023-06-23 07:21:52,815 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 0 2023-06-23T07:21:54.816852500Z 2023-06-23 07:21:54,816 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 1 2023-06-23T07:21:56.817344627Z 2023-06-23 07:21:56,816 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 2 2023-06-23T07:21:58.818581617Z 2023-06-23 07:21:58,818 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 3 2023-06-23T07:22:00.820421010Z 2023-06-23 07:22:00,818 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 4 2023-06-23T07:22:02.820960997Z 2023-06-23 07:22:02,819 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 5 2023-06-23T07:22:04.820918651Z 2023-06-23 07:22:04,820 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 6 2023-06-23T07:22:06.821521635Z 2023-06-23 07:22:06,821 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 7 2023-06-23T07:22:08.822038319Z 2023-06-23 07:22:08,821 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 8 2023-06-23T07:22:10.822732003Z 2023-06-23 07:22:10,822 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: JOIN(a3f459dc2b25-49850) sent to 0ffc70c88670-22937 timed out (after 2000 ms), on try 9 2023-06-23T07:22:10.822770803Z 2023-06-23 07:22:10,822 WARN [org.jgroups.protocols.pbcast.GMS] (keycloak-cache-init) a3f459dc2b25-49850: too many JOIN attempts (10): becoming singleton 2023-06-23T07:22:10.859036526Z 2023-06-23 07:22:10,858 INFO [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000094: Received new cluster view for channel ISPN: [a3f459dc2b25-49850|0] (1) [a3f459dc2b25-49850] 2023-06-23T07:22:10.878978794Z 2023-06-23 07:22:10,878 INFO [org.infinispan.CLUSTER] (keycloak-cache-init) ISPN000079: Channel "ISPN" local address is "a3f459dc2b25-49850", physical addresses are "[169.254.254.4:7800]"
用户疑问
- 是否完全无法访问其他实例?
- 多实例部署是否需要采用其他方案?
- 寻求具体解决方法
问题分析
日志中的GMS JOIN timed out和becoming singleton明确说明Keycloak实例无法组成集群,核心原因是Azure App Service的实例间默认无法通过容器内部IP(169.254.x.x)直接通信——这类IP是链路本地地址,仅在单个实例的容器内部有效,实例之间无法通过该IP互通。
解决方法
方案1:调整JGroups集群发现机制(推荐,无需迁移环境)
Keycloak依赖JGroups实现集群节点发现,在Azure App Service环境下,需替换默认的UDP组播/直接IP通信,改用共享存储或数据库实现节点同步:
子方案1.1:JDBC_PING(基于共享数据库)
- 确保所有Keycloak实例连接同一个关系型数据库(如Azure SQL)
- 添加启动参数:
-Dkeycloak.cache=ispn -Dkeycloak.ispn.config=cache-ispn-jdbc-ping.xml - 编写
cache-ispn-jdbc-ping.xml配置文件,指定JDBC连接信息,让JGroups通过数据库表共享集群节点列表:
对应的<infinispan> <cache-container name="keycloak"> <transport cluster="keycloak" stack="tcp"> <property name="configurationFile">jgroups-jdbc-ping.xml</property> </transport> </cache-container> </infinispan>jgroups-jdbc-ping.xml需配置JDBC_PING协议,指定数据库驱动、URL、用户名和密码。
子方案1.2:FILE_PING(基于Azure存储共享)
- 将Azure存储账户的文件共享挂载到所有Keycloak实例的同一本地路径(如
/opt/jgroups-ping) - 添加启动参数:
-Djgroups.bind_addr=0.0.0.0 -Djgroups.file_ping.location=/opt/jgroups-ping - 确保所有实例拥有该共享目录的读写权限,JGroups会通过共享文件同步集群节点信息。
方案2:迁移到Azure Kubernetes Service(AKS)
若App Service的网络限制难以适配,可将Keycloak迁移到AKS:
- AKS Pod间支持直接网络通信,默认可使用JGroups的UDP组播或TCP栈实现集群
- 搭配Azure Redis Cache或托管式Infinispan集群,可获得更优的分布式缓存性能与可靠性
验证步骤
- 应用配置调整后,查看Keycloak日志,确认出现
ISPN000094: Received new cluster view且包含多个实例节点 - 测试跨实例会话同步:在一个实例完成登录后,切换到另一个实例验证会话是否有效
内容的提问来源于stack exchange,提问作者Thierry Iseli
相关产品推荐
相关产品推荐

