반응형
05-03 07:00
Today
Total
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
관리 메뉴

개발하는 고라니

[Jenkins] Pipeline 본문

Open Source/Jenkins

[Jenkins] Pipeline

조용한고라니 2021. 9. 28. 02:38
반응형

이번 포스팅에서는 젠킨스의 Pipeline 기능의 모든 권장 사항을 다룬다.

개요

  • Pipeline 시작 - Blue Ocean이나 classic UI 또는 SCM을 통해 젠킨스 파이프라인 정의하는 방법
  • Jenkinsfile을 만들고 사용하기
  • 브랜치 작업과 PR
  • Docker와 Pipeline - Jenkins가 어떻게 Docker Container를 부를 수 있는지
  • 공유된 라이브러리로 Pipeline 연장하기
  • Pipeline 생성을 용이하게 하는 다른 개발툴을 사용하기
  • Pipeline Syntax로 작업하기

Jenkins Pipeline

젠킨스 파이프라인이란 젠킨스를 사용하여 CD 파이프라인울 구현하고 통합하는 것을 지원하는 플러그인의 집합이고, 파이프라인은 파이프라인 DSL 굼누을 통해 코드로 간단하거나 복잡한 전송 파이프라인으로 모델링하기 위한 확장 가능한 자동화 서버를 갖추고 있다.

 

젠킨스 파이프라인("P")는 젠킨스 안의 지속적 제공(CD) 파이프라인을 구현하고 통합하는 것을 서포트하는 플러그인의 모음이다. 

 

지속적 제공(CD) 파이프라인은 사용자와 고객에 이르기까지 버전 제어에서 소프트웨어를 가져오는 프로세스의 자동화된 표현이다. 당신의 소프트웨어의 모든 변화는 릴리즈되기 까지 복잡한 프로세스를 거친다. 이 프로세스는 여러 단계의 테스트 및 배포를 통해 빌드된 소프트웨어를 진행하는 것뿐만 아니라 신뢰할 수 있고 반복 가능한 방식의 소프트웨어를 빌드하는 작업이 포함된다.

 

파이프라인은 파이프라인 DSL(Domain-specific Language) 구문을 통해 코드로 간단하거나 복잡한 전송 파이프라인을 모델링하기 위한 확장 가능한 자동화 서버를 갖추고 있다.

 

Jenkins 파이프라인의 정의는 Jenkinsfile 프로젝트의 소스 제어 리포지토리에 커밋될 수 있는 텍스트 파일에 작성된다. 이것은 "Pipeline-as-code"의 기초이다. CD 파이프라인을 응용 프로그램의 일부로 취급하여 다른 코드와 마찬가지로 버전 관리 및 검토한다.

 

Jenkinsfile 소스 제어를 생성하고 커밋하면 여러 즉각적인 이점을 얻을 수 있다.

  • 모든 분기 및 풀 요청에 대한 파이프라인 빌드 프로세스를 자동으로 생성한다.
  • 파이프라인의 코드 검토/반복
  • 파이프라인에 대한 감사 추적
  • 프로젝트의 여러 구성원이 보고 편집할 수 있는 파이프라인의 단일 소스

웹 UI나 Jenkinsfile로 파이프라인을 정의하는 거나 동일하지만, 일반적으로 파이프라인을 정의하고 Jenkinsfile 소스 제어에 체크인 하는 것이 모범 사례이다.

Declarative VS Scripted Pipeline syntax

Jenkinsfile은 두 형태의 구분을 사용하여 쓰여질 수 있다.

 

1) Declarative : 보다 쉽게 작성할 수 있고, 커스텀 되어 있다. Groovy 몰라도 쓸 수 있다.

2) Scripted : Groovy 기반, Declarative 보다 효과적으로 많은 기능 포함하여 작성 가능하지만, Groovy를 잘알아야 한다.

 

Declarative와 Scripted 파이프라인은 근본적으로 다르게 구성된다.

Declarative 파이프라인은 젠킨스 파이프라인의 최신 기능이다.

  • Scripted 파이프라인 구문보다 풍부한 구문 기능을 제공한다.
  • 더 가독성이 좋다.

그러나 Jenkinsfile에 쓰여진 많은 개별 구성요소들은 Declarative나 Scripted나 모두 공통적이다. 

왜 파이프라인인가?

근본적으로 젠킨스는 많은 자동화 패턴을 지원하는 자동화 엔진이다. 파이프라인은 젠킨스위에 강력한 자동화 툴 모음을 추가하고, 단순한 연속 통합에서 포괄적인 CD 파이프라인에 이르는 사용 사례를 지원한다. 연관된 업무들을 모델링함으로써, 사용자들은 파이프라인의 많은 특징 이점을 얻을 수 있다.

 

  • Code (코드)
    • 파이프라인은 코드로 구현되었고, 일반적으로 소스 제어에 체크인하여 팀이 전달 파이프라인을 편집/리뷰/반복할 수 있다.
  • Durable (내구성)
    • 파이프라인은 Jenkins 컨트롤러의 계획된 재시작과 계획되지 않은 재시작 모두에서 살아남는다.
  • Pausable (대기)
    • 파이프라인은 파이프라인 실행을 계속하기 전, 선택적으로 중지하고 사람의 입력이나 승인을 기다릴 수 있다.
  • Versatile (다목적성)
    • 파이프라인은 분기/조인, 루프 및 병렬 작업 수행 기능을 포함하여 복잡한 실제 CD 요구 사항을 지원한다.
  • Extensible (확장 가능성)
    • 파이프라인 플러그인은 DSL에 대한 사용자 정의 확장과 다른 플러그인과의 통합을 위한 여러 옵션을 지원한다.

 

다음은 Jenkins Pipeline에서 쉽게 모델링된 CD 시나리오의 예시이다.

Pipeline 용어 (개념)

다음은 파이프라인 구문과 밀접하게 연관된 젠킨스 파이프라인의 중요한 개념들이다.

파이프라인 - pipeline

 

- 파이프라인은 사용자 정의된 CD 파이프라인 모델이다.

- 파이프라인의 코드는 당신의 전체적인 Build 프로세스를 정의하고, 일반적으로 어플리케이션을 빌드하기 위해 stage를 포함하며 그것을 테스트하고 제공한다.

- 파이프라인 block은 Declarative 파이프라인 구문의 핵심이다.

 

노드 - node

 

- 노드는 젠킨스 환경의 일부이며 파이프라인을 실행할 수 있는 시스템이다.

- 노드 block은 Scripted 파이프라인 구문의 핵심이다.

 

스테이지 - stage

 

- 스테이지 block은 전체 파이프라인을 통해("Build", "Test", "Deploy stages...) 수행된 업무의 별개 부분집합을 개념적으로 정의한다. 이는 젠킨스 파이프라인 상태나 과정을 시각화하거나 표현하기 위해 많은 플러그인에 의해 사용된다.

 

스텝 - step

 

- 단일 업무

- 근본적으로 하나의 스텝은 젠킨스에게 특별한 시점에 무엇을 하라고 지시한다. 예를 들어, 쉘 커맨드 make를 실행하기 위해 sh step: sh 'make'를 사용한다.

- 플러그인이 Pipeline DSL을 확장할 때, 일반적으로 플러그인이 하나의 새로운 스텝을 구현했다는 것을 의미한다.

파이프라인 구문 개요

다음 파이프라인 코드 뼈대는 Declarative와 Scripted의 근본적인 차이를 설명한다.

 

"stage"와 "steps"는 Declarative와 Scripted에서 모두 공통적임을 유의하자.

Declarative 파이프라인 기본

선언적 파이프라인 구문에서, pipeline 블록은 전체 파이프라인 내내 완료된 모든 작업을 정의한다. 

Jenkinsfile (Declarative Pipeline)
pipeline {
    agent any //1
    stages {
        stage('Build') { //2
            steps {
                // 3
            }
        }
        stage('Test') { //4
            steps {
                // 5
            }
        }
        stage('Deploy') { //6
            steps {
                // 7
            }
        }
    }
}
  1. 이용가능한 agent가 이 파이프라인 또는 파이프라인의 어느 스테이지를 실행한다.
  2. "Bulid" 스테이지를 정의한다.
  3. 빌드와 관련된 몇가지 스텝을 수행한다.
  4. "Test" 스테이지를 정의한다.
  5. 테스트와 관련된 몇 가지 스텝을 수행한다.
  6. "Deploy" 스테이지를 정의한다.
  7. 배포와 관련된 몇 가지 스텝을 수행한다.

Scripted 파이프라인 기초

스크립트 파이프라인 구문에서, 하나이상의 node 블럭이 핵심 작업을 파이프라인 내내 수행한다. 비록 스크립트 파이프라인 구문의 의무적인 요구는 아니지만, 파이프라인의 작업을 node 블록 내부로 제한하면 두 가지 작업이 수행된다.

  • Jenkins 대기열에 항목을 추가하여 실행할 블록에 포함된 단계를 예약한다. 실행기가 노드에서 사용가능하게 되면 단계가 실행된다.
  • 소스 제어에서 체크 아웃된파일에서 작업을 수행할 수 있는 작업공간을 만든다.
Jenkinsfile(스크립트된 파이프라인)
node {  //1
    stage('Build') { //2
        // 3
    }
    stage('Test') { //4
        // 5
    }
    stage('Deploy') { //6
        // 7
    }
}
  1. 사용 가능한 에이전트에서 이 파이프라인 또는 해당 단계를 실행합니다.
  2. 빌드 단계를 정의한다. stage 블록은 스크립트 파이프라인 구문에서 선택 사항이다. 그러나 stage 스크립팅된 파이프라인에서 블록을 구현하면 Jenkins UI에서 각 단계의 작업/단계 하위 집합을 더 명확하게 시각화할 수 있다.
  3. 빌드와 관련된 몇 가지 단계를 수행한다.
  4. "테스트" 단계를 정의한다.
  5. 테스트와 관련된 몇 가지 단계를 수행한다.
  6. "배포" 단계를 정의한다.
  7. 배포와 관련된 ~

선언적 파이프라인 예시

Jenkinsfile(선언적 파이프라인)
pipeline { 
    agent any 
    options {
        skipStagesAfterUnstable()
    }
    stages {
        stage('Build') { 
            steps { 
                sh 'make' 
            }
        }
        stage('Test'){
            steps {
                sh 'make check'
                junit 'reports/**/*.xml' 
            }
        }
        stage('Deploy') {
            steps {
                sh 'make publish'
            }
        }
    }
}

Jenkinsfile (Declarative)

파이프라인은 젠킨스 Web UI나 젠킨스 파일로 정의해 사용할 수 있다.

 

젠킨스파일은 파이프라인의 정의를 포함하고 소스 제어에 체크인되는 Text 파일이다. 다음 예시 코드는 기본 3단계 지속적 전달(Continous Delivery) 파이프라인을 구현한다.

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                echo 'Building..'
            }
        }
        stage('Test') {
            steps {
                echo 'Testing..'
            }
        }
        stage('Deploy') {
            steps {
                echo 'Deploying....'
            }
        }
    }
}

 

모든 파이프라인에 위의 3단계가 있는 것은 아니지만, 이를 정의하는 것이 좋다. 위의 Declarative(선언적) 파이프라인 예제에는 CD 파이프라인을 구현하는데 필요한 최소한의 구조가 포함되어 있다.

 

agent

"agent" 키워드는 반드시 있어야 하며, 파이프라인에 대한 수행 및 작업 공간을 할당한다. agent가 없으면 선언적 파이프라인이 유효하지 않으며, 어떠한 작업도 수행할 수 없다. 기본적으로 이 지시문은 소스 Repository가 체크아웃되고 후속 단계에서 사용할 수 있도록 한다.

Build

일반적으로 프로젝트에서 파이프라인의 작업 시작은 "빌드"단계이다.

파이프라인의 이 단계는 소스코드가 어셈블, 컴파일, 또는 패키징 되는 곳이다. 젠킨스파일은 GNU/Make, 메이븐, 그래들같은 존재하는 빌드 툴 대체재가 아니다.  그러나 많은 구문 프로젝트의 개발 생명주기와 함께 (빌드, 테스트, 배포 등) 접착제 층처럼 보여질 수 있다 .

pipeline {
    agent any

    stages {
        stage('Build') {
            steps {
                sh 'make' //1
                archiveArtifacts artifacts: '**/target/*.jar', fingerprint: true //2
            }
        }
    }
}

 

1) sh 단계는 make 명령을 호출하고 명령에 의해 0 종료 코드가 반환되는 경우에만 계속된다. 0이 아닌 종료 코드는 파이프라인에 실패한다.

2) archiveArtifacts포함 패턴 (**/target/*.jar)과 일치하여 빌드된 파일을 캡쳐하고 나중에 검색할 수 있도록 jenkins 컨트롤러에 저장한다.

Test

자동화된 테스트를 실행하는 것은 성공적인 CD 프로세스의 중요한 구성 요소이다. 따라서 Jenkins에는 여러 플러그인에서 제공하는 테스트 기록, 보고 및 시각화 기능이 많이 있다. 기본적인 수준에서 테스트 실패 시, 웹 UI에서 보고 시각화를 위해 Jenkins가 실패를 기록하도록 하는 것이 좋다.

pipeline {
    agent any

    stages {
        stage('Test') {
            steps {
                /* `make check` returns non-zero on test failures,
                * using `true` to allow the Pipeline to continue nonetheless
                */
                sh 'make check || true' //1
                junit '**/target/*.xml' //2
            }
        }
    }
}

 

1) 인라인 셀 조건부(sh 'make check || true')를 사용하면 sh 단계에서 항상 0 종료 코드를 확인하여 Junit 단계에 테스트 보고서를 캡쳐하고 처리할 수 있는 기회를 제공한다.

2) Junit 포함 패턴(**/target/*.xml)과 일치하는 Junit XML 파일을 캡쳐하고 연결한다.

Deploy

배포는 프로젝트 또는 팀 요구 사항에 따라 다양한 단계를 의미할 수 있으며 빌드된 아티팩트를 Artifactory 서버에 게시하는 것부터 코드를 Production에 넘기는 것 까지 될 수 있다.

 

pipeline {
    agent any

    stages {
        stage('Deploy') {
            when {
              expression {
                currentBuild.result == null || currentBuild.result == 'SUCCESS' //1
              }
            }
            steps {
                sh 'make publish'
            }
        }
    }
}

 

1) currentBuild.result 변수에 access 하면 파이프라인에서 테스트 실패가 있는지 확인할 수 있다. 

Jenkinsfile 작업

  • 젠킨스 파일 안의 특정 파이프라인 구문
  • 어플리케이션 또는 파이프라인 프로젝트를 빌드하기 위한 필수 파이프라인의 특징과 기능

환경 변수 사용

젠킨스 파이프라인은 전역 변수를 통해 환경 변수를 노출한다. 이 변수 env는 젠킨스파일 안에 어디서든 사용할 수 있다.

환경 변수의 전체 목록은 ${JENKINS_URL}/pipeline-syntax/globals#env에 문서화되어 있으며 다음을 포함한다.

  • BUILD_ID
  • BUILD NUMBER
  • BUILD TAG
  • BUILD URL
  • EXECUTOR_NUMBER
  • JAVA_HOME
  • JENKINS_URL
  • 작업 이름
  • NODE_NAME
  • 작업 공간의 절대 경로

 

이러한 환경 변수를 참조하거나 사용하는 것은 Groovy Map의 키에 access하는 것처럼 수행될 수 있다.

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo "Running ${env.BUILD_ID} on ${env.JENKINS_URL}"
            }
        }
    }
}

환경 변수 설정

젠킨스 파이프라인 내에서 환경 변수를 설정하는 것은 Declarative / Scripted에 따라 다르게 수행된다.

pipeline {
    agent any
    environment { //1
        CC = 'clang'
    }
    stages {
        stage('Example') {
            environment { //2
                DEBUG_FLAGS = '-g'
            }
            steps {
                sh 'printenv'
            }
        }
    }
}

 

1) environment 최상위 pipeline 블록에 사용된 지시문은 파이프라인 모든 단계에 적용된다.
2) stage에 정의된 environment 지시문은 환경 변수를 주어진 stage내에서 사용할 수 있게 한다.

자격 증명 처리 (Handling Credentials)

※ Secret Text

 

아래 예제에선 두 개의 보안 텍스트 자격 증명이 AWS에 액세스하기 위해 별도의 환경 변수에 할당된다.

pipeline {
    agent {
        // Define agent details here
    }
    environment {
        AWS_ACCESS_KEY_ID     = credentials('jenkins-aws-secret-key-id')
        AWS_SECRET_ACCESS_KEY = credentials('jenkins-aws-secret-access-key')
    }
    stages {
        stage('Example stage 1') {
            steps {
                // 1
            }
        }
        stage('Example stage 2') {
            steps {
                // 2
            }
        }
    }
}
젠킨스는 비밀 정보가 공개될 위험을 줄이기 위해 "******"만 반환한다. 콘솔 출력 및 모든 로그, 자격 증명 ID 자체의 모든 민감한 정보도 파이프라인 실행 출력에서 "*****"로 나간다.

신뢰할 수 없는 파이프라인 작업이 신뢰할 수 있는 자격 증명을 사용하도록 허용하지 말도록 한다.

 

※ Username, Password

 

 

※ Secret file

 

 

# References

 

Pipeline

Jenkins is, fundamentally, an automation engine which supports a number of automation patterns. Pipeline adds a powerful set of automation tools onto Jenkins, supporting use cases that span from simple continuous integration to comprehensive CD pipelines.

www.jenkins.io

 

Using a Jenkinsfile

For more advanced usage with Scripted Pipeline, the example above node is a crucial first step as it allocates an executor and workspace for the Pipeline. In essence, without node, a Pipeline cannot do any work! From within node, the first order of busines

www.jenkins.io

 

반응형
Comments