
1 基础知识
1.1 分布式缓存的简介
– RHBK专为高可用性和多节点集群设置而设计
– RHBK的分布式缓存基于Infinispan实现
1.2 启用分布式缓存
– 生产环境启用分布式缓存,使用RHBK的“start”命令,且会自动发现网络中的RHBK节点
– 默认缓存使用jdbc-ping堆栈,该堆栈基于TCP传输,并使用配置数据库来跟踪加入集群的节点
– RHBK允许你从一组预定义的默认传输堆栈中选择,或者定义你自己的自定义堆栈
分布式缓存启动用范例,
bin/kc.[sh|bat] start --cache=ispn
注:开发模式启动的是隐式“–cache=local”选项,该选项禁用分布式缓存
1.3 配置分布式缓存
1.3.1 分布式缓存介绍
– RHBK提供缓存配置文件,位于“conf/cache-ispan.xml”
– RHBK的缓存分为本地、复制和分布式缓存三种类型
– 配置文件“conf/cache-ispan.xml”的缓存配置参数,请参阅下表,
Cache name | Cache Type | Description |
---|---|---|
realms | Local | Cache persisted realm data |
users | Local | Cache persisted user data |
authorization | Local | Cache persisted authorization data |
keys | Local | Cache external public keys |
crl | Local | Cache for X.509 authenticator CRLs |
work | Replicated | Propagate invalidation messages across nodes |
authenticationSessions | Distributed | Caches authentication sessions, created/destroyed/expired during the authentication process |
sessions | Distributed | Cache persisted user session data |
clientSessions | Distributed | Cache persisted client session data |
offlineSessions | Distributed | Cache persisted offline user session data |
offlineClientSessions | Distributed | Cache persisted offline client session data |
loginFailures | Distributed | keep track of failed logins, fraud detection |
actionTokens | Distributed | Caches action Tokens |
1.3.2 本地缓存的介绍
本地缓存该类型的缓存会在本地持久缓存,以避免数据库间的非必要的往返,本地缓存将以下数据保存在集群中的每个节点,
– realms,即领域相关数据,如客户端、角色和组(默认最多容纳10000各条目)
– users,即用户相关数据,如授予的角色和组成员资格。(默认最多容纳10000各条目)
– authorization,即授权相关数据,如资源、权限和策略。(默认最多容纳10000各条目)
– keys,即公钥数据(默认最多容纳10000各条目)
1.3.3 复制式缓存的介绍
– 当共享数据库被多个分布式的RHBK节点更新后,则缓存应该失效,否则会破坏数据的一致性。
– work,是一种复制式缓存,用于发送本地缓存失效的信息
1.3.4 分布式缓存的介绍
– authenticationSessions,依赖分布式缓存,可供集群任意节点使用。缓存身份验证会话,记录身份会话创建、销毁和过期
– sessions,依赖分布式缓存,可供集群任意节点使用。标记用户会话数据。(默认最多容纳10000各条目)
– clientSessions,依赖分布式缓存,可供集群任意节点使用。标记客户端会话数据。(默认最多容纳10000各条目)
– offlineSessions,依赖分布式缓存,可供集群任意节点使用。标记离线的用户会话。(默认最多容纳10000各条目)
– offlineClientSessions,依赖分布式缓存,可供集群任意节点使用。标记离线的用户端会话。(默认最多容纳10000各条目)
– loginFailures,依赖分布式缓存,可供集群任意节点使用。标记登陆失败的数据。
– actionTokens,依赖分布式缓存,可供集群任意节点使用。标记有关操作令牌的数据。
1.3.5 配置缓存的节点数量
<distributed-cache name="sessions" owners="2"> </distributed-cache>
如上所示,
– 条目名称为“sessions”的分布式缓存条目中包含属性“owners”
– 属性“owners”的数量控制者缓存节点的数量,如2则该属性分布到2各节点
– 默认情况下,我们推荐3以上的基数节点
1.3.6 易失性用户会话
– 默认情况下,用户会话存储在数据库中,并按需加载到缓存中
– RHBK支持用户会话仅存储到缓存,并最小化数据利用率
但这有两个缺点,
– 当所有RHBK节点重启时,会话会丢失
– 增加内存消耗
设置的启用方式,
<distributed-cache name="sessions" owners="2"> <expiration lifespan="-1"/> <!-- <memory max-count="10000"/> --> </distributed-cache>
以上配置意思是,
– 缓存是用户和客户端会话的唯一来源
– 因此注解掉“memory max-count=”10000″”配置表示不限制条目数量
– 因此设置“owners=”2″”或者更大是声明每个条目至少复制两个以上节点
并且,你还需要使用如下命令禁用“persistent-user-sessions”功能,
bin/kc.sh start --features-disabled=persistent-user-sessions ...
1.3.7 配置缓存规格
--cache-embedded-${CACHE_NAME}-max-count=<number>
以上格式表达式对某个缓存中的存储条目数量设置上限,例如对离线会话“offlineSessions”缓存设置上限,按如下格式,
--cache-embedded-offline-sessions-max-count=1000
1.3.8 自定义缓存配置文件
bin/kc.[sh|bat] start --cache=ispn
以上默认的“–cache=ispn”命令行启动参数加载的是默认配置文件““conf/cache-ispan.xml””,如果你需要指定自定义的配置文件,请使用如下命令行格式启动,
bin/kc.[sh|bat] start --cache-config-file=my-cache-file.xml
1.3.9 缓存服务器相关的CLI选项
– 命令选项“cache-remote-host”,指定分布式缓存服务(Infinispan)服务器IP地址,多个地址需使用负载均衡器代理后端多地址。
– 命令选项“cache-remote-port”,指定分布式缓存服务(Infinispan)服务器端口,一般填“11222”。
– 命令选项“cache-remote-username”,指定分布式缓存服务(Infinispan)服务器登陆用户名
– 命令选项“cache-remote-password”,指定分布式缓存服务(Infinispan)服务器登陆密码
– 命令选项“cache-remote-tls-enabled”,指定分布式缓存服务(Infinispan)服务器连接使用TLS加密通讯
使用范例如下,
bin/kc.sh start --cache-remote-host=192.168.1.100 --cache-remote-port=11222 --cache-remote-username=myUser --cache-remote-password=myPassword --cache-remote-tls-enabled=true
1.4 传输堆栈
1.4.1 传输堆栈的作用
– 传输堆栈保证RHBK以可靠的方式在集群中构建Keycloak节点
– RHBK支持多种的传输堆栈
1.4.2 RHBK支持的传输堆栈
– jdbc-ping,TCP协议,使用JGroups JDBC_PING2协议进行数据库注册(默认)
– jdbc-ping-udp,UDP协议,使用JGroups JDBC_PING2协议进行数据库注册(已弃用)
– kubernetes,TCP协议,使用JGroups JDBC_PING协议的DNS解析,需设置jgroups.dns.query为无头服务FQDN
– tcp,TCP协议,使用JGroups MPING 协议IP多播,需设置唯一jgroups.mcast_addr或jgroups.mcast_port(已弃用)
– UDP,UDP协议,使用JGroups MPING 协议IP多播,需设置唯一jgroups.mcast_addr或jgroups.mcast_port(已弃用)
– ec2(已弃用)
– Azure(已弃用)
– Google(已弃用)
需要注意的是,
– 启用分布式缓存时,默认的传输堆栈为“jdbc-ping”
– 使用“tcp”、“udp”或“jdbc-ping-udp”堆栈时,每个集群都必须使用不同的多播地址或端口,以便组成不同的集群
– 默认情况下,RHBK使用“239.6.7.8”作为“jgroup.mcast_addr”的多播地址
– 默认情况下,RHBK使用“46655”作为“jgroup.mcast_port”的多播端口
1.4.3 指定传输堆栈
bin/kc.[sh|bat] start --cache-stack=<stack>
1.4.4 指定传输堆栈的端口范例
bin/kc.[sh|bat] start -Djgroups.bind.port=7600
1.5 传输堆栈的加密
1.5.1 传输堆栈的加密介绍
– 默认情况下基于TCP的传输堆栈启用TLS的加密
– 只要你使用基于TCP的传输堆栈,则无需而外的CLI选项或修改缓存XML
如果你使用基于UDP或TCP_NIO2的传输堆栈,请按照以下步骤配置传输堆栈的加密,
– 参数“cache-embedded-mtls-enabled”设置为“false”
– 请遵循JGroups加密文档和加密集群传输的说明
关于证书的说明,
– 启用TLS后,RHBK会自动生成自签名的RSA 2048位证书以保护连接,并使用TLS来保证通讯安全
– 密钥和证书存储在数据库中,以便所有节点都可以访问
– 默认情况下,证书有效期为60天,并且每30天在运行时进行一次轮换。
– 参数“cache-embedded-mtls-rotation-interval-days”支持定义轮换间隔天数
1.5.2 服务网格内相关的配置
– 当使用向lstio这样的服务网格时,你可选使用RHBK Pods之间直接mTLS通讯以便双向身份验证能正常工作。
– 或者选择以来服务网格的传输来加密通讯并进行对等验证。
要允许RHBK Pods之间直接mTLS通讯,请使用如下配置,
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: infinispan-allow-nomtls spec: selector: matchLabels: app: keycloak portLevelMtls: "7800": mode: PERMISSIVE
需要注意的是,
– 更新标签以便匹配你的RHBK部署
– 端口7800是默认值,如果需要更改请自行调整
另外,如果禁用mTLS通讯并依赖服务网格来加密流量,
– 需要将参数“cache-embedded-mtls-enabled”设置为“false”
– 配置你的服务网格,仅授权RHBK Pods的数据传输端口流量(默认7800)
1.5.3 自定义密钥或证书
标准设置不推荐自动以密钥或证书,但如果需要设置,以下参数供你参考,
– 参数“cache-embedded-mtls-key-store-file”设置密钥库的路径
– 参数“cache-embedded-mtls-key-store-password”设置解密该密钥库的密码
– 参数“cache-embedded-mtls-trust-store-file”设置信任库的路径
– 参数“cache-embedded-mtls-trust-store-password”设置解密信任库的密码
1.6 网络端口
– 为确保RHBK的集群健康,需要开放集群工作所需的网络端口
– 端口支持通过环境变量“JAVA_OPTS_APPEND”或CLI命令来声明,格式“-D<property>=<value>”
“jdbc-ping”堆栈的端口默认设置如下,
Port | Property | Description |
---|---|---|
7800 |
jgroups.bind.port |
单播数据传输 |
57800 |
jgroups.fd.port-offset |
通过 FD_SOCK2 协议进行故障检测。它监听套接字的突然关闭,以怀疑红帽构建的 Keycloak 服务器失败。jgroups.fd.port-offset 属性定义了与 jgroups.bind.port 的偏移量。 |
1.7 网络绑定地址
– 为确保RHBK的集群健康,网络端口必须绑定在一个可被集群中所有其他节点访问的接口上
– 默认情况下,程序会选择站点本地IP地址(不跨网段路由),例如“192.168.0.0/16”或“10.0.0.0/8”的地址范围
– 要自修改默认设置,请设置参数“jgroups.bind.address”
– 参数“jgroups.bind.address”支持通过环境变量“JAVA_OPTS_APPEND”或CLI命令来声明
如果需要禁用IPv4只使用IPv6,请参阅如下声明范例,
export JAVA_OPTS_APPEND="-Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true"
1.8 在不同的网络上运行实例
– 如果在不同的网络(例如防火墙或容器)上运行RHBK
– 需要使用“jgroups.external_addr”和“jgroups.external_port”属性将外部地址通告给其他节点
– 参数支持通过环境变量“JAVA_OPTS_APPEND”或CLI命令来声明
详细的参数功能描述,
– 参数“jgroups.external_port”,其他RHBK集群实例使用的端口
– 参数“jgroups.external_addr”,其他RHBK集群实例使用的IP地址
1.9 启用缓存指标直方图
– 如需启用缓存指标直方图,你需要设置参数“cache-metrics-histograms-enabled”为“true”
– 启用缓存指标直方图,会对性能有一定影响,因此负荷重的集群需要谨慎启用。
以下是启用的命令行选项,
bin/kc.[sh|bat] start --metrics-enabled=true --cache-metrics-histograms-enabled=true
2 最佳实践
2.1 配置环境
2.1.2 准备纯净不包含数据库的RHBK节点
RHBK 节点1,
Host Name = rhbk01.cmdschool.org
IP Addresses = 10.168.0.54
OS = rhel 9.x x86_64
RHBK 节点2,
Host Name = rhbk02.cmdschool.org
IP Addresses = 10.168.0.55
OS = rhel 9.x x86_64
关于RHBK的节点配置,请参阅如下章节(该节点不需要配置数据库),
2.1.2 准备独立的数据库节点
Host Name = rhbkdb01.cmdschool.org
IP Addresses = 10.168.0.69
OS = rhel 9.x x86_64
DB = MariaDB
DB Port = 3306
需要注意的是,
– 推荐运行在VMWare HA环境,确保不会因为单个物理服务器节点故障而变得不可用。
– 该数据库为后面的rhbk01和rhbk02提供共享式数据库
关于MariaDB的设置,请参阅如下章节,
然后,你需要使用如下命令配置KeyCloak节点连接所需的权限,
mysql -uroot -p create database keycloak character set utf8; grant all privileges on keycloak.* to 'keycloak'@'10.168.0.54' identified by 'keycloakpwd'; grant all privileges on keycloak.* to 'keycloak'@'10.168.0.55' identified by 'keycloakpwd'; flush privileges;
2.1.3 配置名称解析
In rhbkdb01 & rhbk0[1-2],
vim /etc/hosts
加入如下配置,
10.168.0.54 rhbk01 rhbk01.cmdschool.org 10.168.0.55 rhbk02 rhbk02.cmdschool.org 10.168.0.69 rhbkdb01 rhbkdb01.cmdschool.org
2.2 配置分布式缓存集群
2.2.1 修改节点配置
In rhbk01,
vim /etc/keycloak/keycloak.conf
配置修改如下,
# Basic settings for running in production. Change accordingly before deploying the server. # Database db = mariadb db-username = keycloak db-password = keycloakpwd db-url = jdbc:mariadb://rhbkdb01.cmdschool.org:3306/keycloak?characterEncoding=UTF-8 # Observability health-enabled = true metrics-enabled = true # HTTP https-certificate-file = /etc/keycloak/wildcard.cmdschool.org.crt https-certificate-key-file = /etc/keycloak/wildcard.cmdschool.org.key # The proxy address forwarding mode if the server is behind a reverse proxy. # proxy = reencrypt # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route = false # Uncomment to disable route attachment to cookies # Hostname for the Keycloak server. hostname = https://rhbk01.cmdschool.org:8443 # Logging configuration log = console,file log-level = INFO,org.hibernate:debug,org.hibernate.hql.internal.ast:info log-file = /var/log/keycloak/keycloak.log log-file-size = 10MB log-file-count = 20 # Infinispan configuration cache-stack = jdbc-ping cache = ispn
In rhbk02,
vim /etc/keycloak/keycloak.conf
配置修改如下,
# Basic settings for running in production. Change accordingly before deploying the server. # Database db = mariadb db-username = keycloak db-password = keycloakpwd db-url = jdbc:mariadb://rhbkdb01.cmdschool.org:3306/keycloak?characterEncoding=UTF-8 # Observability health-enabled = true metrics-enabled = true # HTTP https-certificate-file = /etc/keycloak/wildcard.cmdschool.org.crt https-certificate-key-file = /etc/keycloak/wildcard.cmdschool.org.key # The proxy address forwarding mode if the server is behind a reverse proxy. # proxy = reencrypt # Do not attach route to cookies and rely on the session affinity capabilities from reverse proxy #spi-sticky-session-encoder-infinispan-should-attach-route = false # Uncomment to disable route attachment to cookies # Hostname for the Keycloak server. hostname = https://rhbk02.cmdschool.org:8443 # Logging configuration log = console,file log-level = INFO,org.hibernate:debug,org.hibernate.hql.internal.ast:info log-file = /var/log/keycloak/keycloak.log log-file-size = 10MB log-file-count = 20 # Infinispan configuration cache-stack = jdbc-ping cache = ispn
以下配置重点解析如下,
– 节点“rhbk0[1-2]”都指向相同的数据库“rhbkdb01”
– 节点“rhbk0[1-2]”分别指定测试连接“https://rhbk01.cmdschool.org:8443”和“https://rhbk02.cmdschool.org:8443”
– 节点“rhbk0[1-2]”声明集群堆栈“cache-stack”使用“jdbc-ping”的方式
– 节点“rhbk0[1-2]”声明缓存“cache”使用内置嵌入式的“ispn”实现
2.2.2 测试节点启动
In rhbk01,
sudo -u keycloak bash -c 'export JAVA_OPTS_APPEND="-Djgroups.bind.address=10.168.0.54 -Djgroups.bind.port=7600;KEYCLOAK_ADMIN=admin;export KEYCLOAK_ADMIN_PASSWORD=adminpwd;/opt/keycloak/rhbk-26.2.5/bin/kc.sh start'
In rhbk02,
sudo -u keycloak bash -c 'export JAVA_OPTS_APPEND="-Djgroups.bind.address=10.168.0.55 -Djgroups.bind.port=7600;KEYCLOAK_ADMIN=admin;export KEYCLOAK_ADMIN_PASSWORD=adminpwd;/opt/keycloak/rhbk-26.2.5/bin/kc.sh start'
需要注意的是,本章重点声明环境变量”JAVA_OPTS_APPEND”,该环境变量声明如下,
– 参数“-Djgroups.bind.address”声明Infinispan的服务器倾听地址是当前服务器的可用网卡地址
– 参数“-Djgroups.bind.port”声明Infinispan的服务器倾听端口
服务启动后,你可以使用如下命令确认Infinispan的服务在倾听,
ss -antp | grep 7600
可见如下显示,
LISTEN 0 50 [::ffff:10.168.0.55]:7600 *:* users:(("java",pid=21793,fd=350))
当两个节点都启动后,你还可能见到如下同步的通讯,
LISTEN 0 50 [::ffff:10.168.0.55]:7600 *:* users:(("java",pid=22661,fd=350)) SYN-SENT 0 1 [::ffff:10.168.0.55]:47771 [::ffff:10.168.0.54]:7600 users:(("java",pid=22661,fd=354))
根据上面的配置,你可能需要在集群的每个节点开放如下端口,
In rhbk0[1-2],
firewall-cmd --permanent --add-port 7600/tcp firewall-cmd --reload firewall-cmd --list-all
2.2.3 创建服务控制脚本
In rhbk01,
vim /etc/systemd/system/keycloak.service
加入如下配置,
[Unit] Description=Redhat build of Keycloak (RHBK) Requires=network.target After=syslog.target network.target [Service] Type=simple User=keycloak Group=keycloak WorkingDirectory=/opt/keycloak/rhbk-26.2.5 Environment="KEYCLOAK_ADMIN=admin" Environment="KEYCLOAK_ADMIN_PASSWORD=adminpwd" Environment="JAVA_OPTS_APPEND=-Djgroups.bind.address=10.168.0.54 -Djgroups.bind.port=7600" ExecStart=/usr/bin/bash -c '/opt/keycloak/rhbk-26.2.5/bin/kc.sh start' Restart=on-failure StandardOutput=journal LimitNOFILE=102642 [Install] WantedBy=multi-user.target
In rhbk02,
vim /etc/systemd/system/keycloak.service
加入如下配置,
[Unit] Description=Redhat build of Keycloak (RHBK) Requires=network.target After=syslog.target network.target [Service] Type=simple User=keycloak Group=keycloak WorkingDirectory=/opt/keycloak/rhbk-26.2.5 Environment="KEYCLOAK_ADMIN=admin" Environment="KEYCLOAK_ADMIN_PASSWORD=adminpwd" Environment="JAVA_OPTS_APPEND=-Djgroups.bind.address=10.168.0.55 -Djgroups.bind.port=7600" ExecStart=/usr/bin/bash -c '/opt/keycloak/rhbk-26.2.5/bin/kc.sh start' Restart=on-failure StandardOutput=journal LimitNOFILE=102642 [Install] WantedBy=multi-user.target
In rhbk0[1-2],
配置创建后,你需要使用如下命令重载服务使配置生效,
systemctl daemon-reload
重启服务使配置生效,
systemctl restart keycloak.service
重启服务后,你如果使用如下命令检索日志,
grep -i cluster /var/log/keycloak/keycloak.log | grep -i members | grep -i finished
可见包含关键字“Finished rebalance with members”的日志,
2025-08-01 10:46:21,971 INFO [org.infinispan.CLUSTER] (jgroups-6,rhbk01-22113) [Context=org.infinispan.CONFIG] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,026 INFO [org.infinispan.CLUSTER] (jgroups-6,rhbk01-22113) [Context=actionTokens] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,052 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=authenticationSessions] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,101 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=clientSessions] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,139 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=loginFailures] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,159 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=offlineClientSessions] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,182 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=offlineSessions] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,204 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=sessions] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5 2025-08-01 10:46:22,223 INFO [org.infinispan.CLUSTER] (jgroups-9,rhbk01-22113) [Context=work] ISPN100010: Finished rebalance with members [rhbk01-22113, rhbk02-40877], topology id 5
2.3 测试集群配置
In Linux Client,
2.3.1 配置客户端名称解析
vim /etc/hosts
加入如下配置,
10.168.0.54 rhbk01 rhbk01.cmdschool.org 10.168.0.55 rhbk02 rhbk02.cmdschool.org 10.168.0.69 rhbkdb01 rhbkdb01.cmdschool.org
2.3.2 创建服务控制脚本
https://rhbk01.cmdschool.org:8443
https://rhbk02.cmdschool.org:8443
2.4 设置集群反向代理
参阅文档
=========
分布式缓存的使用方法
—————–
https://www.keycloak.org/server/caching
https://docs.redhat.com/zh-cn/documentation/red_hat_build_of_keycloak/26.2/html-single/server_configuration_guide/index#caching-
https://docs.redhat.com/zh-cn/documentation/red_hat_build_of_keycloak/26.2/html-single/server_configuration_guide/index
JGroups群集通信
——————
https://docs.redhat.com/zh-cn/documentation/red_hat_jboss_enterprise_application_platform/7.4/html/configuration_guide/cluster_communication_jgroups
多站点部署
————–
https://www.keycloak.org/high-availability/introduction
支持写到配置文件中的参数
————–
https://www.keycloak.org/server/all-config
没有评论