news 2026/4/16 8:05:09

K8s 实战:基于 GitLab CI/CD 构建全流程持续集成流水线,从环境部署到应用自动发布

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
K8s 实战:基于 GitLab CI/CD 构建全流程持续集成流水线,从环境部署到应用自动发布

大家好,今天给大家带来一篇 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 的官方推荐方案。

整体流水线架构

我们最终实现的完整流程如下:

  1. 开发者提交代码到 GitLab 项目仓库
  2. GitLab 自动触发 CI/CD 流水线,将任务下发给 GitLab Runner
  3. Runner 在 K8s 集群中创建临时 Pod,按流水线阶段依次执行:
    • 代码编译构建
    • 容器镜像打包
    • 镜像推送到私有镜像仓库
    • 自动部署应用到 K8s 集群
  4. 全程自动化,无需人工干预,实现代码提交即发布

二、前置环境与准备工作

先给大家同步我的实操环境,所有操作均在 K8s 集群中执行,大家可以根据自己的环境对应调整:

环境项详细配置
Kubernetes 集群1 个 master 节点 + 1 个 worker 节点,版本 1.20+
容器运行时containerd
核心工具Helm 3 已在 master 节点安装完成
master 节点 IP172.18.10.44
worker 节点 IP172.18.10.45
资源包Gitlab-CI.tar.gz(包含所有镜像、安装包、2048 demo 项目代码)

基础环境初始化

首先我们先完成资源包解压、镜像导入,因为 K8s 调度 Pod 会分布在不同节点,所以需要把镜像导入到集群所有节点的 containerd 中。

1.解压资源包

# 进入root目录,所有操作均在此目录下执行 cd /root # 解压GitLab CI资源包 tar -zvxf Gitlab-CI.tar.gz

2.镜像分发与导入

# 将镜像压缩包拷贝到worker节点,确保worker节点也能加载到所需镜像 scp /root/gitlab-ci/images/images.tar k8s-worker-node1:/root

3.master 节点导入镜像

# 导入镜像到k8s.io命名空间(containerd中K8s使用的默认命名空间) ctr -n k8s.io image import gitlab-ci/images/images.tar

4.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 --image=gitlab/gitlab-ce:latest --port=80 --namespace=gitlab-ci --dry-run=client -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: admin@123 # 设置root用户邮箱 - name: GITLAB_ROOT_EMAIL value: 123456@qq.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 --namespace=gitlab-ci --tcp=80:80 --node-port=30880 --dry-run=client -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、密码admin@123即可登录 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 wide

2.编辑 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 30

3.重启 CoreDNS 使配置生效

# 滚动重启CoreDNS Deployment kubectl -n kube-system rollout restart deploy coredns # 输出deployment.apps/coredns restarted即重启成功

4.2 创建 GitLab 项目并上传代码

接下来我们创建一个 demo 项目,用于后续的 CI/CD 流水线测试,这里使用 2048 游戏项目作为示例。

  1. 创建项目登录 GitLab 后,点击New a projectCreate blank project,项目名称填写demo-2048,可见等级选择Public,点击创建即可。

  1. 上传 demo 代码到 GitLab 仓库

# 进入demo项目代码目录 cd /root/gitlab-ci/demo-2048 # 配置git全局用户信息 git config --global user.name "administrator" git config --global user.email "admin@example.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 服务的注册绑定:

  1. 登录 GitLab 管理界面,访问http://master节点IP:30880/admin
  2. 点击左侧菜单栏CI/CDRunners
  3. 记录下页面中的注册令牌,后续配置会用到

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 --role=gitlab-ci --serviceaccount=gitlab-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 --clusterrole=cluster-admin --serviceaccount=gitlab-ci:default

5.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-runner

2.修改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 = true

3.(可选)配置构建缓存 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 --user=gitlab-runner \ --working-directory=/home/gitlab-runner

4.执行 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.tag=v16.2.0 \ --set config.token=qbn5FDiW4d1hytg-EA7WFKcidG-rwz-WyGY5hBBAwn8ZWt_jAw \ --set config.kasAddress=ws://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 作为私有仓库,提前完成以下配置:

  1. 在 Harbor 中创建一个公开项目demo
  2. 将基础镜像推送到 Harbor 仓库,确保流水线能正常拉取
  3. 配置 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-http=true --user admin:Harbor12345
2. 配置 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 -DskipTests=true # 进入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 我踩过的核心坑点,帮大家避坑

  1. Runner 注册失败

    • 大概率是 GitLab 地址无法解析,检查 CoreDNS 的 hosts 配置是否正确,确保 Runner Pod 能 ping 通 GitLab 的 Service 和 Pod 地址
    • 检查注册令牌是否正确,GitLab 的项目级令牌和全局管理员令牌不能混用
  2. 流水线镜像构建失败

    • 必须给 Runner 开启 privileged 特权模式,否则 Docker-in-Docker 无法正常运行
    • 检查 Harbor 仓库的 HTTP 配置,containerd 和 dind 服务都需要配置 insecure-registry,否则会报 HTTPS 证书错误
  3. K8s 部署权限不足

    • 检查流水线使用的 ServiceAccount 是否有对应的命名空间权限,提前给 default SA 绑定 cluster-admin 权限,或者按需配置最小权限
  4. GitLab 启动慢 / 无法访问

    • GitLab 对资源要求较高,最低需要 2 核 4G 配置,资源不足会导致启动失败、页面无法访问
    • 检查 NodePort 端口是否被防火墙拦截,开放 30880 端口的访问权限

8.2 生产环境注意事项

  1. 高可用部署
    • GitLab 服务建议使用多副本部署,使用共享存储做数据持久化,避免单点故障
    • Runner 部署多个副本,提升流水线并发执行能力
  2. 安全加固
    • 所有默认密码必须更换为强密码,包括 GitLab root 账号、Harbor 账号、数据库密码
    • GitLab 和 Harbor 都配置 HTTPS 证书,替换 HTTP 访问,避免数据传输泄露
    • 给 Runner 配置最小权限原则,不要直接绑定 cluster-admin 集群管理员权限
  3. 持久化存储
    • GitLab 的代码数据、Runner 的构建缓存、Harbor 的镜像数据都必须使用持久化存储,避免数据丢失
    • 生产环境建议使用分布式存储(如 Ceph、NFS),不要使用 hostPath 模式
  4. 资源限制
    • 给所有 Deployment 都配置 CPU 和内存的 requests 和 limits,避免单个服务占用过多资源,影响集群稳定
  5. 流水线优化
    • 配置依赖缓存,减少重复下载,提升构建速度
    • 增加单元测试、代码扫描、漏洞检测阶段,提升代码质量
    • 配置多环境流水线,实现开发、测试、生产环境的分级部署

结尾总结

今天这篇教程,我带大家从零开始,在 K8s 集群中完成了 GitLab 服务部署、Runner 执行器配置、K8s 集群 Agent 集成,最终落地了一套完整的代码提交→自动构建→镜像打包→仓库推送→自动部署的全流程 CI/CD 流水线。

整个流程下来,大家不仅能掌握 GitLab CI/CD 的核心原理和实操技能,更能理解 DevOps 持续集成的核心思想 —— 通过自动化减少人工操作,提升研发效率,降低发布风险。后续大家还可以基于这套体系,扩展代码扫描、自动化测试、灰度发布、回滚机制等高级功能,打造更完善的企业级 DevOps 体系。

如果大家在部署过程中遇到任何问题,欢迎在评论区留言交流,我会一一回复。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 8:04:28

Poppler预编译包:Windows生态中的PDF处理标准化方案

Poppler预编译包&#xff1a;Windows生态中的PDF处理标准化方案 【免费下载链接】poppler-windows Download Poppler binaries packaged for Windows with dependencies 项目地址: https://gitcode.com/gh_mirrors/po/poppler-windows 在跨平台软件开发实践中&#xff0…

作者头像 李华
网站建设 2026/4/16 8:03:15

李慕婉-仙逆-造相Z-Turbo部署避坑指南:新手常见问题与解决方案

李慕婉-仙逆-造相Z-Turbo部署避坑指南&#xff1a;新手常见问题与解决方案 1. 镜像部署准备 1.1 系统环境检查 在部署李慕婉-仙逆-造相Z-Turbo镜像前&#xff0c;请确保您的环境满足以下要求&#xff1a; 操作系统&#xff1a;推荐使用Ubuntu 20.04/22.04或CentOS 7/8Docke…

作者头像 李华
网站建设 2026/4/16 7:52:10

软件实例化管理中的对象池技术

软件实例化管理中的对象池技术 在软件开发中&#xff0c;对象池技术是一种高效管理资源的方法&#xff0c;尤其适用于频繁创建和销毁对象的场景。通过预先创建并缓存对象&#xff0c;对象池技术能够显著减少系统开销&#xff0c;提升性能。无论是数据库连接、线程管理&#xf…

作者头像 李华
网站建设 2026/4/16 7:51:42

终极Dell G15散热控制指南:如何彻底告别游戏本过热问题

终极Dell G15散热控制指南&#xff1a;如何彻底告别游戏本过热问题 【免费下载链接】tcc-g15 Thermal Control Center for Dell G15 - open source alternative to AWCC 项目地址: https://gitcode.com/gh_mirrors/tc/tcc-g15 还在为Dell G15游戏本的散热问题烦恼吗&…

作者头像 李华
网站建设 2026/4/16 7:51:07

Python的__class_getitem__实现泛型别名

Python类型系统中的__class_getitem__魔法方法为泛型编程带来了全新可能。这个在Python 3.7引入的特殊机制&#xff0c;允许类通过方括号语法接收类型参数&#xff0c;为构建类型安全的泛型别名提供了底层支持。本文将深入解析这个特性如何改变我们处理类型提示的方式。泛型别名…

作者头像 李华
网站建设 2026/4/16 7:48:11

大麦网抢票自动化:Python脚本帮你轻松购票

大麦网抢票自动化&#xff1a;Python脚本帮你轻松购票 【免费下载链接】Automatic_ticket_purchase 大麦网抢票脚本 项目地址: https://gitcode.com/GitHub_Trending/au/Automatic_ticket_purchase 还在为热门演出门票一票难求而烦恼吗&#xff1f;你是否曾经在开票瞬间…

作者头像 李华