目 录CONTENT

文章目录

基于jenkins的不同容器工具推送harbor仓库方法

JamKing
2025-11-26 / 0 评论 / 0 点赞 / 57 阅读 / 0 字

前言

构建工具 优点 缺点 参考构建链接
buildkit 并发构建、缓存复用高效,支持 secrets 安全传递,增量构建 配置较复杂,需要Docker 18.09+,部分旧Dockerfile指令不支持 buildkit
kaniko 专为K8s设计,无需Docker守护进程,在容器内安全执行构建 构建速度较慢,本地开发体验差,缓存管理较复杂 kaniko
pod man daemonless架构,rootless运行,兼容Docker CLI,集成了Buildah 在macOS/Windows需要虚拟机,网络配置较复杂,企业生态不及Docker podman
img 基于BuildKit但更简单,并行构建高效,缓存利用好 项目活跃度下降,维护更新少,社区支持有限 img
buildah 无需守护进程,rootless构建,精细控制镜像层,可生成OCI镜像 CLI与Docker不完全兼容,需要学习新命令,生态系统较小 buildah
docker 生态最成熟,CLI用户体验好,支持多阶段构建,集成镜像管理 需要守护进程,有root权限安全风险,构建缓存层多导致镜像较大 docker
nerdctl 兼容Docker CLI,直接使用containerd,支持rootless,集成了BuildKit 相对较新,某些高级功能可能缺失,文档较少 nerdctl

选择建议

  • 本地开发:Docker/Podman(体验好)
  • CI/CD流水线:Kaniko/BuildKit(安全性好)
  • Kubernetes环境:Kaniko/nerdctl(云原生集成)
  • 精细控制:Buildah(无守护进程需求)
  • 性能优先:BuildKit/img(缓存和并行优化)

PS:

  • k8s+containerd可以优先考虑buildkit、podman、kaniko
  • k8s+docker可以优先考虑原生docker构建功能

1、BuildKit

1.1 Jenkinsfile

1.1.1 忽略证书语法

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、buildkit、kubectl三个容器模板,buildkit需要root特权模式运行
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'buildkit', image: 'harbor.test.com/devops/buildkit:v0.23.2', command: 'cat', ttyEnabled: true, privileged: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn')])

{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('buildkit构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('buildkit') {
        echo "2.构建镜像"
        sh """
          #创建harbor认证文件
          mkdir -p /root/.docker
          cat > /root/.docker/config.json << EOF
{
    "auths": {
        "${registryUrl}": {
        "auth": "\$(echo -n "${HARBOR_USER}:${HARBOR_PASSWORD}" | base64)"
        }
    }
}
EOF
          #需创建配置文件,否则无法进行证书忽略或校验
          mkdir -p /etc/buildkit
          cat > /etc/buildkit/buildkitd.toml << EOF
[registry."${registryUrl}"]
  insecure = true
  mirrors = ["${registryUrl}"]
EOF
          #启动buildkitd守护进程
          buildkitd &
          sleep 5
          buildctl build \
            --frontend dockerfile.v0 \
            --local context=. \
            --local dockerfile=.\
            --export-cache type=inline \
            --import-cache type=registry,ref=${image}:buildcache \
            --output type=image,name=${image},push=true \
            --registry-auth-tlscontext host=${registryUrl},insecure=true
        """
        }
      }
    }
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


1.1.2 证书校验语法

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'buildkit', image: 'harbor.test.com/devops/buildkit:v0.23.2', command: 'cat', ttyEnabled: true, privileged: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn'),
  //挂载harbor证书目录
  hostPathVolume(mountPath: '/tmp/certs.d', hostPath: '/data/nfs-data/certs.d')])

{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('buildkit构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('buildkit') {
        echo "2.构建镜像"
        sh """
          #创建harbor认证文件
          mkdir -p /root/.docker
          cat > /root/.docker/config.json << EOF
{
    "auths": {
        "${registryUrl}": {
        "auth": "\$(echo -n "${HARBOR_USER}:${HARBOR_PASSWORD}" | base64)"
        }
    }
}
EOF
          #需创建配置文件,否则无法进行证书忽略或校验
          mkdir -p /etc/buildkit
          cat > /etc/buildkit/buildkitd.toml << EOF
[registry."${registryUrl}"]
  insecure = true
  mirrors = ["${registryUrl}"]
EOF
          #启动buildkitd守护进程
          buildkitd &
          sleep 5
          buildctl build \
            --frontend dockerfile.v0 \
            --local context=. \
            --local dockerfile=.\
            --export-cache type=inline \
            --import-cache type=registry,ref=${image}:buildcache \
            --output type=image,name=${image},push=true \
            --registry-auth-tlscontext host=${registryUrl},insecure=false,ca=/tmp/certs.d/ca.pem,cert=/tmp/certs.d/cert.pem,key=/tmp/certs.d/key.pem 
        """
        }
      }
    }
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


1.2 Dockerfile

FROM harbor.test.com/jdk/openjdk:8-jre-alpine
#FROM openjdk:8-jre-alpine 
WORKDIR /app
COPY target/hello-world-app-0.0.1-SNAPSHOT.jar /app/app.jar
# 启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

1.3 流水线运行情况

image-swsq.png

1.4 访问demo

0da642f65199ffc95781eace5bc6927d.png

2、Kaniko

2.1 Jenkinsfile

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'kaniko', image: 'swr.cn-north-4.myhuaweicloud.com/ddn-k8s/gcr.io/kaniko-project/executor:v1.9.1-debug', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn')])
{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "172.16.10.131"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('kaniko构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('kaniko') {
        echo "2.构建镜像"
        sh """
          # 创建 .docker 目录
          mkdir -p /kaniko/.docker
          # 生成 base64 编码的认证信息,'echo -n' 非常重要,它不会在末尾添加换行符
          AUTH=\$(echo -n "${HARBOR_USER}:${HARBOR_PASSWORD}" | base64 -w 0)
          # 创建 Kaniko 需要的 config.json 文件
          cat <<EOF > /kaniko/.docker/config.json
{
  "auths": {
    "${registryUrl}": {
    "auth": "\${AUTH}"
    }
  }
}
EOF
          #skip-tls-verify参数可以忽略自签证书的报错问题,${WORKSPACE}确认目前jenkins-agent的工作目录,否则是kaniko的默认工作目录/workspace
          /kaniko/executor \
          --context=${WORKSPACE} \
          --dockerfile=Dockerfile \
          --destination=${image} \
          --cache=true \
          --cache-repo=${registryUrl}/cache \
          --skip-tls-verify
        """
        }
      }
    }
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}

2.2 Dockerfile

FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/openjdk:8-jre-alpine 
WORKDIR /app
COPY target/hello-world-app-0.0.1-SNAPSHOT.jar /app/app.jar
# 启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

2.3 流水线运行情况

耗时:6分16秒

image-hxtb.png

2.4 访问demo

image-oQNK.png

3、pod man

3.1 Jenkinsfile

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'podman', image: 'quay.io/podman/stable', command: 'cat', ttyEnabled: true, privileged: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
    hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn'),
  //挂载harbor证书目录
    hostPathVolume(mountPath: '/tmp/certs.d', hostPath: '/data/nfs-data/certs.d')])
{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('buildah构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('podman') {
        echo "2.构建镜像"
        sh """
          cp /tmp/certs.d/ca.pem /etc/pki/ca-trust/source/anchors/ca.crt
          update-ca-trust
          #--tls-verify=false绕过harbor的ssl证书检查
          podman login --username ${HARBOR_USER} --password ${HARBOR_PASSWORD} ${registryUrl}
          #使用 VFS 存储驱动,避免需要 FUSE
          podman build -t ${image} .
          podman push ${image}
        """
        }
      }
    }

    //第三阶段
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


3.2 Dockerfile

FROM harbor.test.com/jdk/openjdk:8-jre-alpine
#FROM openjdk:8-jre-alpine 
WORKDIR /app
COPY target/hello-world-app-0.0.1-SNAPSHOT.jar /app/app.jar
# 启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

3.3 流水线运行情况

image-IErh.png

3.4 访问demo

78ddc7c552ee3e5f08b9a05664e531f2.png

4、img

4.1 Jenkinsfile

def label = "jenkins-agent"

podTemplate(label: label, 

containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'img', image: 'harbor.test.com/devops/img', command: 'cat', ttyEnabled: true, runAsUser: '0', runAsGroup: '0', privileged: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn'),
  hostPathVolume(mountPath: '/tmp/certs.d', hostPath: '/data/nfs-data/certs.d')])

{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com:443"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('Img构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('img') {
        echo "2.构建镜像"
        sh """
          #强制信任harbor证书
          cat >> /etc/ssl/certs/ca-certificates.crt << EOF
\$(cat /tmp/certs.d/ca.pem)
EOF
          #img创建本地密码验证,额外登录可能无法跳过ssl证书检查
          mkdir -p \$HOME/.docker
          cat > \$HOME/.docker/config.json << EOF
{
    "auths": {
        "${registryUrl}": {
            "auth": "\$(echo -n ${HARBOR_USER}:${HARBOR_PASSWORD} | base64)"
            }
        }
}
EOF
          #构建和推送镜像
          img build -t ${image} .
          img push ${image}
        """
        }
      }
    }

    //第三阶段
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


4.2 Dockerfile

FROM harbor.test.com/jdk/openjdk:8-jre-alpine
#FROM openjdk:8-jre-alpine 
WORKDIR /app
COPY target/hello-world-app-0.0.1-SNAPSHOT.jar /app/app.jar
# 启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

4.3 流水线运行情况

image-qepC.png

4.4 访问demo

d38bd92006a5553b4901b67e91b20508.png

5、Buildah

5.1 Jenkinsfile

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'buildah', image: 'quay.io/buildah/stable', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn')])
{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "172.16.10.131"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('buildah构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('buildah') {
        echo "2.构建镜像"
        sh """
          #--tls-verify=false绕过harbor的ssl证书检查
          buildah login --tls-verify=false --username ${HARBOR_USER} --password ${HARBOR_PASSWORD} ${registryUrl}
          #使用 VFS 存储驱动,避免需要 FUSE
          buildah bud --storage-driver vfs -t ${image} .
          buildah --storage-driver vfs push --tls-verify=false ${image}
        """
        }
      }
    }

    //第三阶段
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


5.2 Dockerfile

5.3 流水线运行情况

耗时:

image-qtrW.png

5.4 访问demo

image-kqaJ.png

6、Docker

6.1 DinD

6.1.1 Jenkinsfile

因本服务器k8s集群基于containerd运行时,没有docker-cli环境,理论上挂载/var/run/docker.sock套接字文件,也可能需要挂载docker的运行目录,即可实现docker in docker模式

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'docker', image: 'harbor.test.com/devops/docker:dind', command: 'cat', ttyEnabled: true);
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn'),
  //挂载本机docker套接字
  hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock')
  ])

{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('tcp docker推送镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('docker') {
        echo "2.构建镜像"
        sh """
          #创建harbor认证文件
          #export DOCKER_HOST=tcp://172.16.10.131:2375
          #sleep 100
          mkdir -p /root/.docker
          cat > /root/.docker/config.json << EOF
{
    "auths": {
        "${registryUrl}": {
        "auth": "\$(echo -n "${HARBOR_USER}:${HARBOR_PASSWORD}" | base64)"
        }
    }
}
EOF
          #docker ps
          docker login ${registryUrl}
          docker build -t ${image} .
          docker push ${image}
        """
        }
      }
    }
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


6.2 外部Docker

6.2.1 Jenkinsfile

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'docker', image: 'harbor.test.com/devops/docker:20.10.12', command: 'cat', ttyEnabled: true,envVars: [
        envVar(key: 'DOCKER_HOST', value: 'tcp://172.16.10.131:2375')
      ]
    ),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
  hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn')])

{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('tcp docker推送镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('docker') {
        echo "2.构建镜像"
        sh """
          #创建harbor认证文件
          #export DOCKER_HOST=tcp://172.16.10.131:2375
          #sleep 100
          mkdir -p /root/.docker
          cat > /root/.docker/config.json << EOF
{
    "auths": {
        "${registryUrl}": {
        "auth": "\$(echo -n "${HARBOR_USER}:${HARBOR_PASSWORD}" | base64)"
        }
    }
}
EOF
          #docker ps
          docker login ${registryUrl}
          docker build -t ${image} .
          docker push ${image}
        """
        }
      }
    }
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


6.2.2 Dockerfile

FROM harbor.test.com/jdk/openjdk:8-jre-alpine
#FROM openjdk:8-jre-alpine 
WORKDIR /app
COPY target/hello-world-app-0.0.1-SNAPSHOT.jar /app/app.jar
# 启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

6.2.3 流水线运行情况

image-soME.png

6.2.4 访问demo

image-yLOX.png

7、nerdctl

7.1 Jenkinsfile

nerdctl是containerd的额外前端组件,完善ctr命令的不足,但是需要运行nerdctl容器需要额外挂载本机的containerd运行目录,若数据目录过大,可能较消耗资源,不推荐此种方式,不做演示。

def label = "jenkins-agent"

podTemplate(label: label, containers: [
  //设置mvn、kaniko、kubectl三个容器模板
  containerTemplate(name: 'maven', image: 'harbor.test.com/devops/maven:3.8.5-openjdk-11', command: 'cat', ttyEnabled: true),
  containerTemplate(name: 'nerdctl', image: 'harbor.test.com/devops/nerdctl', command: 'cat', ttyEnabled: true, privileged: true),
  containerTemplate(name: 'kubectl', image: 'harbor.test.com/devops/kubectl', command: 'cat', ttyEnabled: true)], 
  //sa权限
  serviceAccount: 'jenkins-master',
  volumes: [
    hostPathVolume(mountPath: '/root/.m2', hostPath: '/data/nfs-data/mvn'),
    hostPathVolume(mountPath: '/var/run/containerd/containerd.sock', hostPath: '/run/containerd/containerd.sock'),
    //额外挂载containerd的运行目录,耗资源,不推荐
    hostPathVolume(mountPath: '/data/containerd', hostPath: '/data/containerd')
    ])
  //挂载harbor证书目录
   // hostPathVolume(mountPath: '/tmp/certs.d', hostPath: '/data/nfs-data/certs.d')])
{
  node(label) {
    // 拉取git代码
    def myRepo = checkout scm
    // 获取 git commit id 作为镜像标签
    def imageTag = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
    // 仓库地址
    def registryUrl = "harbor.test.com"
    def imageEndpoint = "java-demo/demo"
    // 镜像标签
    def image = "${registryUrl}/${imageEndpoint}:${imageTag}"
  
    //第一阶段
    stage('mvn构建jar包') {
      container('maven') {
        echo "1.mvn构建"
        sh """
          export JAVA_HOME=/usr/local/openjdk-11
          mvn -B -q clean install -DskipTests
        """
      }
    }

    //第二阶段
    stage('nerdctl构建镜像') {
      //引入harbor仓库认证
      withCredentials([usernamePassword(
        // 凭据id以实际为准
        credentialsId: 'harbor_auth',
        passwordVariable: 'HARBOR_PASSWORD', 
        usernameVariable: 'HARBOR_USER')]) {
      container('nerdctl') {
        echo "2.构建镜像"
        sh """
          #cp /tmp/certs.d/ca.pem /etc/pki/ca-trust/source/anchors/ca.crt
          #update-ca-trust
          #--tls-verify=false绕过harbor的ssl证书检查
          buildkitd &
          sleep 5
          mkdir -p /data/containerd/root
          ls /data/containerd/
          #ls
          #nerdctl --help
          nerdctl login --insecure-registry --username ${HARBOR_USER} --password ${HARBOR_PASSWORD} ${registryUrl}
          #使用 VFS 存储驱动,避免需要 FUSE
          nerdctl build -t ${image} .
          nerdctl push --insecure-registry ${image}
        """
        }
      }
    }

    //第三阶段
    stage('kubectl一键部署') {
      withCredentials([file(
        credentialsId: 'kubeconfig', 
        variable: 'KUBECONFIG')]) {
      container('kubectl') {
        echo "3.kubectl更新镜像"
        sh """
          kubectl --kubeconfig=$KUBECONFIG set image deployment/java-demo java-demo=${image} -n devops
          sleep 10
          kubectl --kubeconfig=$KUBECONFIG get pod -n devops |grep java-demo|grep Running
        """
        }
      }
    }
  }
}


0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区