如何从在 kubernetes 上运行的 jenkins 代理构建 docker 镜像?

如何从在 kubernetes 上运行的 jenkins 代理构建 docker 镜像?

我尝试使用下面的管道代码来检查 docker 命令是否有效,但失败了。

pipeline {
  agent {
    kubernetes {
      yaml """
      apiVersion: v1
      kind: Pod
      metadata:
        labels:
          app: jenkins-agent
      spec:
        containers:
        - name: jnlp
          image: 'jenkins/jnlp-slave:latest'
          args: ['${JENKINS_SECRET}', '${JENKINS_AGENT_NAME}']
          env:
          - name: AWS_ACCESS_KEY_ID
            valueFrom:
              secretKeyRef:
                name: aws-credentials
                key: accessKeyId
          - name: AWS_SECRET_ACCESS_KEY
            valueFrom:
              secretKeyRef:
                name: aws-credentials
                key: secretAccessKey
          - name: AWS_REGION
            value: us-east-1
          volumeMounts:
          - name: docker-sock
            mountPath: /var/run/docker.sock
        volumes:
        - name: docker-sock
          hostPath:
            path: /var/run/docker.sock
      """
      defaultContainer 'jnlp'
    }
  }
    environment {
        AWS_REGION = credentials('my-aws-region')
        ENVIRONMENT = 'dev'
        LAMBDA_FUNCTION_NAME = 'my-lambda-function'
    }
  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }
    stage('Test') {
        steps {
            sh 'python -m unittest discover tests'
        }
    }
    stage('Package') {
      steps {
        sh 'mkdir package'
        sh 'pip install -r requirements.txt -t package'
        sh 'cp lambda_function.py package/'
        sh 'cp -r tests/ package/'
        sh 'cd package && zip -r9 ../function.zip .'
      }
    }

    stage('Deploy') {
        environment {
            TF_VAR_aws_region = "${AWS_REGION}"
            TF_VAR_environment = "${ENVIRONMENT}"
            TF_VAR_lambda_function_name = "${LAMBDA_FUNCTION_NAME}"
        }
        steps {
            sh 'terraform init'
            sh 'terraform plan'
            sh 'terraform apply -auto-approve'
        }
    }
  }

  post {
    always {
      cleanWs()
    }
  }
}

我得到的错误:

Error when executing always post condition:
hudson.AbortException: Attempted to execute a step that requires a node context while ‘agent none’ was specified. Be sure to specify your own ‘node { ... }’ blocks when using ‘agent none’.
    at org.jenkinsci.plugins.workflow.steps.ErrorStep$Execution.run(ErrorStep.java:64)
    at org.jenkinsci.plugins.workflow.steps.ErrorStep$Execution.run(ErrorStep.java:51)
    at org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution.start(SynchronousStepExecution.java:37)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
    at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
    at org.jenkinsci.plugins.workflow.cps.CpsScript.invokeMethod(CpsScript.java:124)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:47)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
    at org.jenkinsci.plugins.pipeline.modeldefinition.ModelInterpreter.catchRequiredContextForNode(ModelInterpreter.groovy:399)

所以我删除了帖子部分并尝试了一下。这次得到了这个。

groovy.lang.MissingPropertyException: No such property: JENKINS_SECRET for class: groovy.lang.Binding
    at groovy.lang.Binding.getVariable(Binding.java:63)
    at 

我听说 JENKINS_SECRET 是自动生成的,但出现这个错误。

因此,尝试了不同的代码,但这次出现错误,因为没有 docker 守护进程。

podTemplate(containers: [
    containerTemplate(
        name: 'maven', 
        image: 'maven:3.8.1-jdk-8', 
        command: 'sleep', 
        args: '30d'
        ),
    containerTemplate(
        name: 'docker', 
        image: 'docker:latest', 
        command: 'sleep', 
        args: '30d')
  ]) {

    node(POD_LABEL) {
        stage('Get a Maven project') {
            git url: 'https://github.com/spring-projects/spring-petclinic.git', branch: 'main'
            container('maven') {
                stage('Build a Maven project') {
                    sh '''
                    echo "maven build"
                    '''
                }
            }
        }

        stage('Get a docker Project') {
            git url: 'https://github.com/hashicorp/terraform.git', branch: 'main'
            container('docker') {
                stage('Build a Go project') {
                    sh '''
                    echo "Go Build"
                    docker --version
                    docker ps -a
                    '''
                }
            }
        }

    }
}     

我得到的错误:

+ docker --version
Docker version 23.0.1, build a5ee5b1
+ docker ps -a
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

我改变了我的管道并尝试了下面的方法。

pipeline {
    agent {
        kubernetes {
            label 'kubeagent'
            defaultContainer 'kube-agent'
            yaml """
            apiVersion: v1
            kind: Pod
            metadata:
              labels:
                app: my-docker-build
            spec:
              containers:
              - name: docker
                image: jpetazzo/dind:latest
                command: ["cat"]
                tty: true
              volumes:
              - name: docker-sock
                hostPath:
                  path: /var/run/docker.sock
              - name: my-repo
                gitRepo:
                  repository: https://github.com/my/repo.git
            """
        }
    }
    stages {
        stage( 'docker start starting' ){
            steps {
                container('docker') {
                    sh 'hostname'
                    sh 'sleep 50'
                    sh 'docker --version'
                    sh 'curl -o Dockerfile https://raw.githubusercontent.com/ukreddy-erwin/jenkins_custom_image/ukreddy-erwin-patch-1/Dockerfile'
                    sh 'docker build -t jenkins:test .'
                    sh 'docker image ls'
                }
            }
        }
        stage('Test Docker Image') {
            steps {
                container('docker') {
                sh 'hostname'
                sh 'sleep 50'
                sh 'docker --version'
                sh 'docker build -t my-docker-image:latest .'
                }
            }
        }
        
        stage('Push Docker Image') {
            steps {
                sh 'hostname'
                sh 'docker push my-docker-image:latest'
            }
    }
}
}

但此操作失败并出现错误:

hudson.remoting.ProxyException: io.fabric8.kubernetes.client.KubernetesClientException: container docker not found in pod kube-agent-gc6rw
    at io.fabric8.kubernetes.client.dsl.internal.core.v1.PodOperationsImpl.validateOrDefaultContainerId(PodOperationsImpl.java:344)

因此,我在 kubernetes 插件屏幕管理节点/配置云/kubernetes 类型区域中添加了容器镜像 docker spec,并在管道中无规范地运行。它工作正常,能够运行 docker images ls、docker ps 命令。但是当我尝试 docker build 时,我收到错误,因为 apt、yum repo 镜像无法连接,即使对于 dockerfile 中的 yum update 命令也是如此。

docker文件

FROM amd64/amazonlinux:2
RUN yum -y update

错误详情:

root@kube-agent-mgjsl:/home/jenkins/agent# docker build -t jenkins:test .
Sending build context to Docker daemon  20.77MB
Step 1/6 : FROM jenkins/jenkins:lts
 ---> f16216f97fcb
Step 2/6 : USER root
 ---> Using cache
 ---> 4563ef4109a2
Step 3/6 : RUN apt update && apt install -y wget
 ---> Running in 4e3756cd5298

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Err:1 https://packagecloud.io/github/git-lfs/debian bullseye InRelease
  Temporary failure resolving 'packagecloud.io'
Err:2 http://deb.debian.org/debian bullseye InRelease
  Temporary failure resolving 'deb.debian.org'
Err:3 http://deb.debian.org/debian-security bullseye-security InRelease
  Temporary failure resolving 'deb.debian.org'
Err:4 http://deb.debian.org/debian bullseye-updates InRelease
  Temporary failure resolving 'deb.debian.org'
Reading package lists...
Building dependency tree...
Reading state information...
All packages are up to date.
W: Failed to fetch http://deb.debian.org/debian/dists/bullseye/InRelease  Temporary failure resolving 'deb.debian.org'
W: Failed to fetch http://deb.debian.org/debian-security/dists/bullseye-security/InRelease  Temporary failure resolving 'deb.debian.org'
W: Failed to fetch http://deb.debian.org/debian/dists/bullseye-updates/InRelease  Temporary failure resolving 'deb.debian.org'
W: Failed to fetch https://packagecloud.io/github/git-lfs/debian/dists/bullseye/InRelease  Temporary failure resolving 'packagecloud.io'
W: Some index files failed to download. They have been ignored, or old ones used instead.

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Reading package lists...
Building dependency tree...
Reading state information...
E: Unable to locate package wget
The command '/bin/sh -c apt update && apt install -y wget' returned a non-zero code: 100
root@kube-agent-mgjsl:/home/jenkins/agent# 

相关内容