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)、节点存储等。

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

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

  • 此外,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 组件处于集群模式,需额外配置一个 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: disable # PostgreSQL 实例 SSL 模式
        dbSecret:
          key: secret # PostgreSQL 实例密码所在 secret 的 key
          secret: praefect-db # Gitaly 集群使用的 PostgreSQL 数据库 secret
        enabled: true
        virtualStorages:
        - gitalyReplicas: 3
          maxUnavailable: 1
          name: default
存储

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 中存储密码的 key
          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 中存储密码的 key
          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 中存储密码的 key
          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 中存储密码的 key
        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 中存储密码的 key
          secret: gitlab-pg-password # PostgreSQL 实例 secret
        port: 5432 # PostgreSQL 实例端口
        username: gitlab-user # PostgreSQL 实例访问用户
      redis:
        auth:
          enabled: true
          key: password # Redis 实例 secret 中存储密码的 key
          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: disable
        dbSecret:
          key: password # PostgreSQL 实例 secret 中存储密码的 key
          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 中存储密码的 key
          secret: gitlab-pg # PostgreSQL 实例 secret
        port: 5432 # PostgreSQL 实例端口
        username: gitlab-user # PostgreSQL 实例访问用户
      redis:
        auth:
          enabled: true
          key: password # Redis 实例 secret 中存储密码的 key
          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,获取其中的 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 安全策略(PSP)的命名空间部署 GitLab 时,确保策略的执行级别设置为 privileged

提示:若命名空间的 Pod 安全策略执行级别设置为 restrictedbaseline,可能导致 GitLab 部署失败。