如何部署RHBK的分布式缓存集群?

Keycloak

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的节点配置,请参阅如下章节(该节点不需要配置数据库),

如何部署RHBK 26.2.5生产模式?

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的设置,请参阅如下章节,

如何部署Oracle Linux 9.x 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 设置集群反向代理

如何部署RHBK集群Nginx反向代理?

参阅文档
=========

分布式缓存的使用方法
—————–
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

没有评论

发表回复

Keycloak
如何部署RHBK集群Nginx反向代理?

1 前言 一个问题,一篇文章,一出故事。 之前的章节我们完成了RHBK的单节点代理,本章将要完成RH …

Keycloak
如何部署RHBK 26.2.5的Nginx反代?

1 基础知识 1.1 代理模式 1.1.1 Edge模式 – 该模式代理与红帽构建的Ke …

Keycloak
如何部署RHBK 26.2.5生产模式?

1 配置红帽构建的Keycloak 1.1 KeyCloak的配置 1.1.1 配置加载顺序 &#8 …