bin/kc.[sh|bat] start --cache=ispn
Keycloak 旨在实现高可用性和多节点集群设置。当前的分布式缓存实现构建在 Infinispan 之上,Infinispan 是一款高性能、可分布式的内存数据网格。
当您使用 start
命令在生产模式下启动 Keycloak 时,缓存将被启用,并且网络中的所有 Keycloak 节点都将被发现。
默认情况下,缓存使用 UDP 传输栈,以便节点使用基于 UDP 的 IP 多播传输进行发现。对于大多数生产环境而言,存在比 UDP 更好的发现替代方案。Keycloak 允许您从一组预定义的默认传输栈中选择,或者定义您自己的自定义栈,正如您将在本指南的后面部分看到的那样。
要显式启用分布式 infinispan 缓存,请输入以下命令
bin/kc.[sh|bat] start --cache=ispn
当您使用 start-dev
命令在开发模式下启动 Keycloak 时,Keycloak 只使用本地缓存,并且分布式缓存通过隐式设置 --cache=local
选项而完全禁用。local
缓存模式仅供开发和测试之用。
Keycloak 提供了一个带有合理默认值的缓存配置文件,位于 conf/cache-ispn.xml
中。
缓存配置是一个常规的 Infinispan 配置文件。
下表概述了 Keycloak 使用的特定缓存。您可以在 conf/cache-ispn.xml
中配置这些缓存
缓存名称 | 缓存类型 | 描述 |
---|---|---|
realms |
本地 |
缓存持久化的 realm 数据 |
users |
本地 |
缓存持久化的用户数据 |
authorization |
本地 |
缓存持久化的授权数据 |
keys |
本地 |
缓存外部公钥 |
work |
复制 |
在节点之间传播失效消息 |
authenticationSessions |
分布式 |
缓存身份验证会话,在身份验证过程中创建/销毁/过期 |
sessions |
分布式 |
缓存持久化的用户会话数据 |
clientSessions |
分布式 |
缓存持久化的客户端会话数据 |
offlineSessions |
分布式 |
缓存持久化的离线用户会话数据 |
offlineClientSessions |
分布式 |
缓存持久化的离线客户端会话数据 |
loginFailures |
分布式 |
跟踪登录失败,欺诈检测 |
actionTokens |
分布式 |
缓存操作令牌 |
Keycloak 在本地缓存持久数据,以避免不必要的往返数据库。
以下数据使用本地缓存保存在集群中的每个节点上
realms 和相关数据,如客户端、角色和组。
users 和相关数据,如授予的角色和组成员资格。
authorization 和相关数据,如资源、权限和策略。
keys
realm、用户和授权的本地缓存默认配置为最多保存 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 支持各种传输堆栈
tcp
udp
kubernetes
ec2
azure
要应用特定缓存堆栈,请输入以下命令
bin/kc.[sh|bat] start --cache-stack=<stack>
当启用分布式缓存时,默认堆栈设置为 udp
。
下表显示了无需任何进一步配置即可使用 --cache-stack
构建选项使用的可用传输堆栈
堆栈名称 | 传输协议 | 发现 |
---|---|---|
tcp |
TCP |
MPING(使用 UDP 多播)。 |
udp |
UDP |
UDP 多播 |
下表显示了使用 --cache-stack
运行时选项和最小配置即可使用的传输堆栈
堆栈名称 | 传输协议 | 发现 |
---|---|---|
kubernetes |
TCP |
DNS_PING(需要将 |
下表显示了 Keycloak 支持的传输堆栈,但需要一些额外的步骤才能工作。请注意,这些堆栈都不是 Kubernetes / OpenShift 堆栈,因此如果要在 Google Kubernetes 引擎上运行 Keycloak,则无需启用 google
堆栈。在这种情况下,请使用 kubernetes
堆栈。相反,如果您有一个在 AWS EC2 实例上运行的分布式缓存设置,则需要将堆栈设置为 ec2
,因为 ec2 不支持 UDP 等默认发现机制。
堆栈名称 | 传输协议 | 发现 |
---|---|---|
ec2 |
TCP |
NATIVE_S3_PING |
TCP |
GOOGLE_PING2 |
|
azure |
TCP |
AZURE_PING |
云供应商特定堆栈对 Keycloak 有额外的依赖项。有关这些依赖项的更多信息和指向存储库的链接,请参阅 Infinispan 文档。
要为 Keycloak 提供依赖项,请将相应的 JAR 文件放在 providers
目录中,然后通过输入以下命令构建 Keycloak
bin/kc.[sh|bat] start --cache-stack=<ec2|google|azure>
如果可用的传输堆栈都不适合您的部署,您可以更改缓存配置文件并定义自己的传输堆栈。
有关更多详细信息,请参阅 使用内联 JGroups 堆栈。
<jgroups>
<stack name="my-encrypt-udp" extends="udp">
<SSL_KEY_EXCHANGE keystore_name="server.jks"
keystore_password="password"
stack.combine="INSERT_AFTER"
stack.position="VERIFY_SUSPECT2"/>
<ASYM_ENCRYPT asym_keylength="2048"
asym_algorithm="RSA"
change_key_on_coord_leave = "false"
change_key_on_leave = "false"
use_external_key_exchange = "true"
stack.combine="INSERT_BEFORE"
stack.position="pbcast.NAKACK2"/>
</stack>
</jgroups>
<cache-container name="keycloak">
<transport lock-timeout="60000" stack="my-encrypt-udp"/>
...
</cache-container>
默认情况下,设置为 cache-stack
选项的值优先于您在缓存配置文件中定义的传输堆栈。如果您正在定义自定义堆栈,请确保未使用 cache-stack
选项,以便自定义更改生效。
当前的 Infinispan 缓存实现应该通过各种安全措施(如 RBAC、ACL 和传输堆栈加密)来保护。
JGroups 处理 Keycloak 服务器之间的所有通信,并且它支持用于 TCP 通信的 Java SSL 套接字。Keycloak 使用 CLI 选项来配置 TLS 通信,而无需创建自定义 JGroups 堆栈或修改缓存 XML 文件。
要启用 TLS,cache-embedded-mtls-enabled
必须设置为 true
。它需要一个带有要使用的证书的密钥库: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 部署使用自签名证书。
对于具有 UDP
或 TCP_NIO2
的 JGroups 堆栈,请参阅 JGroups 加密文档,了解如何设置协议堆栈。
有关保护缓存通信的更多信息,请参阅 Infinispan 安全指南。
启用指标后,缓存的指标会自动公开。
要为缓存指标启用直方图,请将 cache-metrics-histograms-enabled
设置为 true
。虽然这些指标提供了更多关于延迟分布的洞察,但收集它们可能会对性能产生影响,因此您应该谨慎地在已经饱和的系统中激活它们。
bin/kc.[sh|bat] start --metrics-enabled=true --cache-metrics-histograms-enabled=true
有关如何启用指标的更多详细信息,请参阅 启用 Keycloak 指标。
值 | |
---|---|
|
|
|
|
|
|
仅在配置了嵌入式 Infinispan 集群时可用 |
|
|
|
|
|
|
|
|
|
|
|
|
|
仅在配置了嵌入式 Infinispan 集群时可用 |
|
仅在配置了嵌入式 Infinispan 集群时可用 |
|
|
|
仅在配置了嵌入式 Infinispan 集群时可用 |
|
|
|
仅在启用指标时可用 |
|
|
|
仅在设置了远程主机时可用 |
|
仅在设置了远程主机时可用 |
(默认) |
仅在设置了远程主机时可用 |
|
仅在设置了远程主机时可用 |
|
|
|