Jenkins: 여러 Docker 컨테이너를 사용하여 애플리케이션 구축 및 배포

Jenkins: 여러 Docker 컨테이너를 사용하여 애플리케이션 구축 및 배포

배경: Jenkins는 훌륭하게 작동하는 docker 컨테이너 내에서 실행되지만, 설계상 Jenkins 컨테이너 내부에 설치된 소프트웨어를 최소화하기 위해 모든 빌드 프로세스가 docker 컨테이너 내에서 실행되기를 원합니다.

문제: 세 단계가 모두 파일을 공유하는 두 개의 다른 도커 컨테이너를 사용하여 3단계 프로세스를 어떻게 구축합니까?

1단계: 빌드

  • npm 빌드

2단계: 테스트

  • npm 테스트`

3단계: AWS 코드 배포 실행

  • aws 배포 푸시 --application-name app-name --s3-location s3://my-bucket/app-name --ignore-hidden-files
  • aws 배포 create-deployment --application-name 앱 이름 --s3-location bucket=my-bucket,key=app-name,bundleType=zip --deployment-group-name dg

Jenkins 파일을 여러 단계로 나누고 첫 번째 단계의 출력을 다른 단계에 공유하려면 어떻게 해야 합니까?

간단한 2단계 Jenkinsfile

pipeline {
  agent {
    docker {
      image 'node:10.8.0'
    }
  }
  stages {
    stage('Build') {
      steps {
        sh 'npm install'
      }
    }
    stage('Test') {
      steps {
        sh 'npm test'
      }
    }
  }
}

그런데 세 번째 단계에 추가하면 전역 도커 이미지(에이전트)를 사용할 수 없기 때문에 상황이 더욱 흥미로워집니다.

pipeline {
  agent none
  stages {
    stage('Build') {
      agent {
        docker { image 'node:10.8.0' }
      }
      steps {
        sh 'npm install'
      }
    }
    stage('Test') {
      agent {
        docker { image 'node:10.8.0' }
      }
      steps {
        sh 'npm test'
      }
    }
    stage('Deploy') {
      agent {
        docker { image 'coreos/awscli' }
      }
      steps {
        sh 'echo "Deploying to AWS"'
        sh 'aws help'
      }
    }
  }
}

위의 경우 빌드 단계의 결과가 손실되어 'npm test'가 실패합니다. 그리고 모든 빌드 아티팩트가 손실되므로 코드 배포가 작동하지 않습니다.

테스트 작업을 위한 한 가지 해결 방법은 이미지를 사용하는 'BuildAndTest' 단계를 갖는 것이지만, 이렇게 하면 별도 단계의 장점 중 일부가 손실됩니다.

pipeline {
  agent none
  stages {
    stage('Build And Test') {
      agent {
        docker { image 'node:10.8.0' }
      }
      steps {
        sh 'npm install'
        sh 'npm test'
      }
    }
    stage('Deploy') {
      agent {
        docker { image 'coreos/awscli' }
      }
      steps {
        sh 'echo "Deploying to AWS"'
        sh 'aws help'
      }
    }
  }
}

또 다른 (아주 추악한) 해결책은 node와 aws가 모두 설치된 사용자 정의 이미지를 생성하는 것입니다. 그러나 이는 노드 및/또는 aws의 최신 버전으로 마이그레이션할 때마다 업데이트된 버전으로 또 다른 도커 이미지를 생성해야 함을 의미합니다. , 실제로는 완전히 별개의 작업입니다.

다른 해결책은 모든 인스턴스 간에 공유 이미지를 마운트하는 것입니다. 하지만 이 빌드에만 공유되고 빌드가 완료된 후 삭제되는 '임시' 이미지를 만들려면 어떻게 해야 합니까?

답변1

질문을 게시한 직후 Jenkins 개발자의 기사를 발견했습니다.

https://jenkins.io/blog/2018/07/02/whats-new-declarative-piepline-13x-series-stages/

이것이 내가 생각해낸 것이다

pipeline {
  agent none
  stages {
    stage('Build and Test') {
      agent {
        docker 'node:10.8.0'
      }
      stages {
        stage('Build') {
          steps {
            sh 'npm install'
          }
        }
        stage('Test') {
          steps {
            sh 'npm test'
          }
        }
      }
      post {
        success {
          stash name: 'artifacts', includes: "node_modules/**/*"
        }
      }
    }

    stage('Deploy') {
      agent {
        docker 'coreos/awscli'
      }
      steps {
        unstash 'artifacts'
        sh 'echo "Deploying to AWS"'
        sh 'aws help'
      }
    }
  }
}

Jenkins는 이제 선언문 내에서 여러 단계를 허용하며 나에게 매우 효과적인 'stash/unstash' 명령에 대해 몰랐습니다.

관련 정보