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 访问:
- GitLab: http://gitlab.zsfund.com
- Registry: http://gitlab-registry.zsfund.com
- MinIO: http://gitlab-minio.zsfund.com
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