DevOps全链路实战 | 第 4 天:GitLab CE 自托管部署:代码仓库与项目管理平台

第 4/18 天

引言

在前面三天的内容中,我们已经完成了全链路架构总览、K8s 集群离线部署以及 Harbor 私有镜像仓库的搭建。今天,我们继续推进 DevOps 全链路的核心组件——GitLab CE 自托管部署。

GitLab 是一个端到端的 DevOps 平台,提供代码托管、CI/CD 流水线、安全扫描、制品库等一体化能力。选择自托管 GitLab CE(Community Edition)而非 SaaS 版本,主要基于以下考量:数据完全自主可控、无用户数限制、可深度定制 CI/CD 流水线、与内部 Harbor 和 Argo CD 无缝集成。在金融、政企等对数据合规有严格要求的场景中,自托管几乎是唯一选择。

K8s

本文将从 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,复用集群已有的 Traefik
  • certmanager.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 全链路的基础设施层已具备三个核心组件:

  1. K8s 集群——应用运行平台(第 2 天)
  2. Harbor 私有镜像仓库——容器镜像存储与分发(第 3 天)
  3. GitLab CE——代码托管与 CI/CD 引擎(本篇)

三者之间的协同将在后续篇章中逐步串联。明天我们将部署 GitLab Runner,打通从代码提交到镜像构建的 CI 执行环节,让代码仓库真正”动”起来。

下期预告

明天将发布 第 5 天:GitLab Runner 配置:K8s Executor 与 RBAC 权限设置,届时我们将深入 Runner 的 K8s Executor 运行模式,配置 ServiceAccount 和 RBAC 权限,并让 Runner 与 Harbor 仓库完成认证对接,为第 6 天的 CI 流水线搭建铺平道路。

系列目录

  1. 全链路架构总览:从代码提交到灰度发布的完整管道设计
  2. K8s 集群与网络基础:kubeadm 离线部署与 Cilium 网络插件
  3. Harbor 私有镜像仓库部署与验证:Helm 安装与镜像推送
  4. GitLab CE 自托管部署:代码仓库与项目管理平台 ← 本篇
  5. GitLab Runner 配置:K8s Executor 与 RBAC 权限设置 🔜
  6. GitLab CI 流水线搭建:.gitlab-ci.yml 与 Kaniko 无守护进程构建 🔜
  7. Harbor 镜像版本管理与 Tag 策略配置 🔜
  8. Argo CD 部署与 GitOps 配置仓库创建 🔜
  9. CI 与 CD 联动:从代码提交到部署的全自动闭环 🔜
  10. Prometheus 部署:kube-prometheus-stack 与 ServiceMonitor 指标采集 🔜
  11. Grafana 看板搭建:K8s 标准面板与自定义业务看板 🔜
  12. 告警规则与 Alertmanager:钉钉/邮件通知渠道配置 🔜
  13. Argo Rollouts 安装与基础概念:CRD 与 Rollout 资源定义 🔜
  14. 金丝雀发布实战:setWeight 流量分割与 pause 步骤 🔜
  15. AnalysisTemplate 指标分析与自动回滚机制 🔜
  16. 全链路端到端演示:代码提交→构建→灰度→监控→告警完整流程 🔜
  17. 生产化加固要点:Harbor/GitLab/Argo CD 高可用方案 🔜
  18. 供应链安全闭环:Trivy 扫描 + cosign 签名 + Kyverno 验签 🔜
微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 恒星
欢迎您留下宝贵的见解!
提交
头像 - 恒星

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容