- 当使用独立 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
错误 - 删除具有重复路径的存储后更新仓库
排查 Gitaly 问题
请参考以下信息进行 Gitaly 的问题排查。有关 Gitaly 集群(Praefect)的排查信息,请参阅 排查 Gitaly 集群。
以下部分提供了 Gitaly 错误的可能解决方案。
另请参阅 Gitaly 超时 设置,以及我们关于 解析 gitaly/current
文件 的建议。
当使用独立 Gitaly 服务器时检查版本
使用独立 Gitaly 服务器时,必须确保它们与极狐GitLab保持相同版本以确保完全兼容:
- 在左侧边栏底部选择 管理员。
- 选择 概览 > Gitaly 服务器。
- 确认所有 Gitaly 服务器显示已更新。
查找存储资源详情
您可以在 Rails 控制台 中运行以下命令,以确定 Gitaly 存储上的可用和已用空间:
Gitlab::GitalyClient::ServerService.new("default").storage_disk_statistics
# 对于 Gitaly 集群
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>
例如,要在软件包实例中通过 Gitaly 在仓库的工作目录中运行 git ls-tree
:
sudo -u git -- /opt/gitlab/embedded/bin/gitaly git ls-tree --name-status HEAD
提交、推送和克隆返回 401
remote: GitLab: 401 Unauthorized
您需要同步 gitlab-secrets.json
文件与您的极狐GitLab 应用程序节点。
仓库页面上的 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 跟踪也可以通过 GODEBUG=http2debug
环境变量在 Gitaly 本身中启用。要在 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 file
指示正在使用的密钥文件。如果该设置丢失,极狐GitLab 默认使用 /opt/gitlab/embedded/service/gitlab-rails/.gitlab_shell_secret
下的 .gitlab_shell_secret
。
仓库推送失败并显示 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 origin +refs/heads/*:refs/heads/* +refs/tags/*:refs/tags/*
管理员希望推送的其他命名空间也可以通过附加模式包括在内。
命令行工具无法连接到 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 的条目正确 gitlab_rails['internal_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
文件系统上的进程
将 noexec
选项应用于挂载点(例如 /var
)会导致 Gitaly 抛出与分叉进程相关的 permission denied
错误。例如:
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 操作
- 在极狐GitLab 16.9 中引入,带有名为
log_git_traces
的标记。默认情况下禁用。
log_git_traces
。在 GitLab.com 上,此功能可用但只能由 GitLab.com 管理员配置。在 GitLab Dedicated 上,此功能不可用。您可以通过向 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
服务重启后,新规则生效。
删除具有重复路径的存储后更新仓库
- 在极狐GitLab 17.1 中引入的 Rake 任务
gitlab:gitaly:update_removed_storage_projects
。
在极狐GitLab 17.0 中,支持配置具有重复路径的存储被移除。这可能意味着您必须从 gitaly
配置中删除重复的存储配置。
从 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
:::TabTitle Linux 软件包安装
sudo gitlab-rake "gitlab:gitaly:update_removed_storage_projects[duplicate-path, default]"
:::TabTitle 自编译安装
sudo -u git -H bundle exec rake "gitlab:gitaly:update_removed_storage_projects[duplicate-path, default]" RAILS_ENV=production
::EndTabs