欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 高考 > Gitlab + Jenkins 实现 CICD

Gitlab + Jenkins 实现 CICD

2025/11/9 14:05:05 来源:https://blog.csdn.net/leblanceAndSherry/article/details/148414396  浏览:    关键词:Gitlab + Jenkins 实现 CICD

CICD 是持续集成(Continuous Integration, CI)和持续交付/部署(Continuous Delivery/Deployment, CD)的缩写,是现代软件开发中的一种自动化流程实践。下面介绍 Web 项目如何在代码提交到 Gitlab 后,自动发布到 Kubernetes 集群中。

一 、前期准备

1、部署 Gitlab

点击查看安装教程

2、部署 Jenkins

点击查看安装教程

3、部署 Docker Harbor

点击查看安装教程

4、部署 Kubernetes

点击查看安装教程

5、服务器配置

服务IP角色
master192.168.31.110集群管理节点
node1192.168.31.111集群工作节点
node2192.168.31.112集群工作节点
harbor192.168.31.113镜像仓库
gitlab192.168.31.114代码托管
jenkins192.168.31.115自动化构建与部署

二、配置 Gitlab

Gitlab 中主要是配置 webhooks,作用是接收到代码推送后触发 Jenkins 任务。有两种方式,下面是配置过程截图:

(一)方式一:使用 Webhooks 触发 Jenkins(传统方式)

1、新建项目 HelloWorld,地址:http://192.168.31.114/root/helloworld.git

在这里插入图片描述

2、点击 管理员 - 设置 - 网络

在这里插入图片描述

3、勾选 允许来自 webhooks 和集成对本地网络的请求,然后保存更改

作用:代码推送后可以触发自动化通知

在这里插入图片描述

4、选择项目,点击设置,点击 Webhooks

在这里插入图片描述

5、配置 Webhooks

URL 和 Secret 令牌从 Jenkins 获取,如何获取下面配置 Jenkins 有截图
在这里插入图片描述

(二)方式二:使用 GitLab 的 Jenkins 集成(推荐方式)

1、新建项目,在项目设置中点击集成,然后添加 Jenkins 集成模块

在这里插入图片描述

2、Jenkins 集成模块配置

URL 从 Jenkins 获取,如何获取下面配置 Jenkins 有截图
在这里插入图片描述

(三)两种方式比较

特性Webhooks 手动配置GitLab Jenkins 插件
配置难度较高简单
灵活性中等
维护成本
支持的功能完全自定义包括 MR、PR、状态反馈等
是否需要插件是(如 Generic Webhook Trigger)是(GitLab Plugin)
安全性需手动配置 Secret支持 Token 验证
多项目支持需手动逐一配置可集中管理
GitLab 回调支持需要自己开发内置支持

GitLab 提供的 Jenkins 集成模块本质上也是基于 Webhook 实现的,但封装更易用和安全。但使用 Webhooks 触发 Jenkins 的传统方式依然会经常使用,尤其适用于:自建的服务,第三方不支持 GitLab 内置集成的系统,需要高度定制化的场景。只是 GitLab 建议你在“有内置集成可用”的情况下,优先使用集成,因为它们更可靠、更易于维护。

三、配置 Jenkins

1、添加全局凭据

在这里插入图片描述

2、新建任务

在这里插入图片描述

3、Triggers(触发器)配置

需要安装插件 Gitlab,在系统管理 - 插件管理 - Available plugins 中搜索并安装

(1)勾选 “Build when a change is pushed to GitLab” 配置项,目的是实现 GitLab 与 Jenkins 之间的自动化触发关联

在这里插入图片描述

(2)点开高级 - 选择 Filter branches by name,作用是让你能精确控制哪些 Git 分支的代码变更可以触发当前 Jenkins 任务(这里是 “helloworld” 任务 )的构建 。

在这里插入图片描述

4、流水线配置

(1)关联 GitLab 代码仓库

需要在 Jenkins 服务器(192.168.31.115)上安装 Git

dnf install git -y

在这里插入图片描述

(2)设置 Jenkins 从 Git 仓库的 main 分支拉取代码,并用仓库里的 Jenkinsfile 定义的流程来跑自动化构建 。

在这里插入图片描述

四、DockerHarbor,新建项目 helloworld

在这里插入图片描述

五、部署 web 项目

1、web 项目内容

(1)index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>WebView Test</title>
</head>
<body><h1>Hello World!</h1>
</body>
</html>
(2)Dockerfile 文件
# 使用官方的 Nginx 镜像作为基础镜像
FROM nginx:latest# 将当前目录下的所有文件复制到 Nginx 容器的默认网页根目录(/usr/share/nginx/html)
COPY . /usr/share/nginx/html# 暴露 Nginx 服务的默认端口 80
EXPOSE 80
(3)Jenkinsfile 文件
pipeline {agent any // 在任何可用代理上运行此流水线environment {// Docker 镜像配置DOCKER_REGISTRY = "harbor.yiyang.com:443"  // 私有Docker仓库地址IMAGE_NAME = "helloworld/helloworld"      // 镜像名称TIMESTAMP = "${new Date().format('yyyyMMdd_HHmmss', TimeZone.getTimeZone('Asia/Shanghai'))}"  // 带时区的时间戳IMAGE_TAG_LATEST = "latest"              // 最新标签// Kubernetes 配置K8S_DEPLOYMENT_NAME = "helloworld-deployment"  // 必须与 helloworld.yaml 中的 Deployment 名称一致K8S_CONFIG_FILE = "helloworld.yaml"            // Kubernetes部署文件}stages {// 代码检出stage('Checkout') {steps {git credentialsId: '9ba151c2-08ec-4e25-a38c-4b322c40e2bf', url: 'http://192.168.31.114/root/helloworld.git', branch: 'main'}}// 构建Docker镜像stage('Build Docker Image') {steps {sh """docker build --pull --no-cache --network none \-t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP} .docker tag ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP} \${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG_LATEST}"""}}// 登录Docker仓库stage('Login to Docker Harbor') {steps {withCredentials([usernamePassword(credentialsId: '61e24bcf-39b1-42b3-8815-080502c30a53',usernameVariable: 'DOCKER_USER',passwordVariable: 'DOCKER_PASSWORD')]) {sh '''echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USER}" --password-stdin ${DOCKER_REGISTRY}'''}}}// 推送Docker镜像stage('Push Docker Image') {steps {sh """docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP}docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${IMAGE_TAG_LATEST}"""}}// 部署到Kubernetesstage('Deploy to Kubernetes') {steps {script {withCredentials([file(credentialsId: '34fffd5d-e5f4-465d-b3ff-205929444c95', variable: 'KUBECONFIG')]) {try {// 1. 预检查sh "kubectl apply --dry-run=client -f ${K8S_CONFIG_FILE}"// 2. 执行部署sh """kubectl set image deployment/${K8S_DEPLOYMENT_NAME} *=${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP} --recordkubectl rollout status deployment/${K8S_DEPLOYMENT_NAME} --timeout=5m"""echo "Deployment succeeded for image: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP}"} catch (err) {// 3. 失败时自动回滚echo "Deployment failed! Error: ${err}"echo "Initiating rollback..."sh """kubectl rollout undo deployment/${K8S_DEPLOYMENT_NAME}kubectl rollout status deployment/${K8S_DEPLOYMENT_NAME} --timeout=3m"""error "Deployment failed and was rolled back. Original error: ${err}"}}}}}}// 后置处理post {// 无论成功失败都执行的步骤always {// 镜像清理sh "docker rmi -f ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP} || true"// 可选:清理悬空镜像sh "docker image prune -f || true"}// 仅当流水线成功时执行的步骤success {echo "Pipeline succeeded! Image: ${DOCKER_REGISTRY}/${IMAGE_NAME}:${TIMESTAMP}"}// 仅当流水线失败时执行的步骤failure {echo "Pipeline failed. Check logs for details."}}
}
(4)helloworld.yaml
---   
apiVersion: apps/v1
kind: Deployment
metadata:name: helloworld-deployment
spec:replicas: 2selector:matchLabels:app: helloworldtemplate:metadata:labels:app: helloworldspec:containers:- name: helloworldimage: cicd.ddzhixu.com:443/helloworld/helloworld:{{TIMESTAMP}}ports:- containerPort: 80resources:requests:cpu: "200m"memory: "256Mi"limits:cpu: "500m"memory: "512Mi"imagePullPolicy: IfNotPresentenv:- name: ENVIRONMENTvalue: "production"imagePullSecrets:- name: cicd  // Docker Harbor 镜像仓库认证的 Secret 名称---
# Service
apiVersion: v1
kind: Service
metadata:name: helloworld-service
spec:type: NodePortselector:app: helloworldports:- name: httpprotocol: TCPport: 80targetPort: 80nodePort: 30001---
# Horizontal Pod Autoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:name: helloworld-hpa
spec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: helloworld-deploymentminReplicas: 1maxReplicas: 10metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 70- type: Resourceresource:name: memorytarget:type: UtilizationaverageUtilization: 70

2、测试

将 web 项目上传到 Gitlab 仓库之后,会触发 Jenkins 执行 web 项目下 Jenkinsfile 中定义的一系列任务 ,然后浏览器访问 http://192.168.31.111:30001 或 http://192.168.31.112:30001

Jenkins 执行成功或者失败,可以在 Jenkins 中查看日志
在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词