Jenkins with Docker and GitHub

Dion·2020년 6월 9일
10

DevOps

목록 보기
1/1
post-thumbnail

Jenkins 정리

이 정리는 Local 환경에서 Jenkins 서버를 Docker에 설치하고 Github 연동을 하는것을 목표로 합니다.

Jenkins는 CI&CD를 환경을 제공하는 자동화 서버입니다.

Jenkins를 Local에 Docker로 설치하는 이유는 EC2에 설치하는 공식 가이드를 참조해보면 월 84$ 정도의 비용이 예상된다고 나와있는데, 딱봐도 그냥 우리집 전기세가 덜 나올 것 같아서 데스크톱으로 설정하도록 하였다.

$ docker pull jenkins/jenkins:lts

Docker Hub에서 jenkins 이미지를 가져옵니다. 위치

참고로 Docker Official Images로 등록된 Jenkins 이미지는 지원이 중단된 상태입니다. 참고

이 이미지로 설치하게 되면, 플러그인을 설치할 수 없습니다.

LTS 버전을 받는 이유는 안정적인 동작을 위해서입니다.

$ docker run -d -p 8080:8080 -p 50000:50000 --name jenkins jenkins/jenkins:lts 

로 실행할 수 있습니다. 이 예제에서는 위의 명령으로 진행하려고 합니다.

주의! 8080포트는 톰캣 기본 포트여서 겹칠 수 있으니 이를 주의합시다.
-p <호스트 포트>:<컨테이너 포트> 의 순서입니다. 호스트 포트를 변경해줍니다.

이렇게 하면, jenkins의 데이터는 /var/jenkins_home 에 저장이 됩니다.
이는 영구적인 데이터가 아니므로 가능하다면 영구적인 볼륨으로 만드는 것이 좋다고 합니다.

$ docker run -d -p 8080:8080 -p 50000:50000 -v /your/home:/var/jenkins_home --name jenkins jenkins/jenkins:lts

jenkins 데이터를 /your/home 에 저장합니다.

이는 jenkins user -uid 1000 이 접근할 수 있도록 하거나, -u some_other_user 파라미터로 컨테이너가 실행될 리눅스 사용자 계정 이름 또는 UID를 설정할 수 있습니다.

위의 방법은 조금 어려우므로 다음과 같이 하는 방법을 호눅스가 추천하였습니다.

$ docker run -d -p 8080:8080 -p 50000:50000 -v /var/jenkins_home --name jenkins jenkins/jenkins:lts

-v 옵션은 docker volume을 사용하는 옵션입니다. 도커 volume 공식 문서

학습 키워드: docker run -u 옵션, linux uid, gid, docker volume

docker run 설명

해당 명령을 실행하면, docker에서 jenkins가 구동되게 됩니다.

localhost에 해당 포트를 입력해서 jenkins 웹서버에 접속합니다. 그렇게 하면 아래와 같은 화면이 출력됩니다.

jenkins의 초기 관리자 비밀번호를 요구하는 화면입니다.

해당 경로(/var/jenkins_home/secrets/initialAdminPassword)에 있는 파일의 내용을 읽어서 Administrator password란에 입력해주면됩니다.

이 파일은 docker volume을 사용하지 않았다면, docker 내부에만 존재하는 파일이므로 아래와 같은 명령어를 입력하여 jenkins container에 접근해야합니다.

$ docker exec -it jenkins /bin/bash

docker container 내부 쉘에서

$ cat /var/jenkins_home/secrets/initialAdminPassword

을 입력하면 초기 관리자 비밀번호가 출력되게 됩니다.

Continue 버튼을 눌러 진행합니다.

플러그인을 설치하는 화면이 나오게됩니다.

왼쪽 Install suggested plugins를 눌러 설치합니다.

참고로 여기서 실패한다면 jenkins의 버전과 plugin의 버전이 호환되지 않거나 알 수 없는 이유로 설치가 안된 것이니 처음부터 다시 진행하시면 되겠습니다.

사실 이거 하다가 한 번 실패해서 다시 만들었다는건 안비밀...

플러그인 설치가 완료되면 아래와 같은 화면이 나옵니다.

Username을 제외한 다른 항목들은 변경이 가능하다는 것을 생각하고 유저를 만듭니다.

Save and Continue버튼을 눌러 다음 항목을 진행합니다.

Jenkins URL을 설정하는 부분입니다. 이는 추후에 변경가능하나. 중요한 옵션입니다.

이 URL은 일종의 변수처럼 활용되며, 이 URL에 따라서 webhook도 설정하니 외부에 개방된 jenkins를 구성할 경우 localhost가 아니어야함을 알고있어야 합니다.

Save and Finish버튼을 클릭하여 다음으로 진행합니다.

젠킨스가 준비 완료되었습니다.

젠킨스의 유저 정책

젠킨스는 기본적으로 관리자가 유저 계정을 만들어주는 정책을 Default로 하고 있습니다.

따라서 계정이 없는 유저가 계정을 만들기 위한 정책을 설정해줄 수 있습니다.

사용자 정책

하지만 대부분의 경우 계정을 생성하지 않도록 한다는게 주요 골자이다.

Jenkins와 Github 연동하기

사전 요구사항

  • 젠킨스 설치완료
  • 젠킨스가 외부(WWW)에 개방되어 있어야 함 - 적어도 깃헙에서 webhook이 가능해야 함.
  • 간단한 spring boot web project(테스트 코드가 있으면 더 좋습니다.)

기본적으로 webhook을 이용하기 때문에 외부에서 접속이 가능해야 합니다.

왼쪽 상단에 New Item을 클릭합니다.

저는 영문 설정으로 OS및 Browser가 설정되어 있어 Jenkins가 영문으로 표시되지만, 한국어 설정의 경우 Jenkins가 한국어로 표시되므로 차이가 있을 수 있습니다.

item의 이름을 입력해주고 Freestyle project를 선택합니다.

그러면 이제 Job을 설정해주어야 합니다.

먼저 우리 예제 프로젝트의 url을 가져옵니다.

위와 같이 GitHub project에 체크하고 Project url을 입력해줍니다.

그 다음 Source Code Management 메뉴에서 Git을 선택해줍니다.

거기에 Repository의 정보를 입력해줍니다. url과 branch 정보를 일단 먼저 작성해줍니다.

그 다음 Credentials를 추가하겠습니다.

Credential이 - none - 밖에 없을 텐데, Add 버튼을 눌러 추가해줍니다.

버튼을 클릭하면 Jenkins Credential을 추가할 수 있는 화면이 뜹니다.

Kind는 Username with password로 설정합니다. 이 옵션은 github id와 password를 요구하므로 보안에 취약한 옵션이라 실제 업무에선 사용하지 않는다고 합니다.

다른 옵션은 이 곳을 참조하세요.

Add 버튼을 눌러 추가하면 Credential이 추가됩니다.

그러면 아까전엔 - none - 밖에 없던 Credential이 제가 추가한 Credential 정보를 가지게 됩니다.

이를 선택해줍니다.

빌드 트리거를 설정해줍니다. 아까 전에도 설명했듯이 Github webhook을 이용해서 trigger를 걸어줄 것 입니다.

Build에서는 Execute shell을 클릭해서 설정합니다.

그 다음 아래와 같은 명령을 입력해줍니다.

그리고 나서 Save 버튼을 눌러서 끝내줍니다.

Jenkins에서 해줄 부분은 모두 끝났습니다. 이제는 github에서 설정해주기만 하면 됩니다.

예제 프로젝트 repository의 settings 탭으로 들어갑니다.

Webhooks 메뉴를 클릭합니다.

Add webhook 버튼을 누릅니다.

여기서 Payload URL을 입력하는데, 이 때 외부 접속이 가능한 URL만 입력해야합니다.

localhost:8080은 되지 않습니다. 공유기를 사용한다면 DDNS 기능을 사용해서 외부에 포트를 개방해줄 수 있습니다.

혹은 ngrok이라는 외부에서 로컬에 터널로 접속할 수 있게 해주는 터널 프로그램을 사용할 수 있습니다.

참고

jenkins URL에 /github-webhook/ 을 추가해야합니다.

꼭 마지막 / 를 넣어야 동작하니 잊지 말것!

그리고 Content typeapplication/json으로 바꾸어줍니다.

그리고 Add webhook 버튼을 눌러줍니다.

정상적으로 webhook이 설정되었다면 위와 같이 초록색 체크표시가 나옵니다.

실패한 경우 경고 표시가 나오고 왜 되지 않는지 설명이 나오니 그에 맞게 대처하면 되겠습니다.

그 다음 trigger가 동작하는 branch에 push 동작을 수행하면 우리가 입력한 스크립트가 동작하게 됩니다.

푸시를 수행한 직후 trigger가 되면 jenkins에 해당 build가 보이게됩니다.

해당 빌드의 번호를 클릭하면 다음과 같은 화면이 나오게 됩니다.

Console Output 을 클릭해서 Console로 출력되는 정보를 볼 수 있습니다.

깃헙과 Jenkins의 연동이 끝났습니다.

reference

이동욱님의 옛날 글: 현재와는 맞지 않는 부분이 조금 있어서 시행착오가 좀 많았음.

도커에 Jenkins 설치하기: 도커 설치의 경우는 이 글을 참고하였음.

Github 연동 관련 글: Github의 경우에는 이 글을 참고하였음.

이걸론 부족한데?

  • Jenkins CI를 Github PR과 연동하기
  • Jenkins CD를 AWS와 연동하기

Jenkins CI를 Github PR과 연동하기

Github Pull Request Builder Plugin 설치

Manage Jenkins를 클릭합니다.

Manage Plugins를 클릭합니다.

그 다음 Available 탭에서 Github Pull request builder 플러그인을 설치해줍니다.

플러그인을 설치합니다. 그리고 나서 안정적인 동작을 위해 Jenkins를 restart 합니다.

Jenkins server Github 인증 받기

Manage Jenkins 메뉴에서 Configure System을 클릭합니다.

쭉 내려서 GitHub Pull Request Builder에 정보를 작성합니다.

credentials는 위에 작성한 정보를 그대로 활용해도 됩니다. 정확히는 Github repository에 접근 가능한 유저여야 합니다.

Test Credentials 버튼을 클릭합니다.

그 다음 Test basic connection to Github 체크박스를 클릭하고 Connect to API를 누릅니다.

그러면 아래와 같은 화면이 나오게 됩니다.

Repository owner/name에는 여기서 복사해서 붙여넣습니다.

해당 리포지토리에 권한이 있는지, 이슈에 코멘트가 달리는지 테스트 합니다.

정상적으로 되었다면 맨 아래에 위치한 Save 버튼을 클릭해서 저장합니다.

아까 생성해 두었던 Project로 들어갑니다. 거기서 Configure 메뉴에 접근합니다.

Source Code Management 메뉴에 접근합니다.

Advacned... 버튼을 눌러줍니다.

Name에 origin

Refspec에 +refs/pull/${ghprbPullId}/*:refs/remotes/origin/pr/${ghprbPullId}/*

⇒ PR이 될 때 build 되는 것 만을 원한다면 설정합니다.


Source Code Management에서 꼭 Branch Specifier를 변경해줍니다. ${ghprbActualCommit} 으로 해야 PR된 브랜치가 build 됩니다.

Under Advanced, set Name to origin
If you just want to build PRs, set refspec to +refs/pull/${ghprbPullId}/*:refs/remotes/origin/pr/${ghprbPullId}/*

If you want to build PRs and branches, set refspec to +refs/heads/*:refs/remotes/origin/* +refs/pull/*:refs/remotes/origin/pr/* (see note below about parameterized builds)
In Branch Specifier, enter ${sha1} instead of the default */master.
If you want to use the actual commit in the pull request, use ${ghprbActualCommit} instead of ${sha1}

More detailed instructions can be found here

ref: https://medium.com/@mreigen/integrate-jenkins-builds-into-github-pull-requests-33bc053d6210

Github PR에 Check 추가하기

Build Triggers 에 GitHub Pull Request Builder를 체크합니다.

그리고 Trigger pharse에 다음과 같이 입력합니다. .*(re)?run tests.*

그리고 Trigger Setup을 클릭하고 Add를 눌러서 Update commit status during build를 클릭합니다.

다음과 같이 Trigger를 설정해줍니다. 이모지는 못넣습니다.🥺

PR을 테스트 해보면 다음과 같은 결과를 얻을 수 있습니다.

아바타는 어쩔 수 없이 사용자의 아바타를 사용합니다.

reference

미디엄 글

Jenkins AWS CodeDeploy 연동

Ubuntu Server용 CodeDeploy Agent 설치

Ubuntu Server용 CodeDeploy 에이전트 설치 또는 다시 설치

리전별 리소스 키트 버킷 이름

sudo apt install ruby -y
sudo apt install wget -y
cd /home/ubuntu
# 서울리전 기준
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto

잘 안뜨는 경우가 많다.

서비스 상태 확인

sudo service codedeploy-agent status

서비스 재시작은 restart

꺼져있는 경우는 이렇게 나옴

● codedeploy-agent.service - LSB: AWS CodeDeploy Host Agent
   Loaded: loaded (/etc/init.d/codedeploy-agent; generated)
   Active: inactive (dead)
     Docs: man:systemd-sysv-generator(8)

켜져있는 경우는 이렇게 나옴

● codedeploy-agent.service - LSB: AWS CodeDeploy Host Agent
   Loaded: loaded (/etc/init.d/codedeploy-agent; generated)
   Active: active (exited) since Fri 2020-06-12 01:57:09 UTC; 3s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 31065 ExecStart=/etc/init.d/codedeploy-agent start (code=exited, status=0/SUCCESS)

Jun 12 01:57:08 ip-10-0-1-61 systemd[1]: Starting LSB: AWS CodeDeploy Host Agent...
Jun 12 01:57:09 ip-10-0-1-61 codedeploy-agent[31065]: Starting codedeploy-agent:
Jun 12 01:57:09 ip-10-0-1-61 systemd[1]: Started LSB: AWS CodeDeploy Host Agent.

IAM Role 만들기

EC2에서 CodeDeploy, S3에 접근 가능한 role

CodeDeploy의 role

EC2 인스턴스와 CodeDeploy에 생성한 role을 부여해주면 된다.

CodeDeploy만들기

만들고, 배포그룹 설정

  • 아까 만든 role 부여
  • 현재 위치
  • Amazon EC2 인스턴스 선택
  • 배포구성은 AllAtOnce
  • 로드밸런싱 Off

Jenkins Credentials 제대로 설정하기

docker에 exec으로 접근합니다.

cd ~
mkdir .ssh
ssh-keygen -t rsa -f ~/.ssh/id_rsa_{project_name}
# passphrase는 편의상 입력하지 않음

ssh key가 생성되었습니다.

Jenkins에 접속한 다음, Credentials를 클릭합니다.

그 다음 System으로 들어갑니다.

그 다음 Global credentials 클릭

Add Credentials 클릭

생성된 SSH 키를 등록해줍니다. 참고로 공개키가 아닌 private key를 등록해야합니다.

근데, 다른 글을 보니 다른 옵션이 없던데 새로운 버전으로 올라오면서 누락된 것인지 Private key를 직접 입력해야한다는 점은 아쉬웠습니다.

아래와 같이 생성되면 완료된 것입니다.

github에 deploy key로 등록을 해봅시다.

github repository → Settings tab → Deploy keys 탭에 접근합니다.

그 다음 Add deploy key 버튼을 클릭합니다.

그 다음 공개키를 입력합니다.

공개키는 노출되어도 상관 없습니다.

jenkins에서 push를 할 일은 없으므로 write access는 사용하지 않습니다.

Jenkins Deploy Key가 생성되었습니다.

IAM에 Jenkins가 Code Deploy에 접근할 수 있게끔 유저와 권한을 줍니다.

권한은 Custom 권한을 줄 것 입니다. 정책 생성을 클릭해주세요.

{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": ["codedeploy:*", "s3:*"], "Resource": "*"}]}

위의 내용을 복사해서 넣습니다.

그리고 생성된 정책을 유저에게 부여합니다.

Access Key와 Secret을 잘 기억합니다.

Jenkins CodeDeploy 플러그인을 설치합니다.

CD용 Deploy Job을 생성합니다.

OK 클릭

이 부분이 중요합니다.

CodeDeploy의 Application Name, 배포 그룹 이름 그리고 배포 설정이 있는데, Code Deploy에서 순서대로 입력해주시면 됩니다. 배포 설정은 링크를 참조해주세요. 리전은 한국의 경우 저 설정 그대로 가주시면 됩니다.

S3의 경우 버킷명과 Prefix를 따로 지정해주고 싶다면 생성후에 지정합니다.

Include Files는 동작되고 있는 directory를 기준으로 합니다.

Access/Secret Key를 잘 기억하고 있으셨나요? 여기서 입력해주시면 됩니다.

Save를 누르고, 빌드를 테스트하시면 모든 작업이 끝납니다.

고생하셨습니다.

빌드 뱃지 생성

https://www.youtube.com/watch?v=clQEdNdOBm0

여기에 아주 잘 나와있다.

profile
코드리뷰와 고양이를 좋아하는 개발자입니다. 좋은 글을 위한 비판은 언제든 환영합니다.

0개의 댓글