Keycloak配置和数据存储在关系数据库中,通常持久化到硬盘上。这包括领域设置、用户、组和角色成员资格、身份验证流程等数据。但用户会话只会存储在临时内存中的 infinispan 缓存中。因此,当 keycloak 服务器重新启动时,此缓存中的会话数据将会丢失。
需要重启Keycloak服务器的原因有很多。主要操作系统升级、Keycloak 服务器升级到新版本、对 keycloak 电子邮件模板应用更改或将 keycloak pod 重新调度到 kubernetes 或其他基于云的环境中的其他工作节点。
如何保留会话数据以在重新启动后继续存在。理想情况下,无需维护自定义 infinspan 服务器或使用 keycloak“离线会话”。
一种解决方案可能是简单地使用所谓的 keycloak “离线会话”,但这些会话也有巨大的缺点:
请参阅:https://www.keycloak.org/docs/latest/server_admin/#_offline-access
当 keycloak > 17 发布并使用全新的 quarkus 发行版时,这个问题还会存在吗? 因为在以下文章中声称诸如 容器优先方法、零停机升级和存储重新架构等目标.
正如您在问题中所写的那样,使用 Infinispan 将是首选解决方案。 Infinispan 有两种使用方式:
仅拥有Infinispan并不能解决会话丢失问题。但 Infinispan 缓存可以由数据库支持,例如Postgres 数据库。然后会话被存储在ISPN缓存和相应的数据库表中。这可以防止内部和外部 Infinispan 集群的会话丢失。
因此,解决您的问题的方法可能是配置内部 ISPN 缓存以使用数据库持久性。在你的cache-ispn.xml中这可能看起来像这样:
<cache-container name="keycloak">
<!-- other config ... -->
<replicated-cache name="sessions">
<expiration/>
<persistence>
<string-keyed-jdbc-store xmlns="urn:infinispan:config:store:jdbc:14.0" dialect="POSTGRES">
<connection-pool
connection-url="${env.ISPN_DATABASE_CONNECTION_URL}"
username="${env.ISPN_DATABASE_USERNAME:ispn}"
password="${env.INFINISPAN_DB_OWNER_PASSWORD:ispn}"
driver="org.postgresql.Driver"
properties-file="conf/ispn/infinispan-cache.properties"/>
<string-keyed-table create-on-start="true" prefix="ispn">
<id-column name="id" type="VARCHAR(255)"/>
<data-column name="data" type="bytea"/>
<timestamp-column name="ts" type="BIGINT"/>
<segment-column name="seg" type="INT"/>
</string-keyed-table>
</string-keyed-jdbc-store>
</persistence>
</replicated-cache>
<!-- other config ... -->
</cache-container
Keycloak 25 有一个预览功能“持久用户会话”,它将用户会话存储在其数据库中。如果内存中没有找到会话,则会从数据库加载会话,用户可以继续使用其会话,而无需重新进行身份验证。
来源:https://www.keycloak.org/2024/06/persistent-user-sessions-in-preview.html