gitlab部署手册(helm版本)

1. 概述

本文档介绍如何使用 Helm 在 Kubernetes 集群上部署 GitLab 全套服务,包括 GitLab Core、Runner、MinIO 和 Container Registry。

2. 前提条件

  • Kubernetes 集群 (v1.19+)
  • Helm 3 已安装
  • Ingress Controller 已部署 (推荐 nginx-ingress)
  • 域名解析配置完成
  • 至少 8GB 可用内存

3. 部署步骤

3.1 添加 Helm 仓库

helm repo add gitlab https://charts.gitlab.io
helm repo update

3.2 创建命名空间

kubectl create namespace gitlab

3.3 准备gitlab初始密码配置文件

创建 gitlab-initial-root-password.yaml 文件,内容如下:

apiVersion: v1
kind: Secret
metadata:
  name: gitlab-initial-root-password   # Secret 名称(必须与 Helm 配置中的 `secret` 字段一致)
  namespace: gitlab                    # 必须与 GitLab 部署的命名空间一致
type: Opaque
stringData:
  password: "admin123456."   # 替换为你的自定义密码(明文,Kubernetes 会自动加密)

3.4 准备gitlab values.yaml 配置文件

创建 gitlab-values.yaml 文件,内容如下:

# 全局配置部分
global:
  # 主机域名配置
  hosts:
    domain: zsfund.com       # 主域名,所有服务将基于此域名生成子域名
    https: false             # 是否启用HTTPS(全局开关)
    # 各子组件域名配置(均继承全局HTTPS设置)
    gitlab:
      name: gitlab.zsfund.com    # GitLab核心服务域名
    minio:
      name: gitlab-minio.zsfund.com  # MinIO对象存储服务域名
    registry:
      name: gitlab-registry.zsfund.com  # 容器镜像仓库域名
    kas:
      name: gitlab-kas.zsfund.com  # Kubernetes Agent Server域名
  
  # Ingress全局配置
  ingress:
    enabled: true                    # 是否启用Ingress控制器
    configureCertmanager: false      # 是否自动申请TLS证书(需要预先安装Cert-Manager)
    class: nginx                     # 指定Ingress控制器类型为nginx
    tls:
      enabled: false                 # 是否启用TLS终止(HTTPS)

  # 初始管理员密码配置(安全建议:部署后应立即修改)
  initialRootPassword:
    secret: gitlab-initial-root-password  # 存储密码的Secret名称
    key: password                         # Secret中的键名

# Cert-Manager安装开关(需要先安装Cert-Manager CRD)
installCertmanager: false  # 是否安装Cert-Manager(建议单独安装)

# GitLab Runner配置
gitlab-runner:
  install: true  # 是否安装GitLab Runner
  
  # RBAC权限配置
  rbac:
    create: true  # 是否创建RBAC资源
    clusterWideAccess: true  # 是否授予集群范围权限(创建ClusterRole而非Role)
    # 自定义权限规则(精细控制Runner权限)
    rules:
      - apiGroups: [""]
        resources: ["*"]
        verbs: ["*"]
      - apiGroups: ["apps"]
        resources: ["deployments", "daemonsets", "statefulsets", "replicasets"]
        verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
      - apiGroups: [""]
        resources: ["pods", "services", "endpoints", "persistentvolumeclaims", "persistentvolumes", "events", "configmaps", "secrets", "namespaces"]
        verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
      - apiGroups: ["networking.k8s.io"]
        resources: ["ingresses", "ingressclasses"]
        verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
      - apiGroups: ["batch"]
        resources: ["jobs", "cronjobs"]
        verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
      - apiGroups: ["storage.k8s.io"]
        resources: ["storageclasses", "volumeattachments"]
        verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
      - apiGroups: ["rbac.authorization.k8s.io"]
        resources: ["clusterrolebindings", "clusterroles", "rolebindings", "roles"]
        verbs: ["create", "get", "list", "watch", "update", "patch", "delete"]
  
  # Runner实例配置
  runners:
    privileged: true  # 是否以特权模式运行(需要Docker in Docker时开启)
    
    # Runner主配置文件
    config: |
      [[runners]]
        # 环境变量设置
        environment = [
          "CI_REGISTRY=gitlab-registry.zsfund.com",  # 显式覆盖容器仓库地址   
        ]
        
        # Kubernetes执行器配置
        [runners.kubernetes]
          image = "ubuntu:22.04"      # 默认构建镜像
          privileged = true           # 构建容器特权模式
          
          # ServiceAccount配置
          service_account = "gitlab-gitlab-runner"  # 指定使用的SA
          service_account_overwrite_allowed = ""     # 禁止覆盖SA设置
          namespace = "gitlab"         # SA所在的命名空间
          bearer_token_overwrite_allowed = true  # 允许使用Pod的bearer token

          # 卷挂载配置
          [runners.kubernetes.volumes]
            # 内存临时卷配置(用于Docker配置)
            [[runners.kubernetes.volumes.empty_dir]]
              name = "docker-config"
              mount_path = "/etc/docker"
              read_only = false
              medium = "Memory"
            
            # 主机路径挂载(用于Docker守护进程连接)
            [[runners.kubernetes.volumes.host_path]]
              name = "docker-daemon"
              mount_path = "/var/run/docker.sock"
              path = "/var/run/docker.sock"
          
          # Docker配置
          [runners.kubernetes.docker_config]
            insecure_registries = ["gitlab-registry.zsfund.com"]  # 信任自签名仓库
        
        # 缓存配置(当MinIO启用时)
        {{- if .Values.global.minio.enabled }}
        [runners.cache]
          Type = "s3"                # 使用S3兼容存储
          Path = "gitlab-runner"     # 缓存路径前缀
          Shared = true              # 共享缓存
          [runners.cache.s3]
            ServerAddress = {{ include "gitlab-runner.cache-tpl.s3ServerAddress" . }}  # MinIO地址
            BucketName = "runner-cache"      # 存储桶名称
            BucketLocation = "us-east-1"     # 模拟AWS区域
            Insecure = true                  # 不使用TLS
        {{ end }}

# Nginx Ingress控制器安装开关(建议单独安装)
nginx-ingress:
  enabled: false  # 是否安装Nginx Ingress(通常已存在则设为false)

3.5 部署GitLab

kubectl apply -f gitlab-initial-root-password.yaml

helm upgrade --install gitlab gitlab/gitlab \
  -n gitlab \
  --create-namespace \
  -f gitlab-values.yaml \
  --version 9.1.0

3.6 访问GitLab

部署完成后,可以通过以下 URL 访问:

4 CI/CD 流水线配置

4.1 .gitlab-ci.yml 示例

stages:
  - build
  - deploy

variables:
  SOLUTION_PATH: "Demo.sln"           # 替换为你的解决方案文件路径
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  PROJECT_NAME: "Demo"                 # 替换为你的项目名称
  KUBE_NAMESPACE: "default"           # 替换为你的K8s命名空间
  BUILD_CONFIGURATION: "Release"

# 缓存NuGet包加速构建
cache:
  key: "$CI_COMMIT_REF_SLUG"
  paths:
    - .nuget/packages/
    - "**/bin/"
    - "**/obj/"

# 1. 构建阶段
build:
  stage: build
  image: mcr.microsoft.com/dotnet/sdk:9.0     # 根据你的.NET版本调整
  script:
    - dotnet restore $SOLUTION_PATH
    - dotnet build $SOLUTION_PATH --configuration $BUILD_CONFIGURATION --no-restore
    - dotnet publish $SOLUTION_PATH -c $BUILD_CONFIGURATION -o ./publish
  artifacts:
    paths:
      - ./publish/
    expire_in: 1 hour

# 2. 构建并推送Docker镜像
docker_build:
  stage: deploy
  image: docker:20.10
  services:
    - docker:20.10-dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $DOCKER_IMAGE .
    - docker push $DOCKER_IMAGE
  dependencies:
    - build

# 3. Kubernetes部署
deploy_k8s:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    # 简化kubectl配置 (使用内置的service account)
    - kubectl config set-cluster k8s --server="$KUBE_API_URL" --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
    - kubectl config set-credentials ci-user --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
    - kubectl config set-context ci-context --cluster=k8s --user=ci-user --namespace=$KUBE_NAMESPACE
    - kubectl config use-context ci-context
    # 安装envsubst工具
    - apk add --no-cache gettext
    # 替换变量并生成最终文件
    - envsubst < k8s/deployment.yaml > deployment-final.yaml
    # 应用部署
    - kubectl apply -f deployment-final.yaml
    # 检查滚动更新状态
    - kubectl rollout status deployment/$PROJECT_NAME -n $KUBE_NAMESPACE --timeout=90s
  only:
    - main
  when: manual  # 设置为手动触发部署

4.2 应用服务yaml示例

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ${PROJECT_NAME}
  namespace: ${KUBE_NAMESPACE}
  annotations:
    gitlab.com/commit: "${CI_COMMIT_SHA}"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ${PROJECT_NAME}
  template:
    metadata:
      labels:
        app: ${PROJECT_NAME}
        version: "${CI_COMMIT_SHORT_SHA}"
    spec:
      containers:
      - name: app
        image: ${DOCKER_IMAGE}
        imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: ${PROJECT_NAME}
  namespace: ${KUBE_NAMESPACE}
  labels:
    app: ${PROJECT_NAME}
spec:
  selector:
    app: ${PROJECT_NAME}
  ports:
    - protocol: TCP
      port: 80
      targetPort: http
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ${PROJECT_NAME}
  namespace: ${KUBE_NAMESPACE}
spec:
  ingressClassName: nginx
  rules:
  - host: ${PROJECT_NAME}.zsfund.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: ${PROJECT_NAME}
            port:
              number: 80
posted @ 2025-07-07 16:00  怀恋小时候  阅读(254)  评论(0)    收藏  举报