阶段三:Kubernetes基于Jenkins+Gitlab实现CICD
Kubernetes 集群部署CICD流程图

安装gitlab(已经安装好了不用再部署)
- 创建名称空间
[root@master01 ops]# kubectl create ns ops
[root@master01 ops]# mkdir ops && cd ops注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
YAML 保存位置: ~/k8s-manifests/ops/gitlab.yaml
先在 Kubernetes 管理节点执行:
mkdir -p ~/k8s-manifests/ops
cd ~/k8s-manifests/ops
vi gitlab.yaml把下方 YAML 全部复制进去;红色字段按当前环境修改;按 Esc 后输入 :wq 保存退出。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: gitlab
namespace: ops
spec:
serviceName: "gitlab-svc"
selector:
matchLabels:
app: gitlab
template:
metadata:
labels:
app: gitlab
spec:
containers:
- name: gitlab-ce
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gitlab/gitlab-ce:15.4.6-ce.0
env:
- name: TZ #设置时区
value: Asia/Shanghai
- name: GITLAB_ROOT_PASSWORD #设置GitLab的root密码
value: "gitlab123"
- name: GITLAB_OMNIBUS_CONFIG #需要修改gitlab.rb文件中的配置可以在这里配置,每个配置一行,需要定义GitLab的URL,关闭无用组件
value: | #"|"表示以下内容是一个多行字符串
external_url "http://gitlab.lanqicheng.top"
gitlab_rails['time_zone'] = 'Asia/Shanghai'
node_exporter['enable'] = false
redis_exporter['enable'] = false
postgres_exporter['enable'] = false
gitlab_exporter['enable'] = false
grafana['enable'] = false
grafana['reporting_enabled'] = false
prometheus['enable'] = false
prometheus['monitor_kubernetes'] = false
alertmanager['enable'] = false
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
volumeMounts:
- name: data
mountPath: /etc/gitlab
subPath: config
- name: data
mountPath: /var/opt/gitlab
subPath: data
- name: data
mountPath: /var/log/gitlab
subPath: logs
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "csi-rbd-sc"
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
name: gitlab-svc
namespace: ops
spec:
clusterIP: None
selector:
app: gitlab
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitlab-ingress
namespace: ops
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "512m"
spec:
ingressClassName: "nginx"
rules:
- host: "gitlab.lanqicheng.top"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitlab-svc
port:
name: http
[root@master01 ops]# kubectl apply -f gitlab-statefulset.yaml
#安装过程很漫长,需要耐心等等配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: ops | 与实际命名空间一致;使用默认命名空间时可不写。 |
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/gitlab/gitlab-ce:15.4.6-ce.0 | 替换为实际可拉取的镜像地址和版本。 |
accessModes: ["ReadWriteOnce"] | 按存储类型与读写需求确认。 |
storageClassName: csi-rbd-sc | 替换为集群中存在的 StorageClass。 |
storage: 5Gi | 按数据量调整容量。 |
port: 80 | 对外暴露的 Service 端口;调用方按此端口访问。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
Jenkins 概述
Jenkins 是一个开源的自动化平台工具,主要用于 持续交付(CI)和持续部署(CD)。
它可以帮开发团队在 代码提交后,自动完成:
- 拉取代码
- 编译构建
- 自动化测试
- 构建镜像
- 推送到镜像仓库
- 部署到服务器或 Kubernetes
安装jenkins
- 先创建RBAC, 后期Jenkins需要创建Slave Pod来完成流水线的执行
kubectl create ns ops
mkdir /data/ops && cd /data/ops可复制 YAML:
YAML 保存位置: ~/k8s-manifests/ops/jenkins-rbac.yaml
先在 Kubernetes 管理节点执行:
mkdir -p ~/k8s-manifests/ops
cd ~/k8s-manifests/ops
vi jenkins-rbac.yaml把下方 YAML 全部复制进去;红色字段按当前环境修改;按 Esc 后输入 :wq 保存退出。
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins
namespace: ops
---
# clusterRole
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: jenkins
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments", "ingresses"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["services"]
verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: [""]
resources: ["pods/exec"]
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
- apiGroups: [""]
resources: ["pods/log", "events"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
# clusterrolebinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: jenkins
namespace: ops
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: jenkins
subjects:
- kind: ServiceAccount
name: jenkins
namespace: ops配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: ops | 与实际命名空间一致;使用默认命名空间时可不写。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
YAML 保存位置: ~/k8s-manifests/ops/jenkins.yaml
先在 Kubernetes 管理节点执行:
mkdir -p ~/k8s-manifests/ops
cd ~/k8s-manifests/ops
vi jenkins.yaml把下方 YAML 全部复制进去;红色字段按当前环境修改;按 Esc 后输入 :wq 保存退出。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: jenkins
namespace: ops
spec:
serviceName: "jenkins-svc"
selector:
matchLabels:
app: jenkins
template:
metadata:
labels:
app: jenkins
spec:
serviceAccount: jenkins
containers:
- name: jenkins
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jenkins/jenkins:lts-jdk21 #这个版本是2.492.2
securityContext: #初始容器安全上下文,用来控制容器的权限
privileged: true #privileged属性设置为true时,容器将被授予主机操作系统的完全权限,包括对底层硬件和内核的访问
runAsUser: 0 #容器启动以UID为0的用户运行
ports:
- name: http
containerPort: 8080
- name: agent #jenkins slave访问jenkins master端口
containerPort: 50000
env:
- name: JAVA_OPTS #设置Jenkins程序时区
value: -Duser.timezone=Asia/Shanghai
- name: TZ
value: "Asia/Shanghai" #设置Jenkins镜像时区
readinessProbe: #就绪探针
httpGet:
path: /login
port: 8080
initialDelaySeconds: 60 #首次探测时间
timeoutSeconds: 5 #超时时间
volumeMounts:
- name: data
mountPath: /var/jenkins_home # Jenkins的家目录
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-storage"
resources:
requests:
storage: 5Gi
---
apiVersion: v1
kind: Service
metadata:
name: jenkins-svc
namespace: ops
spec:
clusterIP: None
selector:
app: jenkins
ports:
- name: http
port: 8080
targetPort: 8080
- name: agent #jenkins slave访问jenkins master端口
port: 50000
targetPort: 50000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: ops
spec:
ingressClassName: "nginx"
rules:
- host: "jenkins.lanqicheng.top"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: jenkins-svc
port:
name: http
[root@master01 ops]# kubectl apply -f jenkins-statefulset.yaml配置详解:
| 需要改的项 | 为什么改 |
|---|---|
namespace: ops | 与实际命名空间一致;使用默认命名空间时可不写。 |
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jenkins/jenkins:lts-jdk21 | 替换为实际可拉取的镜像地址和版本。 |
port: 8080 | 对外暴露的 Service 端口;调用方按此端口访问。 |
accessModes: ["ReadWriteOnce"] | 按存储类型与读写需求确认。 |
storageClassName: nfs-storage | 替换为集群中存在的 StorageClass。 |
storage: 5Gi | 按数据量调整容量。 |
注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
- YAML 缩进不能乱;同级字段要对齐,子字段要多缩进两个空格。
- 资源名称、命名空间、标签选择器要互相对应,否则资源创建了也可能找不到彼此。
- 镜像地址、版本号和拉取权限要确认,否则 Pod 会进入
ImagePullBackOff。
[root@master01 ops]# kubectl logs jenkins-0 -n ops
*************************************************************
*************************************************************
*************************************************************
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:
bcf879b5d5b448e1979ee0fc9a53b127 #第一次登录密钥
This may also be found at: /var/jenkins_home/secrets/initialAdminPassword
*************************************************************
*************************************************************
*************************************************************
2025-09-15 09:19:02.376+0000 [id=33] INFO jenkins.InitReactorRunner$1#onAttained: Completed initialization
2025-09-15 09:19:02.474+0000 [id=24] INFO hudson.lifecycle.Lifecycle#onReady: Jenkins is fully up and running
2025-09-15 09:19:06.211+0000 [id=51] INFO h.m.DownloadService$Downloadable#load: Obtained the updated data file for hudson.tasks.Maven.MavenInstaller
2025-09-15 09:19:06.213+0000 [id=51] INFO hudson.util.Retrier#start: Performed the action check updates server successfully at the attempt #1注意事项:
- 修改配置前先备份原文件,尤其是 SSH、Nginx、数据库和 Kubernetes 生产配置。
Jenkins Slave环境准备
所谓 Jenkins Master/Slave 架构,在Master上进行任务分配。然后由Slave来完成

- 配置Jenkins Slave
系统管理--->cloud--->New cloud


- 输入kubernetes

- 输入https://kubernetes.default.svc.cluster.local

- 输入http://jenkins-svc.ops.svc.cluster.local:8080和jenkins-svc.ops.svc.cluster.local:50000

- 点击保存

Pipeline流水线
- Pipeline(流水线):就是把软件交付的整个过程(拉代码 → 编译-->测试 → 构建 → 推送仓库 → 部署)用一份脚本描述出来。
- 在 Jenkins 中,Pipeline 是通过 Jenkinsfile(Groovy DSL 脚本)来实现的。
- 它相当于一个 自动化的工厂流水线,每次代码更新,就会按照定义好的步骤顺序执行。
- 流水线语法示例
pipeline {
//指定任务在哪个节点上执行(any表示任意节点)
agent any
//用于声明全局环境变量,后面可调用
environment {
key='value'
}
//stages表示一个流水线任务的集合,所有任务的步骤都要定义在stages中
stages {
//一个stage就是一个阶段
stage('拉取代码') {
//在steps中定义执行的命令
steps {
echo 'SUCCESS'
}
}
stage('构建项目') {
steps {
echo 'SUCCESS'
}
}
stage('制作镜像') {
steps {
echo 'SUCCESS'
}
}
stage('推送镜像到仓库') {
steps {
echo 'SUCCESS'
}
}
stage('部署') {
steps {
echo 'SUCCESS'
}
}
}
}命令作用:
- 把命令后的文本或变量展开结果写到标准输出;配合
>或>>时会改为写入文件,前者覆盖、后者追加。
执行结果:
- 成功后文本或变量展开结果会输出到终端;带重定向时会写入目标文件。
关键参数:
注意事项:
containerd拉取镜像代理设置 [Service] Environment="HTTP_PROXY=http://192.168.110.188:7897" Environment="HTTPS_PROXY=http://192.168.110.188:7897" Environment="NO_PROXY=localhost,127.0.0.1,::1,10.0.0.0/8,192.168.0.0/16,172.16.0.0/12,.cluster.local,harbor.lanqicheng.top"
**注意事项:**
}
}
//会显示Pod的名称
}
}
//由于Pod执行完任务就销毁,所以等待一段时间验证Pod是否成功运行
steps{
}
}
}
}



**注意事项:**
metadata:
spec:
accessModes:
resources:
requests:注意事项:
镜像构建 #定义基础镜像 #安装nodejs和npm
**注意事项:**
#构建镜像
#推送镜像注意事项:
[kubernetes-tencent] baseurl=https://mirrors.cloud.tencent.com/kubernetes_new/core:/stable:/v1.30/rpm/ enabled=1 gpgcheck=0
[kubernetes-aliyun] baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ enabled=1 gpgcheck=0 repo_gpgcheck=0
#拷贝集群的配置文件 #定义镜像
#构建镜像
#推送镜像
**注意事项:**spec: containers: env: volumeMounts: env: env: env: volumes: persistentVolumeClaim: """ } } } } } } } } } } } } } } } }
**注意事项:**
**代码提交(Commit/Push)**
**持续集成(CI)**
**持续交付(CD)**
**持续部署(CD)**




修改仓库上传大小(代码仓库没有部署在K8s,这一步忽略)
---metadata: spec: rules: http: paths: backend: service: port:
**注意事项:**
#设置Git用户及邮箱
#初始化本地仓库并上传项目代码
#添加当前目录文件到本地仓库
#添加远程仓库地址
#推送本地仓库代码到远程仓库注意事项:









metadata: spec: accessModes: resources: requests:
**注意事项:**spec: containers: env: volumeMounts: env: env: volumes: persistentVolumeClaim: """ } } } } } } }
**注意事项:**
spec: containers: env: volumeMounts: env: env: volumes: persistentVolumeClaim: """ } } } } } } } } } }
**注意事项:**
注意事项:
[Unit]
[Socket]
[Install]
**注意事项:**
[Unit]
Description=buildkitd
Documentation=https://github.com/moby/buildkit
Requires=buildkit.socket
After=buildkit.socket
[Service]
[Install]
WantedBy=multi-user.target 注意事项:
**注意事项:**spec: containers: env: volumeMounts: env: env: volumes: persistentVolumeClaim: hostPath: hostPath: """ } } } } } } } } script{ //env是Groovy中的一个内置对象,用于操作环境变量 } } } } } }
**注意事项:**
}
}
}注意事项:





填入Jenkins集群内部服务地址http://jenkins-svc:8080/project/pipeline-zzyl/和c1a4fe022c07b264b61416c4cdaed15b






} } } } } }
**注意事项:**
spec: containers: env: volumeMounts: env: env: volumes: persistentVolumeClaim: hostPath: hostPath: """ } } } } } } } } script{ //env是Groovy中的一个内置对象,用于操作环境变量 } } } } } } } } } } } } } } } }
**注意事项:**
本文由飞书云文档同步生成。涉及命令、SQL、配置示例时,请以飞书源文档和实际环境执行结果为准。