由时钟偏差导致的 Gitaly PermissionDenied
问题描述
-
在 GitLab UI 中访问与存储库相关的页面时返回 HTTP 500。
-
Gitaly pod 日志包含以下关键字:
-
Gitaly pod 的系统时间与
webservice/sidekiqpod 的系统时间相差数秒或更多。
根本原因
Gitaly 使用包含时间戳声明的 JWT 对其客户端(webservice、sidekiq)进行身份验证。如果节点时钟发生漂移,Gitaly 端会将 JWT 视为已过期或尚未生效,并以 PermissionDenied 拒绝 RPC。实际情况下,超过 ~30 秒的漂移通常会触发此问题,但确切的容差取决于 JWT 库的宽限期设置。
时钟漂移的常见原因:
- 集群节点未配置 NTP,或 NTP 服务未运行。
- 已配置 NTP,但无法访问上游时间源(例如被防火墙阻止)。
- 节点运行在实时硬件时钟(RTC)不准确的硬件上,并且从未进行过同步。
故障排除
-
在 Gitaly 日志中确认
PermissionDenied关键字: -
比较 Gitaly pod 和客户端 pod(
webservice或sidekiq)报告的时间。相差数秒以上则需要引起怀疑: -
确定受影响 pod 所在的节点,然后直接检查主机时钟:
在每个节点上检查系统时钟是否已与 NTP 源同步。如果 NTP 未处于活动状态,则该节点是产生漂移的源头。
解决方案
前提条件
- 具备对所有集群节点的 SSH 访问权限(重新调度后,这些 pod 可能由任意节点承载)。
- 具备重启 GitLab 组件的权限。
注意事项
- 更改运行中节点的系统时间是一项敏感操作。请尽可能在维护窗口期间执行。
- 大幅向后调整时间可能会干扰数据库和分布式系统。应优先采用逐步调整,而不是使用
date -s之类的硬跳变。
步骤
-
在每个集群节点上配置 NTP,并确保服务处于活动状态。具体工具(chrony、systemd-timesyncd、ntpd 等)取决于操作系统,本文不作介绍。完成更改后,确认每个节点的系统时钟都已与上游时间源同步。
-
在时钟对齐后重启 GitLab 组件,使其签发新的 JWT。请根据您的发行版调整工作负载名称:
-
验证修复结果:
- Gitaly 日志不再输出
PermissionDenied条目。 - GitLab UI 中的存储库页面返回 200。
- 在 Gitaly 和 webservice pod 内执行的
date -u现在相差小于一秒。
- Gitaly 日志不再输出
提示
- 如需快速检查整个集群的时间偏差,请在每个节点上运行
date -u并进行比较;任何偏离值较大的节点都可能是问题节点。
GitLab 是 GitLab Inc. 的商标。
Alauda 是独立供应商。本产品与 GitLab Inc. 没有关联,也未获得其认可或赞助。所有商标均归其各自所有者所有,仅用于识别目的。