자습서: GitHub 및 Docker를 사용하여 Jenkins 파이프라인 만들기

Important

많은 Azure 서비스에 Jenkins 플러그 인이 있습니다. 이러한 플러그 인 중 일부는 2024년 2월 29일부터 지원되지 않습니다. Azure CLI는 현재 Jenkins를 Azure 서비스와 통합하는 데 권장되는 방법입니다. 자세한 내용은 Azure용 Jenkins 플러그 인 문서를 참조하세요.

애플리케이션 개발의 빌드 및 테스트 단계를 자동화하려면 CI/CD(연속 통합 및 배포) 파이프라인을 사용할 수 있습니다. 이 자습서에서는 다음 방법을 포함하여 Azure VM에 CI/CD 파이프라인을 만듭니다.

  • Jenkins VM 만들기
  • Jenkins 설치 및 구성
  • GitHub 및 Jenkins 간 웹후크 통합 만들기
  • GitHub 커밋에서 Jenkins 빌드 작업 만들기 및 트리거
  • 앱에 대한 Docker 이미지 만들기
  • GitHub 커밋이 새 Docker 이미지 빌드 및 앱 실행 업데이트 확인

이 자습서에서는 지속적으로 최신 버전으로 업데이트되는 Azure Cloud Shell 내의 CLI를 사용합니다. Cloud Shell 을 열려면 코드 블록 맨 위에서 사용해 보세요.

CLI를 로컬로 설치하고 사용하도록 선택하는 경우 이 자습서에서는 Azure CLI 버전 2.0.30 이상을 실행해야 합니다. az --version을 실행하여 버전을 찾습니다. 설치 또는 업그레이드해야 하는 경우 Azure CLI 설치를 참조하세요.

Jenkins 인스턴스 만들기

처음 부팅 시 Linux 가상 머신을 사용자 지정하는 방법에 대한 이전 자습서에서 cloud-init를 사용하여 VM 사용자 지정을 자동화하는 방법을 배웠습니다. 이 자습서에서는 cloud-init 파일을 사용하여 VM에 Jenkins 및 Docker를 설치합니다. Jenkins는 CI(연속 통합) 및 CD(지속적인 업데이트)를 사용하도록 Azure와 원활하게 통합되는 인기 있는 오픈 소스 자동화 서버입니다. Jenkins를 사용하는 방법에 대한 자세한 자습서는 Azure Hub의 Jenkins를 참조하세요.

현재 셸에서 cloud-init-jenkins.txt라는 파일을 만들고 다음 구성을 붙여넣습니다. 예를 들어 로컬 컴퓨터가 아닌 Cloud Shell에서 파일을 만듭니다. 파일을 만들고 사용 가능한 편집기 목록을 보려면 입력 sensible-editor cloud-init-jenkins.txt 합니다. 전체 cloud-init 파일, 특히 첫 번째 줄이 올바르게 복사되었는지 확인합니다.

#cloud-config
package_upgrade: true
write_files:
  - path: /etc/systemd/system/docker.service.d/docker.conf
    content: |
      [Service]
        ExecStart=
        ExecStart=/usr/bin/dockerd
  - path: /etc/docker/daemon.json
    content: |
      {
        "hosts": ["fd://","tcp://127.0.0.1:2375"]
      }
runcmd:
  - apt install openjdk-8-jre-headless -y
  - wget -q -O - https://pkg.jenkins.io/debian/jenkins-ci.org.key | sudo apt-key add -
  - sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
  - apt-get update && apt-get install jenkins -y
  - curl -sSL https://get.docker.com/ | sh
  - usermod -aG docker azureuser
  - usermod -aG docker jenkins
  - service jenkins restart

VM을 만들기 전에 az group create를 사용하여 리소스 그룹을 만듭니다. 다음 예제에서는 eastus 위치에 myResourceGroupJenkins 라는 리소스 그룹을 만듭니다.

az group create --name myResourceGroupJenkins --location eastus

이제 az vm create를 사용하여 VM을 만듭니다. 매개 변수를 --custom-data 사용하여 cloud-init 구성 파일을 전달합니다. 현재 작업 디렉터리 외부에 파일을 저장한 경우 cloud-init-jenkins.txt 에 대한 전체 경로를 제공합니다.

az vm create --resource-group myResourceGroupJenkins \
    --name myVM \
    --image UbuntuLTS \
    --admin-username azureuser \
    --generate-ssh-keys \
    --custom-data cloud-init-jenkins.txt

VM을 만들고 구성하는 데 몇 분 정도 걸립니다.

웹 트래픽이 VM에 도달할 수 있도록 하려면 az vm open-port를 사용하여 Jenkins 트래픽용 포트 8080을 열고 샘플 앱을 실행하는 데 사용되는 Node.js 앱의 경우 포트 1337을 엽니다.

az vm open-port --resource-group myResourceGroupJenkins --name myVM --port 8080 --priority 1001
az vm open-port --resource-group myResourceGroupJenkins --name myVM --port 1337 --priority 1002

Jenkins 구성

Jenkins 인스턴스에 액세스하려면 VM의 공용 IP 주소를 가져옵니다.

az vm show --resource-group myResourceGroupJenkins --name myVM -d --query [publicIps] --o tsv

보안을 위해 VM에서 텍스트 파일로 저장된 초기 관리자 암호를 입력하여 Jenkins 설치를 시작해야 합니다. 이전 단계에서 가져온 공용 IP 주소를 사용하여 VM에 SSH를 수행합니다.

ssh azureuser@<publicIps>

Jenkins가 다음 명령을 사용하여 실행 중인지 확인합니다.service

$ service jenkins status
● jenkins.service - LSB: Start Jenkins at boot time
   Loaded: loaded (/etc/init.d/jenkins; generated)
   Active: active (exited) since Tue 2019-02-12 16:16:11 UTC; 55s ago
     Docs: man:systemd-sysv-generator(8)
    Tasks: 0 (limit: 4103)
   CGroup: /system.slice/jenkins.service

Feb 12 16:16:10 myVM systemd[1]: Starting LSB: Start Jenkins at boot time...
...

Jenkins 설치를 initialAdminPassword 확인하고 복사합니다.

sudo cat /var/lib/jenkins/secrets/initialAdminPassword

파일을 아직 사용할 수 없는 경우 cloud-init이 Jenkins 및 Docker 설치를 완료할 때까지 몇 분 더 기다립니다.

이제 웹 브라우저를 열고 .http://<publicIps>:8080 다음과 같이 초기 Jenkins 설정을 완료합니다.

  • 설치할 플러그 인 선택을 선택합니다.
  • 위쪽의 텍스트 상자에서 GitHub 를 검색합니다. GitHub에 대한 확인란을 선택한 다음 설치를 선택합니다.
  • 첫 번째 관리자 사용자를 만듭니다. 관리자와 같은 사용자 이름을 입력한 다음 사용자 고유의 보안 암호를 제공합니다. 마지막으로, 전체 이름 및 이메일 주소를 입력합니다.
  • 저장 및 마침 선택
  • Jenkins가 준비되면 Jenkins를 사용하여 시작을 선택합니다.
    • Jenkins 사용을 시작할 때 웹 브라우저에 빈 페이지가 표시되면 Jenkins 서비스를 다시 시작합니다. SSH 세션에서 입력 sudo service jenkins restart한 다음 웹 브라우저를 새로 고칩니다.
  • 필요한 경우 만든 사용자 이름과 암호를 사용하여 Jenkins에 로그인합니다.

GitHub 웹후크 만들기

GitHub와의 통합을 구성하려면 Azure 샘플 리포지토리에서 Node.js 헬로 월드 샘플 앱을 엽니다. 리포지토리를 사용자 고유의 GitHub 계정으로 포크하려면 오른쪽 위 모서리에서 포크 단추를 선택합니다.

만든 포크 내에 웹후크를 만듭니다.

  • 설정 선택한 다음 왼쪽에서 웹후크를 선택합니다.
  • Add webhook(웹후크 추가)를 선택한 다음, 필터 상자에서 Jenkins를 입력합니다.
  • Payload URL(페이로드 URL)에 대해 http://<publicIps>:8080/github-webhook/를 입력합니다. 후행을 포함해야 합니다.
  • 콘텐츠 형식의 경우 application/x-www-form-urlencoded를 선택합니다.
  • 이 웹후크를 트리거하려는 이벤트는 무엇입니까?에서 푸시 이벤트만 선택합니다.
  • 활성을 검사 설정
  • 웹후크 추가를 클릭합니다.

Add GitHub webhook to your forked repo

Jenkins 작업 만들기

Jenkins가 코드 커밋과 같은 GitHub의 이벤트에 응답하도록 하려면 Jenkins 작업을 만듭니다. 사용자 고유의 GitHub 포크에 대한 URL을 사용합니다.

Jenkins 웹 사이트에서 홈페이지에서 새 작업 만들기를 선택합니다.

  • HelloWorld를 작업 이름으로 입력합니다. 프리스타일 프로젝트를 선택한 다음 확인을 선택합니다.
  • 일반 섹션에서 GitHub 프로젝트를 선택하고 https://github.com/cynthn/nodejs-docs-hello-world와 같은 포크된 리포지토리 URL을 입력합니다.
  • 소스 코드 관리 섹션에서 Git을 선택하고 포크된 리포지토리 .git URL(예: )을 입력합니다.https://github.com/cynthn/nodejs-docs-hello-world.git
  • 빌드 트리거 섹션에서 GITscm 폴링에 대한 GitHub 후크 트리거를 선택합니다.
  • 빌드 섹션에서 빌드 추가 단계를 선택합니다. 셸 실행을 선택한 다음 명령 창에 입력 echo "Test" 합니다.
  • 작업 창 아래쪽에서 저장을 선택합니다.

GitHub 통합 테스트

Jenkins와 GitHub의 통합을 테스트하려면 사용자 분기의 변경 내용을 커밋합니다.

GitHub 웹 UI로 돌아가서 분기된 리포지토리를 선택한 다음, index.js 파일을 선택합니다. 연필 아이콘을 선택하여 이 파일을 편집하면 6번 줄은 다음과 같습니다.

response.end("Hello World!");

변경 내용을 커밋하려면 아래쪽에서 변경 내용 커밋 단추를 선택합니다.

Jenkins에서 작업 페이지의 왼쪽 아래 모서리에 있는 기록 빌드 섹션에서 새 빌드가 시작됩니다. 빌드 번호 링크를 선택하고 왼쪽에서 콘솔 출력을 선택합니다. 코드가 GitHub에서 로드되면 Jenkins가 수행하는 단계와 콘솔에 메시지 Test을 출력하는 빌드 작업을 확인할 수 있습니다. GitHub에서 커밋이 수행 될 때마다 웹후크는 Jenkins에 도달하고 이러한 방식으로 새 빌드를 트리거합니다.

Docker 빌드 이미지 정의

GitHub 커밋에 기반하여 실행되는 Node.js 앱을 확인하려면 Docker 이미지를 빌드하여 앱을 실행합니다. 이미지는 앱을 실행하는 컨테이너를 구성하는 방법을 정의하는 Dockerfile에서 빌드됩니다.

VM에 대한 SSH 연결에서 이전 단계에서 만든 작업의 이름을 따서 명명된 Jenkins 작업 영역 디렉터리로 변경합니다. 이 예제에서는 HelloWorld라는 이름이 지정 되었습니다.

cd /var/lib/jenkins/workspace/HelloWorld

sudo sensible-editor Dockerfile을 사용하여 이 작업 영역 디렉터리에 파일을 만들고 다음 콘텐츠를 붙여넣습니다. 전체 Dockerfile, 특히 첫 번째 줄이 올바르게 복사되었는지 확인합니다.

FROM node:alpine

EXPOSE 1337

WORKDIR /var/www
COPY package.json /var/www/
RUN npm install
COPY index.js /var/www/

이 Dockerfile은 Alpine Linux를 사용하여 기본 Node.js 이미지를 사용하고, 헬로 월드 앱이 실행되는 포트 1337을 노출한 다음, 앱 파일을 복사하고 초기화합니다.

Jenkins 빌드 규칙 만들기

이전 단계에서는 콘솔에 메시지를 출력하는 기본 Jenkins 빌드 규칙을 만들었습니다. Dockerfile을 사용하고 앱을 실행하는 빌드 단계를 만들 수 있습니다.

Jenkins 인스턴스로 돌아가서 이전 단계에서 만든 작업을 선택합니다. 왼쪽에서 구성을 선택하고 빌드 섹션까지 아래로 스크롤합니다.

  • 기존 echo "Test" 빌드 단계를 제거합니다. 기존 빌드 단계 상자의 오른쪽 위 모서리에서 빨간색 십자가를 선택합니다.

  • 빌드 단계 추가를 선택한 다음, 셸 실행을 선택합니다.

  • 명령 상자에서 다음 Docker 명령을 입력한 다음, 저장을 선택합니다.

    docker build --tag helloworld:$BUILD_NUMBER .
    docker stop helloworld && docker rm helloworld
    docker run --name helloworld -p 1337:1337 helloworld:$BUILD_NUMBER node /var/www/index.js &
    

Docker 빌드 단계는 이미지를 만들고, 이미지에 대한 기록을 유지할 수 있도록 하는 Jenkins 빌드 번호로 태그를 만듭니다. 앱을 실행하는 모든 기존 컨테이너가 중지된 다음 제거됩니다. 새 컨테이너는 이미지를 사용하여 시작되었다가 GitHub의 최신 커밋에 따라 Node.js 앱을 실행합니다.

파이프라인 테스트

전체 파이프라인의 실제 동작을 확인하려면 분기된 GitHub 리포지토리에서 다시 index.js 파일을 편집하고 변경 내용 커밋을 선택합니다. GitHub에 대한 웹후크에 기반하는 Jenkins에서 새 작업이 시작됩니다. Docker 이미지를 만들고 새 컨테이너에서 앱을 시작하는 데 몇 초 정도 걸립니다.

필요한 경우 다시 VM의 공용 IP 주소를 가져옵니다.

az vm show --resource-group myResourceGroupJenkins --name myVM -d --query [publicIps] --o tsv

웹 브라우저를 열고 http://<publicIps>:1337을 입력합니다. Node.js 앱이 표시되고 다음과 같이 GitHub 포크의 최신 커밋을 반영합니다.

Running Node.js app

이제 GitHub에서 index.js 파일을 다시 편집하고 변경 내용을 커밋합니다. Jenkins에서 작업이 완료되기까지 몇 초 정도 기다린 다음 웹 브라우저를 새로 고쳐 다음과 같이 새 컨테이너에서 실행 중인 앱의 업데이트된 버전을 확인합니다.

Running Node.js app after another GitHub commit

다음 단계

이 자습서에서는 각 코드 커밋에서 Jenkins 빌드 작업을 실행한 다음 Docker 컨테이너를 배포하여 앱을 테스트하도록 GitHub를 구성했습니다. 다음 방법에 대해 알아보았습니다.

  • Jenkins VM 만들기
  • Jenkins 설치 및 구성
  • GitHub 및 Jenkins 간 웹후크 통합 만들기
  • GitHub 커밋에서 Jenkins 빌드 작업 만들기 및 트리거
  • 앱에 대한 Docker 이미지 만들기
  • GitHub 커밋이 새 Docker 이미지 빌드 및 앱 실행 업데이트 확인

Azure DevOps Services와 Jenkins를 통합하는 방법에 대한 자세한 내용을 보려면 다음 자습서로 이동합니다.