大家好今天给大家带来一篇 DevOps 核心技能的实战原创教程 —— 基于 Kubernetes 集群从零搭建完整的 GitLab CI/CD 持续集成体系最终实现代码提交→自动构建→镜像打包→仓库推送→K8s 自动部署的全自动化流水线。在如今的云原生研发体系中DevOps 已经成为企业提效的核心手段而GitLab CI/CD凭借与代码仓库的深度原生集成、轻量化的配置方式、强大的 Kubernetes 生态适配能力已经成为从创业团队到大型企业构建持续集成体系的首选方案。这篇教程我会全程以第一实操视角带大家走完从 GitLab 服务部署、Runner 执行器配置、K8s 集群集成到最终流水线落地的全流程每一行代码都附带详细注释同时给大家讲清每个组件的核心作用、配置逻辑以及我踩过的所有坑新手也能跟着一步步落地。一、先搞懂GitLab CI/CD 核心概念与架构解析很多刚接触 CI/CD 的朋友会搞不清各个组件的分工这里我用最通俗的话给大家讲清楚核心概念和整体架构先懂原理再动手事半功倍。核心术语解析组件名称核心定位核心作用GitLab代码托管与 CI/CD 调度中枢开源的分布式代码托管平台自带完整的 CI/CD 能力负责代码版本管理、流水线定义、任务调度、执行结果展示是整个 DevOps 流程的核心载体。GitLab CI/CD持续集成 / 持续交付核心引擎GitLab 内置的自动化引擎通过项目根目录的.gitlab-ci.yml文件定义流水线规则代码提交后自动触发流水线实现从构建、测试、打包到部署的全流程自动化。GitLab Runner流水线任务执行器CI/CD 流水线的 干活的节点负责接收 GitLab 下发的流水线任务我们将其部署在 K8s 集群中支持动态创建临时 Pod 执行构建、打包等任务执行完成后自动销毁资源利用率极高。GitLab AgentGitLab 与 K8s 集群的安全桥梁用于实现 GitLab 和 K8s 集群的安全集成无需暴露 K8s APIServer 到公网即可实现 GitOps 自动化部署、集群状态监控、流水线中直接操作 K8s 资源是 GitLab 对接 K8s 的官方推荐方案。整体流水线架构我们最终实现的完整流程如下开发者提交代码到 GitLab 项目仓库GitLab 自动触发 CI/CD 流水线将任务下发给 GitLab RunnerRunner 在 K8s 集群中创建临时 Pod按流水线阶段依次执行代码编译构建容器镜像打包镜像推送到私有镜像仓库自动部署应用到 K8s 集群全程自动化无需人工干预实现代码提交即发布二、前置环境与准备工作先给大家同步我的实操环境所有操作均在 K8s 集群中执行大家可以根据自己的环境对应调整环境项详细配置Kubernetes 集群1 个 master 节点 1 个 worker 节点版本 1.20容器运行时containerd核心工具Helm 3 已在 master 节点安装完成master 节点 IP172.18.10.44worker 节点 IP172.18.10.45资源包Gitlab-CI.tar.gz包含所有镜像、安装包、2048 demo 项目代码基础环境初始化首先我们先完成资源包解压、镜像导入因为 K8s 调度 Pod 会分布在不同节点所以需要把镜像导入到集群所有节点的 containerd 中。1.解压资源包# 进入root目录所有操作均在此目录下执行 cd /root # 解压GitLab CI资源包 tar -zvxf Gitlab-CI.tar.gz2.镜像分发与导入# 将镜像压缩包拷贝到worker节点确保worker节点也能加载到所需镜像 scp /root/gitlab-ci/images/images.tar k8s-worker-node1:/root3.master 节点导入镜像# 导入镜像到k8s.io命名空间containerd中K8s使用的默认命名空间 ctr -n k8s.io image import gitlab-ci/images/images.tar4.worker 节点导入镜像# 登录worker节点执行镜像导入 ssh k8s-worker-node1 ctr -n k8s.io image import images.tar至此基础环境准备完成所有节点都已加载好所需镜像接下来正式开始服务部署。三、第一步K8s 集群中部署 GitLab 服务首先我们要在 K8s 中部署 GitLab 服务作为整个 CI/CD 体系的核心中枢。我们会创建专属命名空间通过 Deployment 部署 GitLab用 NodePort 方式对外暴露服务同时预配置 root 用户密码避免首次登录手动修改。3.1 创建专属命名空间我们为 GitLab CI/CD 体系创建独立的命名空间实现资源隔离便于后续权限管理和运维# 创建gitlab-ci命名空间 kubectl create ns gitlab-ci # 输出namespace/gitlab-ci created即创建成功3.2 编写 GitLab Deployment 部署文件Deployment 是 K8s 中用于部署无状态应用的核心资源我们通过它定义 GitLab 的镜像、环境变量、端口等配置。首先生成 Deployment 的基础模板再进行自定义修改# 生成Deployment基础yaml模板输出到gitlab-deploy.yaml文件 kubectl create deployment gitlab --imagegitlab/gitlab-ce:latest --port80 --namespacegitlab-ci --dry-runclient -o yaml gitlab-deploy.yaml修改后的完整gitlab-deploy.yaml文件附带逐行详细注释apiVersion: apps/v1 # 资源类型为Deployment kind: Deployment metadata: creationTimestamp: null labels: app: gitlab # Deployment名称 name: gitlab # 所属命名空间 namespace: gitlab-ci spec: # 副本数单节点部署设置1即可生产环境可调整为多副本 replicas: 1 selector: # 标签选择器匹配对应标签的Pod matchLabels: app: gitlab strategy: {} # Pod模板定义 template: metadata: creationTimestamp: null labels: app: gitlab spec: # 容器定义 containers: - name: gitlab # GitLab镜像我们已提前导入到集群 image: gitlab/gitlab-ce:latest # 镜像拉取策略IfNotPresent表示本地有镜像就不拉取避免外网拉取失败 imagePullPolicy: IfNotPresent # 环境变量配置预设置GitLab root用户的密码和邮箱 env: # 设置root用户初始密码生产环境请更换为强密码 - name: GITLAB_ROOT_PASSWORD value: admin123 # 设置root用户邮箱 - name: GITLAB_ROOT_EMAIL value: 123456qq.com # 容器端口暴露 ports: - name: http containerPort: 80 # 资源限制生产环境请根据服务器配置调整GitLab最低建议2核4G resources: {} status: {}3.3 编写 GitLab Service 服务文件Service 用于给 GitLab Pod 提供固定的访问入口我们使用 NodePort 类型将 GitLab 的 80 端口映射到宿主机的 30880 端口实现集群外访问。生成 Service 基础模板# 生成NodePort类型的Service模板输出到gitlab-service.yaml文件 kubectl create service nodeport gitlab --namespacegitlab-ci --tcp80:80 --node-port30880 --dry-runclient -o yaml gitlab-service.yaml修改后的完整gitlab-service.yaml文件附带详细注释apiVersion: v1 # 资源类型为Service kind: Service metadata: creationTimestamp: null labels: app: gitlab # Service名称 name: gitlab # 所属命名空间 namespace: gitlab-ci spec: # 端口映射配置 ports: - name: http # NodePort端口集群外通过这个端口访问GitLab nodePort: 30880 # Service端口 port: 80 # 目标Pod端口和Deployment中暴露的容器端口一致 targetPort: http # 标签选择器匹配GitLab Pod的标签实现流量转发 selector: app: gitlab # Service类型为NodePort实现集群外访问 type: NodePort status: loadBalancer: {}3.4 部署 GitLab 服务并验证1.执行部署命令# 部署GitLab Deployment kubectl apply -f gitlab-deploy.yaml # 输出deployment.apps/gitlab created即部署成功 # 部署GitLab Service kubectl apply -f gitlab-service.yaml # 输出service/gitlab created即部署成功2.查看部署状态GitLab 启动较慢需要等待 1-3 分钟Pod 状态变为 Running 即为启动成功# 查看gitlab-ci命名空间下的Pod状态 kubectl get pod -n gitlab-ci # 正常输出示例 NAME READY STATUS RESTARTS AGE gitlab-5df67d6c7f-jgbpp 1/1 Running 0 86s # 查看Service状态 kubectl get svc -n gitlab-ci # 正常输出示例 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gitlab NodePort 10.96.193.92 none 80:30880/TCP 3m24s访问 GitLab 服务此时我们可以通过浏览器访问http://master节点IP:30880比如我的环境就是http://172.18.10.44:30880使用账号root、密码admin123即可登录 GitLab。四、第二步GitLab 集群内 DNS 解析配置与项目初始化4.1 配置 CoreDNS 实现 GitLab Pod 域名解析GitLab 在流水线中会返回 Pod 内的仓库地址为了让集群内的 Runner 能正常解析 GitLab 的地址我们需要修改 K8s 的 CoreDNS 配置添加 GitLab Pod 的 hosts 解析。1.首先获取 GitLab Pod 的 IP 和名称# 获取GitLab Pod的详细信息记录NAME和IP kubectl get pod -n gitlab-ci -o wide2.编辑 CoreDNS 的 ConfigMap 配置# 编辑kube-system命名空间下的coredns配置 kubectl edit configmap coredns -n kube-system在 Corefile 中添加 hosts 配置注释掉默认的 forward 配置修改后的核心配置如下hosts { # 这里替换为你的GitLab Pod IP和Pod名称 10.244.0.18 gitlab-f6874fdb8-zfx9v fallthrough } prometheus :9153 # forward . /etc/resolv.conf { # max_concurrent 1000 # } cache 303.重启 CoreDNS 使配置生效# 滚动重启CoreDNS Deployment kubectl -n kube-system rollout restart deploy coredns # 输出deployment.apps/coredns restarted即重启成功4.2 创建 GitLab 项目并上传代码接下来我们创建一个 demo 项目用于后续的 CI/CD 流水线测试这里使用 2048 游戏项目作为示例。创建项目登录 GitLab 后点击New a project→Create blank project项目名称填写demo-2048可见等级选择Public点击创建即可。上传 demo 代码到 GitLab 仓库# 进入demo项目代码目录 cd /root/gitlab-ci/demo-2048 # 配置git全局用户信息 git config --global user.name administrator git config --global user.email adminexample.com # 移除默认的远程仓库添加我们刚创建的GitLab仓库地址 git remote remove origin # 这里替换为你的GitLab仓库地址IP为master节点IP git remote add origin http://172.18.10.44:30880/root/demo-2048.git # 添加所有代码文件到暂存区 git add . # 提交代码到本地仓库 git commit -m initial commit # 推送代码到GitLab远程仓库的drone分支 git push -u origin drone执行完成后刷新 GitLab 项目页面就能看到我们上传的代码了。这里注意我们的默认分支是drone如果需要修改默认分支可以在项目的设置→仓库→默认分支中调整。五、第三步部署 GitLab CI Runner 执行器GitLab Runner 是 CI/CD 流水线的执行器负责接收 GitLab 下发的任务并执行。我们将通过 Helm 在 K8s 集群中部署 Runner实现流水线任务的动态 Pod 执行。5.1 前置配置获取 Runner 注册令牌首先我们需要获取 GitLab 的 Runner 注册令牌用于 Runner 和 GitLab 服务的注册绑定登录 GitLab 管理界面访问http://master节点IP:30880/admin点击左侧菜单栏CI/CD→Runners记录下页面中的注册令牌后续配置会用到5.2 配置 RBAC 权限Runner 需要在 K8s 集群中创建、删除 Pod所以需要给它配置对应的 RBAC 权限这里提供两种配置方式效果一致。方式一命令行快速创建# 创建ServiceAccount kubectl create serviceaccount gitlab-ci -n gitlab-ci # 创建Role授予gitlab-ci命名空间下所有资源的所有权限 kubectl create role gitlab-ci --resource* --verb* -n gitlab-ci # 创建RoleBinding将Role绑定到ServiceAccount kubectl create rolebinding gitlab-ci --rolegitlab-ci --serviceaccountgitlab-ci:gitlab-ci -n gitlab-ci方式二YAML 文件创建推荐便于版本管理创建runner-rbac.yaml文件内容如下# ServiceAccount给Runner提供身份凭证 apiVersion: v1 kind: ServiceAccount metadata: name: gitlab-ci namespace: gitlab-ci --- # Role定义权限规则授予命名空间下所有资源的所有操作权限 kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: gitlab-ci namespace: gitlab-ci rules: - apiGroups: [] resources: [*] verbs: [*] --- # RoleBinding将Role和ServiceAccount绑定使权限生效 kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: gitlab-ci namespace: gitlab-ci subjects: - kind: ServiceAccount name: gitlab-ci namespace: gitlab-ci roleRef: kind: Role name: gitlab-ci apiGroup: rbac.authorization.k8s.io执行部署命令kubectl apply -f runner-rbac.yaml同时我们需要给 default ServiceAccount 授予集群管理员权限用于后续流水线中操作集群资源# 创建ClusterRoleBinding给gitlab-ci命名空间下的default SA绑定cluster-admin集群管理员权限 kubectl create clusterrolebinding default --clusterrolecluster-admin --serviceaccountgitlab-ci:default5.3 Helm 部署 GitLab Runner我们使用官方的 GitLab Runner Helm Chart 进行部署实现高可用、可配置的 Runner 部署。1.解压 Helm Chart 包# 解压Runner Helm Chart包 tar -zxvf gitlab-runner-0.43.0.tgz # 进入Chart目录 cd gitlab-runner2.修改values.yaml核心配置编辑values.yaml文件修改以下四个核心参数同时添加特权模式配置# 1. 指定我们创建的ServiceAccount名称 serviceAccountName: gitlab-ci # 2. GitLab服务地址替换为你的master节点IP gitlabUrl: http://172.18.10.44:30880/ # 3. 之前记录的Runner注册令牌 runnerRegistrationToken: 3x2Q7nbinwq58eN2KbGj # 4. Runner配置开启特权模式用于容器镜像构建 runners: config: | [[runners]] [runners.kubernetes] namespace {{.Release.Namespace}} image ubuntu:16.04 # 开启特权模式必须开启否则Docker in Docker构建镜像会失败 privileged true3.可选配置构建缓存 PVC为了避免每次构建都重新下载依赖提升构建速度我们配置 PVC 用于构建缓存持久化创建templates/pvc.yaml文件定义 PV 和 PVC# 持久化卷PV使用hostPath模式单节点测试使用生产环境建议使用分布式存储 apiVersion: v1 kind: PersistentVolume metadata: name: ci-build-cache-pv namespace: gitlab-ci labels: type: local spec: storageClassName: manual capacity: storage: 10Gi accessModes: - ReadWriteOnce hostPath: path: /opt/ci-build-cache --- # 持久化卷声明PVC apiVersion: v1 kind: PersistentVolumeClaim metadata: name: ci-build-cache-pvc namespace: gitlab-ci spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 5Gi在values.yaml文件末尾追加缓存配置## configure build cache cibuild: cache: pvcName: ci-build-cache-pvc mountPath: /home/gitlab-runner/ci-build-cache编辑templates/configmap.yaml文件在 Runner 启动前添加 PVC 挂载配置# 在start the runner之前添加如下配置实现PVC自动挂载 cat /home/gitlab-runner/.gitlab-runner/config.toml EOF [[runners.kubernetes.volumes.pvc]] name {{.Values.cibuild.cache.pvcName}} mount_path {{.Values.cibuild.cache.mountPath}} EOF # Start the runner exec /entrypoint run --usergitlab-runner \ --working-directory/home/gitlab-runner4.执行 Helm 安装# 在gitlab-runner目录下执行安装命令安装到gitlab-ci命名空间 helm -n gitlab-ci install gitlab-runner .安装成功后会输出如下提示NAME: gitlab-runner LAST DEPLOYED: Mon Sep 11 15:56:17 2025 NAMESPACE: gitlab-ci STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Your GitLab Runner should now be registered against the GitLab instance reachable at: http://172.18.10.44:30880/5.验证 Runner 部署与注册# 查看gitlab-ci命名空间下的Pod确认Runner Pod正常Running kubectl get pod -n gitlab-ci # 正常输出示例Runner Pod状态为Running NAME READY STATUS RESTARTS AGE gitlab-f6874fdb8-8w9vx 1/1 Running 0 66m gitlab-runner-768f67cffb-kczpp 1/1 Running 0 112s此时回到 GitLab 的 Runner 页面刷新后就能看到我们刚部署的 Runner 已经成功注册状态为在线至此 Runner 部署完成。六、第四步配置 GitLab Agent 实现 K8s 集群集成GitLab Agent 是 GitLab 官方推荐的 K8s 集群集成方案用于实现 GitOps 自动化部署、流水线中安全操作 K8s 资源无需暴露 K8s APIServer 到公网安全性更高。6.1 创建 Agent 配置文件在 GitLab 的 demo-2048 项目中创建 Agent 配置文件路径为.gitlab/agents/kubernetes-agent/config.yaml内容如下# GitLab Agent配置定义GitOps管理的项目和规则 gitops: manifest_projects: # 要管理的项目ID格式为 用户名/项目名 - id: root/demo-2048 # 部署的默认命名空间 default_namespace: gitlab-ci # 要扫描的K8s资源清单路径匹配所有yaml/yml/json文件 paths: - glob: /**/*.{yaml,yml,json}提交配置文件到 GitLab 仓库后进入项目的运维→Kubernetes页面点击添加Kubernetes集群选择连接现有集群记录下 Agent 的令牌和接入地址。6.2 Helm 安装 GitLab Agent回到 master 节点执行以下 Helm 命令安装 Agent替换为你的令牌和 GitLab 地址helm install kubernetes-agent gitlab-agent-1.1.0.tgz --namespace gitlab-ci \ --set image.tagv16.2.0 \ --set config.tokenqbn5FDiW4d1hytg-EA7WFKcidG-rwz-WyGY5hBBAwn8ZWt_jAw \ --set config.kasAddressws://172.18.10.44:30880/-/kubernetes-agent/安装完成后验证 Agent 状态# 查看helm发布列表 helm -n gitlab-ci list # 查看Agent Pod状态正常为Running kubectl get pod -n gitlab-ci | grep kubernetes-agent回到 GitLab 的 Kubernetes 页面刷新后就能看到集群已成功连接Agent 状态为在线。七、第五步构建完整 CICD 流水线实现自动构建与部署接下来就是最核心的环节我们通过编写.gitlab-ci.yml文件定义完整的 CI/CD 流水线实现代码提交后自动完成代码构建→镜像打包→仓库推送→K8s 部署的全流程自动化。7.1 前置配置Harbor 镜像仓库准备我们需要一个私有镜像仓库来存储构建好的应用镜像这里使用 Harbor 作为私有仓库提前完成以下配置在 Harbor 中创建一个公开项目demo将基础镜像推送到 Harbor 仓库确保流水线能正常拉取配置 K8s 集群的 containerd使其能正常访问 Harbor 仓库1. 推送基础镜像到 Harbor# 给tomcat基础镜像打标签替换为你的Harbor仓库IP ctr -n k8s.io images tag docker.io/library/tomcat:8.5.64-jdk8 172.18.10.44/library/tomcat:8.5.64-jdk8 # 推送镜像到Harbor仓库替换为你的Harbor账号密码 ctr -n k8s.io images push 172.18.10.44/library/tomcat:8.5.64-jdk8 --plain-httptrue --user admin:Harbor123452. 配置 containerd 支持 Harbor HTTP 仓库修改集群所有节点的 containerd 配置文件添加 Harbor 仓库配置# 编辑containerd配置文件 vi /etc/containerd/config.toml # 在[plugins.io.containerd.grpc.v1.cri.registry.mirrors]下添加以下内容 [plugins.io.containerd.grpc.v1.cri.registry.mirrors.172.18.10.44] endpoint [http://172.18.10.44] # 重启containerd使配置生效 systemctl daemon-reload systemctl restart containerd⚠️ 注意master 和 worker 节点都需要修改配置并重启 containerd。7.2 编写.gitlab-ci.yml 流水线文件在 demo-2048 项目的根目录创建.gitlab-ci.yml文件定义流水线的三个核心阶段build代码构建、release镜像打包推送、review应用部署完整代码附带逐行注释如下# 定义流水线的阶段按顺序执行 stages: - build - release - review # 全局环境变量所有阶段都能使用 variables: # Maven本地仓库路径配合PVC缓存避免每次重新下载依赖 MAVEN_OPTS: -Dmaven.repo.local/opt/cache/.m2/repository # Harbor仓库账号 REGISTRY_USER: admin # Harbor仓库密码 REGISTRY_PASSWORD: Harbor12345 # Harbor仓库地址替换为你的IP REGISTRY: 172.18.10.44 # 镜像名称 REGISTRY_IMAGE: demo # Harbor项目名称 REGISTRY_PROJECT: demo # 第一阶段代码构建使用Maven镜像编译打包Java项目 maven_build: # 使用的镜像包含Maven和JDK8环境 image: maven:3.6-jdk-8 # 所属阶段 stage: build # 触发规则仅drone分支提交代码时触发 only: - drone # 执行的脚本 script: # 拷贝预下载的依赖到缓存目录加速构建 - cp -r /opt/repository /opt/cache/.m2/ # 执行Maven打包跳过单元测试 - mvn clean install -DskipTeststrue # 进入target目录解压war包用于后续镜像构建 - cd target jar -xf 2048.war # 将解压后的文件拷贝到PVC缓存目录供下一阶段使用 - cp -rfv 2048 /home/gitlab-runner/ci-build-cache # 第二阶段镜像构建与推送使用Docker-in-Docker实现容器镜像打包 image_build: image: docker:18.09.7 stage: release # Docker环境变量 variables: DOCKER_DRIVER: overlay2 DOCKER_HOST: tcp://localhost:2375 # 依赖的服务Docker-in-Docker用于镜像构建 services: - name: docker:18.09.7-dind entrypoint: [dockerd-entrypoint.sh] # 开启HTTP仓库支持避免HTTPS证书问题 command: [--insecure-registry, 0.0.0.0/0] script: # 从缓存目录拷贝上一阶段构建好的项目文件 - cp -rfv /home/gitlab-runner/ci-build-cache/2048 . # 替换Dockerfile中的Harbor地址为当前环境变量 - sed -i s/10.24.2.3/$REGISTRY/g ./Dockerfiles/Dockerfile # 构建Docker镜像 - docker build -t ${REGISTRY_IMAGE}:latest -f ./Dockerfiles/Dockerfile . # 给镜像打标签符合Harbor仓库规范 - docker tag ${REGISTRY_IMAGE}:latest ${REGISTRY}/${REGISTRY_PROJECT}/${REGISTRY_IMAGE}:latest # 登录Harbor仓库 - docker login -u ${REGISTRY_USER} -p ${REGISTRY_PASSWORD} ${REGISTRY} # 推送镜像到Harbor仓库 - docker push ${REGISTRY}/${REGISTRY_PROJECT}/${REGISTRY_IMAGE}:latest # 第三阶段自动部署到K8s集群 deploy_review: # 包含kubectl工具的镜像用于操作K8s集群 image: bitnami/kubectl:1.22.1 stage: review only: - drone script: # 替换部署文件中的镜像仓库地址为当前环境变量 - sed -i s/REGISTRY/$REGISTRY/g template/demo-2048.yaml # 应用K8s部署文件自动部署应用到集群 - kubectl apply -f template/7.3 触发流水线并验证将.gitlab-ci.yml文件提交并推送到 GitLab 仓库后GitLab 会自动触发流水线我们可以在项目的CI/CD→流水线页面查看执行状态。流水线执行成功后我们可以验证应用是否部署成功# 查看gitlab-ci命名空间下的Pod确认demo应用Pod正常Running kubectl get pod -n gitlab-ci # 正常输出示例 NAME READY STATUS RESTARTS AGE demo-2048-56847d667c-59dtp 1/1 Running 0 95s # 查看Service确认应用端口映射正常 kubectl get svc -n gitlab-ci # 正常输出示例 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-2048 NodePort 10.96.67.233 none 8080:8889/TCP 4h28m此时我们通过浏览器访问http://master节点IP:8889就能看到我们部署的 2048 游戏应用至此完整的 CI/CD 流水线全部落地完成八、踩坑指南与生产环境注意事项8.1 我踩过的核心坑点帮大家避坑Runner 注册失败大概率是 GitLab 地址无法解析检查 CoreDNS 的 hosts 配置是否正确确保 Runner Pod 能 ping 通 GitLab 的 Service 和 Pod 地址检查注册令牌是否正确GitLab 的项目级令牌和全局管理员令牌不能混用流水线镜像构建失败必须给 Runner 开启 privileged 特权模式否则 Docker-in-Docker 无法正常运行检查 Harbor 仓库的 HTTP 配置containerd 和 dind 服务都需要配置 insecure-registry否则会报 HTTPS 证书错误K8s 部署权限不足检查流水线使用的 ServiceAccount 是否有对应的命名空间权限提前给 default SA 绑定 cluster-admin 权限或者按需配置最小权限GitLab 启动慢 / 无法访问GitLab 对资源要求较高最低需要 2 核 4G 配置资源不足会导致启动失败、页面无法访问检查 NodePort 端口是否被防火墙拦截开放 30880 端口的访问权限8.2 生产环境注意事项高可用部署GitLab 服务建议使用多副本部署使用共享存储做数据持久化避免单点故障Runner 部署多个副本提升流水线并发执行能力安全加固所有默认密码必须更换为强密码包括 GitLab root 账号、Harbor 账号、数据库密码GitLab 和 Harbor 都配置 HTTPS 证书替换 HTTP 访问避免数据传输泄露给 Runner 配置最小权限原则不要直接绑定 cluster-admin 集群管理员权限持久化存储GitLab 的代码数据、Runner 的构建缓存、Harbor 的镜像数据都必须使用持久化存储避免数据丢失生产环境建议使用分布式存储如 Ceph、NFS不要使用 hostPath 模式资源限制给所有 Deployment 都配置 CPU 和内存的 requests 和 limits避免单个服务占用过多资源影响集群稳定流水线优化配置依赖缓存减少重复下载提升构建速度增加单元测试、代码扫描、漏洞检测阶段提升代码质量配置多环境流水线实现开发、测试、生产环境的分级部署结尾总结今天这篇教程我带大家从零开始在 K8s 集群中完成了 GitLab 服务部署、Runner 执行器配置、K8s 集群 Agent 集成最终落地了一套完整的代码提交→自动构建→镜像打包→仓库推送→自动部署的全流程 CI/CD 流水线。整个流程下来大家不仅能掌握 GitLab CI/CD 的核心原理和实操技能更能理解 DevOps 持续集成的核心思想 —— 通过自动化减少人工操作提升研发效率降低发布风险。后续大家还可以基于这套体系扩展代码扫描、自动化测试、灰度发布、回滚机制等高级功能打造更完善的企业级 DevOps 体系。如果大家在部署过程中遇到任何问题欢迎在评论区留言交流我会一一回复。