- 检查使用独立 Gitaly 服务器时的版本
- 查找存储资源详细信息
- 使用
gitaly-debug
- 当需要 Git 进行故障排除时使用
gitaly git
- 提交、推送和克隆返回 401
- 存储库页面上的 500 和
fetching folder content
错误 - 客户端 gRPC 日志
- 服务器端 gRPC 日志
- 将 Git 进程与 RPC 关联
- 存储库更改失败并出现
401 Unauthorized
错误 - 存储库推送失败并出现
401 Unauthorized
和JWT::VerificationError
- 命令行工具无法连接到 Gitaly
- 访问存储库时 Gitaly 或 Praefect 日志中出现权限被拒绝错误
- 重新配置后 Gitaly 未在新地址上监听
- 健康检查警告
- 文件未找到错误
- 启用 Dynatrace 时 Git 推送速度缓慢
gitaly check
失败并显示401
状态代码- 启用 Gitaly TLS 时新合并请求的更改(差异)未加载
- Gitaly 无法分叉存储在
noexec
文件系统上的进程 - 提交签名失败并显示
invalid argument
或invalid data
- Gitaly 日志在
info
消息中显示错误 - 分析 Gitaly
- 在极狐GitLab 还原后存储库显示为空
- 在启用
fapolicyd
的 RHEL 实例上推送时出现Pre-receive hook declined
错误 - 移除具有重复路径的存储后更新存储库
{{< details >}}
- Tier: 基础版,专业版,旗舰版
- Offering: 私有化部署
{{< /details >}}
在排查 Gitaly 问题时,请参考以下信息。有关 Gitaly 集群(Praefect)的故障排除信息,请参阅 故障排除 Gitaly 集群。
以下部分提供了可能的 Gitaly 错误解决方案。
另请参阅 Gitaly 超时 设置,以及我们关于 解析 gitaly/current
文件 的建议。
检查使用独立 Gitaly 服务器时的版本
使用独立 Gitaly 服务器时,必须确保它们与极狐GitLab 的版本一致,以确保完全兼容:
- 在左侧边栏底部,选择 管理员。
- 选择 概览 > Gitaly 服务器。
- 确认所有 Gitaly 服务器表明它们是最新的。
查找存储资源详细信息
您可以在 Rails 控制台 中运行以下命令,以确定 Gitaly 存储上的可用和已用空间:
Gitlab::GitalyClient::ServerService.new("default").storage_disk_statistics
# For Gitaly Cluster
Gitlab::GitalyClient::ServerService.new("<storage name>").disk_statistics
使用 gitaly-debug
gitaly-debug
命令为 Gitaly 和 Git 性能提供 “生产调试” 工具。它旨在帮助生产工程师和支持工程师调查 Gitaly 性能问题。
要查看 gitaly-debug
的帮助页面以获取支持的子命令列表,请运行:
gitaly-debug -h
当需要 Git 进行故障排除时使用 gitaly git
使用 gitaly git
执行 Git 命令,使用与 Gitaly 相同的 Git 执行环境进行调试或测试目的。gitaly git
是确保版本兼容性的首选方法。
gitaly git
将所有参数传递给底层的 Git 调用,并支持 Git 支持的所有形式输入。要使用 gitaly git
,请运行:
sudo -u git -- /opt/gitlab/embedded/bin/gitaly git <git-command>
例如,要在 Linux 软件包实例的存储库工作目录中通过 Gitaly 运行 git ls-tree
:
sudo -u git -- /opt/gitlab/embedded/bin/gitaly git ls-tree --name-status HEAD
提交、推送和克隆返回 401
remote: 极狐GitLab: 401 Unauthorized
您需要与您的极狐GitLab 应用节点同步 gitlab-secrets.json
文件。
存储库页面上的 500 和 fetching folder content
错误
Fetching folder content
,以及在某些情况下 500
,错误表明极狐GitLab 和 Gitaly 之间的连接问题。
咨询 客户端 gRPC 日志 以获取详细信息。
客户端 gRPC 日志
Gitaly 使用 gRPC RPC 框架。Ruby gRPC 客户端有自己的日志文件,当您看到 Gitaly 错误时,其中可能包含有用的信息。您可以使用 GRPC_LOG_LEVEL
环境变量控制 gRPC 客户端的日志级别。
默认级别是 WARN
。
您可以运行 gRPC 跟踪:
sudo GRPC_TRACE=all GRPC_VERBOSITY=DEBUG gitlab-rake gitlab:gitaly:check
如果此命令因 failed to connect to all addresses
错误失败,请检查 SSL 或 TLS 问题:
/opt/gitlab/embedded/bin/openssl s_client -connect <gitaly-ipaddress>:<port> -verify_return_error
检查 Verify return code
字段是否指示 已知 Linux 软件包安装配置问题。
如果 openssl
成功但 gitlab-rake gitlab:gitaly:check
失败,请检查 Gitaly 的 证书要求。
服务器端 gRPC 日志
gRPC 跟踪也可以在 Gitaly 中通过 GODEBUG=http2debug
环境变量启用。要在 Linux 软件包安装中设置此项:
-
将以下内容添加到您的
gitlab.rb
文件中:gitaly['env'] = { "GODEBUG=http2debug" => "2" }
-
重新配置 极狐GitLab。
将 Git 进程与 RPC 关联
有时您需要找出哪个 Gitaly RPC 创建了特定的 Git 进程。
一种方法是使用 DEBUG
日志。然而,这需要提前启用,并且生成的日志非常详细。
一种轻量级的方法是检查 Git 进程的环境(使用它的 PID
)并查看 CORRELATION_ID
变量:
PID=<Git process ID>
sudo cat /proc/$PID/environ | tr '\0' '\n' | grep ^CORRELATION_ID=
此方法对于 git cat-file
进程并不可靠,因为 Gitaly 在 RPC 之间内部池化并重复使用这些进程。
存储库更改失败并出现 401 Unauthorized
错误
如果您在自己的服务器上运行 Gitaly 并注意到这些情况:
- 用户可以成功克隆和获取存储库,使用 SSH 和 HTTPS。
- 用户无法推送到存储库,或在尝试在 Web UI 中对其进行更改时收到
401 Unauthorized
消息。
Gitaly 可能无法与 Gitaly 客户端进行身份验证,因为它具有错误的密钥文件。
确认以下所有条件均为真:
-
当任何用户对该 Gitaly 服务器上的任何存储库执行
git push
时,它会失败并出现401 Unauthorized
错误:remote: 极狐GitLab: 401 Unauthorized To <REMOTE_URL> ! [remote rejected] branch-name -> branch-name (pre-receive hook declined) error: failed to push some refs to '<REMOTE_URL>'
- 当任何用户使用极狐GitLab UI 从存储库添加或修改文件时,它会立即失败,并显示红色
401 Unauthorized
横幅。 - 创建新项目并 使用 README 初始化它 成功创建项目但未创建 README。
-
在 Gitaly 客户端上 尾随日志 并重现错误时,您会在访问
/api/v4/internal/allowed
端点时收到401
错误:# api_json.log { "time": "2019-07-18T00:30:14.967Z", "severity": "INFO", "duration": 0.57, "db": 0, "view": 0.57, "status": 401, "method": "POST", "path": "\/api\/v4\/internal\/allowed", "params": [ { "key": "action", "value": "git-receive-pack" }, { "key": "changes", "value": "REDACTED" }, { "key": "gl_repository", "value": "REDACTED" }, { "key": "project", "value": "\/path\/to\/project.git" }, { "key": "protocol", "value": "web" }, { "key": "env", "value": "{\"GIT_ALTERNATE_OBJECT_DIRECTORIES\":[],\"GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE\":[],\"GIT_OBJECT_DIRECTORY\":null,\"GIT_OBJECT_DIRECTORY_RELATIVE\":null}" }, { "key": "user_id", "value": "2" }, { "key": "secret_token", "value": "[FILTERED]" } ], "host": "gitlab.example.com", "ip": "REDACTED", "ua": "Ruby", "route": "\/api\/:version\/internal\/allowed", "queue_duration": 4.24, "gitaly_calls": 0, "gitaly_duration": 0, "correlation_id": "XPUZqTukaP3" } # nginx_access.log [IP] - - [18/Jul/2019:00:30:14 +0000] "POST /api/v4/internal/allowed HTTP/1.1" 401 30 "" "Ruby"
要解决此问题,请确认 Gitaly 服务器上的 gitlab-secrets.json
文件 与 Gitaly 客户端上的文件匹配。如果不匹配,请更新 Gitaly 服务器上的密钥文件以匹配 Gitaly 客户端,然后重新配置。
如果您已确认所有 Gitaly 服务器和客户端上的 gitlab-secrets.json
文件是相同的,应用程序可能正在从不同的文件中获取此密钥。您的 Gitaly 服务器的
config.toml 文件
指示正在使用的密钥文件。
存储库推送失败并出现 401 Unauthorized
和 JWT::VerificationError
尝试 git push
时,您可以看到:
-
401 Unauthorized
错误。 -
服务器日志中的以下内容:
{ ... "exception.class":"JWT::VerificationError", "exception.message":"Signature verification raised", ... }
这种错误组合发生在极狐GitLab 服务器已升级到极狐GitLab 15.5 或更高版本,但 Gitaly 尚未升级时。
从极狐GitLab 15.5 开始,极狐GitLab 使用 JWT 令牌而不是共享密钥与极狐GitLab Shell 进行身份验证。您应遵循 关于升级外部 Gitaly 的建议 并在极狐GitLab 服务器之前升级 Gitaly。
存储库推送失败并出现 deny updating a hidden ref
错误
Gitaly 有只读的、内部极狐GitLab 引用,用户不允许更新。如果您尝试使用 git push --mirror
更新内部引用,Git 会返回拒绝错误,deny updating a hidden ref
。
以下引用是只读的:
- refs/environments/
- refs/keep-around/
- refs/merge-requests/
- refs/pipelines/
要仅镜像推送分支和标签,并避免尝试镜像推送受保护的引用,请运行:
git push --force-with-lease origin 'refs/heads/*:refs/heads/*' 'refs/tags/*:refs/tags/*'
管理员希望推送的任何其他命名空间也可以通过额外的 refspecs 包含在内。
命令行工具无法连接到 Gitaly
如果:
- 您无法使用命令行工具连接到 Gitaly 服务器。
- 某些操作导致出现
14: Connect Failed
错误消息。
请验证您可以通过 TCP 连接到 Gitaly:
sudo gitlab-rake gitlab:tcp_check[GITALY_SERVER_IP,GITALY_LISTEN_PORT]
如果 TCP 连接:
- 失败,请检查您的网络设置和防火墙规则。
- 成功,您的网络和防火墙规则正确。
如果您在命令行环境中使用代理服务器(例如 Bash),这些可能会影响您的 gRPC 流量。
如果您使用 Bash 或兼容的命令行环境,运行以下命令以确定是否配置了代理服务器:
echo $http_proxy
echo $https_proxy
如果这些变量中的任何一个有值,您的 Gitaly CLI 连接可能会通过无法连接到 Gitaly 的代理进行路由。
要删除代理设置,请运行以下命令(取决于哪些变量有值):
unset http_proxy
unset https_proxy
访问存储库时 Gitaly 或 Praefect 日志中出现权限被拒绝错误
您可能会在 Gitaly 和 Praefect 日志中看到以下内容:
{
...
"error":"rpc error: code = PermissionDenied desc = permission denied: token has expired",
"grpc.code":"PermissionDenied",
"grpc.meta.client_name":"gitlab-web",
"grpc.request.fullMethod":"/gitaly.ServerService/ServerInfo",
"level":"warning",
"msg":"finished unary call with code PermissionDenied",
...
}
日志中的这些信息是 gRPC 调用错误响应代码。
如果此错误发生,即使 Gitaly 身份验证令牌已正确设置,很可能 Gitaly 服务器经历了时钟漂移。发送到 Gitaly 的身份验证令牌包含时间戳。为了被认为有效,Gitaly 要求时间戳在 Gitaly 服务器时间的 60 秒内。
确保 Gitaly 客户端和服务器同步,并使用网络时间协议 (NTP) 时间服务器使它们保持同步。
重新配置后 Gitaly 未在新地址上监听
更新 gitaly['configuration'][:listen_addr]
或 gitaly['configuration'][:prometheus_listen_addr]
值时,Gitaly 可能
在 sudo gitlab-ctl reconfigure
后继续监听旧地址。
发生这种情况时,运行 sudo gitlab-ctl restart
来解决问题。
健康检查警告
可以忽略 /var/log/gitlab/praefect/current
中的以下警告。
"error":"full method name not found: /grpc.health.v1.Health/Check",
"msg":"error when looking up method info"
文件未找到错误
可以忽略 /var/log/gitlab/gitaly/current
中的以下错误。
它们是由极狐GitLab Rails 应用程序检查存储库中不存在的特定文件引起的。
"error":"not found: .gitlab/route-map.yml"
"error":"not found: Dockerfile"
"error":"not found: .gitlab-ci.yml"
启用 Dynatrace 时 Git 推送速度缓慢
Dynatrace 可能会导致 sudo -u git -- /opt/gitlab/embedded/bin/gitaly-hooks
参考事务钩子,启动和关闭需要几秒钟。当用户推送时会两次执行 gitaly-hooks
,这导致显著延迟。
如果启用 Dynatrace 时 Git 推送速度过慢,请禁用 Dynatrace。
gitaly check
失败并显示 401
状态代码
如果 Gitaly 无法访问极狐GitLab 内部 API,gitaly check
可能会失败并显示 401
状态代码。
解决此问题的一种方法是确保在 gitlab.rb
中配置的极狐GitLab 内部 API URL 的条目正确。
启用 Gitaly TLS 时新合并请求的更改(差异)未加载
启用 Gitaly 使用 TLS 后,新合并请求的更改(差异)未生成,您会在极狐GitLab 中看到以下消息:
Building your merge request... This page will update when the build is complete
Gitaly 必须能够连接到自己才能完成某些操作。如果 Gitaly 证书不受 Gitaly 服务器信任,无法生成合并请求差异。
如果 Gitaly 无法连接到自己,您会在 Gitaly 日志 中看到类似以下的消息:
{
"level":"warning",
"msg":"[core] [Channel #16 SubChannel #17] grpc: addrConn.createTransport failed to connect to {Addr: \"ext-gitaly.example.com:9999\", ServerName: \"ext-gitaly.example.com:9999\", }. Err: connection error: desc = \"transport: authentication handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority\"",
"pid":820,
"system":"system",
"time":"2023-11-06T05:40:04.169Z"
}
{
"level":"info",
"msg":"[core] [Server #3] grpc: Server.Serve failed to create ServerTransport: connection error: desc = \"ServerHandshake(\\\"x.x.x.x:x\\\") failed: wrapped server handshake: remote error: tls: bad certificate\"",
"pid":820,
"system":"system",
"time":"2023-11-06T05:40:04.169Z"
}
要解决此问题,请确保您已将 Gitaly 证书添加到 Gitaly 服务器上的 /etc/gitlab/trusted-certs
文件夹中,并且:
- 重新配置极狐GitLab 以便证书被链接
- 手动重启 Gitaly
sudo gitlab-ctl restart gitaly
以便 Gitaly 进程加载证书。
Gitaly 无法分叉存储在 noexec
文件系统上的进程
对挂载点(例如 /var
)应用 noexec
选项会导致 Gitaly 抛出与分叉进程相关的 权限被拒绝
错误。例如:
fork/exec /var/opt/gitlab/gitaly/run/gitaly-2057/gitaly-git2go: permission denied
要解决此问题,请从文件系统挂载中删除 noexec
选项。另一种选择是更改 Gitaly 运行时目录:
- 在
/etc/gitlab/gitlab.rb
中添加gitaly['runtime_dir'] = '<PATH_WITH_EXEC_PERM>'
并指定没有noexec
设置的位置。 - 运行
sudo gitlab-ctl reconfigure
。
提交签名失败并显示 invalid argument
或 invalid data
如果提交签名失败并出现以下错误之一:
invalid argument: signing key is encrypted
invalid data: tag byte does not have MSB set
此错误发生是因为 Gitaly 提交签名是无头的,与特定用户无关。必须创建没有密码的 GPG 签名密钥,或者在导出前移除密码。
Gitaly 日志在 info
消息中显示错误
由于极狐GitLab 16.3 中引入的错误,额外的条目被写入 Gitaly 日志。这些日志条目包含 "level":"info"
但 msg
字符串似乎包含错误。
例如:
{"level":"info","msg":"[core] [Server #3] grpc: Server.Serve failed to create ServerTransport: connection error: desc = \"ServerHandshake(\\\"x.x.x.x:x\\\") failed: wrapped server handshake: EOF\"","pid":6145,"system":"system","time":"2023-12-14T21:20:39.999Z"}
此日志条目的原因是底层 gRPC 库有时输出详细的传输日志。这些日志条目似乎是错误,但通常可以安全地忽略。
此错误在极狐GitLab 16.4.5、16.5.5 和 16.6.0 中 修复,防止此类消息被写入 Gitaly 日志。
分析 Gitaly
Gitaly 在 Prometheus 监听端口上公开了几个 Go 内置性能分析工具。例如,如果 Prometheus 在极狐GitLab 服务器的端口 9236
上监听:
-
获取正在运行的
goroutines
列表及其回溯:curl --output goroutines.txt "http://<gitaly_server>:9236/debug/pprof/goroutine?debug=2"
-
运行 30 秒的 CPU 分析:
curl --output cpu.bin "http://<gitaly_server>:9236/debug/pprof/profile"
-
分析堆内存使用情况:
curl --output heap.bin "http://<gitaly_server>:9236/debug/pprof/heap"
-
记录 5 秒的执行跟踪。这会影响 Gitaly 的性能:
curl --output trace.bin "http://<gitaly_server>:9236/debug/pprof/trace?seconds=5"
在安装了 go
的主机上,可以在浏览器中查看 CPU 分析和堆分析:
go tool pprof -http=:8001 cpu.bin
go tool pprof -http=:8001 heap.bin
可以通过运行来查看执行跟踪:
go tool trace heap.bin
分析 Git 操作
{{< history >}}
- 在极狐GitLab 16.9 中引入,并具有名为
log_git_traces
的标志。默认情况下禁用。
{{< /history >}}
{{< alert type=”flag” >}}
在极狐GitLab 私有化部署中,默认情况下此功能不可用。要使其可用,管理员可以 启用特性标志名为 log_git_traces
。在 JihuLab.com 上,此功能可用但只能由 JihuLab.com 管理员配置。在极狐GitLab Dedicated 上,此功能不可用。
{{< /alert >}}
您可以通过向 Gitaly 日志发送有关 Git 操作的额外信息来分析 Gitaly 执行的 Git 操作。借助此信息,用户可以获得更多洞察力用于性能优化、调试和一般遥测收集。有关更多信息,请参阅 Git Trace2 API 参考。
为了防止系统过载,额外的信息记录是限速的。如果超过速率限制,跟踪将被跳过。但是,在速率恢复到健康状态后,跟踪会自动再次处理。限速确保系统保持稳定,并避免因过度的跟踪处理而产生任何不利影响。
在极狐GitLab 还原后存储库显示为空
为了增加安全性使用 fapolicyd
时,极狐GitLab 可以报告从极狐GitLab 备份文件还原成功但:
- 存储库显示为空。
-
创建新文件导致类似于以下的错误:
13:commit: commit: starting process [/var/opt/gitlab/gitaly/run/gitaly-5428/gitaly-git2go -log-format json -log-level -correlation-id 01GP1383JV6JD6MQJBH2E1RT03 -enabled-feature-flags -disabled-feature-flags commit]: fork/exec /var/opt/gitlab/gitaly/run/gitaly-5428/gitaly-git2go: operation not permitted.
-
Gitaly 日志可能包含类似于以下的错误:
"error": "exit status 128, stderr: \"fatal: cannot exec '/var/opt/gitlab/gitaly/run/gitaly-5428/hooks-1277154941.d/reference-transaction': Operation not permitted\\nfatal: cannot exec '/var/opt/gitlab/gitaly/run/gitaly-5428/hooks-1277154941.d/reference-transaction': Operation not permitted\\nfatal: ref updates aborted by hook\\n\"", "grpc.code": "Internal", "grpc.meta.deadline_type": "none", "grpc.meta.method_type": "client_stream", "grpc.method": "FetchBundle", "grpc.request.fullMethod": "/gitaly.RepositoryService/FetchBundle", ...
您可以使用调试模式来帮助确定 fapolicyd
是否根据当前规则拒绝执行。
如果您发现 fapolicyd
拒绝执行,请考虑以下事项:
-
在您的
fapolicyd
配置中允许/var/opt/gitlab/gitaly
中的所有可执行文件:allow perm=any all : ftype=application/x-executable dir=/var/opt/gitlab/gitaly/
-
重启服务:
sudo systemctl restart fapolicyd sudo gitlab-ctl restart gitaly
在启用 fapolicyd
的 RHEL 实例上推送时出现 Pre-receive hook declined
错误
当推送到启用了 fapolicyd
的基于 RHEL 的实例时,您可能会收到 Pre-receive hook declined
错误。此错误可能是由于 fapolicyd
可以阻止 Gitaly 二进制文件的执行而发生。要解决此问题,请执行以下任一操作:
- 禁用
fapolicyd
。 - 创建一个
fapolicyd
规则以允许在启用fapolicyd
时执行 Gitaly 二进制文件。
要创建一个允许 Gitaly 二进制文件执行的规则:
- 在
/etc/fapolicyd/rules.d/89-gitlab.rules
创建一个文件。 -
在文件中输入以下内容:
allow perm=any all : ftype=application/x-executable dir=/var/opt/gitlab/gitaly/
-
重启服务:
systemctl restart fapolicyd
守护进程重启后,新规则生效。
移除具有重复路径的存储后更新存储库
{{< history >}}
- Rake 任务
gitlab:gitaly:update_removed_storage_projects
在极狐GitLab 17.1 中引入。
{{< /history >}}
在极狐GitLab 17.0 中,配置具有重复路径的存储的支持 被移除。这可能意味着您必须从 gitaly
配置中移除重复的存储配置。
{{< alert type=”warning” >}}
仅在旧的和新的存储共享同一磁盘路径并位于同一 Gitaly 服务器上时使用此 Rake 任务。在任何其他情况下使用此 Rake 任务会导致存储库无法访问。使用 项目存储库存储移动 API 在所有其他情况下在存储之间传输项目。
{{< /alert >}}
从 Gitaly 配置中移除使用与另一个存储相同路径的存储时, 必须将与旧存储相关联的项目重新分配给新存储。
例如,您可能有类似以下的配置:
gitaly['configuration'] = {
storage: [
{
name: 'default',
path: '/var/opt/gitlab/git-data/repositories',
},
{
name: 'duplicate-path',
path: '/var/opt/gitlab/git-data/repositories',
},
],
}
如果要从配置中移除 duplicate-path
,您将运行以下 Rake 任务将任何分配给它的项目与 default
相关联:
{{< tabs >}}
{{< tab title=”Linux 软件包安装” >}}
sudo gitlab-rake "gitlab:gitaly:update_removed_storage_projects[duplicate-path, default]"
{{< /tab >}}
{{< tab title=”自编译安装” >}}
sudo -u git -H bundle exec rake "gitlab:gitaly:update_removed_storage_projects[duplicate-path, default]" RAILS_ENV=production
{{< /tab >}}
{{< /tabs >}}