Final Goal
젠킨스를 활용하여 CI/CD를 구축하는 것이다. HTTPS에 공개키 비밀키 통신을 원리를 아는사람은 이 플로우가 이해될 것이다.
젠킨스 EC2
: Jenkins, DockerHub, JDK 11, Gradle 7.6.1(젠킨스에서 제공), Docker를 설치.배포 EC2
: JDK 11, Docker (각자의 스팩에 맞게끔…)
최종 서버구조 플로우
젠킨스 설치
가장 처음으로 해야하는 것은 당연하게도 EC2 인스턴스 2개를 만드는 것이다. 필자는 EC2 우분투로 EC2 두개를 만들었다. (참고로 앞으로 sudo 엄청 붙이는데 귀찮으면 sudo su 하고 써도 된다. 권장은 안함)
1
2
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
이렇게 하다보면 GPG 에러가 나올 수 있는데 서명검증이 안된것이니… 아래와같이 입력한다.
1GPG error: https://pkg.jenkins.io/debian-stable binary/ Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY [16자리키]
로그에 뜬 16자리를 복사해서 아래와 같이 명령어를 넣어주면 된다.
1
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys [16자리키]
그 후… 젠킨스를 업데이트하고 재시작하면된다.
1
2
3
sudo apt-get update
sudo apt-get upgrade jenkins
sudo systemctl restart jenkins
모든 설치가 완료 되었으면 아래의 명령어를 통해 active 중인지 확인하면 된다.
1
systemctl status jenkins
젠킨스 설정
젠킨스를 접속하기 위해선 {EC2 퍼블릭 IPv4 DNS}:8080 으로 접속하면 아래와 같은 화면이 나온다.
이때 비밀번호를 입력하라고 하는데 아래의 명령어를 입력해서 나온 비번을 복붙하자
1
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
그 후, Install suggested plugins을 선택하고 설치를 하면 젠킨스를 사용할 수 있는 기본적인 세팅이 된다. 어차피, 필요한게 있다면 추후 설치하면된다.
젠킨스를 깃헙에 접근 하는 권한주기
젠킨스가 github repository에 접근하려면 github에 배포키를 등록해야한다. 그러므로 젠킨스 ec2에서 SSH키를 만들어야한다.
1
2
$ sudo mkdir /var/lib/jenkins/.ssh
$ sudo ssh-keygen -t -rsa -f /var/lib/jenkis/.ssh/[키명칭]
그 후, 깃헙 repo에서 Settings > Deploy Keys > Add deploy key 를 통해서 우리가 만든 SSH키를 등록한다.
title
은 본인이 식별가능한 값 key는 [키명칭].pub 을 cat해서 복붙. .pub
공개키 아무것도 없으면 비밀키
젠킨스 Credential 등록하기
공개키를 Github에 등록했으니, 이제 우린 그걸 복호화할 비밀키를 젠킨스에게 등록해야한다. Jenkins관리 -> Manage Credentials -> Stores scoped to Jenkins 에서 아래와 같이 Add Credentials
을 클릭한다.
필자는 Credentials에 key가 많은게 추후 빌드 시, 숨겨놓은 키 값을 전달 받기 위해 설정해둔 것이다. 다 완성되면 맨 위처럼 지문 모양의 SSH키등록이 보일 것이다.
본론으로 돌아가서 앞서 만든 프라이빗키를 복사해온다.
1
2
3
4
5
$ cat [키명칭]
-----BEGIN OPENSSH PRIVATE KEY-----
비밀키 내용들
-----END OPENSSH PRIVATE KEY-----
Kind
는 SSH Username with private key, ID
는 식별가능한 크레덴셜 ID 그리고 복사해온 데이터를 Private key에 ADD하고 생성하면 끝!
젠킨스 ec2와 배포서버 ec2 SSH 연결
젠킨스가 설치된 ec2
에서 PEM 형식의 키를 만든다.
1
ssh-keygen -t rsa -C "키이름" -m PEM -P "" -f /var/lib/jenkins/.ssh/[키이름]
젠킨스 ec2에서 만든 SSH키의 공개키를 배포서버에 등록한다.
1
$ sudo cat /var/lib/jenkins/.ssh/[키명칭].pub //젠킨스 ec2
나온 데이터를 복사한 후
1
$ sudo nano .ssh/authorized_keys //배포서버 ec2
붙여넣기를 한다. 이 작업을 통해 젠킨스가 배포서버에 접근할 권리를 얻었다.
젠킨스 Publish Over SSH 플러그인 설치
Jenkins 관리-> 플러그인 관리 -> Available plugins 에서 Publish Over SSH 검색 후 설치한다.
설치 후 Jenkins 관리 -> Configure System에서 Ctrl+F
Publish over SSH를 검색하면 아래와 같은 곳을 볼 수 있는데…
Path to key
배포 ec2에게 준 공개키를 읽기 위한 비밀키를 보관한 곳의 경로를 입력하고 Key
에는 비밀키 내용을 복붙한다.
SSH Server 추가 버튼을 누르면…
아래의 이미지와같이 추가하면된다. Hostname을 백엔드 인스턴스 IP주소라고 했는데 배포서버 IP주소라고 생각하면된다. aws 인스턴스 대시보드 가면 있다. 모든 내용을 입력한 후 TEST Configuration을 진행해서 확인한다.
자 여기까지가 젠킨스와 배포서버, Github과의 통신이 연결된 것이다. 다음으론 도커로 배포하기 위해 도커를 설치하자.
DOCKER 설치 + Docker Hub repo 만들기
설치를 위해서 apt 업데이트를 하자. 그 후 HTTPS 프로토콜을 통해 안전하게 패키지를 다운로드하고 SSL/TLS 인증서를 받아올 수 있도록 도와주는 패키지들을 설치하는 명령어를 입력한다. 그 후 변조된 데이터 방지 및 컴퓨터를 보호하기 위해 GPG 키를 설정한다. 안하면 도커가 설치가 안될 것이다.
1
2
3
4
5
6
7
8
$ sudo apt update //우분투 패키지 인덱스 업데이트
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common //HTTPS를 통해 패키지 다운로드를 지원하는 패키지 설치
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - //Docker GPG 키 추가
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" //Docker repo 추가
$ sudo apt-get install docker-ce docker-ce-cli containerd.io //docker Ce 설치
$ sudo systemctl start docker // 도커 재시작
도커를 설치한 후 docker Hub에 들어가서 도커 이미지를 저장할 Repo를 생성하면 도커의 세팅은 끝난다.
젠킨스 빌드 결과물을 도커로…
여기서 잠깐! 본인이 프리티어 ec2면 꼭 swap 메모리를 설정하자
swap 메모리 설정
1
2
3
4
5
6
7
8
9
10
$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16 //스왑 파일 생성 프리티어의 메모리는 1GB이니, 권장사항대로라면 2GB를 증설
$ sudo chmod 600 /swapfile // 스왑 파일에 대한 읽기 및 쓰기 권한을 업데이트
$ sudo mkswap /swapfile //Linux 스왑 영역을 설정
$ sudo swapon /swapfile //스왑 공간에 스왑 파일을 추가하여 스왑 파일을 즉시 사용할 수 있도록 만든다
$ sudo swapon -s //절차가 성공했는지 확인
$ sudo nano /etc/fstab // /etc/fstab 파일을 편집하여 부팅 시 스왑 파일을 활성화
/swapfile swap swap defaults 0 0 // <<해당 내용을 입력한다.
$ free 명령어를 통해 swap 메모리 설정을 확인한다.
이제 정말 다왔다. 젠킨스 빌드 결과물을 도커로 전송하기만 하면 끝난다. docker 그룹에 젠킨스을 추가하여 도커허브에 빌드한 이미지를 푸쉬할 수 있도록 세팅을 해야한다.
1
2
3
4
5
6
7
8
9
10
11
$ sudo usermod -aG docker $USER //도커 그룹에 현재 사용자 추가 여기선 $USER = jenkins로해도 무방하다.
$ su - ${USER} //새 그룹 구성원 자격을 적용, 명령어 입력시 유저 암호를 입력해야함
$ id -nG //를 통해 사용자가 잘 추가 됐는지 확인
// jenkins docker
$ sudo chmod 666 /var/run/docker.sock //도커 서버와 도커 클라이언트 간의 통신을 위한 Unix 소켓 파일의 권한변경
//젠킨스에서 Docker hub로 로그인 해야할 권한설정
$ sudo su - jenkins
$ docker login
이로써 젠킨스은 도커의 acess 권한까지 얻은 것이다. 자 이제 이 모든걸 정리하는 단계가 남았다.
젠킨스 빌드 과정 설정 .feat jenkins item
새로운 ITEM
을 클릭하면 아래와 같은 페이지가 나온다. 한번에 많은 이미지를 동시에 배포하고 순서에 따라 배포를 해야하면 Pipeline을 이용해서 배포하면 된다. 하지만 여기선 Freestyle project를 통해서 배포를 할 예정이다. 도커에서 redis는 이미 계속 실행중이기 때문에 굳이 pipeline까지 필요없었다. item name은 본인이 원하는데로!!
우선 가장 처음으로 해야하는 것은 소스관리 탭에서 Github repo URL을 지정하는것이다. 그 후, 앞서 설정했던 깃헙 Credentials를 선택한다.(아마 처음 하시면 한개만 있을 것이다.) 그리고 우린 프론트와 같은 repo를 쓰기때문에 main 브랜치가 아닌 백엔드 브랜치를(*/bedev) 이용해서 작업을 진행했다.
Delete workspace before build starts
를 체크해야 작고 소중한 EC2 용량을 아낄 수 있다.
Send files or execute commands over SSH after the build runs
을 클릭한다.
1번에다가 아래의 내용을 입력한다.
1
2
3
4
5
6
sudo docker pull ${docker hub name}
sudo docker stop ${docker name} || true && sudo docker rm ${docker name} || true
sudo docker run -d --network="host" --name ${docker name} -p {배포 서버 포트}:{젠킨스 서버 포트} -p {레디스 서버 포트}:{젠킨스 ec2 레디스 서버 포트} -e "REDIS_HOST=localhost" ${docker hub name} // redis가 localhost를 못 찾을때 하는 설정이다.
sudo docker run -d --name [containerName] -p 8080:8080 [dockerHub UserName]/[dockerHub Repository]:[version] // redis를 사용하지않는다면 이 명령어를 입력하면된다.
Build 탭에서 Add build step > Execute shell 선택하여 명령어를 입력한다.
1
2
3
4
5
6
7
8
9
// 2
sudo chmod +x ./be/gradlew // 프로젝트의 gradlew의 권한을 부여한다.
cd /var/lib/jenkins/workspace/asap/be // 저장되어 있는 프로젝트 위치를 찾는다.
./gradlew clean build //
// 3
sudo docker build -t {dockerHub UserName} -f {/dockerHub Repo경로/Dockerfile} .
sudo docker push {dockerHub UserName}
대망의 자동배포 설정
플러그인 설치
Jenkins 관리-> *플러그인 관리 *->** Available plugins 에서 github **Integration을 설치한다. **
젠킨스 webhook 설정
해당 프로젝트 item에서 빌드 유발 탭에서 GitHub hook trigger for GITScm polling
체크한다.
Github Webhook 추가
Settings > Webhooks > add Webhook을 통해 webhook을 추가한다.
Payload URL 설정
1
[구축서버 인스턴스 URL]:[젠킨스 PORT]/github-webhook/
content type은 application/json으로 설정한다.
이것으로 CI/CD가 완성되었다~~~