Keycloak 生产巡检与运维清单 — IAM 运维日常健康检查与应急处理 | IDaaS Book
场景
你已经在生产环境跑起了 Keycloak 集群,Prometheus 监控也接了,备份脚本也写了。但运维不只是"配好就忘"——每天需要确认哪些指标?证书什么时候过期?磁盘是不是快满了?用户会话数是否异常暴涨?
这份清单来自多个 Keycloak 生产集群的实际运维经验,覆盖日常、每周和月度巡检项,以及常见 IAM 运维故障的应急响应步骤。
适用与不适用
| 适用 | 不适用 |
|---|---|
| Keycloak 24+ Quarkus 生产集群 | 开发环境(start-dev 模式) |
| 2 个以上节点的集群部署 | 单节点测试部署 |
| 已配置 Prometheus + Grafana 监控 | 没有监控手段的裸部署 |
| 运维人员需要标准化巡检流程 | 初次部署(先看 Kubernetes 生产部署指南) |
日常巡检(每天)
以下检查项应在每天开始工作前完成,单次耗时不超过 5 分钟。
1. 节点存活检查
# 检查每个节点的健康端点
for node in keycloak-0 keycloak-1 keycloak-2; do
curl -s -o /dev/null -w "%{http_code}" "https://${node}.internal/health/live"
echo " ${node}"
done期望输出:全部返回 200。健康端点在 Quarkus 中默认启用(/health/live 和 /health/ready),不需要额外配置。
2. 会话数量趋势
# 通过 Prometheus 查询活跃会话数
# Metrics: keycloak_sessions_total关注点:如果会话数突然翻倍或骤降 50% 以上,可能是以下原因:
- 会话突然翻倍:Token 刷新循环或客户端配置错误导致频繁创建新会话
- 会话骤降:节点被踢出集群(检查 Infinispan 集群状态)或负载均衡器健康检查失败
正常波动范围:工作日 ±20% 属于正常。突发流量(如全员早会登录)短暂峰值后可回落。
3. 登录失败率
# PromQL:登录错误占比
rate(keycloak_failed_login_attempts_total[5m]) /
rate(keycloak_login_attempts_total[5m]) * 100阈值:失败率 > 10% 告警。常见原因:
- 用户密码过期(批量到期)
- LDAP/AD 后端不可达(IAM 身份源故障)
- 暴力破解攻击(检查 暴力破解检测 日志)
4. JVM 内存与 GC
# 堆内存使用率
jvm_memory_used_bytes{area="heap"} / jvm_memory_max_bytes{area="heap"} * 100阈值:堆内存使用率持续 > 80% 应排查。常见原因:
- 会话缓存膨胀(用户数增长,缓存没设上限)
- 内存泄漏(检查
jvm_memory_pool_bytes_used的趋势) - JVM 参数不当(生产建议
-Xmx至少 2G)
5. 磁盘使用率
# 检查数据目录大小
du -sh /opt/keycloak/data/关注项:
data/h2/仅在开发模式使用,生产应指向外部数据库data/log/日志轮转是否正常(不应出现单个日志文件超过 500MB)data/tmp/定期清理,避免临时文件堆积
每周巡检
6. 证书到期检查
Keycloak 涉及多类证书,任一过期都会导致服务不可用:
| 证书类型 | 检查方式 | 到期前告警 |
|---|---|---|
| HTTPS 证书(Ingress/TLS) | openssl s_client -connect | 30 天 |
| ID Token 签名密钥(RS256/ES256) | Keycloak Admin Console → Realm Settings → Keys | 30 天 |
| JGroup 集群通信证书 | keytool -list -v -keystore | 30 天 |
| 数据库 TLS 证书 | openssl s_client -connect db:5432 -starttls postgres | 30 天 |
| LDAPS 证书 | openssl s_client -connect ad-server:636 | 30 天 |
# 批量检查 HTTPS 证书到期时间
echo | openssl s_client -servername idaas.example.com -connect idaas.example.com:443 2>/dev/null | openssl x509 -noout -enddateKeycloak 的 Realm 密钥有两组开关:Active(是否可用于签名)与 Enabled(是否启用)。轮换时应先把新密钥加入并保持 Active=Off(被动:公钥已发布、不参与签名),确认验签方都已刷新到新公钥后,再通过优先级让它成为签名密钥;旧密钥先留在被动状态,等超过最大令牌寿命与离线令牌刷新周期后再禁用或删除。直接禁用(Enabled=Off)会让公钥立刻从 JWKS 消失,正在流通的令牌立即验签失败。轮换顺序与等待时间的推导见
IAM 签名密钥轮换排错。
7. 数据库连接池
# 活跃连接数 vs 最大连接数
hikaricp_connections_active / hikaricp_connections_max阈值:活跃连接 > 80% 最大值时告警。排查方向:
- 慢查询导致连接堆积
- 连接池太小(生产建议
db-pool-initial-size=10,db-pool-max-size=50)
8. 备份验证
# 检查最近备份文件是否正常
ls -lh /backup/keycloak/$(date +%Y%m%d)*
# 实际恢复测试:在 staging 环境还原备份重要:备份不验证等于没备份。每周在隔离环境做一次还原测试,确认:
- 数据库 dump 可正常导入
- Realm JSON 导出可正常导入
- 用户密码哈希迁移后仍可登录
用 keycloak-config-cli 做配置即代码的部署,还要额外核对一次「Git 声明是否真的被应用」:读取 realm attributes 中 de.adorsys.keycloak.config.* 前缀的 state 与 checksum 条目,与最近一次流水线运行的 checksum 对齐。这一步能发现「流水线静默跳过」的情况——checksum 一致时工具不对 realm 做任何写入,但 CI 依然是绿的,从流水线状态上完全看不出配置没生效。判定机制与排错见
IAM 配置即代码:keycloak-config-cli 声明式 Realm 管理与误删防护。
9. 用户会话异常审计
# 按客户端统计活跃会话
keycloak_sessions_total by (realm, client_id)关注:某客户端会话数异常(如测试客户端突然有 500+ 活跃会话),可能是:
- 测试脚本忘了关
- 客户的 Refresh Token 循环(每 30 秒刷新一次,需要检查客户端配置)
月度巡检
10. 性能基线对比
记录以下指标作为月度基线,与上月对比:
| 指标 | 记录方式 | 异常阈值 |
|---|---|---|
| 登录 P99 延迟 | Prometheus keycloak_request_duration_seconds 分位数 | 比上月增加 50% |
| Token 签发 QPS | rate(keycloak_token_requests_total[1h]) | 用于容量规划 |
| 数据库查询延迟 | HikariCP metrics | > 100ms P99 |
| Infinispan 集群通讯延迟 | JGroups metrics | > 50ms avg |
| 平均会话时长 | keycloak_session_duration_seconds | 监控用户行为变化 |
11. 用户与角色审计
IAM 权限的"熵增"是不可逆的——权限只会越来越多,不会自动减少。月度审计项:
- 过去 30 天内新增的管理员账号列表(检查是否有未授权的管理员创建)
- 拥有
realm-admin角色的用户清单(是否都是已知运维人员) - 30 天未登录的用户(是否应该禁用)
- 未使用的 Client/Scope/Role(考虑清理或归档)
# 通过 Admin REST API 查询管理员用户
curl -s "https://keycloak.example.com/admin/realms/{realm}/roles/realm-admin/users" \
-H "Authorization: Bearer ${TOKEN}" | jq '.[].username'12. 日志审计抽样
随机抽取过去 24 小时的 100 条 ADMIN_EVENT,检查:
- 是否有非工作时间的配置变更
- 是否有异常的 IP 来源(如境外 IP 操作管理后台)
DELETE操作是否有对应的审计记录
13. 升级窗口准备(按需触发)
每次准备升级 Keycloak 前过一遍,其中的判定必须用真实二进制跑,不要按印象决定要不要排停机窗口:
- 在旧版本上生成元数据:
kc.sh update-compatibility metadata --file=/tmp/kc-compat.json,配置项与生产完全一致(从 Deployment/StatefulSet 的 env 或 Operator CR 导出,不要凭记忆敲) - 在新版本上判定:
kc.sh update-compatibility check --file=/tmp/kc-compat.json,退出码0可滚动、3/4必须停机 - 本次变更是否包含
--db*、--cache*或特性开关?包含则一定停机,且不要与版本升级合并成一次变更 - Operator 部署:确认
spec.update.strategy不是默认的RecreateOnImageChange(默认策略下 image tag 一变就是重建停机) - 负载均衡遵循 readiness probe;节点关闭日志里有
Keycloak stopped in ...s - 数据库备份已生成、并在隔离环境验证过可恢复(这是唯一的回滚手段)
- 变更窗口已包含「恢复数据库」的耗时,而不是「回退镜像」的耗时
判定命令、强制停机的变更清单与回滚顺序见 Keycloak 升级与零停机滚动更新:IAM 升级判定、数据库迁移与回滚。
告警规则速查
建议在 Prometheus AlertManager 中配置以下规则:
groups:
- name: keycloak
rules:
- alert: KeycloakNodeDown
expr: up{job="keycloak"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Keycloak node {{ $labels.instance }} is down"
- alert: KeycloakHighLoginFailureRate
expr: |
rate(keycloak_failed_login_attempts_total[5m])
/ rate(keycloak_login_attempts_total[5m]) > 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "Login failure rate > 10% in realm {{ $labels.realm }}"
- alert: KeycloakHighHeapUsage
expr: |
jvm_memory_used_bytes{area="heap"}
/ jvm_memory_max_bytes{area="heap"} > 0.85
for: 10m
labels:
severity: warning
annotations:
summary: "JVM heap usage > 85% on {{ $labels.instance }}"
- alert: KeycloakCertificateExpiry
expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 14
for: 1h
labels:
severity: warning
annotations:
summary: "TLS certificate expires in less than 14 days"常见 IAM 运维应急场景
场景一:所有节点同时不可达
症状:/health/live 全部返回非 200,用户登录失败
应急步骤:
- 检查数据库是否存活——Keycloak 强依赖数据库,数据库挂了所有节点不可用
- 检查 Kubernetes Node/基础设施——是否发生了节点驱逐或网络分区
- 如果数据库正常但 Keycloak 异常,优先重启一个节点,观察日志中的启动错误
- 不要在数据库恢复前同时重启所有节点——可能导致 Infinispan 集群分裂
场景二:用户批量无法登录
症状:故障率从 2% 突然跳到 30%+,大量用户报告"账号或密码错误"
应急步骤:
- 确认是否某个 Identity Provider(LDAP/AD)不可达——IAM 身份源故障是批量登录失败的首要原因
- 检查 LDAP 连接配置:
test ldap-connection或ldapsearch -H ldaps://ad-server -D "cn=bind-user" -w ${PASSWORD} -b "dc=example,dc=com" - 如果 LDAP 正常,检查 Realm 级的
bruteForceDetection是否误封了大量用户
场景三:磁盘空间不足
症状:Keycloak 日志报 No space left on device,节点不可写
应急步骤:
- 立即清理过期日志:
find /opt/keycloak/data/log -name "*.log" -mtime +7 -delete - 检查数据目录是否有异常大文件:
du -sh /opt/keycloak/data/* | sort -rh | head -10 - 如果是数据库磁盘满(外部 PostgreSQL),优先清理审计事件表(
event_entity表可能非常大)
场景四:管理控制台进不去(管理员访问丢失)
症状:所有服务正常、用户能在应用侧登录,但没有人能登录管理控制台——管理员密码丢失、管理员账号被误删,或密码正确却卡在 OTP/passwordless 步骤。
应急步骤:
- 先确认不是暴力破解检测的临时锁定:短时间连续失败会被临时拒绝,这不是账号丢失,等待锁定窗口即可。
- 确认 master realm 里还有哪些管理员账号可用(其它运维同事手上的凭据、受管密码库)。
- 全都不可用时走停服恢复:所有节点降到 0 副本 → 用与服务器相同的 db 选项执行
kc.sh bootstrap-admin user(或强化认证场景下的bootstrap-admin service)→ 用临时账号建正式管理员并重置原凭据 → 删除临时账号。
完整命令、--optimized 与 db 选项前提、常见错误对照见
Keycloak 管理员账号进不去:bootstrap-admin 恢复与 26.x 变量变更。
预防:至少保留两个长期管理员账号、凭据入密码库、强化认证配置备用凭据——否则每次故障都必须付出一次停服代价。
IAM 运维 FAQ
Q1:IAM 运维和普通应用运维有什么本质区别?
IAM 是基础设施中的"基础设施"——如果 IAM 挂了,所有依赖它的应用都无法登录。这决定了 IAM 运维的两个特点:
- 可用性要求极高:IAM 不可用 = 全公司停工,SLA 通常要求 99.95% 以上
- 安全与便利的平衡:紧急恢复时可能需要临时放宽安全策略(如关闭 MFA),但事后必须记录和回滚
Q2:Keycloak 有内置的巡检工具吗?
Keycloak 本身没有一键巡检命令。但可以从以下三个维度组合使用:
/health/live和/health/ready端点(存活和就绪检测)/metrics端点暴露的 Prometheus 指标(需要启用--metrics-enabled=true)- Admin REST API(查询用户数、会话数、事件审计)
建议基于上述接口编写运维脚本,而非在控制台手动点检。
Q3:IAM 证书轮换时如何做到不中断服务?
Keycloak 的 Realm 密钥支持多密钥共存,但"新密钥设为 PASSIVE 等 24 小时"这个说法漏了两个关键点:被动密钥的公钥是发布出去的(JWKS 只按"启用且有公钥"过滤),所以新密钥设为被动即可让验签方提前拿到;而新密钥要成为签名密钥由 provider 优先级决定,不是把 Active 打开就行。完整顺序:
- 新建密钥 provider,保持
Active=Off(被动:公钥已发布、不参与签名); - 等待超过所有验签方的 JWKS 缓存上界(Spring Security 默认 5 分钟、Envoy 默认 10 分钟、Istio 侧见对应文章,取最大值并留余量);
- 提高它的优先级使其成为签名密钥,旧密钥保持被动;
- 等超过 Access Token 寿命、SSO 会话空闲上限与离线令牌刷新周期后,再禁用或删除旧密钥。
第 4 步之前不要禁用旧密钥:Enabled=Off 会让公钥立刻从 JWKS 消失。各组件默认值的来源、误禁用后的恢复路径与不可回滚的 not-before 推送见
IAM 签名密钥轮换排错:Keycloak 的 kid、JWKS 缓存与切换顺序,官方流程见
Keycloak 密钥轮换文档。
Q4:如何评估 Keycloak 需要扩容?
纬度 → 指标 → 阈值:
| 信号 | 指标 | 扩缩动作 |
|---|---|---|
| CPU 持续高负载 | process_cpu_usage > 0.7 超过 30 分钟 | 扩容节点或增加 CPU request |
| 内存 GC 频繁 | jvm_gc_pause_seconds P99 > 500ms | 增加 heap 或扩容节点 |
| 登录 QPS 接近上限 | 单节点 keycloak_token_requests > 预期的 80% | 扩容节点 |
| 数据库连接池耗尽 | hikaricp_connections_pending > 0 | 先优化慢查询,再扩容连接池 |
先垂直扩容(增加 CPU/Memory),再水平扩容(增加节点)。Keycloak 的 Infinispan 分布式缓存在节点数变化时需要重新平衡,扩容超过 4 个节点时回报递减明显。
小结
IAM 运维的核心不是"会不会配",而是"能不能在凌晨三点被叫起来时,30 分钟内定位问题并恢复服务"。这份清单的价值在于把隐性知识显性化——每周照着走一遍,大多数问题在变成事故之前就能被发现。
配合 Keycloak 集群缓存调优指南 中的缓存排错和 Keycloak 高可用与灾难恢复 中的容灾架构,可以建立完整的 IAM 运维体系。