Using the GitLab-Gitaly chart

  • Tier: 基础版, 专业版, 旗舰版
  • Offering: 极狐GitLab 私有化部署

gitaly 子图表提供了一个可配置的 Gitaly 服务器部署。

要求#

此图表依赖于对 Workhorse 服务的访问,可以是完整极狐GitLab 图表的一部分,也可以是从 Kubernetes 集群中可以访问的外部服务。

设计选择#

此图表中使用的 Gitaly 容器还包含极狐GitLab Shell 代码库,以执行尚未移植到 Gitaly 上的 Git 仓库操作。Gitaly 容器内包含一份极狐GitLab Shell 容器的副本,因此我们也需要在此图表中配置极狐GitLab Shell。

配置#

gitaly 图表配置分为两部分:外部服务图表设置

Gitaly 默认作为组件部署在极狐GitLab 图表中。如果单独部署 Gitaly,需要将 global.gitaly.enabled 设置为 false,并按照外部 Gitaly 文档中的说明进行其他配置。

安装命令行选项#

下表包含可以通过 --set 标志传递给 helm install 命令的所有可能图表配置。

参数默认值描述
annotationsPod 注释
backup.goCloudUrl服务器端 Gitaly 备份 的对象存储 URL。
common.labels{}应用于此图表创建的所有对象的补充标签。
podLabels补充 Pod 标签。不会用于选择器。
external[].hostname- ""外部节点的主机名
external[].name- ""外部节点存储的名称
external[].port- ""外部节点的端口
extraContainers包含要包含的容器列表的多行文字样式字符串
extraInitContainers要包含的额外初始化容器列表
extraVolumeMounts要执行的额外卷挂载列表
extraVolumes要创建的额外卷列表
extraEnv要公开的额外环境变量列表
extraEnvFrom要从其他数据源公开的额外环境变量列表
gitaly.serviceName生成的 Gitaly 服务的名称。覆盖 global.gitaly.serviceName,默认为 <RELEASE-NAME>-gitaly
gpgSigning.enabledfalse如果应使用 Gitaly GPG 签名
gpgSigning.secret用于 Gitaly GPG 签名的密钥名称。
gpgSigning.keyGPG 密钥中包含的 Gitaly GPG 签名密钥。
image.pullPolicyAlwaysGitaly 镜像拉取策略
image.pullSecrets镜像仓库的密钥
image.repositoryregistry.gitlab.com/gitlab-org/build/cng/gitalyGitaly 镜像仓库
image.tagmasterGitaly 镜像标签
init.image.repositoryinitContainer 镜像
init.image.taginitContainer 镜像标签
init.containerSecurityContextinitContainer 特定的 securityContext
init.containerSecurityContext.allowPrivilegeEscalationfalseinitContainer 特定:控制进程是否可以获得比其父进程更多的权限
init.containerSecurityContext.runAsNonRoottrueinitContainer 特定:控制容器是否以非 root 用户身份运行
init.containerSecurityContext.capabilities.drop[ "ALL" ]initContainer 特定:移除容器的 Linux 能力
internal.names[]- defaultStatefulSet 存储的有序名称
serviceLabels{}补充服务标签
service.externalPort8075Gitaly 服务暴露端口
service.internalPort8075Gitaly 内部端口
service.namegitalyGitaly 在服务对象中的服务端口名称。
service.typeClusterIPGitaly 服务类型
service.clusterIPNone您可以在服务创建请求中指定自己的集群 IP 地址。遵循与 Kubernetes 服务对象的 clusterIP 相同的约定。如果 service.type 是 LoadBalancer,则不能设置此项。
service.loadBalancerIP如果未设置,将创建临时 IP 地址。遵循与 Kubernetes 服务对象的 loadbalancerIP 配置相同的约定。
serviceAccount.annotations{}ServiceAccount 注释
serviceAccount.automountServiceAccountTokenfalse指示是否应在 pod 中挂载默认 ServiceAccount 访问令牌
serviceAccount.createfalse指示是否应创建 ServiceAccount
serviceAccount.enabledfalse指示是否使用 ServiceAccount
serviceAccount.nameServiceAccount 的名称。如果未设置,将使用完整图表名称
securityContext.fsGroup1000启动 pod 时使用的组 ID
securityContext.fsGroupChangePolicy更改卷所有权和权限的策略(需要 Kubernetes 1.23)
securityContext.runAsUser1000启动 pod 时使用的用户 ID
securityContext.seccompProfile.typeRuntimeDefault使用的 seccomp 配置文件
shareProcessNamespacefalse允许同一 pod 中的所有其他容器可见容器进程
containerSecurityContext覆盖启动 Gitaly 容器时的容器 securityContext
containerSecurityContext.runAsUser1000允许覆盖启动 Gitaly 容器时的特定安全上下文用户 ID
containerSecurityContext.allowPrivilegeEscalationfalse控制 Gitaly 容器的进程是否可以获得比其父进程更多的权限
containerSecurityContext.runAsNonRoottrue控制 Gitaly 容器是否以非 root 用户身份运行
containerSecurityContext.capabilities.drop[ "ALL" ]移除 Gitaly 容器的 Linux 能力
tolerations[]pod 分配的容忍标签
affinity{}pod 分配的 亲和性规则
persistence.accessModeReadWriteOnceGitaly 持久性访问模式
persistence.annotationsGitaly 持久性注释
persistence.enabledtrueGitaly 启用持久性标志
persistance.labelsGitaly 持久性标签
persistence.matchExpressions绑定的标签表达式匹配
persistence.matchLabels绑定的标签值匹配
persistence.size50GiGitaly 持久性卷大小
persistence.storageClassprovisioning 的 storageClassName
persistence.subPathGitaly 持久性卷挂载路径
priorityClassNameGitaly StatefulSet priorityClassName
logging.level日志级别
logging.formatjson日志格式
logging.sentryDsnSentry DSN URL - 来自 Go 服务器的异常
logging.sentryEnvironment用于日志记录的 Sentry 环境
shell.concurrency[]每个 RPC 端点的并发性,使用键 rpcmaxPerRepo 指定
packObjectsCache.enabledfalse启用 Gitaly pack-objects 缓存
packObjectsCache.dir/home/git/repositories/+gitaly/PackObjectsCache缓存文件存储的目录
packObjectsCache.max_age5m缓存条目寿命
packObjectsCache.min_occurrences1创建缓存条目所需的最小计数
git.catFileCacheSizeGit cat-file 进程使用的缓存大小
git.config[][]Gitaly 启动 Git 命令时应设置的 Git 配置
prometheus.grpcLatencyBucketsGitaly 记录的 GRPC 方法调用直方图延迟对应的桶。输入需要数组的字符串形式(例如 "[1.0, 1.5, 2.0]"
statefulset.strategy{}允许配置 StatefulSet 使用的更新策略
statefulset.livenessProbe.initialDelaySeconds0活性探测启动前的延迟。如果启用了 startupProbe,这将设置为 0。
statefulset.livenessProbe.periodSeconds10执行活性探测的频率
statefulset.livenessProbe.timeoutSeconds3活性探测超时时间
statefulset.livenessProbe.successThreshold1活性探测在失败后被认为成功的最低连续成功次数
statefulset.livenessProbe.failureThreshold3活性探测在成功后被认为失败的最低连续失败次数
statefulset.readinessProbe.initialDelaySeconds0就绪探测启动前的延迟。如果启用了 startupProbe,这将设置为 0。
statefulset.readinessProbe.periodSeconds5执行就绪探测的频率
statefulset.readinessProbe.timeoutSeconds3就绪探测超时时间
statefulset.readinessProbe.successThreshold1就绪探测在失败后被认为成功的最低连续成功次数
statefulset.readinessProbe.failureThreshold3就绪探测在成功后被认为失败的最低连续失败次数
statefulset.startupProbe.enabledtrue是否启用启动探测。
statefulset.startupProbe.initialDelaySeconds1启动探测启动前的延迟
statefulset.startupProbe.periodSeconds1执行启动探测的频率
statefulset.startupProbe.timeoutSeconds1启动探测超时时间
statefulset.startupProbe.successThreshold1启动探测在失败后被认为成功的最低连续成功次数
statefulset.startupProbe.failureThreshold60启动探测在成功后被认为失败的最低连续失败次数
metrics.enabledfalse是否应为抓取提供一个指标端点
metrics.port9236指标端点端口
metrics.path/metrics指标端点路径
metrics.serviceMonitor.enabledfalse是否应创建 ServiceMonitor 以启用 Prometheus Operator 管理指标抓取,注意启用此功能将删除 prometheus.io 抓取注释
metrics.serviceMonitor.additionalLabels{}添加到 ServiceMonitor 的其他标签
metrics.serviceMonitor.endpointConfig{}ServiceMonitor 的其他端点配置
metrics.metricsPort已弃用 使用 metrics.port
gomemlimit.enabledtrue这将自动为 Gitaly 容器设置 GOMEMLIMIT 环境变量为 resources.limits.memory,如果该限制也设置了。用户可以通过将此值设置为 false 并在 extraEnv 中设置 GOMEMLIMIT 来覆盖此值。必须满足 文档格式标准
cgroups.enabledfalseGitaly 具有内置的 cgroups 控制。配置后,Gitaly 会根据 Git 命令所在的仓库将 Git 进程分配到一个 cgroup。此参数将启用仓库 cgroups。请注意,启用时仅支持 cgroups v2。
cgroups.initContainer.image.repositoryregistry.com/gitlab-org/build/cng/gitaly-init-cgroupsGitaly 镜像仓库
cgroups.initContainer.image.tagmasterGitaly 镜像标签
cgroups.initContainer.image.pullPolicyIfNotPresentGitaly 镜像拉取策略
cgroups.mountpoint/etc/gitlab-secrets/gitaly-pod-cgroup父 cgroup 目录挂载的位置。
cgroups.hierarchyRootgitalyGitaly 创建组的父 cgroup,预期由 Gitaly 运行的用户和组拥有。
cgroups.memoryBytes对 Gitaly 生成的所有 Git 进程施加的总内存限制。0 表示无限制。
cgroups.cpuShares对 Gitaly 生成的所有 Git 进程施加的 CPU 限制。0 表示无限制。最大值为 1024 份,代表 100% 的 CPU。
cgroups.cpuQuotaUs用于限制 cgroups 进程超过此配额值的情况。我们将 cpuQuotaUs 设置为 100ms,因此 1 核心为 100000。0 表示无限制。
cgroups.repositories.countcgroups 池中的 cgroups 数量。每次生成新的 Git 命令时,Gitaly 会根据命令所在的仓库将其分配给这些 cgroups 之一。循环哈希算法将 Git 命令分配给这些 cgroups,因此针对仓库的 Git 命令总是分配给同一个 cgroup。
cgroups.repositories.memoryBytes对包含在仓库 cgroup 中的所有 Git 进程施加的总内存限制。0 表示无限制。此值不能超过顶级 memoryBytes。
cgroups.repositories.cpuShares对包含在仓库 cgroup 中的所有 Git 进程施加的 CPU 限制。0 表示无限制。最大值为 1024 份,代表 100% 的 CPU。此值不能超过顶级 cpuShares。
cgroups.repositories.cpuQuotaUs对包含在仓库 cgroup 中的所有 Git 进程施加的 cpuQuotaUs。Git 进程不能使用超过给定配额。我们将 cpuQuotaUs 设置为 100ms,因此 1 核心为 100000。0 表示无限制。
cgroups.repositories.maxCgroupsPerRepo1针对特定仓库的 Git 进程可以分布在的仓库 cgroups 数量。这使得可以为仓库 cgroups 配置更保守的 CPU 和内存限制,同时仍允许突发工作负载。例如,对于 maxCgroupsPerRepo2memoryBytes 限制为 10GB,针对特定仓库的独立 Git 操作可以消耗多达 20GB 的内存。
gracefulRestartTimeout25Gitaly 关闭宽限期,等待进行中的请求完成的时间(秒)。Pod terminationGracePeriodSeconds 设置为此值 + 5 秒。
timeout.uploadPackNegotiation参见 配置协商超时
timeout.uploadArchiveNegotiation参见 配置协商超时
dailyMaintenance.disabled允许禁用每日后台维护。
dailyMaintenance.duration每日后台维护的最长持续时间。例如 "1h" 或 "45m"。
dailyMaintenance.startHour每日后台维护的开始分钟。
dailyMaintenance.startMinute每日后台维护的开始分钟。
dailyMaintenance.storages执行每日后台维护的存储名称数组。例如 [ "default" ]。
bundleUri.goCloudUrl请参阅 捆绑 URI 文档

图表配置示例#

extraEnv#

extraEnv 允许您在 pod 中的所有容器中公开额外的环境变量。

以下是 extraEnv 的一个示例:

yaml
extraEnv: SOME_KEY: some_value SOME_OTHER_KEY: some_other_value

启动容器时,您可以确认环境变量已公开:

shell
env | grep SOME SOME_KEY=some_value SOME_OTHER_KEY=some_other_value

extraEnvFrom#

extraEnvFrom 允许您从其他数据源在 pod 中的所有容器中公开额外的环境变量。

以下是 extraEnvFrom 的一个示例:

yaml
1extraEnvFrom: 2 MY_NODE_NAME: 3 fieldRef: 4 fieldPath: spec.nodeName 5 MY_CPU_REQUEST: 6 resourceFieldRef: 7 containerName: test-container 8 resource: requests.cpu 9 SECRET_THING: 10 secretKeyRef: 11 name: special-secret 12 key: special_token 13 # optional: boolean 14 CONFIG_STRING: 15 configMapKeyRef: 16 name: useful-config 17 key: some-string 18 # optional: boolean

image.pullSecrets#

pullSecrets 允许您验证访问私有注册表以拉取 pod 镜像。

有关私有注册表及其身份验证方法的更多详细信息,请参阅 Kubernetes 文档

以下是 pullSecrets 的一个示例

yaml
1image: 2 repository: my.gitaly.repository 3 tag: latest 4 pullPolicy: Always 5 pullSecrets: 6 - name: my-secret-name 7 - name: my-secondary-secret-name

serviceAccount#

此部分控制是否应创建 ServiceAccount 以及默认访问令牌是否应挂载在 pod 中。

名称类型默认值描述
annotationsMap{}ServiceAccount 注释。
automountServiceAccountTokenBooleanfalse控制是否应在 pod 中挂载默认 ServiceAccount 访问令牌。除非某些 sidecars 要正常工作(例如 Istio)需要,否则不应启用此功能。
createBooleanfalse指示是否应创建 ServiceAccount。
enabledBooleanfalse指示是否使用 ServiceAccount。
nameStringServiceAccount 的名称。如果未设置,将使用完整图表名称。

tolerations#

tolerations 允许您在被标记为不可调度的工作节点上调度 pod

以下是 tolerations 的一个示例:

yaml
1tolerations: 2- key: "node_label" 3 operator: "Equal" 4 value: "true" 5 effect: "NoSchedule" 6- key: "node_label" 7 operator: "Equal" 8 value: "true" 9 effect: "NoExecute"

affinity#

有关更多信息,请参阅 affinity

annotations#

annotations 允许您为 Gitaly pod 添加注释。

以下是 annotations 的一个示例:

yaml
annotations: kubernetes.io/example-annotation: annotation-value

priorityClassName#

priorityClassName 允许您为 Gitaly pod 分配一个 PriorityClass

以下是 priorityClassName 的一个示例:

yaml
priorityClassName: persistence-enabled

git.config#

git.config 允许您为 Gitaly 启动的所有 Git 命令添加配置。接受以 key / value 对形式记录在 git-config(1) 中的配置,如下所示。

yaml
1git: 2 config: 3 - key: "pack.threads" 4 value: 4 5 - key: "fsck.missingSpaceBeforeDate" 6 value: ignore

cgroups#

为了防止耗尽,Gitaly 使用 cgroups 根据正在操作的仓库将 Git 进程分配给一个 cgroup。每个 cgroup 都有内存和 CPU 限制,确保系统稳定性并防止资源耗尽。

请注意,在 Gitaly 启动之前运行的 initContainer 需要 以 root 身份执行。此容器将配置权限,以便 Gitaly 可以管理 cgroups。因此,它将在文件系统上挂载一个卷以具有对 /sys/fs/cgroup 的写访问权限。

超额订阅示例

yaml
1cgroups: 2 enabled: true 3 # 总限制跨所有仓库 cgroups 4 memoryBytes: 64424509440 # 60GiB 5 cpuShares: 1024 6 cpuQuotaUs: 1200000 # 12 cores 7 # 每个仓库限制,1000 个仓库 cgroups 8 repositories: 9 count: 1000 10 memoryBytes: 32212254720 # 30GiB 11 cpuShares: 512 12 cpuQuotaUs: 400000 # 4 cores

外部服务#

此图表应附加到 Workhorse 服务。

Workhorse#

yaml
workhorse: host: workhorse.example.com serviceName: webservice port: 8181
名称类型默认值描述
hostStringWorkhorse 服务器的主机名。可以省略,而使用 serviceName
portInteger8181连接到 Workhorse 服务器的端口。
serviceNameStringwebservice操作 Workhorse 服务器的 service 的名称。如果存在,并且 host 不存在,图表将在 host 值中替换为服务(和当前 .Release.Name)的主机名。使用 Workhorse 作为整体极狐GitLab 图表的一部分时,这很方便。

图表设置#

以下值用于配置 Gitaly Pods。

Gitaly 使用身份验证令牌与 Workhorse 和 Sidekiq 服务进行身份验证。身份验证令牌密钥和密钥来自 global.gitaly.authToken 值。此外,Gitaly 容器包含极狐GitLab Shell 的副本,其中包含一些可以设置的配置。Shell 身份验证令牌来自 global.shell.authToken 值。

Git 仓库持久性#

此图表配置了一个 PersistentVolumeClaim 并为 Git 仓库数据挂载了相应的持久卷。您需要在 Kubernetes 集群中有可用的物理存储才能正常工作。如果您宁愿使用 emptyDir,请禁用 PersistentVolumeClaim:persistence.enabled: false

Gitaly 的持久性设置用于 volumeClaimTemplate 中,应对所有 Gitaly pod 有效。您不应包含旨在引用单个特定卷的设置(例如 volumeName)。如果要引用特定卷,则需要手动创建 PersistentVolumeClaim。

部署后无法通过我们的设置更改这些。在 StatefulSet 中,VolumeClaimTemplate 是不可变的。

yaml
1persistence: 2 enabled: true 3 storageClass: standard 4 accessMode: ReadWriteOnce 5 size: 50Gi 6 matchLabels: {} 7 matchExpressions: [] 8 subPath: "data" 9 annotations: {}
名称类型默认值描述
accessModeStringReadWriteOnce在 PersistentVolumeClaim 中请求的访问模式。详细信息请参阅 Kubernetes 访问模式文档
enabledBooleantrue设置是否为存储库数据使用 PersistentVolumeClaims。如果为 false,则使用 emptyDir 卷。
matchExpressionsArray接受要匹配的标签条件对象数组,以在选择要绑定的卷时进行匹配。这用于 PersistentVolumeClaim selector 部分。请参阅 卷文档
matchLabelsMap接受要匹配的标签名称和值的 Map,以在选择要绑定的卷时进行匹配。这用于 PersistentVolumeClaim selector 部分。请参阅 卷文档
sizeString50Gi数据持久性请求的最小卷大小。
storageClassString在卷请求上设置 storageClassName 以便动态供应。未设置或为 null 时,将使用默认供应程序。如果设置为连字符,则禁用动态供应。
subPathString设置在卷中挂载的路径,而不是卷根。如果 subPath 为空,则使用根。
annotationsMap设置动态供应的卷请求的注释。详细信息请参阅 Kubernetes 注释文档

通过 TLS 运行 Gitaly#

本节指在集群内使用 Helm 图表运行的 Gitaly。如果您使用的是外部 Gitaly 实例,并希望使用 TLS 与其通信,请参阅 外部 Gitaly 文档

Gitaly 支持通过 TLS 与其他组件通信。这由 global.gitaly.tls.enabledglobal.gitaly.tls.secretName 设置控制。按照以下步骤通过 TLS 运行 Gitaly:

  1. Helm 图表需要提供一个证书,以便通过 TLS 与 Gitaly 通信。此证书应适用于所有存在的 Gitaly 节点。因此,应该将每个 Gitaly 节点的所有主机名作为主题备用名称(SAN)添加到证书中。

    要了解要使用的主机名,请检查 Toolbox pod 中的文件 /srv/gitlab/config/gitlab.yml,并检查其中 repositories.storages 键下指定的各种 gitaly_address 字段。

    shell
    kubectl exec -it <Toolbox pod> -- grep gitaly_address /srv/gitlab/config/gitlab.yml

内部 Gitaly pod 自定义签名证书生成的基本脚本 可以在此存储库中找到。用户可以使用或参考该脚本生成具有适当 SAN 属性的证书。

  1. 使用创建的证书创建 k8s TLS 密钥。

    shell
    kubectl create secret tls gitaly-server-tls --cert=gitaly.crt --key=gitaly.key
  2. 通过传递 --set global.gitaly.tls.enabled=true 重新部署 Helm 图表。

全局服务器挂钩#

Gitaly StatefulSet 支持 全局服务器挂钩。挂钩脚本在 Gitaly pod 上运行,因此仅限于 Gitaly 容器 中可用的工具。

通过 ConfigMaps 填充挂钩,适当设置以下值即可使用:

  1. global.gitaly.hooks.preReceive.configmap
  2. global.gitaly.hooks.postReceive.configmap
  3. global.gitaly.hooks.update.configmap

要填充 ConfigMap,您可以将 kubectl 指向脚本目录:

shell
kubectl create configmap MAP_NAME --from-file /PATH/TO/SCRIPT/DIR

极狐GitLab 创建的提交的 GPG 签名#

Gitaly 能够 对通过极狐GitLab UI 创建的所有提交进行 GPG 签名,例如 WebIDE,以及极狐GitLab 创建的提交,如合并提交和压缩。

  1. 使用您的 GPG 私钥创建 k8s 密钥。

    shell
    kubectl create secret generic gitaly-gpg-signing-key --from-file=signing_key=/path/to/gpg_signing_key.gpg
  2. 在您的 values.yaml 中启用 GPG 签名。

    yaml
    1gitlab: 2 gitaly: 3 gpgSigning: 4 enabled: true 5 secret: gitaly-gpg-signing-key 6 key: signing_key

服务器端备份#

该图表支持 Gitaly 服务器端备份。要使用它们:

  1. 创建一个存储备份的存储桶。

  2. 配置对象存储凭证和存储 URL。

    yaml
    1gitlab: 2 gitaly: 3 extraEnvFrom: 4 # 将现有对象存储密钥挂载到预期的环境变量。 5 AWS_ACCESS_KEY_ID: 6 secretKeyRef: 7 name: <Rails object store secret> 8 key: aws_access_key_id 9 AWS_SECRET_ACCESS_KEY: 10 secretKeyRef: 11 name: <Rails object store secret> 12 key: aws_secret_access_key 13 backup: 14 # 这是 Gitaly 服务器端备份的连接字符串。 15 goCloudUrl: <object store connection URL>

    有关对象存储后端的预期环境变量和存储 URL 格式,请参阅 Gitaly 文档

  3. 使用 backup-utility 启用服务器端备份