본문 바로가기

개발하자

Jenkins Declarative: 여러 에이전트가 있는 Kubernetes 플러그인

반응형

Jenkins Declarative: 여러 에이전트가 있는 Kubernetes 플러그인

Jenkins 선언 파이프라인이 실행되는 동안 두 개의 다른 에이전트를 사용하도록 설정하려고 합니다. 에이전트는 Kubernetes 플러그인에 의해 동적으로 생성됩니다. 논쟁과 단순성을 위해, 내가 이것을 하고 싶다고 가정해보자:

에이전트 1(클라우드 이름: "ubuntu"):

  • apt-get 및 일부 설치 실행
  • 셸 스크립트 실행
  • 추가 단계

에이전트 2(클라우드 이름: "fedora"):

  • dnf 및 일부 설치 실행
  • 셸 스크립트 실행
  • 추가 단계

내 문제는 만약 내가 글로벌 에이전트 선언을 사용한다면:

pipeline {
  agent {
    kubernetes {
      cloud 'ubuntu'
      label "ubuntu-agent"
      containerTemplate {
        name 'support'
        image 'blenderfox/support'
        ttyEnabled true
        command 'cat'
      }
    }
  }
...
}

그러면 제가 각 스테이지에 에이전트를 선언하지 않으면 모든 스테이지에 걸쳐 사용됩니다.

사용하는 경우:

pipeline {
  agent none
  ...
}

그런 다음 각 단계에 대해 다음과 같은 에이전트 사양을 선언해야 합니다:

    stage ("apt update") {
      agent {
        kubernetes {
          cloud 'ubuntu'
          label "ubuntu-agent"
          containerTemplate {
            name 'support'
            image 'blenderfox/support'
            ttyEnabled true
            command 'cat'
          }
        }
      }
      steps {
        sh """
        apt update
        """
      }
    }

이 방법은 단계별로 원하는 에이전트를 선언할 수 있다는 점에서 효과가 있지만, 이 방법이 야기하는 문제는 단계별로 새로운 에이전트를 회전시킨다는 것입니다. 이는 예를 들어 다음 두 단계 사이에 상태가 전달되지 않는다는 것을 의미합니다:

    stage ("apt-update") {
      agent {
        ....
      }
      steps {
        sh """
        apt update
        """
      }
    }
    stage ("apt-install") {
      agent {
        ....
      }
      steps {
        sh """
        apt install -y ....
        """
      }
    }

여러 단계에 걸쳐 동일한 에이전트를 재사용할 수 있습니까? 예를 들어 다음과 같습니다:

stage ("provision agent") {
  agent {
    ...
    label "ubuntu-agent"
    ...
  }
  steps {
    sh """
    echo "Provisioning agent"
    """
  }
}
stage ("apt-update") {
  agent {
    label "ubuntu-agent" //reuse agent from previous stage
  }
  steps {
    sh """
    apt update
    """
  }
}
stage ("apt-install") {
  agent {
    label "ubuntu-agent" //reuse agent from previous stage
  }
  steps {
    sh """
    apt install -y ....
    """
  }
}



해결책을 찾았습니다. 매우 까다롭지만 효과가 있습니다:

pipeline {

  agent none

  stages {
    stage ("Provision dev agent") {
      agent {
        kubernetes {
          cloud 'dev-cloud'
          label "dev-agent-${env.BUILD_NUMBER}"
          slaveConnectTimeout 300
          idleMinutes 5
          yamlFile "jenkins-dev-agent.yaml"
        }
      }
      steps {
        sh """
        ## Do any agent init steps here
        """
      }

    }
    stage ("Do something on dev agent") {
      agent {
        kubernetes {
          label "dev-agent-${env.BUILD_NUMBER}"
        }
      }
      steps {
        sh """
        ## Do something here
        """
      }
    }


    stage ("Provision production agent") {
      agent {
        kubernetes {
          cloud 'prod-cloud'
          label "prod-agent-${env.BUILD_NUMBER}"
          slaveConnectTimeout 300
          idleMinutes 5
          yamlFile "jenkins-prod-agent.yaml"
        }
      }
      steps {
        sh """
        ## Do any agent init steps here
        """
      }
    }
    stage ("Do something on prod agent") {
      agent {
        kubernetes {
          label "prod-agent-${env.BUILD_NUMBER}"
        }
      }
      steps {
        sh """
        ## Do something here
        """
      }
    }
  }
}

에이전트 yamls는 다양하지만 다음과 같은 작업을 수행할 수 있습니다:

spec:
   containers:
   - name: docker
     image: docker:18.06.1
     command: ["tail", "-f", "/dev/null"]
     imagePullPolicy: Always
     volumeMounts:
       - name: docker
         mountPath: /var/run/docker.sock
   volumes:
   - hostPath:
      path: "/var/run/docker.sock"
     name: "docker"

그런 다음 에이전트를 다음과 같이 사용합니다:

stage ("docker build") {
  agent {
    kubernetes {
      label "dev-agent-${env.BUILD_NUMBER}"
    }
  }
  steps {
    container('docker') {
      sh """
        ## docker build....
      """
    }
  }
}



에이전트를 사용하여 단계를 정의한 다음 다른 단계를 그 안에 중첩할 수 있습니다

pipeline {

  agent none

  stages {
    stage ("Provision dev agent") {
      agent {
        kubernetes {
          cloud 'dev-cloud'
          slaveConnectTimeout 300
          yamlFile "jenkins-dev-agent.yaml"
        }
      }

      stages {
        stage ("Do something on dev agent") {
          steps {
            sh """
            ## Do something here
            """
          }
        }

        stage ("Do something else on dev agent") {
          steps {
            sh """
            ## Do something here
            """
          }
        }
      }
    }

    stage ("Provision prod agent") {
      agent {
        kubernetes {
          cloud 'prod-cloud'
          slaveConnectTimeout 300
          yamlFile "jenkins-prod-agent.yaml"
        }
      }

      stages {
        stage ("Do something on prod agent") {
          steps {
            sh """
            ## Do something here
            """
          }
        }

        stage ("Do something else on prod agent") {
          steps {
            sh """
            ## Do something here
            """
          }
        }
      }
    }
  }
}

반응형