SSAFY 9기 특화 프로젝트가 끝난 후 프로젝트 회고와 포스팅을 동시에 진행하려고 합니다.
이번 프로젝트에서 DevOps 포지션을 담당했으며, CI/CD 에피소드를 게시글로 풀어가보려 합니다.
총 4편으로 구성되며
1편. Jenkins 설치 <<현재 게시글
2편. Jenkins 환경설정
3편. GitHub연동 및 Http로 배포하기
4편. Https로 변경하기(feat. nginx)
5편. Blue-Green 무중단 배포 순서대로 포스팅 하겠습니다.
순서대로 포스팅 하겠습니다.
🚨주의사항🚨
- 도커 이미지는 인스턴스 이다. Volume을 마운트 하지 않는 경우 도커를 종료하게 되었을 때 설정 정보가 날아갈 수 있습니다.
볼륨, 마운트 경로 체크
docker inspect ${컨테이너 이름}
명령어 수행에서 Type : bind 이고 Source라는 경로로 도커 이미지를 마운트 해주면 정상적으로 데이터를 불러올 수 있다
사견
docker volume create ${볼륨이름}
명령어를 통해 도커 볼륨을 생성한 후 맵핑을 하는게 좋습니다.
=> 볼륨을 명시하지 않을 경우 해쉬값의 이름을 가지게 되는데 파일 관리가 조금 어려웠기 때문....
본격적으로 프로젝트의 아키텍쳐를 가볍게 훑어보겠습니다.
실행 프로세스는 다음과 같다.
gitlab, github에서 push가 발생
1. webhook을 이용해 jenkins script실행
2. Spring boot 프로젝트 / React 프로젝트 Build
3. 각 프로젝트 build 산출물로 dockerfile 생성 → docker image생성
4. image들을 docker-compose로 실행시킨다.
1. EC2에 접속
Windows : Windows Terminal, Termius, Putty 등
MacOS : Terminal, iTerm2 등
아래 링크를 통해 접속 방법을 확인할 수 있습니다.
2. ⛏ Docker & Docker-compose 설치(on EC2)
- EC2는 Ubuntu이기 때문에 Ubuntu 버전 도커를 설치한다.
- 공식문서(ubuntu 버전) 참고
# Add Docker's official GPG key:
$ sudo apt-get update $ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg`
# Add the repository to Apt sources:
$ echo
"deb \[arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg\] [https://download.docker.com/linux/ubuntu](https://download.docker.com/linux/ubuntu)
"$(. /etc/os-release && echo "$VERSION\_CODENAME")" stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose
- 이후 Docker-compose 설치 후 파일 권한을 수정한다.
- 설치 후 권한을 지정해주지 않으면 Permission에러 발생
sudo chmod +x /usr/local/bin/docker-compose
- 설치 결과 확인하기
$ docker -v
# Docker version 24.0.6, build ed223bc
$ docker compose version
# Docker Compose version v2.21.0
3. ⛏ Jenkins 설치(By. Docker)
- 프로젝트 Java의 버전이 11이기에 버전을 맞추고 환경을 통일하기 위해 Docker Image로 설치했습니다.
- 추가로 현재는 프리티어 계정이지만 추후 SSAFY에서 제공하는 EC2와도 동일하게 환경을 구성할 수 있다는 장점이 있습니다.
# 2버전 중 맞춰서 설치 권장
$ sudo docker pull image jenkins/jenkins:jdk11 # jdk 11버전으로 받는것
$ sudo docker pull image jenkins/jenkins:latest # 최신 버전으로 받는 것
4. Jenkins 실행
여기까지 설치를 진행했다면 1가지 문제가 있습니다.
- Jenkins : Tomcat 기반 실행 → 포트번호
8080
- Spring Boot : Tomcat 기반 실행 → 포트번호
8080
두 프로그램의 포트가 겹치기 때문에 서로의 포트를 변경해줘야합니다. 따라서 다음과 같이 Jenkins를 실행 시킬 수 있습니다.
Jenkins 포트 변경하기
$ docker run -d --name special_jenkins -p 9090:8080 -v jenkinsVolume:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -u root jenkins/jenkins:jdk11
# -v /var/run/docker.sock:/var/run/docker.sock : 호스트(EC2)에 설치된 Docker와 Jenkins에 설치된 Docker Daemon을 통일한다. 이 덕분에 DooD를 적용할 수 있게 됩니다.
# DooD : Docker Out Of Docker의 약어로 추후 설명드리겠습니다.
# -p 9999:9999 : 외부에서 접근할 포트번호:Jenkons opts로 설정한 jenkins포트 번호
4. Jenkins 초기화⚒
1. Jenkins 실행
- 도커 컨테이너는 1회용이다. 볼륨 혹은 마운트를 하지 않을 경우 다시 컨테이너를 실행시키면 기존 데이터가 날아갈 수 있다.
# jenkins 환경 설정 저장을 위한 볼륨 생성
$ docker volume create ${볼륨이름}
# jenkins 이미지 실행
$ docker run -d --name special_jenkins -p 9090:8080 -v jenkinsVolume:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -u root jenkins/jenkins:jdk11
$ docker run -d --name ${컨테이너 이름} -p ${호스트접근포트}:${도커내부접근포트} -v ${생성한 볼륨이름}:/var/lib/jenkins -v /var/run/docker.sock:/var/run/docker.sock -u root ${jenkins이미지명 (이미지명:태그) 형태로 입력하자]
# -d : 백그라운드에서 실행한다
# --name : 컨테이너 이름을 지정해준다
# -p : 포트 포워딩, 호스트로 접근하는 포트번호:도커 컨테이너 내부포트
# -v : 볼륨 바인딩, ${호스트 경로 or docker volume}:${도커 컨테이너 내부 저장소} <- 여러개 등록할 수 있다.
# -> 여기서는 도커 컨테이너 내부 저장소를 `var/lib/jenkins` 라고 지정
# -v /var/run/docker.sock:/var/run/docker.sock 해당 부분은 DooD를 구현하기 위해 적은 코드, 추후 설명
# -u : 실행되는 도커 프로세스의 사용자 지정
# jenkins:jdk11 : 실행시킬 docker image:tag
2. Jenkins 초기화
http://EC2의 퍼블릭 IP주소:${호스트로 접근하는 포트번호}
로 접근하면 다음과 같은 화면이 뜰 것이다.
- 다음과 같은 명령어를 통해 jenkins initialAdminPassword를 조회할 수 있고 input창에 입력하면 초기 설정을 할 수 있다.
docker exec ${jenkins 컨테이너 이름} cat /var/lib/jenkins/secrets/initialAdminPassword
# >>> output
# hash형태의 AdminPassword가 발급된다.
# 명령어 해석
# docker exec : 도커 컨테이너 내부에서 특정 명령을 실해하기 위한 명령어
# cat : 특정 파일의 내용을 조회한다.
3. Jenkins 관련 플러그인을 설치한다
- Install suggested plugins 클릭
4. 관리자 계정 생성
플러그인 설치가 완료되면 어드민 계정을 생성하는 페이지를 활용해 Admin 계정을 등록하자.
- Jenkins URL은 꼭 변경하기
- ID/PW까먹은 사람은 여기로
5. Jenkins 환경 설정🛠
- Jenkins 컨테이너에 Docker 설치
- Jenkins를 통해 Spring과 React를 Build, 배포하기 때문에 Jenkins에도 Docker를 설치해야한다.
- Jenkins 실행환경은 Linux(Debian)이므로 해당 링크를 통해 Do를 설치하자.
- 호스트OS에서 실행중인 Jenkins 컨테이너를 완전히 종료할 경우 Docker를 다시 설치해야하니 주의
$ apt-get update
$ apt-get install ca-certificates curl gnupg
$ install -m 0755 -d /etc/apt/keyrings
$curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ chmod a+r /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
$ apt-get update
$ apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose
Jenkins에도 Docker를 설치했다면 기본 설정은 끝났다..!
이제 Jenkins에 접속해서 GitHub 계정 등록과 Plugin을 설치해 CI/CD를 해보자
Jenkins에 접근하는 URL은 다음과 같다
http://${EC2 퍼블릭 IPv4}:${Jenkins 컨테이너 포트}