Jenkins CI_CD流水线案例

Jenkins CI/CD流水线案例

核心目的:实现Jenkins CI/CD流水线全流程,完成代码打包、Docker镜像构建,最终将应用发布到K8s集群;适配开源demo代码(https://gitee.com/devin-alan/springboot-docker.git)的master分支,Jenkins镜像已预装必要插件(持久化时需注意避免插件被覆盖)。

部署时需重点关注:

第一章 环境准备

1.1 部署Jenkins(需自行安装最新版Docker)

采用Docker容器化部署Jenkins,使用指定镜像(已安装必要插件),注意持久化配置时避免插件被覆盖;需提前自行安装最新版Docker,确保兼容容器化部署需求。

yaml 复制代码
version: '3.3'
services:
  jenkins:
    image: registry.cn-shenzhen.aliyuncs.com/rmyyds/jenkins:2.516.3
    container_name: jenkins
    restart: always
    user: root
    privileged: true
    environment:
      - TZ=Asia/Shanghai
    ports:
      - '8080:8080'
      - '50000:50000'
    volumes:
      - '/etc/localtime:/etc/localtime:ro' 
      #- '/var/run/docker.sock:/var/run/docker.sock'
      #- '/usr/bin/docker:/usr/bin/docker'
      #- './data:/var/jenkins_home'  

补充说明:

  • Docker安装:需自行安装最新版,安装完成后确保正常启动并设置开机自启,避免因Docker版本过低导致Jenkins容器运行异常。

  • 持久化注意:若需配置Jenkins数据持久化,可取消注释最后一行挂载配置(./data:/var/jenkins_home),挂载前需创建对应目录并赋予777权限,避免权限不足;同时注意持久化过程中不要覆盖已安装的插件。

  • Jenkins初始化:启动容器后,访问http://服务器IP:8080,从容器日志中获取初始管理员密码(搜索"initialAdminPassword"),完成管理员账户创建及初始化配置即可。

bash 复制代码
# 启动 jenkins
docker compose up

# 查看 jenkins日志和提取 访问密码
docker compose logs

1.2 安装K3s(已有K8s可忽略)

若服务器未部署K8s集群,推荐安装轻量级K3s集群,用于后续应用发布;已有K8s集群可直接跳过本步骤,确保Jenkins能正常连接K8s集群。

关键注意:K3s/K8s集群部署完成后,需确保kubectl版本与集群版本兼容(流水线中kubectl镜像版本和k8s版本建议不要超一个大版本),避免后续发布步骤报错。

1.3 jenkins 配置 (关键是配置和k8s连接认证)

在jenkins中添加 kubernetes cloud

jenkins上使用kubeconfig 创建 和k8s 连接的认证

第二章 Jenkinsfile流水线

以下为完整的Jenkinsfile流水线配置;该流水线实现代码拉取、Maven打包、Docker镜像构建、K8s发布全流程,适配指定开源demo代码及master分支。

groovy 复制代码
pipeline {
    environment {
        // HARBOR = "registry.cn-shenzhen.aliyuncs.com"
        HARBOR = "192.168.133.140"
        REPO_NAME = "rmyyds/demo-java"
        // 按照日期作为镜像 TAG
        IMAGE_TAG = new Date().format("yyyyMMddHHmmss")
        IMAGE = "${HARBOR}/${REPO_NAME}:${IMAGE_TAG}"
        //  # 对应 jenkins 对应的 k8s cloud 名
        K8S_TOKEN = "k3s-token" 
        // # 替换成实际的代码仓库地址
        GIT_URL = "https://gitee.com/devin-alan/springboot-docker.git"
        // # 无密码忽略;有密码的仓库需要先在 jenkins中 添加名为 gitee 的认证(名字可自定义)
        GITEE = "gitee"   
    }
    parameters {
        booleanParam(name: 'build', defaultValue: true, description: '是否构建')
        booleanParam(name: 'deploy', defaultValue: false, description: '是否发布')
        gitParameter type: 'PT_BRANCH',
                     name: 'BRANCH',
                     branchFilter: 'origin/(.*)',
                     defaultValue: 'master',
                     description: '选择分支',
                     selectedValue: 'DEFAULT',
                     sortMode: 'DESCENDING_SMART'
    }
    agent {
        kubernetes {
            cloud env.K8S_TOKEN
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: jnlp
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/jenkins/inbound-agent:3327.v868139a_d00e0-6
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"

  - name: dind
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/docker:dind
    securityContext:
      privileged: true
    command: ["dockerd"]
    args:
    - "--insecure-registry=192.168.133.140:5000"
    - "--insecure-registry=192.168.133.140"
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"

  - name: maven
    #image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/maven:3.6.3-openjdk-17-slim
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/maven:3.6.3-jdk-8
    command: ['sleep', '2d']
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"

  - name: kubectl
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/kubesphere/kubectl:v1.33.4
    command: ['sleep', '2d']
    volumeMounts:
    - mountPath: "/home/jenkins/agent"
      name: "workspace-volume"

  volumes:
  - name: "workspace-volume"
    emptyDir: {}
'''
        }
    }

    stages {
        stage('拉取代码') {
            steps {
                checkout scmGit(
                    branches: [[name: "origin/${params.BRANCH}"]],
                    extensions: [],
                    userRemoteConfigs: [[
                        credentialsId: "${env.GITEE}",
                        url: "${env.GIT_URL}"
                    ]]
                )
            }
        }

        stage('Maven 构建 jar') {
            // 仅deploy=true时执行
            when { expression { params.build == true } } 
            steps {
                container('maven') {
                    // 替换成对应的 代码构建 命令
                    sh """
                    pwd
                    ls -al 
                    mvn clean package -Dmaven.test.skip=true 
           
                    """
                    // 保存构建后的 jar 包
                    archiveArtifacts artifacts: 'target/*.jar', followSymlinks: false, onlyIfSuccessful: true
                    // archiveArtifacts artifacts: '**/*', followSymlinks: false, onlyIfSuccessful: true
                    // archiveArtifacts artifacts: 'k8s/springboot-docker-canary-deployment.yaml', followSymlinks: false, onlyIfSuccessful: true
                }
            }
        }

        stage('Docker构建 + 推送') {
            steps {
                container('dind') {
                    sh """
                    # docker login $HARBOR -u admin -p Harbor12345

                    docker info 
                    docker build -t  $IMAGE . --no-cache
                    # docker push  $IMAGE
                    docker images
                    """
                }
            }
        }

        stage('kubectl 发布') {
            // 仅deploy=true时执行
            when { expression { params.deploy == true } } 
            steps {
                withKubeConfig([credentialsId: env.K8S_TOKEN]) {
                    container('kubectl') {
                        sh """
                         # 替换成对应的 kubectl 发布命令
                         cd k8s 
                         ls -al
                         sed -i  "s@registry.cn-shanghai.aliyuncs.com/shalousun/springboot:2.6.6-tomcat@$IMAGE@g" springboot-docker-canary-deployment.yaml
                         kubectl diff -f springboot-docker-canary-deployment.yaml || true
                         # kubectl apply -f springboot-docker-canary-deployment.yaml
                        """
                    }
                }
            }
        }
    }
}

流水线关键注意事项

  • 代码仓库配置:流水线中GIT_URL已指定为开源demo代码地址(https://gitee.com/devin-alan/springboot-docker.git),适配master分支;若该地址拉取失败,需替换为实际可用的仓库地址,有密码的仓库需在Jenkins中添加名为"gitee"的认证(可自定义名称,需与流水线中GITEE参数一致)。

  • 参数说明:流水线包含3个参数(是否构建、是否发布、选择分支),默认分支为master,可根据实际需求修改参数默认值;仅当"是否构建"为true时执行Maven打包,仅当"是否发布"为true时执行K8s发布。

  • 镜像与版本兼容:流水线中dind、maven、kubectl、jnlp镜像地址已固定,需确保镜像可正常拉取;kubectl镜像版本为v1.33.4,需与K3s/K8s集群版本兼容,否则会导致发布失败。

  • Docker相关:dind容器已配置特权模式及 insecure-registry,适配HARBOR(192.168.133.140),若HARBOR地址修改,需同步修改insecure-registry参数;Docker登录、镜像推送命令已注释,使用时需取消注释并填写正确的用户名和密码。

  • K8s发布:需确保Jenkins中已配置名为"k3s-token"的K8s集群凭证(与流水线中K8S_TOKEN参数一致);发布命令中yaml文件路径及镜像替换规则已固定,需确保项目中存在对应yaml文件,且镜像替换路径正确。

  • Jenkins插件:Jenkins镜像已安装必要插件,持久化配置时需注意避免覆盖插件目录,若出现插件缺失,需重新安装Git、Pipeline、Kubernetes、Docker Pipeline等核心插件。

  • 报错处理:若出现代码拉取失败,优先检查仓库地址、认证配置及网络;若出现Docker构建失败,检查dind容器运行状态及镜像拉取情况;若出现K8s发布失败,检查kubectl版本兼容性、kubeconfig配置及yaml文件语法。

相关推荐
深色風信子2 小时前
Docker sub2api
运维·docker·容器·sub2api
Sapphire~2 小时前
Linux-15 ubuntu 和 windows 双系统,更新系统导致丢失ubuntu 入口
linux·运维·ubuntu
zzzsde2 小时前
【Linux】线程概念与控制(1)线程基础与分页式存储管理
linux·运维·服务器·开发语言·算法
小樱花的樱花2 小时前
Linux进程管理相关命令
linux·运维·服务器
计算机安禾2 小时前
【Linux从入门到精通】第13篇:磁盘管理与文件系统——数据存在哪了?
linux·运维·服务器
温柔一只鬼.2 小时前
Ubuntu 安装 Python 3.10 完整指南
linux·运维·ubuntu
飞舞花下2 小时前
redis部署在A服务器,B服务器无法访问
运维·服务器
天空属于哈夫克32 小时前
行为审计与全链路追踪:私域自动化执行的安全性设计
java·运维·微服务
keyipatience2 小时前
10.Makefile构建奥秘:从基础到高效编译
linux·运维·服务器