第 4/18 天
引言
在前面三天的内容中,我们已经完成了全链路架构总览、K8s 集群离线部署以及 Harbor 私有镜像仓库的搭建。今天,我们继续推进 DevOps 全链路的核心组件——GitLab CE 自托管部署。
GitLab 是一个端到端的 DevOps 平台,提供代码托管、CI/CD 流水线、安全扫描、制品库等一体化能力。选择自托管 GitLab CE(Community Edition)而非 SaaS 版本,主要基于以下考量:数据完全自主可控、无用户数限制、可深度定制 CI/CD 流水线、与内部 Harbor 和 Argo CD 无缝集成。在金融、政企等对数据合规有严格要求的场景中,自托管几乎是唯一选择。

本文将从 Helm Chart 部署 GitLab CE 开始,覆盖域名与 TLS 证书配置、项目管理初始化、SSH Key 与 Access Token 设置等实战步骤,确保你在完成本文后拥有一个可用的代码托管平台,为后续 CI/CD 流水线搭建奠定基础。
一、GitLab CE 架构概述
1.1 核心组件一览
GitLab 采用面向服务的架构(SOA),由多个独立组件协作运行。在 Helm Chart 部署模式下,每个组件以独立的 Deployment 形式运行在 K8s 中:
| 组件 | 功能 | 说明 |
|---|---|---|
| Webservice(Puma) | Web API 与页面渲染 | Rails 应用,处理所有 HTTP 请求 |
| Gitaly | Git 仓库存储服务 | 管理底层 Git 操作,读写仓库数据 |
| Sidekiq | 后台任务队列 | 处理邮件通知、Pipeline 执行等异步任务 |
| Workhorse | 反向代理网关 | 处理大文件上传、Git Smart HTTP 请求分发 |
| Redis | 缓存与会话存储 | 存储会话数据和缓存 |
| PostgreSQL | 主数据库 | 存储用户、项目、Pipeline 等元数据 |
| Runner | CI/CD 执行器 | 执行 .gitlab-ci.yml 中定义的作业(第 5 天详解) |
1.2 部署方式选型
在 K8s 上部署 GitLab 有两种主流方式:
官方 Helm Chart(推荐):GitLab 官方维护的 Helm Chart,内置所有依赖组件(PostgreSQL、Redis、MinIO 等),支持水平扩缩容和高可用配置,适合生产环境。
Omnibus 容器化:将 Omnibus 打包版塞进单个容器中运行,部署简单但不具备弹性能力,仅适合测试或小规模环境。
本系列采用官方 Helm Chart 方案,为后续的 Runner 集成和高可用加固打下基础。
二、前置准备
2.1 资源要求评估
GitLab 是一个资源密集型应用,部署前务必确认集群资源充足:
# 查看 K8s 节点资源使用情况
kubectl top nodes
# GitLab 最低配置要求:
# CPU: 4 核可用
# 内存: 8GB 可用
# 存储: 100GB SSD
# 推荐生产配置:8 核 CPU / 16GB 内存 / 200GB SSD
# 确认节点是否有 taint 导致 Pod 无法调度
kubectl describe nodes | grep -A5 Taints
2.2 StorageClass 与域名准备
# 确认 StorageClass 已就绪(前序文章已部署)
kubectl get sc
# 预期输出:
# NAME PROVISIONER RECLAIMPOLICY
# local-storage kubernetes.io/no-provisioner Delete
# ceph-block-rbd rook-ceph.rbd.csi.ceph.com Delete
# 规划域名解析(以 stellardata.top 为例)
# 需要的子域名:
# gitlab.stellardata.top → GitLab Web 服务
# minio.stellardata.top → 内置对象存储(用于 LFS/上传附件)
#
# 查看现有 Ingress Controller 的外部 IP
kubectl -n kube-system get svc traefik
# 将 gitlab.stellardata.top 的 A 记录指向该外部 IP
2.3 添加 GitLab Helm 仓库
# 添加 GitLab 官方 Helm Chart 仓库
helm repo add gitlab https://charts.gitlab.io/
helm repo update
# 查询可用版本
helm search repo gitlab/gitlab –versions | head -5
# 预期输出:
# gitlab/gitlab 8.9.2 17.8.2 GitLab is the most comprehensive…
三、Helm 部署 GitLab CE
3.1 编写 values 配置文件
GitLab Helm Chart 支持大量配置项,以下是一份经过验证的最小化生产配置:
# gitlab-values.yaml
global:
edition: CE
hosts:
domain: stellardata.top
gitlab:
name: gitlab.stellardata.top
https: true
ingress:
class: traefik
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
tls:
enabled: true
certmanager:
install: false
nginx-ingress:
enabled: false
redis:
install: true
resources:
requests:
cpu: 500m
memory: 1Gi
postgresql:
install: true
resources:
requests:
cpu: 500m
memory: 1Gi
minio:
install: true
resources:
requests:
cpu: 250m
memory: 256Mi
gitlab-runner:
install: false
webservice:
resources:
requests:
cpu: 1
memory: 3.5Gi
limits:
memory: 5Gi
sidekiq:
resources:
requests:
cpu: 500m
memory: 1Gi
gitaly:
resources:
requests:
cpu: 500m
memory: 512Mi
配置说明:
edition: CE明确使用社区版,避免商业功能许可限制nginx-ingress.enabled: false禁用内置 Ingress,复用集群已有的 Traefikcertmanager.install: false禁用自动证书签发,采用手动管理的 TLS 证书gitlab-runner.install: false暂不安装 Runner,第 5 天单独配置- 各组件 resources 配置保障资源预留,避免因调度不足导致 OOM
3.2 执行 Helm 安装
# 创建命名空间
kubectl create namespace gitlab
# 执行 Helm 部署
helm install gitlab gitlab/gitlab
-n gitlab
-f gitlab-values.yaml
–timeout 15m
–version 8.9.2
# 实时监控部署进度
kubectl -n gitlab get pods -w
# 等待所有 Pod 就绪(约 5-10 分钟)
kubectl -n gitlab wait –for=condition=Ready pods –all
-n gitlab –timeout=600s
# 最终状态确认
kubectl -n gitlab get pods
# 预期输出:
# NAME READY STATUS RESTARTS
# gitlab-gitaly-0 1/1 Running 0
# gitlab-minio-xxxxx 1/1 Running 0
# gitlab-postgresql-0 1/1 Running 0
# gitlab-redis-master-0 1/1 Running 0
# gitlab-sidekiq-all-in-1-v2-xxxx 1/1 Running 0
# gitlab-webservice-default-xxxx 1/1 Running 0
# gitlab-workhorse-xxxxx 1/1 Running 0
3.3 获取初始密码与访问
# 获取 root 用户初始密码
kubectl -n gitlab get secret gitlab-gitlab-initial-root-password
-o jsonpath="{.data.password}" | base64 -d
# 输出示例:4xK9mP2vQ8rT1nB7sW3dF6hJ0lY5cZ
# 查看 Ingress 访问入口
kubectl -n gitlab get ingress
# NAME CLASS HOSTS ADDRESS
# gitlab-webservice traefik gitlab.stellardata.top 10.0.0.50
使用浏览器访问 https://gitlab.stellardata.top,用户名 root,密码使用上面获取的初始密码。登录后第一时间修改密码。
四、初始化配置
4.1 创建项目组与项目
通过 GitLab API 批量初始化项目结构:
# 创建 DevOps 全链路专用 Group
curl -k –request POST "https://gitlab.stellardata.top/api/v4/groups"
–header "PRIVATE-TOKEN: <your-access-token>"
–header "Content-Type: application/json"
–data '{"name": "devops-chain", "path": "devops-chain", "visibility": "private"}'
# 在 Group 下创建示例项目
curl -k –request POST "https://gitlab.stellardata.top/api/v4/projects"
–header "PRIVATE-TOKEN: <your-access-token>"
–header "Content-Type: application/json"
–data '{"name": "demo-app", "path": "demo-app", "namespace_id": 2, "visibility": "private", "initialize_with_readme": true}'
4.2 生成 Access Token
# 在 GitLab Web 界面操作:
# User Settings → Access Tokens → Create new token
# Name: ci-deploy-token
# Scopes: api, read_repository, write_repository
# 记录生成的 Token(仅显示一次)
# 验证 Token 可用性
curl -k –header "PRIVATE-TOKEN: <your-token>"
"https://gitlab.stellardata.top/api/v4/user"
# 预期返回 JSON:
# {"id":1,"username":"root","name":"Administrator",…}
4.3 配置 SSH Key
# 在开发机上生成 ed25519 SSH Key
ssh-keygen -t ed25519 -C "devops@stellardata.top"
-f ~/.ssh/gitlab_key -N ""
# 查看并复制公钥
cat ~/.ssh/gitlab_key.pub
# 添加到 GitLab:
# User Settings → SSH Keys → Add SSH Key → 粘贴公钥 → Add Key
# 测试 SSH 连接
ssh -i ~/.ssh/gitlab_key -T git@gitlab.stellardata.top
# 预期输出:
# Welcome to GitLab, @root!
五、推送首个代码仓库
5.1 初始化项目结构
# 克隆仓库
git clone git@gitlab.stellardata.top:devops-chain/demo-app.git
cd demo-app
# 创建项目目录结构
mkdir -p src/app deploy/k8s
# 编写 FastAPI 应用
cat > src/app/main.py << 'PYEOF'
from fastapi import FastAPI
import os
app = FastAPI(title="DevOps Chain Demo")
VERSION = os.getenv("APP_VERSION", "1.0.0")
@app.get("/health")
def health():
return {"status": "ok", "version": VERSION}
@app.get("/")
def root():
return {"message": "Hello from DevOps Chain", "version": VERSION}
PYEOF
# 编写 Dockerfile
cat > Dockerfile << 'DEOF'
FROM python:3.12-slim
WORKDIR /app
COPY src/app/ .
RUN pip install –no-cache-dir fastapi uvicorn
EXPOSE 8000
CMD ["uvicorn", "main:app", "–host", "0.0.0.0", "–port", "8000"]
DEOF
# 编写 .gitignore
cat > .gitignore << 'GEOF'
__pycache__/
*.pyc
.env
.venv/
*.egg-info/
GEOF
# 提交并推送代码
git add .
git commit -m "feat: 初始化 demo-app 项目结构与 FastAPI 应用"
git push origin main
5.2 验证代码仓库
# 通过 API 确认代码已推送
curl -k –header "PRIVATE-TOKEN: <your-token>"
"https://gitlab.stellardata.top/api/v4/projects/2/repository/tree"
# 预期返回 JSON:
# [{"name":"Dockerfile","type":"blob"}, …]
至此,GitLab CE 已成功运行,并完成了首个项目的代码推送。后续的 CI 流水线将以此仓库为基础进行构建。
六、常见问题
Q1: Pod 一直处于 Pending 状态
# 查看 Pod 事件
kubectl -n gitlab describe pod <pod-name> | tail -20
# 检查 PVC 状态
kubectl -n gitlab get pvc
# 若 PVC 处于 Pending,确认 StorageClass 可用且容量充足
常见原因包括 StorageClass 不支持动态供应、节点资源不足或 Taint 导致无法调度。可通过 kubectl describe node 查看资源余量,必要时添加节点或调整资源配置。
Q2: 访问 GitLab 返回 502 错误
# 查看 Webservice Pod 日志
kubectl -n gitlab logs -l app=webservice –tail=50
# 检查 Pod 重启情况
kubectl -n gitlab get pods | grep webservice
# 若 RESTARTS 大于 0,通常是内存不足导致 OOMKilled
# 解决方案:调大 webservice.resources.requests.memory
GitLab Webservice 首次启动需要约 3-5 分钟完成数据库迁移和索引重建,初次部署出现短暂 502 属正常现象,持续 502 则需排查资源或配置问题。
Q3: HTTPS 证书未生效,浏览器报警
# 检查 Ingress TLS Secret
kubectl -n gitlab get ingress -o yaml | grep -A10 tls
# 如使用 cert-manager 自动签发
kubectl get certificate -n gitlab
kubectl describe certificate gitlab-wildcard-tls -n gitlab
# 手动管理证书方式——创建 TLS Secret
kubectl create secret tls gitlab-tls
–cert=fullchain.pem
–key=privkey.pem
-n gitlab
确认 global.tls.enabled: true 且 Ingress 正确引用了 TLS Secret。
七、总结
今天我们完成了 GitLab CE 在 K8s 集群上的 Helm 部署,涵盖架构组件解析、资源规划与 Helm values 配置、初始密码获取与首次登录、API Token 与 SSH Key 配置,以及首个代码仓库的初始化推送。至此,DevOps 全链路的基础设施层已具备三个核心组件:
- K8s 集群——应用运行平台(第 2 天)
- Harbor 私有镜像仓库——容器镜像存储与分发(第 3 天)
- GitLab CE——代码托管与 CI/CD 引擎(本篇)
三者之间的协同将在后续篇章中逐步串联。明天我们将部署 GitLab Runner,打通从代码提交到镜像构建的 CI 执行环节,让代码仓库真正”动”起来。
下期预告
明天将发布 第 5 天:GitLab Runner 配置:K8s Executor 与 RBAC 权限设置,届时我们将深入 Runner 的 K8s Executor 运行模式,配置 ServiceAccount 和 RBAC 权限,并让 Runner 与 Harbor 仓库完成认证对接,为第 6 天的 CI 流水线搭建铺平道路。
系列目录
- 全链路架构总览:从代码提交到灰度发布的完整管道设计
- K8s 集群与网络基础:kubeadm 离线部署与 Cilium 网络插件
- Harbor 私有镜像仓库部署与验证:Helm 安装与镜像推送
- GitLab CE 自托管部署:代码仓库与项目管理平台 ← 本篇
- GitLab Runner 配置:K8s Executor 与 RBAC 权限设置 🔜
- GitLab CI 流水线搭建:.gitlab-ci.yml 与 Kaniko 无守护进程构建 🔜
- Harbor 镜像版本管理与 Tag 策略配置 🔜
- Argo CD 部署与 GitOps 配置仓库创建 🔜
- CI 与 CD 联动:从代码提交到部署的全自动闭环 🔜
- Prometheus 部署:kube-prometheus-stack 与 ServiceMonitor 指标采集 🔜
- Grafana 看板搭建:K8s 标准面板与自定义业务看板 🔜
- 告警规则与 Alertmanager:钉钉/邮件通知渠道配置 🔜
- Argo Rollouts 安装与基础概念:CRD 与 Rollout 资源定义 🔜
- 金丝雀发布实战:setWeight 流量分割与 pause 步骤 🔜
- AnalysisTemplate 指标分析与自动回滚机制 🔜
- 全链路端到端演示:代码提交→构建→灰度→监控→告警完整流程 🔜
- 生产化加固要点:Harbor/GitLab/Argo CD 高可用方案 🔜
- 供应链安全闭环:Trivy 扫描 + cosign 签名 + Kyverno 验签 🔜

















暂无评论内容