GitLab 实例部署

本文档介绍 GitLab Operator 订阅及 GitLab 实例部署功能。

目录

前提条件

  • 本文档适用于平台提供的 GitLab 17 及以上版本,基于 Operator 等技术与平台解耦。

  • 请确保目标集群已部署(订阅)GitLab Operator,即可通过 GitLab Operator 创建 GitLab 实例。

部署规划

GitLab 支持多种资源配置以满足不同客户场景。不同场景下所需资源和配置可能差异较大,因此本节介绍规划 GitLab 实例部署时需要考虑的方面及决策点影响,帮助用户为后续实例部署做出合理决策。

基本信息

  1. 平台提供的 GitLab Operator 基于官方社区 GitLab Operator,具备企业级能力增强,如 IPv6 支持、ARM 支持、安全漏洞修复等,功能上完全兼容社区版本,并通过可选及可定制模板提升 GitLab 部署便利性。

  2. 一个 GitLab 实例包含多个组件,如负责 Git 仓库访问的 Gitaly 组件、提供应用元数据和用户信息存储的 PostgreSQL 组件、用于缓存的 Redis 组件等。平台提供专业的 PostgreSQL Operator 和 Redis Operator,因此部署 GitLab 实例时,不再直接部署 Redis 和 PostgreSQL 资源,而是通过配置特定访问凭证访问已有实例。

部署前资源规划

部署前资源规划指部署前需确定并在部署时生效的资源规划,主要内容包括:

高可用

  • GitLab 支持高可用部署,该模式的主要影响和限制为:

    • 各组件均部署多副本

    • 网络访问不再支持 NodePort,需通过 Ingress 配置的域名访问

    • 存储方式不再支持 节点存储,需通过 StorageClassPVC 访问

资源

根据社区推荐和实践,非高可用 GitLab 实例最低可用 3 核 6Gi 资源,高可用模式下稳定运行最低需 18 核 22Gi 资源。

存储

  • 可使用平台提供的常见存储方式,如存储类、持久卷声明(PVC)、节点存储等。

    • 推荐使用 TopoLVM 存储类作为 Gitaly 存储

    • 节点存储不适用于 高可用 模式,因为其文件存储在主机节点指定路径

  • 此外,GitLab 也支持对象存储,该模式需单独适配存储访问方式,详情请咨询厂商。

网络

  • 平台提供两种主流网络访问方式:NodePortIngress

    • NodePort 需指定 HTTP 和 SSH 端口,并确保端口可用,不适用于 高可用 模式

    • Ingress 需指定域名,并确保域名解析正常

  • 平台支持 HTTPS 协议,需在实例部署后配置,详见配置 HTTPS

Redis

  • GitLab 当前要求 Redis 组件版本为 v6,建议使用平台提供的 Redis Operator 部署 Redis 实例,再通过配置访问凭证完成 Redis 集成。

PostgreSQL

  • GitLab 当前要求 PostgreSQL 组件版本为 v14,建议使用平台提供的 PostgreSQL Operator 部署 PostgreSQL 实例,再通过配置访问凭证完成 PostgreSQL 集成。

  • 注意:高可用模式下,Gitaly 组件为 Cluster 模式,需额外配置一个 PostgreSQL 凭证(同上述方式)访问独立数据库,可为同一 PostgreSQL 实例下的两个不同数据库。

账号凭证

创建 GitLab 实例时需配置 root 账号及密码,通过配置 secret 资源实现,详见配置 Redis、PostgreSQL 及账号凭证

部署后配置规划

部署后配置规划指无需部署前确定,可在部署后通过规范化操作按需完成的配置,主要包括单点登录(SSO)、HTTPS 配置、外部负载均衡配置等,详情见后续步骤

实例部署

平台提供的 GitLab Operator 支持两种部署方式:模板部署和 YAML 部署。

平台内置两个模板:GitLab 快速启动模板和GitLab 高可用模板,同时支持客户自定义模板以满足特定场景需求。

内置模板及 YAML 部署信息如下:

使用 GitLab 快速启动 模板部署

该模板用于快速创建适合开发测试场景的轻量级 GitLab 实例,不推荐用于生产环境。

  • 计算资源:3 核 CPU,6Gi 内存
  • 存储方式:使用本地节点存储,需配置存储节点 IP 和路径
  • 网络访问:使用 NodePort 方式,与存储共享节点 IP,需指定端口
  • 依赖服务:需配置已有 Redis 和 PostgreSQL 访问凭证
  • 其他设置:需配置账号凭证,默认禁用 SSO 功能

根据模板提示填写相关信息完成部署。

使用 GitLab 高可用 模板部署

部署高可用 GitLab 实例需更高资源配置,提供更高可用标准。

  • 计算资源:18 核 CPU,22Gi 内存
  • 存储方式:使用存储类资源存储 Gitaly(代码仓库组件)
  • 网络访问:使用 Ingress 方式,需指定域名
  • 依赖服务:需配置已有 Redis 和 PostgreSQL 访问凭证,且 Gitaly 组件需额外配置独立数据库的访问凭证
  • 其他设置:需配置账号凭证,默认禁用 SSO 功能

实现 GitLab 高可用需满足以下外部依赖条件:

  1. 附件存储类需支持多节点读写(ReadWriteMany)
  2. RedisPostgreSQL 实例需高可用
  3. 网络负载均衡器需高可用;使用 ALB 时需配置 VIP
  4. 集群节点数需大于 2 个

根据模板提示填写相关信息完成部署。

使用 YAML 部署

YAML 部署是最基础且强大的部署能力。这里提供基于“部署规划”各维度的 YAML 片段,随后提供两个不同场景的完整 YAML 示例,帮助用户理解 YAML 配置方式并按需修改。

基于部署规划的 YAML 片段

高可用

高可用模式下,Gitaly 需使用集群模式,其他组件至少 2 副本。高可用部署的 YAML 配置片段如下:

spec:
  helmValues:
    gitlab:
      gitlab-shell:
        maxReplicas: 2
        minReplicas: 2
      sidekiq:
        maxReplicas: 2
        minReplicas: 2
      webservice:
        maxReplicas: 2
        minReplicas: 2
    global:
      praefect:
        psql:
          host: host.example # PostgreSQL 实例地址
          port: 5432 # PostgreSQL 实例端口
          user: username # PostgreSQL 实例访问用户
          dbName: praefect-db # PostgreSQL 实例访问数据库
          sslMode: require # PostgreSQL 实例 SSL 模式
        dbSecret:
          key: secret # PostgreSQL 实例 secret 中存储密码的键
          secret: praefect-db # Gitaly 集群使用的 PostgreSQL 数据库 secret
        enabled: true
        virtualStorages:
        - gitalyReplicas: 3
          maxUnavailable: 1
          name: default
存储 {storage}

GitLab 数据存储主要包括两部分:

  1. Gitaly 存储:存储代码仓库数据
  2. 附件存储:存储用户头像、用户上传图片等

目前支持三种存储配置方式:存储类、PVC、本地节点存储。

存储类配置片段:

spec:
  helmValues:
    gitlab:
      gitaly:
        persistence:
          enabled: true
          size: 20Gi # Gitaly 存储容量
          storageClass: topolvm # Gitaly 使用的存储类
    global:
      uploads:
        persistence:
          enabled: true
          storageClass: ceph # 附件使用的存储类,需支持多节点读写(ReadWriteMany)
          size: 10Gi # 附件存储容量

PVC 配置片段:

spec:
  helmValues:
    gitlab:
      gitaly:
        persistence:
          enabled: true
          existingClaim: pvc-gitaly # Gitaly 存储 PVC 名称,需提前创建
    global:
      uploads:
        persistence:
          enabled: true
          existingClaim: pvc-uploads # 附件存储 PVC 名称,需提前创建

本地节点存储配置片段:

spec:
  helmValues:
    global:
      nodeSelector:
        kubernetes.io/hostname: node-1 # 节点名称,不是节点 IP
      hostpath:
        enabled: true
        nodeName: node-1 # 节点名称
        path: /mnt/data/gitlab-hostpath # 节点存储路径,需提前创建
网络访问

网络访问主要包括域名访问和 NodePort 访问两种方式。

域名访问配置片段:

spec:
  helmValues:
    gitlab:
      webservice:
        ingress:
          enabled: true # 启用域名访问
    global:
      hosts:
        domain: gitlab.example.com # 域名
        gitlab:
          hostnameOverride: gitlab.example.com # 域名
          https: false # 使用 HTTP 访问,非 HTTPS
          name: gitlab.example.com # 域名
        ssh: gitlab.example.com # 域名
      ingress:
        class: "" # 为空则使用集群默认
        enabled: true # 启用域名访问
        tls:
          enabled: false # 使用 HTTP 访问,非 HTTPS

NodePort 方式需配置两个端口:HTTP 端口和 SSH 端口。

NodePort 访问配置片段:

spec:
  helmValues:
    gitlab:
      gitlab-shell:
        service:
          nodePort: 30000 # SSH 端口号
          type: NodePort
      webservice:
        ingress:
          enabled: false # 禁用 ingress 访问
    global:
      appConfig:
        gitlabPort: 30010 # HTTP 端口号
      gitlabNodePort:
        http: 30010 # HTTP 端口号
        ssh: 30000 # SSH 端口号
      hosts:
        domain: 192.168.100.100 # 集群节点 IP
        gitlab:
          https: false
          name: 192.168.100.100 # 集群节点 IP
        ssh: 192.168.100.100 # 集群节点 IP
      ingress:
        enabled: false # 禁用 ingress 访问
      shell:
        port: 30000 # SSH 端口号
Redis 访问凭证配置

指配置好 Redis 凭证的 secret 资源后,GitLab 实例中 Redis 凭证的配置片段:

独立实例示例:

spec:
  helmValues:
    global:
      redis:
        auth:
          enabled: true
          key: password # Redis 连接 secret 中存储密码的键
          secret: gitlab-redis-password # 包含 Redis 连接密钥的 secret
        host: 192.168.100.200 # Redis 实例地址
        port: 6379 # Redis 实例端口

Sentinel 示例:

spec:
  helmValues:
    global:
      redis:
        auth:
          enabled: true
          key: password # Redis 连接 secret 中存储密码的键
          secret: gitlab-redis-password # 包含 Redis 连接密钥的 secret
        host: mymaster # Sentinel 监控实例组名
        sentinels:
          - host: 192.168.100.200 # Sentinel 节点地址
            port: 16379 # Sentinel 节点端口
          - host: 192.168.100.201 # Sentinel 节点地址
            port: 16379 # Sentinel 节点端口
          - host: 192.168.100.202 # Sentinel 节点地址
            port: 16379 # Sentinel 节点端口
PostgreSQL 访问凭证配置

指配置好 PostgreSQL 凭证的 secret 资源后,GitLab 实例中 PostgreSQL 凭证的配置片段,也包含高可用模式下配置两个 PostgreSQL 数据库的情况:

spec:
  helmValues:
    global:
      psql:
        database: gitlab-db # PostgreSQL 实例访问数据库
        host: 192.168.100.300 # PostgreSQL 实例地址
        password:
          key: password # PostgreSQL 实例 secret 中存储密码的键
          secret: gitlab-pg-password # PostgreSQL 实例 secret
        port: 5432 # PostgreSQL 实例端口
        username: gitlab-user # PostgreSQL 实例访问用户
Root 账号配置

指配置好账号凭证的 secret 资源后,GitLab 实例中账号凭证的配置片段:

spec:
  helmValues:
    global:
      initialRootPassword:
        key: password # GitLab root 账号 secret 中存储密码的键
        secret: gitlab-root-password # GitLab root 账号 secret

完整 YAML 示例:单实例、节点存储、NodePort 网络访问

spec:
  helmValues:
    gitlab:
      gitaly:
        persistence:
          enabled: true
        resources:
          limits:
            cpu: 1
            memory: 1Gi
          requests:
            cpu: 500m
            memory: 512Mi
        volumePermissions:
          enabled: true
      gitlab-shell:
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 300m
            memory: 300Mi
      migrations:
        resources:
          limits:
            cpu: 2
            memory: 2Gi
          requests:
            cpu: 500m
            memory: 512Mi
      sidekiq:
        resources:
          limits:
            cpu: 500m
            memory: 1Gi
          requests:
            cpu: 200m
            memory: 200Mi
      webservice:
        ingress:
          enabled: false
        resources:
          limits:
            cpu: 1
            memory: 2.5Gi
          requests:
            cpu: 500m
            memory: 512Mi
        workhorse:
          resources:
            limits:
              cpu: 300m
              memory: 300Mi
            requests:
              cpu: 200m
              memory: 200Mi
    global:
      nodeSelector:
        kubernetes.io/hostname: node-1 # 节点名称
      appConfig:
        gitlabPort: 30010 # HTTP 端口号
        object_store:
          enabled: true
        omniauth:
          blockAutoCreatedUsers: false
          dex:
            enabled: false
          enabled: false
      gitlabNodePort:
        http: 30010 # HTTP 端口号
        ssh: 30000 # SSH 端口号
      hostpath:
        enabled: true
        nodeName: node-1 # 节点名称
        path: /mnt/data/gitlab-hostpath # 节点存储路径,需提前创建
      hosts:
        domain: 192.168.100.100 # 集群节点 IP
        gitlab:
          https: false
          name: 192.168.100.100 # 集群节点 IP
        ssh: 192.168.100.100 # 集群节点 IP
      ingress:
        enabled: false
        tls:
          enabled: false
      initialRootPassword:
        key: password
        secret: gitlab-root-password # Root 账号 secret
      psql:
        database: gitlab-db # PostgreSQL 实例访问数据库
        host: 192.168.100.100 # PostgreSQL 实例地址
        password:
          key: password # PostgreSQL 实例 secret 中存储密码的键
          secret: gitlab-pg-password # PostgreSQL 实例 secret
        port: 5432 # PostgreSQL 实例端口
        username: gitlab-user # PostgreSQL 实例访问用户
      redis:
        auth:
          enabled: true
          key: password # Redis 实例 secret 中存储密码的键
          secret: gitlab-redis-password # Redis 实例 secret
        host: 192.168.100.200 # Redis 实例地址
        port: 6379 # Redis 实例端口
      uploads:
        persistence:
          enabled: true

完整 YAML 示例:高可用、存储类、Ingress 网络访问

spec:
  helmValues:
    gitlab:
      gitaly:
        persistence:
          enabled: true
          size: 20Gi # Gitaly 存储容量
          storageClass: topolvm # Gitaly 使用的存储类
        resources:
          limits:
            cpu: 4
            memory: 4Gi
          requests:
            cpu: 1
            memory: 1Gi
        volumePermissions:
          enabled: true
      gitlab-shell:
        maxReplicas: 2
        minReplicas: 2
        resources:
          limits:
            cpu: 1
            memory: 1Gi
          requests:
            cpu: 250m
            memory: 600Mi
      migrations:
        resources:
          limits:
            cpu: "1"
            memory: 1Gi
      sidekiq:
        maxReplicas: 2
        minReplicas: 2
        resources:
          limits:
            cpu: 2
            memory: 2Gi
          requests:
            cpu: 1
            memory: 1Gi
      webservice:
        ingress:
          enabled: true # 启用 Ingress 访问
        maxReplicas: 2
        minReplicas: 2
        resources:
          limits:
            cpu: 2
            memory: 4Gi
          requests:
            cpu: 1
            memory: 2Gi
        workhorse:
          resources:
            limits:
              cpu: 1
              memory: 1Gi
            requests:
              cpu: 200m
              memory: 200Mi
    global:
      appConfig:
        object_store:
          enabled: true
        omniauth:
          blockAutoCreatedUsers: false
          dex:
            enabled: false
          enabled: false
      hosts:
        domain: gitlab.example.com # 域名
        gitlab:
          hostnameOverride: gitlab.example.com # 域名
          https: false
          name: gitlab.example.com # 域名
        ssh: gitlab.example.com # 域名
      ingress:
        class: ""
        configureCertmanager: false
        enabled: true
        tls:
          enabled: false
      initialRootPassword:
        key: password
        secret: gitlab-root-password # Root 账号 secret
      praefect:
        psql:
          host: 192.168.100.300 # PostgreSQL 实例地址
          port: 5432 # PostgreSQL 实例端口
          user: gitlab-user # PostgreSQL 实例访问用户
          dbName: gitlab-praefect # PostgreSQL 实例访问数据库
          sslMode: require
        dbSecret:
          key: password # PostgreSQL 实例 secret 中存储密码的键
          secret: praefect-db # Gitaly 集群使用的 PostgreSQL 数据库 secret
        enabled: true
        virtualStorages:
          - gitalyReplicas: 3
            maxUnavailable: 1
            name: default
      psql:
        database: gitlab-db # PostgreSQL 实例访问数据库
        host: 192.168.100.300 # PostgreSQL 实例地址
        password:
          key: password # PostgreSQL 实例 secret 中存储密码的键
          secret: gitlab-pg # PostgreSQL 实例 secret
        port: 5432 # PostgreSQL 实例端口
        username: gitlab-user # PostgreSQL 实例访问用户
      redis:
        auth:
          enabled: true
          key: password # Redis 实例 secret 中存储密码的键
          secret: gitlab-redis-password # Redis 实例 secret
        host: 192.168.100.200 # Redis 实例地址
        port: 6379 # Redis 实例端口
      uploads:
        persistence:
          enabled: true
          size: 10Gi # 附件存储容量
          storageClass: ceph # 附件使用的存储类,需支持多节点读写(ReadWriteMany)

后续步骤

配置单点登录(SSO)

配置 SSO 包括以下步骤:

  1. 在 global 集群注册 SSO 认证客户端
  2. 准备 SSO 认证配置
  3. 配置 GitLab 实例使用 SSO 认证配置

在 global 集群创建以下 Oauth2Client 资源以注册 SSO 认证客户端。

apiVersion: dex.coreos.com/v1
kind: OAuth2Client
name: OIDC
metadata:
  name: m5uxi3dbmiwwizlyzpzjzzeeeirsk # 该值基于 id 字段的哈希计算得出,在线计算器:https://go.dev/play/p/QsoqUohsKok
  namespace: cpaas-system
alignPasswordDB: true
id: gitlab-dex # 客户端 ID
public: false
redirectURIs:
  - <gitlab-host>/users/auth/dex/callback # GitLab 认证回调地址,<gitlab-host> 替换为 GitLab 实例访问地址
secret: Z2l0bGFiLW9mZmljaWFsLTAK # 客户端密钥
spec: {}

根据下方 JSON 注释准备配置内容。

{
 "name": "openid_connect",
 "label": "OIDC",
 "args": {
   "name": "dex",
   "scope": ["openid", "profile", "email"],
   "response_type": "code",
   "issuer": "<platform-url>/dex", # 平台认证地址,<platform-url> 替换为平台访问地址
   "discovery": true,
   "client_auth_method": "query",
   "client_options": {
     "identifier": "test-dex", # 客户端 ID
     "secret": "Z2l0bGFiLW9mZmljaWFsLTAK", # 客户端密钥
     "redirect_uri": "<gitlab-host>/users/auth/dex/callback" # GitLab 认证回调地址,<gitlab-host> 替换为 GitLab 实例访问地址
   }
 }
}

将配置内容保存为 secret,并创建到 GitLab 实例所在命名空间。

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-sso-config
  namespace: gitlab
type: Opaque
data:
  provider: <base64 encoded config> # 将上述配置内容 base64 编码后保存到 provider 字段

编辑 GitLab 实例,添加以下配置:

spec:
  helmValues:
    global:
      appConfig:
        omniauth:
          enabled: true
          allowSingleSignOn:
            - dex
          syncProfileAttributes:
            - email
          syncProfileFromProvider:
            - dex
          blockAutoCreatedUsers: false
          providers:
            - key: provider
              secret: dex-provider # 包含 SSO 认证配置的 secret

为使用自签名证书的平台启用 SSO

若平台通过 HTTPS 访问且使用自签名证书,需将自签名证书的 CA 挂载到 GitLab 实例,步骤如下:

在 global 集群的 cpaas-system 命名空间找到名为 dex.tls 的 secret,获取 secret 中的 ca.crt 内容,保存为新 secret 并创建到 GitLab 实例所在命名空间。

apiVersion: v1
data:
  ca.crt: <base64 encode data>
kind: Secret
metadata:
  name: dex-tls
  namespace: cpaas-system
type: kubernetes.io/tls

编辑 GitLab 实例,使用该 CA:

spec:
  helmValues:
    global:
      certificates:
        customCAs:
          - secret: dex-tls

配置 HTTPS

部署 GitLab 实例后,可根据需要配置 HTTPS。

首先在实例所在命名空间创建 TLS 证书 secret。

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-tls-cert
  namespace: gitlab
type: kubernetes.io/tls
data:
  tls.crt: <base64 encoded cert>
  tls.key: <base64 encoded key>

然后编辑 GitLab 实例 YAML 配置,启用 HTTPS 访问:

spec:
  helmValues:
    gitlab:
      webservice:
        ingress:
          enabled: true
    global:
      hosts:
        domain: gitlab.example.com # 域名
        gitlab:
          hostnameOverride: gitlab.example.com # 域名
          https: true # 启用 HTTPS
          name: gitlab.example.com # 域名
        ssh: gitlab.example.com # 域名
      ingress:
        class: ""
        enabled: true
        tls:
          enabled: true # 启用 HTTPS
          secretName: gitlab-tls-cert # 证书 secret 名称

配置监控面板

GitLab Operator 默认支持平台运维中心监控面板。部署 GitLab Operator 和 GitLab 实例后,GitLab Metrics 会自动配置,可在运维中心监控面板查看。

配置外部负载均衡器(LB)

为 GitLab 配置外部负载均衡器(LB)

附加信息

Pod 安全策略

在配置了 Pod Security Policy(PSP)的命名空间部署 GitLab 时,确保策略的 enforce 级别设置为 privileged

提示:若命名空间中 Pod Security Policy enforce 级别设置为 restrictedbaseline,可能导致 GitLab 部署失败。