故障排查

UPGRADE FAILED: Job failed: BackoffLimitExceeded

如果您在升级到 6.0 版本的 chart 时收到此错误,那么可能是因为您没有遵循正确的升级路径,因为您首先需要升级到最新的 5.10.x 版本:

  1. 列出您的所有版本,标识您的 Helm 版本名称(如果您的版本未部署到 default K8s 命名空间,则需要包含-n <namespace>):

     helm ls
    
  2. 假设您的 Helm 版本名为 gitlab,那么您需要查看发布历史并确定最后一次成功的 revision(您可以在 DESCRIPTION 下查看 revision 的状态):

     helm history gitlab
    
  3. 假设您最近成功的 revision 是 1,使用此命令回滚:

    helm rollback gitlab 1
    
  4. 通过将 <x> 替换为适当的 chart 版本来重新运行升级命令:

    helm upgrade --version=5.10.<x>
    
  5. 此时,您可以使用 --version 选项,传递特定的 6.x.x chart 版本或删除升级到最新版本的选项:

    helm upgrade --install gitlab gitlab/gitlab <other_options>
    

有关命令行参数的更多信息,请参阅使用 Helm 部署部分。 有关 chart 版本和极狐GitLab 版本之间的映射,请阅读版本映射

UPGRADE FAILED: "$name" has no deployed releases

如果您的初始安装失败,将在您第二次安装/升级时发生此错误。

如果您的初始安装完全失败,并且极狐GitLab 从未运行过,您应该在再次安装之前先清除失败的安装。

helm uninstall <release-name>

如果相反,初始安装命令超时,但极狐GitLab 仍然成功启动,您可以将 --force 标志添加到 helm upgrade 命令以忽略错误并尝试更新版本。

Error: this command needs 2 arguments: release name, chart path

运行 helm upgrade 时可能会出现这样的错误并且参数中有一些空格。 在以下示例中,错误归咎于 Test Username

helm upgrade gitlab gitlab-jh/gitlab --timeout 600s --set global.email.display_name=Test Username ...

要修复它,请在单引号中传递参数:

helm upgrade gitlab gitlab-jh/gitlab --timeout 600s --set global.email.display_name='Test Username' ...

Application containers constantly initializing

如果您在初始化的状态下遇到 Sidekiq、Webservice 或其它基于 Rails 的容器,您可能正在等待 dependencies 容器通过。

如果您专门针对 dependencies 容器检查给定 Pod 的日志,您可能会看到以下返回:

Checking database connection and schema version
WARNING: This version of GitLab depends on gitlab-shell 8.7.1, ...
Database Schema
Current version: 0
Codebase version: 20190301182457

这表明 migrations Job 尚未完成。Job 的目的是确保数据库已播种,以及所有相关迁移均已就位。应用程序容器正在尝试等待数据库达到或高于其预期的数据库版本。这是为了确保应用程序不会因不符合代码库期望的模式而出现故障。

  1. 找到 migrations Job。kubectl get job -lapp=migrations
  2. 找到 Job 运行的 Pod. kubectl get pod -ljob-name=<job-name>
  3. 检查输出,检查 STATUS 列。

如果 STATUSRunning,继续。如果 STATUSCompleted,应用程序容器应该在下一次检查通过后不久启动。

检查此 pod 中的日志。 kubectl logs <pod-name>

应解决 Job 运行期间的任何故障。 这些将阻止应用程序的使用,直到解决为止。可能的问题是:

  • 无法访问或失败的已配置 PostgreSQL 数据库的身份验证
  • 无法访问或失败的已配置 Redis 服务的身份验证
  • 无法访问 Gitaly 实例

应用配置更改

以下命令将执行必要的操作以应用对 gitlab.yaml 所做的任何更新:

helm upgrade <release name> <chart path> -f gitlab.yaml

GitLab Runner 无法注册

当 GitLab 中的 Runner 注册令牌已更改时,可能会发生这种情况。(这通常发生在您恢复备份后)

  1. 在 GitLab 安装的 admin/runners 网页上找到新的共享 Runner 令牌。
  2. 查找存储在 Kubernetes 中的现有 Runner 令牌 secret 的名称

    kubectl get secrets | grep gitlab-runner-secret
    
  3. 删除现有的 secret

    kubectl delete secret <runner-secret-name>
    
  4. 创建带有两个键的新 secret(带有共享令牌的 runner-registration-token 和一个空的 runner-token

    kubectl create secret generic <runner-secret-name> --from-literal=runner-registration-token=<new-shared-runner-token> --from-literal=runner-token=""
    

太多重定向

如果在 NGINX Ingress 之前有 TLS 终止,并且在配置中指定了 tls-secrets,就会发生这种情况。

  1. 设置 global.ingress.annotations."nginx.ingress.kubernetes.io/ssl-redirect": "false" 以更新您的值

    通过 values 文件:

    # values.yaml
    global:
      ingress:
        annotations:
          "nginx.ingress.kubernetes.io/ssl-redirect": "false"
    

    通过 Helm CLI:

    helm ... --set-string global.ingress.annotations."nginx.ingress.kubernetes.io/ssl-redirect"=false
    
  2. 应用更改

note当使用外部服务进行 SSL 终止时,该服务负责重定向到 https(如果需要)。

升级因不可变字段错误而失败

spec.clusterIP

在这些 chart 的 3.0.0 版本发布之前,尽管没有实际值(""),spec.clusterIP 属性已被填入到多个服务中。这是一个错误,会导致 Helm 3 的三向属性合并出现问题。

一旦使用 Helm 3 部署了图表,除非从各种服务中收集了 clusterIP 属性并将其填入到提供给 Helm 的值中,或者从 Kubernetes 中删除受影响的服务,否则就没有可能的升级路径。

此 chart 的 3.0.0 版本更正了此错误,但需要手动更正。

可以通过简单地删除所有受影响的服务来解决。

  1. 删除所有受影响的服务:

    kubectl delete services -lrelease=RELEASE_NAME
    
  2. 通过 Helm 执行升级。
  3. 以后的升级不会遇到这个错误。
note如果正在使用,这将更改此 chart 中 NGINX Ingress 的LoadBalancer 的任何动态值。 有关 externalIP 的更多详细信息,请参阅 全局 Ingress 设置文档。您可能需要更新 DNS 记录!

spec.selector

Sidekiq pod 在 chart 发布 3.0.0 之前没有收到唯一的选择器。

使用 Helm 升级到 3.0.0 将自动删除旧的 Sidekiq 部署并通过将 -v1 附加到 Sidekiq DeploymentsHPAPods 的名称来创建新的部署。

5.5.0 开始,Helm 将从之前的版本中删除旧的 Sidekiq 部署,并将使用 -v2 后缀作为 PodsDeploymentsHPA

如果您在安装 3.0.0 时在 Sidekiq 部署上继续遇到此错误,请使用以下步骤解决这些问题:

  1. 删除 Sidekiq 服务

    kubectl delete deployment --cascade -lrelease=RELEASE_NAME,app=sidekiq
    
  2. 通过 Helm 执行升级。

cannot patch “RELEASE-NAME-cert-manager” with kind Deployment

CertManager 版本 0.10 升级引入了许多重大更改。 必须从 Helm 的跟踪中卸载并删除旧的 CRD,然后重新安装。

默认情况下,Helm chart 会尝试执行此操作,但如果您遇到此错误,则可能需要采取手动操作。

如果遇到此错误消息,则升级需要比正常多一个步骤,以确保新的 CRD 实际应用于部署。

  1. 删除旧的 CertManager Deployment.

     kubectl delete deployments -l app=cert-manager --cascade
    
  2. 再次运行升级。这次安装新的 CRD。

     helm upgrade --install --values - YOUR-RELEASE-NAME gitlab-jh/gitlab < <(helm get values YOUR-RELEASE-NAME)
    

ImagePullBackOff, Failed to pull imagemanifest unknown 错误

如果您使用 global.gitlabVersion,请先删除该属性。 检查 chart 和 GitLab 之间的版本映射 并在您的 helm 命令中指定一个兼容版本的 gitlab-jh/gitlab chart。

UPGRADE FAILED: “cannot patch …” after helm 2to3 convert

这是一个已知的问题。 将 Helm 2 版本迁移到 Helm 3 后,后续升级可能会失败。 您可以在 从 Helm v2 迁移到 Helm v3 中找到完整的解释和解决方法。

UPGRADE FAILED: type mismatch on mailroom: %!t(<nil>)

如果您没有为需要映射的键提供有效映射,则可能会发生此类错误。

例如,下面的配置会导致这个错误:

gitlab:
  mailroom:

要解决此问题,请执行以下任一操作:

  1. gitlab.mailroom 提供一个有效的映射。
  2. 完全删除 mailroom 键。

请注意,对于可选的键,空映射 ({}) 是有效值。

Restoration failure: ERROR: cannot drop view pg_stat_statements because extension pg_stat_statements requires it

在 Helm chart 实例上恢复备份时,您可能会遇到此错误。 使用以下步骤作为解决方法:

  1. toolbox pod 中打开数据库控制台:

    /srv/gitlab/bin/rails dbconsole -p
    
  2. 删除扩展名:

    DROP EXTENSION pg_stat_statements;
    
  3. 执行恢复过程。
  4. 恢复完成后,在DB控制台重新创建扩展:

    CREATE EXTENSION pg_stat_statements;
    

如果您遇到与 pg_buffercache 扩展相同的问题,请按照上述相同的步骤删除并重新创建它。

Bundled PostgreSQL pod fails to start: database files are incompatible with server

升级到新版本的 GitLab Helm chart 后,捆绑的 PostgreSQL pod 中可能会出现以下错误消息:

gitlab-postgresql FATAL:  database files are incompatible with server
gitlab-postgresql DETAIL:  The data directory was initialized by PostgreSQL version 11, which is not compatible with this version 12.7.

要解决此问题,请对 chart 的先前版本执行 Helm 回滚,然后按照升级指南 来升级捆绑的 PostgreSQL 版本。正确升级 PostgreSQL 后,再次尝试升级 GitLab Helm chart。

Bundled NGINX Ingress pod fails to start: Failed to watch *v1beta1.Ingress

如果运行 Kubernetes 1.22 或更高版本,则捆绑的 NGINX Ingress 控制器 pod 中可能会出现以下错误消息:

Failed to watch *v1beta1.Ingress: failed to list *v1beta1.Ingress: the server could not find the requested resource

要解决此问题,请确保 Kubernetes 版本为 1.21 或更低版本。

/api/v4/jobs/request 端点的负载增加

如果部署服务/api/*的选项workhorse.keywatcher被设置为false,你可能会遇到这个问题。 使用以下步骤进行验证:

  1. 在服务/api/*的 pod 中访问容器gitlab-workhorse

    kubectl exec -it --container=gitlab-workhorse <gitlab_api_pod> -- /bin/bash
    
  2. 检查文件/srv/gitlab/config/workhorse-config.toml。 可能缺少 [redis] 配置:

    cat /srv/gitlab/config/workhorse-config.toml | grep '\[redis\]'
    

如果 [redis] 配置不存在,workhorse.keywatcher 标志在部署期间设置为 false。 从而导致 /api/v4/jobs/request 端点中的额外负载。 要解决此问题,请在 webservice chart 中启用 keywatcher

workhorse:
  keywatcher: true

Git over SSH: the remote end hung up unexpectedly

通过 SSH 的 Git 操作可能会间歇性失败并显示以下错误:

fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

导致此错误的潜在原因有很多:

  • 网络超时

    Git 客户端有时会打开一个连接并让它处于空闲状态,就像在压缩对象时一样。HAProxy 中的 timeout client 等设置可能会导致这些空闲连接被终止。

    在 GitLab 14.0(chart 版本 5.0)及更高版本中,您可以在 sshd 中设置一个 keepalive:

    gitlab:
      gitlab-shell:
        config:
          clientAliveInterval: 15
    
  • gitlab-shell 内存:

    默认情况下,chart 不会对 GitLab Shell 内存设置限制。 如果 gitlab.gitlab-shell.resources.limits.memory 设置得太低,通过 SSH 的 Git 操作可能会因这些错误而失败。

    运行 kubectl describe nodes 以确认这是由内存限制而不是网络超时引起的。

    System OOM encountered, victim process: gitlab-shell
    Memory cgroup out of memory: Killed process 3141592 (gitlab-shell)
    

YAML configuration: mapping values are not allowed in this context

当 YAML 配置包含前导空格时,可能会出现以下错误消息:

template: /var/opt/gitlab/templates/workhorse-config.toml.tpl:16:98:
  executing \"/var/opt/gitlab/templates/workhorse-config.toml.tpl\" at <data.YAML>:
    error calling YAML:
      yaml: line 2: mapping values are not allowed in this context

要解决此问题,请确保配置中没有前导空格。

例如,更改以下示例:

  key1: value1
  key2: value2

… 更改为:

key1: value1
key2: value2

此更改确保添加于 14.5 版本的 gomplate 可以正确填入配置。

TLS 和证书

如果您的实例需要信任私有 TLS 证书颁发机构,则 GitLab 可能无法与其他服务(如对象存储、Elasticsearch、Jira 或 Jenkins)握手:

error: certificate verify failed (unable to get local issuer certificate)

如果出现以下情况,可能会出现对私有证书颁发机构签署的证书的部分信任:

  • 提供的证书不在单独的文件中。
  • 证书初始化容器不执行所有必需的步骤。

此外,GitLab 主要是用 Ruby on Rails 和 Golang 编写的,每种语言的 TLS 库的工作方式都不同。这种差异可能导致诸如作业日志无法在 GitLab UI 中呈现,但原始作业日志下载正常等问题。

此外,根据 proxy_download 配置,如果信任存储配置正确,您的浏览器将正确地重定向到对象存储。 同时,一个或多个 GitLab 组件的 TLS 握手仍然可能失败。

证书信任设置和故障排查

作为解决证书问题的一部分,请务必:

  • 为您需要信任的每个证书创建 secret。
  • 每个文件只提供一个证书。

    kubectl create secret generic custom-ca --from-file=unique_name=/path/to/cert
    

    在此示例中,证书使用密钥名称 unique_name 存储

如果您提供 bundle 或 chain,则某些 GitLab 组件将无法工作。

使用 kubectl get secretskubectl describe secrets/secretname 查询 secret,它在 Data 下显示证书的密钥名称。

使用 global.certificates.customCAs 在 chart 全局 中提供额外的证书来信任。

部署 pod 后,init 容器会挂载证书并进行设置,以便 GitLab 组件可以使用它们。

额外证书安装到容器中的 /usr/local/share/ca-certificates,使用密钥名称作为证书文件名。

init 容器运行 /scripts/bundle-certificates。 在该脚本中,update-ca-certificates

  1. 将自定义证书从 /usr/local/share/ca-certificates 复制到/etc/ssl/certs
  2. 编译一个包 ca-certificates.crt
  3. 为每个证书生成哈希并使用哈希创建符号链接,这是 Rails 所必需的。证书包被跳过并显示警告:

    WARNING: unique_name does not contain exactly one certificate or CRL: skipping
    

对 init 容器的状态和日志进行故障排查。 例如,要查看证书初始化容器的日志并检查警告:

kubectl logs gitlab-webservice-default-pod -c certificates

检查 Rails 控制台

使用 toolbox pod 来验证 Rails 是否信任您提供的证书。

  1. 启动 Rails 控制台(将 <namespace> 替换为安装 GitLab 的命名空间):

    kubectl exec -ti $(kubectl get pod -n <namespace> -lapp=toolbox -o jsonpath='{.items[0].metadata.name}') -n <namespace> -- bash
    /srv/gitlab/bin/rails console
    
  2. 验证 Rails 检查证书颁发机构的位置:

    OpenSSL::X509::DEFAULT_CERT_DIR
    
  3. 在 Rails 控制台中执行 HTTPS 查询:

    ## Configure a web server to connect to:
    uri = URI.parse("https://myservice.example.com")
    
    require 'openssl'
    require 'net/http'
    Rails.logger.level = 0
    OpenSSL.debug=1
    http = Net::HTTP.new(uri.host, uri.port)
    http.set_debug_output($stdout)
    http.use_ssl = true
    
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    # http.verify_mode = OpenSSL::SSL::VERIFY_NONE # TLS verification disabled
    
    response = http.request(Net::HTTP::Get.new(uri.request_uri))
    

对 init 容器进行故障排查

使用 Docker 运行证书容器。

  1. 设置目录结构并用您的证书填入它:

    mkdir -p etc/ssl/certs usr/local/share/ca-certificates
    
      # The secret name is: my-root-ca
      # The key name is: corporate_root
    
    kubectl get secret my-root-ca -ojsonpath='{.data.corporate_root}' | \
         base64 --decode > usr/local/share/ca-certificates/corporate_root
    
      # Check the certificate is correct:
    
    openssl x509 -in usr/local/share/ca-certificates/corporate_root -text -noout
    
  2. 确定正确的容器版本:

    kubectl get deployment -lapp=webservice -ojsonpath='{.items[0].spec.template.spec.initContainers[0].image}'
    
  3. 运行容器,执行 etc/ssl/certs 内容的准备:

    docker run -ti --rm \
         -v $(pwd)/etc/ssl/certs:/etc/ssl/certs \
         -v $(pwd)/usr/local/share/ca-certificates:/usr/local/share/ca-certificates \
         registry.jihulab.com/gitlab-cn/build/cng-images/alpine-certificates:20191127-r2
    
  4. 检查您的证书是否已正确构建:

    • etc/ssl/certs/ca-cert-corporate_root.pem 应该已创建。
    • 应该有一个哈希文件名,它是证书本身的软链接(例如 etc/ssl/certs/1234abcd.0)。
    • 该文件和软链接应显示为:

      ls -l etc/ssl/certs/ | grep corporate_root
      

      例如:

      lrwxrwxrwx   1 root root      20 Oct  7 11:34 28746b42.0 -> ca-cert-corporate_root.pem
      -rw-r--r--   1 root root    1948 Oct  7 11:34 ca-cert-corporate_root.pem
      

308: Permanent Redirect 导致重定向循环

如果您的负载均衡器配置为向 NGINX 发送未加密的流量 (HTTP),则可能会发生 308: Permanent Redirect。 因为 NGINX 默认将 HTTP 重定向到 HTTPS,所以您可能会陷入“重定向循环”。

为了解决这个问题,启用 NGINX 的 use-forward-headers 设置

nginx-controller 日志的 “Invalid Word” 错误和 404 错误

升级到 Helm chart 6.6 或更高版本后,您可能会在访问极狐GitLab 或集群中安装的第三方域名时遇到 404 返回码,并且还会在 gitlab-nginx-ingress-controller 日志中看到 “invalid word” 错误:

gitlab-nginx-ingress-controller-899b7d6bf-688hr controller W1116 19:03:13.162001       7 store.go:846] skipping ingress gitlab/gitlab-minio: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass
gitlab-nginx-ingress-controller-899b7d6bf-688hr controller W1116 19:03:13.465487       7 store.go:846] skipping ingress gitlab/gitlab-registry: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass
gitlab-nginx-ingress-controller-899b7d6bf-lqcks controller W1116 19:03:12.233577       6 store.go:846] skipping ingress gitlab/gitlab-kas: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass
gitlab-nginx-ingress-controller-899b7d6bf-lqcks controller W1116 19:03:12.536534       6 store.go:846] skipping ingress gitlab/gitlab-webservice-default: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass
gitlab-nginx-ingress-controller-899b7d6bf-lqcks controller W1116 19:03:12.848844       6 store.go:846] skipping ingress gitlab/gitlab-webservice-default-smartcard: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass
gitlab-nginx-ingress-controller-899b7d6bf-lqcks controller W1116 19:03:13.161640       6 store.go:846] skipping ingress gitlab/gitlab-minio: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass
gitlab-nginx-ingress-controller-899b7d6bf-lqcks controller W1116 19:03:13.465425       6 store.go:846] skipping ingress gitlab/gitlab-registry: nginx.ingress.kubernetes.io/configuration-snippet annotation contains invalid word proxy_pass

在这种情况下,为使用配置片段,请检查您的极狐GitLab 值和任何第三方 Ingress 对象。 您可能需要调整或修改 nginx-ingress.controller.config.annotation-value-word-blocklist 设置。

有关更多详细信息,请参阅 annotation 值词块列表

卷挂载需要很长时间

挂载大型卷(例如 gitalytoolbox chart 卷)可能需要很长时间,因为 Kubernetes 递归更改卷内容的权限,匹配 Pod 的 securityContext

从 Kubernetes 1.23 开始,您可以将 securityContext.fsGroupChangePolicy 设置为 OnRootMismatch 缓解此问题。所有极狐GitLab 子 chart 都支持此标志。

例如,对于 Gitaly 子 chart:

gitlab:
  gitaly:
    securityContext:
      fsGroupChangePolicy: "OnRootMismatch"

请参阅 Kubernetes 文档,了解更多细节。

对于不支持 fsGroupChangePolicy 的 Kubernetes 版本,您可以通过更改或完全删除 securityContext 的设置来缓解此问题。

gitlab:
  gitaly:
    securityContext:
      fsGroup: ""
      runAsUser: ""
note示例语法完全消除了 securityContext 设置。由于 Helm 将默认值与用户提供的配置合并,设置 securityContext: {}securityContext: 无效。