AWS에 처음부터 배포하기 2) Docker와 Jenkins 설치

Yeshin Lee
8 min readAug 23, 2024

--

지난 포스트에서 생성한 EC2에 Jenkins를 넣어볼 것이다.

왜냐면.. 써보고 싶으니까!

Jenkins는 애플리케이션의 build, 테스트, 배포를 자동화하고 모니터링하는 오픈소스 CI/CD 도구다. 지속적 통합(Continuous Integration, CI) 및 지속적 배포(Continuous Delivery, CD)를 의미하는 CI/CD는 휴먼 에러를 예방하면서 개발 일정을 일정하게 유지하는 데 도움이 된다고 한다.

그러면 배포는 왜 자동화해야 할까?

코드를 변경할 때마다 실행해야하는 build, test, realease 시간을 줄이는 것이 제일 크다. Jenkins는 코드가 변경될 때마다 위 과정들을 자동으로 실행해 배포 주기가 단축시킨다. 이는 곧 코드 품질을 유지하면서 빠르게 배포할 수 있는 환경을 조성한다.

Jenkins는 Java로 작성된 서버라 Java 기반의 환경이나 Docker를 사용하여 설정할 수 있다. 나는 Docker를 사용하여 Jenkins를 설치할 것이다.

시작하기에 앞서, EC2의 보안 그룹 인바운드 규칙에 Jenkins(8080 port)를 추가해놔야 한다.

  • Type: Custom TCP Rule
  • Protocol: TCP
  • Port Range: 8080
  • Source: 0.0.0.0/0

Source 형식의 0.0.0.0/0은 모든 IP 주소에서의 접근을 허용한다는 것을 의미한다.

SSH를 통해 인스턴스에 접속

ssh -i your-key.pem ec2-user@[your-ec2-public-ipv4-ip]

위 명령어를 실행했을 때 접속이 안되고 이런 문구가 보일 수 있는데

SSH 키 권한이 느슨하게 설정되어있어 SSH에서 접속을 거부하는 것이다.

해당 key의 읽기 권한을 소유자에게만 부여함으로써 해결할 수 있다.

chmod 400 ~/[your-key].pem

접속에 성공하면 새 한마리가 반겨주면서 인스턴스의 Private IP DNS name가 보인다.

dnf를 사용하여 docker 설치

왜 dnf로 설치하냐? dnf가 yum보다 확장성이 넓은 것도 있지만 진짜 이유는 아래에 있다.

# update linux
sudo dnf update -y

sudo dnf install dnf-plugins-core -y
sudo dnf config-manager --add-repo <https://download.docker.com/linux/centos/docker-ce.repo>

# Error!
sudo dnf install docker-ce docker-ce-cli containerd.io -y

SSH로 접속할 때마다 가장 먼저 실행하는 행동이 리눅스를 업데이트하는 것인데, 모바일 애플리케이션을 주기적으로 업데이트하는 이유(보안이나 신기능 추가, 의존성 관리 등)와 같다고 보면 된다.

마지막 명령어를 실행하는데 에러가 발생했다.

centos 2023 지원이 종료돼서 404로 뜨는 것 같다.

AL2023에서는 dnf로 docker package를 설치해야 한다고 한다.

# docker 설치
sudo dnf install -y docker

Docker를 시작하여 몇 가지 설정 부여

# 1. Docker 데몬 수동으로 시작
sudo systemctl start docker

# 2. 시스템 부팅 시 Docker 데몬이 자동으로 시작
sudo systemctl enable docker

# 3. ec2-user가 Docker 명령어를 sudo 없이 실행할 수 있도록 권한 부여
sudo usermod -aG docker ec2-user

변경 사항 적용

exit 명령어로 SSH 세션을 종료 후, 다시 접속한다.

systemctl status docker 명령어로 도커가 실행되고 있는지 확인할 수 있다.

앞서 실행한 2, 3번째 명령어덕분에 sudo 명령어 없이 도커 데몬이 자동으로 시작한다.

docker에 jenkins를 pull받는다.

자세히 말하자면, 도커 허브에서 jenkins LTS 버전을 포함한 jenkins/jenkins:lts 도커 이미지를 다운로드 받는다. 해당 이미지를 사용하면 Jenkins 서버를 실행할 수 있다.

# LTS 버전 중 가장 최신 버전(24년 8월 7일 기준, 2.462.1) 다운
docker pull jenkins/jenkins:lts

Jenkins에는 LTS (Long-Term Support)와 Weekly 두 가지 릴리즈 버전을 가지고 있다.

  • LTS: 안정성과 장기적인 지원을 보장하는 버전
  • Weekly: 최신 기능과 개선 사항이 포함된 버전

Jenkins 컨테이너 실행

Jenkins를 Docker 컨테이너로 실행하며, Jenkins가 호스트의 8080 포트를 통해 웹 인터페이스를 제공하도록 설정한다.

docker run -d -p 8080:8080 -p 50000:50000 --name jenkins --restart=on-failure -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts
  • docker run: 새로운 컨테이너(Jenkins 이미지 기반으로 생성된 도커 컨테이너)를 생성하고 실행한다.
  • -d: 컨테이너를 백그라운드에서 실행한다.
  • -p 8080:8080: 호스트(Jenkins)의 8080 port를 컨테이너의 8080 포트에 매핑한다. 이 설정으로 호스트의 웹 브라우저에서 http://<호스트-IP>:8080으로 접근할 수 있다.
  • -p 50000:50000: 호스트의 50000 포트를 컨테이너의 50000 포트에 매핑한다. 해당 포트는 Jenkins의 agent/slave 노드가 master 노드와 통신할 때 사용한다.
  • --name jenkins: 생성되는 컨테이너의 이름을 jenkins로 지정한다.
  • --restart=: 도커 컨테이너가 종료되거나 재시작할 때, 컨테이너가 자동으로 시작되도록 설정한다(자동 복구 기능). 나는 컨테이너가 오류로 인해 종료됐을 때만 재시작하도록 on-failure로 설정했다.
  • -v jenkins_home:/var/jenkins_home: jenkins_home이라는 도커 볼륨을 컨테이너의 /var/jenkins_home 디렉터리에 마운트한다. 만약 jenkins_home이 존재하지 않는다면, 명령어 실행시 도커가 자동으로 jenkins_home이라는 도커 볼륨을 생성한다.
  • jenkins/jenkins:lts: 사용할 Docker 이미지를 지정한다.

docker ps를 통해 docker 컨테이너가 제대로 실행되고 있는지 확인한다.

Jenkins 초기 관리자 비밀번호 확인

Jenkins 웹 인터페이스에 처음 로그인할 때 사용한다.

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
  • docker exec: 컨테이너에서 명령을 실행한다.
  • jenkins: — name로 지정했던, 명령어를 실행할 대상 컨테이너의 이름
  • cat /var/jenkins_home/secrets/initialAdminPassword: Jenkins GUI에서 초기 설정 시 필요한 관리자 비밀번호가 저장된 파일의 내용 출력

Jenkins 웹 브라우저에 접속하여 초기 설정 진행

http://[ec2-public-ipv4-address]:8080에 접속한다.

저 password 칸에 비밀번호를 입력한다.

좌측의 기본적으로 설치되어야 할 패키지만 선택한다.

그러면 이렇게 설치하고 있는 것들이 보이는데

하나빼고 다 실패했다.

가장 먼저 의심가는 부분은 현재 8GiB로 설정되어 있는 EC2 볼륨 용량이다.

(Free tier 사용자는 30GiB까지 무료이므로) 일단 볼륨부터 올려보고 재시도해봐야겠다.

--

--