bin/kc.[sh|bat] start --cache=ispn
Keycloak 被设计用于高可用性和多节点集群部署。当前分布式缓存的实现是基于 Infinispan 构建的,Infinispan 是一个高性能、可分布式内存数据网格。
当你在生产模式下启动 Keycloak 时,通过使用 start
命令,缓存会被启用,并且网络中的所有 Keycloak 节点都会被发现。
默认情况下,缓存使用 jdbc-ping
堆栈,它基于 TCP 传输,并使用配置的数据库来跟踪加入集群的节点。Keycloak 允许你从一组预定义的默认传输堆栈中选择,或者定义你自己的自定义堆栈,正如你将在本指南后面看到的那样。
要显式启用分布式 Infinispan 缓存,请输入此命令
bin/kc.[sh|bat] start --cache=ispn
当你在开发模式下启动 Keycloak 时,通过使用 start-dev
命令,Keycloak 仅使用本地缓存,并且通过隐式设置 --cache=local
选项完全禁用分布式缓存。local
缓存模式仅用于开发和测试目的。
Keycloak 提供了一个缓存配置文件,其中包含合理的默认设置,位于 conf/cache-ispn.xml
。
缓存配置是一个标准的 Infinispan 配置文件。
下表概述了 Keycloak 使用的特定缓存。你在 conf/cache-ispn.xml
中配置这些缓存
缓存名称 | 缓存类型 | 描述 |
---|---|---|
realms |
本地 |
缓存持久化的 realm 数据 |
users |
本地 |
缓存持久化的用户数据 |
authorization |
本地 |
缓存持久化的授权数据 |
keys |
本地 |
缓存外部公钥 |
crl |
本地 |
X.509 身份验证器 CRL 的缓存 |
work |
复制 |
在节点之间传播失效消息 |
authenticationSessions |
分布式 |
缓存身份验证会话,这些会话在身份验证过程中创建/销毁/过期 |
sessions |
分布式 |
缓存持久化的用户会话数据 |
clientSessions |
分布式 |
缓存持久化的客户端会话数据 |
offlineSessions |
分布式 |
缓存持久化的离线用户会话数据 |
offlineClientSessions |
分布式 |
缓存持久化的离线客户端会话数据 |
loginFailures |
分布式 |
跟踪失败的登录,欺诈检测 |
actionTokens |
分布式 |
缓存操作令牌 |
Keycloak 在本地缓存持久化数据,以避免不必要的数据库往返。
以下数据使用本地缓存保存在集群中的每个节点本地
realms 和相关数据,如客户端、角色和组。
users 和相关数据,如授予的角色和组成员资格。
authorization 和相关数据,如资源、权限和策略。
keys
realms、users 和 authorization 的本地缓存默认配置为最多保存 10,000 个条目。本地密钥缓存默认可以保存最多 1,000 个条目,并默认为每小时过期一次。因此,密钥会被强制定期从外部客户端或身份提供商处下载。
为了实现最佳运行时并避免额外的数据库往返,你应该考虑查看每个缓存的配置,以确保最大条目数与你的数据库大小对齐。你可以缓存的条目越多,服务器需要从数据库获取数据的频率就越低。你应该评估内存利用率和性能之间的权衡。
本地缓存提高了性能,但在多节点部署中增加了一个挑战。
当一个 Keycloak 节点更新共享数据库中的数据时,所有其他节点都需要意识到这一点,以便它们从其缓存中使该数据失效。
work
缓存是一个复制缓存,用于发送这些失效消息。此缓存中的条目/消息非常短暂,你不应期望此缓存的大小随时间增长。
每当用户尝试进行身份验证时,都会创建身份验证会话。一旦身份验证过程完成或由于达到其过期时间,它们将自动销毁。
authenticationSessions
分布式缓存用于存储身份验证会话以及在身份验证过程中与之关联的任何其他数据。
通过依赖可分布式缓存,身份验证会话可供集群中的任何节点使用,以便可以将用户重定向到任何节点而不会丢失其身份验证状态。但是,生产就绪型部署应始终考虑会话亲缘性,并倾向于将用户重定向到最初创建其会话的节点。通过这样做,你将避免节点之间不必要的状态转移,并提高 CPU、内存和网络利用率。
一旦用户通过身份验证,就会创建一个用户会话。用户会话跟踪你的活动用户及其状态,以便他们可以无缝地向任何应用程序进行身份验证,而无需再次被要求提供凭据。对于用户使用客户端会话进行身份验证的每个应用程序,服务器可以跟踪用户通过身份验证的应用程序及其在每个应用程序上的状态。
每当用户执行注销、客户端执行令牌撤销或由于达到其过期时间时,用户和客户端会话都会自动销毁。
会话数据默认存储在数据库中,并按需加载到以下缓存中
sessions
clientSessions
通过依赖可分布式缓存,缓存的用户和客户端会话可供集群中的任何节点使用,以便可以将用户重定向到任何节点,而无需从数据库加载会话数据。但是,生产就绪型部署应始终考虑会话亲缘性,并倾向于将用户重定向到最初创建其会话的节点。通过这样做,你将避免节点之间不必要的状态转移,并提高 CPU、内存和网络利用率。
这些用于用户会话和客户端会话的内存缓存默认限制为每个节点 10000 个条目,这减少了大型安装中 Keycloak 的总体内存使用量。内部缓存将为每个缓存条目仅运行一个所有者。考虑内存消耗与数据库利用率之间的权衡,并为缓存设置不同的大小,编辑 Keycloak 的缓存配置文件 (conf/cache-ispn.xml
) 以为这些缓存设置 <memory max-count="..."/>
。
默认情况下,用户会话存储在数据库中,并按需加载到缓存中。可以配置 Keycloak 仅将用户会话存储在缓存中,并最大限度地减少数据库利用率。
由于此设置中的所有会话都存储在内存中,因此存在两个与此相关的副作用
当所有 Keycloak 节点重启时,会话丢失。
内存消耗增加。
按照以下步骤启用此设置
由于缓存是用户和客户端会话的唯一真实来源,请配置缓存以不限制条目数量,并将每个条目复制到至少两个节点。为此,请使用以下更新编辑 Keycloak 的缓存配置文件 (conf/cache-ispn.xml
),以用于 sessions
和 clientSessions
缓存
删除 <memory max-count="..."/>
将 distributed-cache
标记的 owners
属性更改为 2 或更多
sessions
缓存的最终配置示例如下所示。
<distributed-cache name="sessions" owners="2">
<expiration lifespan="-1"/>
</distributed-cache>
使用以下命令禁用 persistent-user-sessions
功能
bin/kc.sh start --features-disabled=persistent-user-sessions ...
当启用 |
作为 OpenID Connect 提供商,服务器还能够对用户进行身份验证并颁发离线令牌。与常规用户和客户端会话类似,当服务器在成功身份验证后颁发离线令牌时,服务器还会创建一个离线用户会话和一个离线客户端会话。
以下缓存用于存储离线会话
offlineSessions
offlineClientSessions
与常规用户和客户端会话缓存类似,离线用户和客户端会话缓存也默认限制为每个节点 10000 个条目。从内存中逐出的项目将在需要时按需从数据库加载。考虑内存消耗与数据库利用率之间的权衡,并为缓存设置不同的大小,编辑 Keycloak 的缓存配置文件 (conf/cache-ispn.xml
) 以为这些缓存设置 <memory max-count="..."/>
。
loginFailures
分布式缓存用于跟踪有关失败登录尝试的数据。此缓存是暴力破解保护功能在多节点 Keycloak 部署中正常工作所必需的。
操作令牌用于用户需要异步确认操作的场景,例如在忘记密码流程发送的电子邮件中。actionTokens
分布式缓存用于跟踪有关操作令牌的元数据。
为了减少内存使用量,可以对给定缓存中存储的条目数设置上限。要指定缓存的上限,你必须提供以下命令行参数 --cache-embedded-${CACHE_NAME}-max-count=
,其中 ${CACHE_NAME}
替换为你想要应用上限的缓存名称。例如,要对 offlineSessions
缓存应用 1000
的上限,你可以配置 --cache-embedded-offline-sessions-max-count=1000
。以下缓存无法定义上限:actionToken
、authenticationSessions
、loginFailures
、work
。
分布式缓存将缓存条目复制到集群中节点的一个子集,并将条目分配给固定的所有者节点。
每个分布式缓存,即数据的主要真实来源 (authenticationSessions
、loginFailures
和 actionTokens
),默认情况下有两个所有者,这意味着两个节点具有特定缓存条目的副本。非所有者节点查询特定缓存的所有者以获取数据。当两个所有者节点都离线时,所有数据都会丢失。
默认的所有者数量足以在至少三个节点的集群设置中承受 1 个节点(所有者)的故障。你可以自由更改所有者的数量,以更好地满足你的可用性要求。要更改所有者的数量,请打开 conf/cache-ispn.xml
并将分布式缓存的 owners=<value>
值更改为你期望的值。
要指定你自己的缓存配置文件,请输入此命令
bin/kc.[sh|bat] start --cache-config-file=my-cache-file.xml
配置文件相对于 conf/
目录。
为了配置 Keycloak 服务器以实现高可用性和多节点集群部署,引入了以下 CLI 选项 cache-remote-host
、cache-remote-port
、cache-remote-username
和 cache-remote-password
,从而简化了 XML 文件中的配置。一旦存在任何声明的 CLI 参数,则表示 XML 文件中不存在与远程存储相关的配置。
不建议在生产环境中禁用安全性! |
在开发或测试环境中,启动不安全的 Infinispan 服务器更容易。对于这些用例,CLI 选项 cache-remote-tls-enabled
禁用 Keycloak 和 Infinispan 之间的加密 (TLS)。如果 Infinispan 服务器配置为仅接受加密连接,Keycloak 将无法启动。
CLI 选项 cache-remote-username
和 cache-remote-password
是可选的,如果未设置,Keycloak 将在不提供任何凭据的情况下连接到 Infinispan 服务器。如果 Infinispan 服务器已启用身份验证,Keycloak 将无法启动。
传输堆栈确保集群中的 Keycloak 节点以可靠的方式进行通信。Keycloak 支持广泛的传输堆栈
jdbc-ping
(默认)
kubernetes
jdbc-ping-udp
(已弃用)
tcp
(已弃用)
udp
(已弃用)
ec2
(已弃用)
azure
(已弃用)
google
(已弃用)
要应用特定的缓存堆栈,请输入此命令
bin/kc.[sh|bat] start --cache-stack=<stack>
当启用分布式缓存时,默认堆栈设置为 jdbc-ping
,这与 Keycloak 26.x 版本流中的默认值向后兼容。
下表显示了可用的传输堆栈,除了使用 --cache-stack
运行时选项外,无需任何其他配置
堆栈名称 | 传输协议 | 发现 |
---|---|---|
|
TCP |
使用 JGroups |
|
UDP |
使用 JGroups |
下表显示了可用的传输堆栈,它们使用 --cache-stack
运行时选项和最少配置
堆栈名称 | 传输协议 | 发现 |
---|---|---|
|
TCP |
使用 JGroups |
|
TCP |
使用 JGroups |
|
UDP |
使用 JGroups |
当使用 tcp
、udp
或 jdbc-ping-udp
堆栈时,每个集群必须使用不同的多播地址和/或端口,以便它们的节点形成不同的集群。默认情况下,Keycloak 使用 239.6.7.8
作为 jgroups.mcast_addr
的多播地址,使用 46655
作为 jgroups.mcast_port
的多播端口。
使用 -D<property>=<value> 通过 JAVA_OPTS_APPEND 环境变量或在 CLI 命令中传递属性。 |
其他堆栈
建议使用上述可用堆栈之一。Infinispan 提供了其他堆栈,但如何配置它们不在本指南的范围之内。有关更多文档,请参阅 设置 Infinispan 集群传输 和 自定义 JGroups 堆栈。
对于基于 TCP 的传输堆栈,默认启用使用 TLS 进行加密,这也是默认配置。只要你使用的是基于 TCP 的传输堆栈,就不需要额外的 CLI 选项或修改缓存 XML。
如果你使用的是基于
|
启用 TLS 后,Keycloak 会自动生成自签名 RSA 2048 位证书以保护连接,并使用 TLS 1.3 来保护通信。密钥和证书存储在数据库中,因此所有节点都可以使用它们。默认情况下,证书有效期为 60 天,并在运行时每 30 天轮换一次。使用选项 cache-embedded-mtls-rotation-interval-days
来更改此设置。
尽管不建议用于标准设置,但如果在特定设置中至关重要,你可以手动配置包含传输堆栈证书的密钥库。cache-embedded-mtls-key-store-file
设置密钥库的路径,cache-embedded-mtls-key-store-password
设置解密密钥库的密码。信任库包含接受连接的有效证书,可以使用 cache-embedded-mtls-trust-store-file
(信任库的路径)和 cache-embedded-mtls-trust-store-password
(解密信任库的密码)进行配置。为了限制未经授权的访问,请始终为每个 Keycloak 部署使用自签名证书。
为了确保 Keycloak 集群的健康运行,需要打开一些网络端口。下表显示了 jdbc-ping
堆栈需要打开的 TCP 端口,以及通过这些端口的流量描述。
端口 | 属性 | 描述 |
---|---|---|
|
|
单播数据传输。 |
|
|
协议 |
使用 -D<property>=<value> 在你的 JAVA_OPTS_APPEND 环境变量或 CLI 命令中修改上述端口。 |
为了确保 Keycloak 集群的健康运行,网络端口必须绑定到可以从集群的所有其他节点访问的接口上。
默认情况下,它会选择站点本地(不可路由)IP 地址,例如,来自 192.168.0.0/16 或 10.0.0.0/8 地址范围。
要覆盖该地址,请设置 jgroups.bind.address
属性。
使用 -Djgroups.bind.address=<IP> 在你的 JAVA_OPTS_APPEND 环境变量或 CLI 命令中修改绑定地址。 |
要设置为仅 IPv6 并让 Keycloak 自动选择绑定地址,请使用以下设置
export JAVA_OPTS_APPEND="-Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true"
如果你在不同的网络上运行 Keycloak 实例,例如在防火墙或容器后面,则不同的实例将无法通过其本地 IP 地址相互访问。在这种情况下,请为它们的本地 IP 地址设置端口转发规则(有时称为“虚拟服务器”)。
当使用端口转发时,请使用以下属性,以便每个节点都正确地将其外部地址通告给其他节点
属性 | 描述 |
---|---|
|
Keycloak 集群中的其他实例应使用此端口来联系此节点。 |
|
Keycloak 集群中的其他实例应使用此 IP 地址来联系此节点。 |
使用 -D<property>=<value> 在你的 JAVA_OPTS_APPEND 环境变量或 CLI 命令中设置此属性。 |
当指标启用时,缓存中的指标会自动公开。
要为缓存指标启用直方图,请将 cache-metrics-histograms-enabled
设置为 true
。虽然这些指标提供了对延迟分布的更深入了解,但收集它们可能会对性能产生影响,因此你应该谨慎地在已经饱和的系统中激活它们。
bin/kc.[sh|bat] start --metrics-enabled=true --cache-metrics-histograms-enabled=true
有关如何启用指标的更多详细信息,请参阅 通过指标获得洞察力。
值 | |
---|---|
|
|
|
|
仅当指标启用时可用 |
|
仅当 'cache' 类型设置为 'ispn' 时可用 使用 'jdbc-ping' 代替 已弃用值: |
|
值 | |
---|---|
|
|
仅当配置了嵌入式 Infinispan 集群时可用 |
|
|
|
|
|
仅当使用基于 TCP 的 cache-stack 时可用 |
|
仅当启用属性 'cache-embedded-mtls-enabled' 时可用 |
|
仅当启用属性 'cache-embedded-mtls-enabled' 时可用 |
|
仅当启用属性 'cache-embedded-mtls-enabled' 时可用 |
(默认) |
仅当启用属性 'cache-embedded-mtls-enabled' 时可用 |
|
仅当启用属性 'cache-embedded-mtls-enabled' 时可用 |
|
仅当配置了嵌入式 Infinispan 集群时可用 |
|
仅当配置了嵌入式 Infinispan 集群时可用 |
|
|
|
仅当配置了嵌入式 Infinispan 集群时可用 |
|
|