이전 포스팅은 여기로
2024.07.01 - [Dev/CI&CD] - Jenkins, Ansible로 CI/CD 구축하기 (1/2)
들어가기 전에
이전 게시글에서는 CI/CD의 등장배경과 실습에 사용할 Jenkins, Ansible에 대한 내용을 간략히 정리했다. 이번 글에서는 실제로 Jenkins를 구축하는 방법에 대해 기술하려고 한다. 기본적인 가상환경 컨테이너의 개념과 서버 간 통신 방식을 알고 있음을 전제로 작성할 예정이므로 해당 키워드에 대한 이해가 부족하다면 다소 불친절할 수 있다.
그 외의 개발 환경은 다음과 같다.
개발환경
Os : MacOs 14.4.1(23E224)
CPU : Apple Silicon M3
추가)
작성하다 보니 내용이 길어져서 ansible 연동은 3편으로 뺐다.
Docker Desktop 설치
Jenkins를 docker에 설치하기 위해서 docker desktop macOS를 설치했다. macOS의 경우 내장된 칩에 따라 설치 파일이 다르니 주의해서 다운받아야 한다.
나는 Apple Silicon M3를 사용하고 있기 때문에 Apple Silicon을 선택해서 다운로드했다.
* docker desktop 이란?
Docker Desktop은 개발자가 컨테이너화된 애플리케이션을 로컬에서 쉽게 개발, 테스트 및 디버그 할 수 있도록 도와주는 애플리케이션이다. 이는 특히 Docker 플랫폼을 사용하여 애플리케이션을 관리하고 배포하는 데 유용하다. Docker Desktop은 Windows, macOS, 그리고 Linux 환경에서 사용할 수 있으며, 여러 가지 유용한 기능들을 제공한다.
Jenkins 기본 설치
이제 Jenkins를 다운받아 보자. 아래 링크를 참조하여 docker image를 다운받았다.
docker pull jenkins/jenkins:lts-jdk17
image가 다운로드가 되었다면 순차적으로 아래 명령어를 실행한다.
// 포그라운드에서 실행할 경우
docker run -p 8080:8080 -p 50000:50000 -name jenkins-server --restart=on-failure jenkins/jenkins:lts-jdk17
// 백그라운드에서 실행 할 경우
// -d 옵션을 추가하면 백그라운드에서 돌아가게 할 수 있다. 즉, 현재 실행한 터미널과 분리해서 실행된다
docker run -d -v jenkins_home:/var/jenkins_home -p 8080:8080 -p 50000:50000 --restart=on-failure jenkins/jenkins:lts-jdk17
포트 설정의 경우 상황에 맞게 변경해서 사용하면 된다. (자세한 내용은 여기로)
docker가 정상적으로 잘 실행되었다면 지정한 jenkins 포트로 접근해서 초기 비밀번호를 입력해줘야 한다. 나는 8080으로 설정했으므로 http://localhost:8080로 접속했다.
접속하면 다음과 같은 화면이 출력된다.
초기 비밀번호는 docker실행 시 발생하는 log를 확인하여 얻을 수 있다.
docker logs jenkins-server // docker log [설정한 서버 이름 혹은 id]
혹은 서버에 접속하여 /var/jenkins_home/secrets/initialAdminPassword 파일을 확인하면 된다.
// 컨테이너 접속 명령어
docker exec -it [container id 혹은 name] bash
초기 비밀번호까지 설정이 완료되면 Plugins설치에 대한 선택지가 출력된다.
Install suggested plugins와 Select plugins to install 중 원하는 것을 선택한다. 일반적으로 Install suggested plugins를 기본 값으로 사용한다.
이후 jenkins dashboard (관리자 화면) 접속 시 사용할 admin 계정정보를 설정하면 기본적인 Jenkins 세팅은 완료되었다고 할 수 있다.
* item : 젠킨스 작업의 최소 단위를 의미
* Jenkins jdk setting : docker image에 기본적으로 내장 jdk가 설정되어 있기 때문에 별도로 설정할 필요 없다
Jenkins 관리 > Plugins
정상적으로 Jenkins Dashboard에 로그인이 된다면 Jenkins 관리 > Plugins에서 필요한 plug-in들을 다운로드해줘야 한다.
나는 git을 사용하기 때문에 git 플러그인을 추가로 받았다.
- Github Branch Source Plugin
- Pipeline: Github Groovy Libraries
또한 간단한 웹서비스(war)를 외부 was 컨테이너에 배포하기 위한 플러그인도 추가했다.
- Deploy to container
- Publish over ssh → 배포 대상 파일을 ssh로 전송하기 때문에 필요하다
프로젝트가 어떤 build tool을 사용하냐에 따라 아래와 같은 플러그인을 추가할 수 있다.
- Maven Integration plugin → maven을 사용할 경우
- Gradle plugin → gradle을 사용할 경우
Jenkins를 사용한 간단한 웹 서비스 배포
이제 실제로 간단한 웹 서비스를 배포해 보자. 서비스 구성도는 다음과 같다.
Jenkins 서버는 다음과 같은 역할을 한다.
- Git에서 build 할 파일을 가져온 뒤, war 또는 jar로 압축 파일을 생성하여 was가 설치되어 있는 대상 서버(docker아이콘에 해당)로 전달한다
- 전송받은 파일을 실행한다
buildTool을 어떤 걸 사용하냐에 따라 jenkins 세팅 방법이 조금 다르다.
공통적으로 [Dashboard > Jenkins관리 > Tools]에 접속해서 기본설정을 할 수 있다.
- maven
- gradle
이제 좌측 상단에 있는 [새로운 item]을 선택해서 추가할 작업을 생성해 보자.
상단에 있는 [Enter an item name]에 작업 이름을 기재하고 [Freestyle project]를 선택했다.
[소스 코드 관리 > Git] 항목에서 다음과 같이 입력한다
Credentials(자격증명)이 필요한 경우에는 하단의 [+Add] > [Jenkins]를 선택해서 자격증명 정보를 업데이트할 수 있다.
출력되는 username, password에 github의 id, passwd를 기재하면 된다.
jenkins는 기재한 git repository에서 소스 파일을 pull 하여 빌드를 진행한다. 빌드 유발(build trigger) 옵션을 통해 언제 빌드가 주기적으로 진행될지에 대해서도 지정할 수 도 있다. 지원하는 옵션들은 다음과 같다.
- build periodically → 커밋이 없어도 주기적으로 빌드
- poll scm → 커밋 내용이 있을 때만 빌드
ssh로 전송한 배포 파일에 대해 docker 이미지를 생성하고 컨테이너를 실행하는 것까지 자동화될 수 있도록 [빌드 후 조치 추가] > [Send build artifacts over SSH]를 추가했다.
위에 기재된 docker-server 에는 war 파일 배포를 위한 tomcat 이미지와 Dockerfile 이미 세팅되어 있다. Dockerfile 에는 war 파일을 지정된 tomcat 폴더의 내부로 옮기는 명령어가 기재되어 있으므로 docker-server에서는 다음과 같은 순서로 실행된다.
- jenkins 서버에서 전달받은 배포 대상 파일(war) 수신
- docker build --tag=cicd-project -f Dockerfile → 대상 파일을 was(tomcat)의 배포 가능 경로로 이동
- docker run -d -p 8080:8080 --name mytomcat cicd-project:latest → tomcat containter 실행
* docker 간단한 명령어
docker ps // 실행되고 있는 컨테이너 확인
docker run // 컨테이너 실행
docker stop // 컨테이너 중지
docker ps -a // 중지된 컨테이너 확인
docker rm // 컨테이너 삭제
* docker 실행 순서
image 다운로드 혹은 image build → container run ( 컨테이너 실행 )
Trouble Shooting
- 설치 중 다른 문제점은 없었는데 docker hub에서 이미지를 다운로드해서 docker 실행을 하면 안 되는 경우가 있었다.
docker run에서 하단 옵션을 추가해서 해결했다.
--cgroupns=host
- --cgroupns=host
컨테이너 프로세스를 격리하기 위한 방법으로, Linux Namespace로 각각 컨테이너에서 실행된 프로세스가 시스템에 대해서 독립될 수 있도록 구현할 수 있으며, Linux의 cgroups를 사용해 각각의 컨테이너(프로세스)가 사용할 수 있는 시스템 리소스(CPU, 메모리, network bandwidth)를 제한함. namespace와 cgroups으로 리소스 사용을 공유하거나 격리되어 사용할 수 있는데, host 방식으로 Docker 호스트의 cgorup namespace를 지정하여 공유하여 사용할 수 있음.
ref.
'Dev > CI&CD' 카테고리의 다른 글
Jenkins, Ansible로 CI/CD 구축하기 (3/3) (0) | 2024.07.15 |
---|---|
Jenkins, Ansible로 CI/CD 구축하기 (1/3) (0) | 2024.07.01 |