Jenkins
이전 글
우리는 이전 포스팅들에서 Ansible이 무엇인지, 왜 사용하는지, Ansible의 Playbook을 알아보며 학습했다.
이제는 학습한 Ansible과 Jenkins를 연동해보자.
Jenkins + Ansible 연동
Jenkins와 Ansible을 연동하기 위해서는 우선 Jenkins에 Ansible Server에 접근할 수 있도록 설정을 해주어야 한다.
설정은 아래 사진과 같다.
Jenkins 관리 -> System -> Publish Over SSH(플러그인 설치) -> 구성
이전 포스팅에서도 설명해왔지만, 추가로 설명하자면
- name: 접속할 서버의 이름
- Hostname: IP Address
- 필자는 도커로 Ansible를 설치했기에 아래 명령어로 docker 컨테이너의 IP Address를 확인했다.
- docker network inspect bridge
- username: 접속할 유저의 이름
- Remote Directory: 접속할 디렉토리 경로
- . 이면 해당 유저의 홈 디렉토리이다.
그리고 고급을 클릭하면 Password를 사용하여 접속이 가능한데 필자의 경우 키를 사용하는 것이 아닌 Password를 사용했다.
고급 탭에선 포트 지정, 커넥션 타임 유지 지정 등 여러 작업이 가능하다.
자, 이제는 ansible-server를 jenkins에서 접속할 수 있도록 구성했다.
Jenkins Item를 만들어 직접 사용해보자.
Jenkins Item 생성
Item을 생성하는 것은 기존과 동일한 방법으로 진행한다.
https://hdbstn3055.tistory.com/125
[Jenkins] Jenkins를 이용한 CI/CD 자동화 사용
Jenkins 우리는 앞선 글에서 Jenkins를 통해 어떻게 빌드하는지를 알아보았다. 빌드가 성공적으로 완료되었다면 우리는 Tomcat 서버에 배포하거나 SSH 서버를 이용하여 배포를 할 수 있게 된다. 1.
hdbstn3055.tistory.com
실행할 Ansible Playbook 생성
성공적으로 Item을 구성했다면 이제는 Jenkins에서 Ansible 서버에 호출할 Playbook을 만들어보자.
ansible-playbook.yml 작성
- hosts: all
# become: true
tasks:
- name: build a docker image with deployed war file
command: docker build -t cicd-project-ansible .
args:
chdir: /root
- name: create a container using cicd-project-ansible image
command: docker run -d --name my_cicd_project -p 8080:8080 cicd-project-ansible
- hosts: 전체 호스트를 지정한다.
- tasks: 작업 목록들을 나열한다.
- 작업 1: Dockerfile를 사용하여 cicd-project-ansible이라는 이름의 이미지를 생성한다.
- args: chdir: /root <- 해당 커맨드가 작업할 위치를 지정하는 것으로 여기서는 /root로 하였다.
- 작업 2: 생성한 이미지를 토대로 도커 컨테이너를 구동한다.
- 여기서는 8080:8080 포트를 사용하도록 하였는데
- 만약, Ansible 서버가 도커로 구성되어있다면 해당 실제 Host PC에서 Ansible 도커 컨테이너를 기동할 때
포트포워딩을 해주자.
- 작업 1: Dockerfile를 사용하여 cicd-project-ansible이라는 이름의 이미지를 생성한다.
사용한 Dockerfile
FROM tomcat:9.0
COPY ./hello-world.war /usr/local/tomcat/webapps
COPY 명령어를 활용해 Maven Build된 war 파일을 이미지 내의 /usr/local/tomcat/webapps 경로로 복사한다.
Dockerfile은 무엇일까?
우리가 만든 우리의 애플리케이션을 이미지로 만든다고 가정해보자. 비어있는 도커 OS 이미지 생성 Git clone을 통해 해당 소스코드를 OS(우분투) 이미지 내로 복사 소스코드 담겨있는 우분투 이미
hdbstn3055.tistory.com
사용한 인벤토리 파일
자, 여기까지 ansible-playbook.yml 및 인벤토리 파일을 구성했다. 그러면 Jenkins에서 관련하여 구성해보자.
Jenkins Item 구성
Jenkins Item 구성은 앞선 포스팅에 진행했던 대로 하면되고 중요한 것은 빌드 후 조치이다.
우리는 ansible-server를 Jenkins 시스템 구성에 등록해놓았다.
따라서, 빌드 후 조치 파트에서 Send build artifacts over SSH 위와 같이 구성해주도록 하자.
여기서 중요한 것은 Exec command 부분이다.
우리는 Ansible Server에 Playbook 파일을 만들어놓았고 이제 그걸 Jenkins에서 실행해야 한다.
따라서, 빌드 한 파일을 복사한 뒤 아래 명령어로 만들어놓은 Playbook 파일을 실행하도록 했다.
ansible-playbook -i hosts {생성한 playbook.yml 이름}
Item을 저장 후 실행해보자.
Jenkins Item 빌드
Item 빌드를 진행했을 때 정상적으로 성공한걸 확인할 수 있고
기존에 없던 도커 이미지와 도커 컨테이너가
잘 생성된 것을 확인할 수 있다.
근데 여기서 문제점은 위 Jenkins Item을 두번 빌드하면 UNSTABLE 상태로 빌드가 실패하게 된다.
이유는 이미 동일한 이름의 도커 컨테이너가 구동되어있는데 같은 이름으로 또 생성하려고 하기 때문이다.
그래서, 다음과 같은 내용을 ansible-playbook.yml에 추가해주자.
- hosts: all
# become: true
tasks:
- name: stop current running container
command: docker stop my_cicd_project
ignore_errors: yes
- name: remove stopped cotainer
command: docker rm my_cicd_project
ignore_errors: yes
- name: remove current docker image
command: docker rmi cicd-project-ansible
ignore_errors: yes
- name: build a docker image with deployed war file
command: docker build -t cicd-project-ansible .
args:
chdir: /root
- name: create a container using cicd-project-ansible image
command: docker run -d --name my_cicd_project -p 8080:8080 cicd-project-ansible
여기서, ignore_errors는 오류를 무시하겠다는 옵션으로, 만약 도커 컨테이너가 구동이 안되어있다면
삭제하려고 했을 때 오류가 발생할 것이므로 위와 같은 옵션을 지정해주었다.
도커 컨테이너 동작 확인
http://{자신이 설정한 Ansible Server 경로}:{PORT}/hello-world로 접속하면 성공한 것을 알 수 있다.
(필자는 이도원 강사님의 인프런 강의를 보고 만들었기에 Maven 빌드된 hello-world.war 파일을 사용하였다.)
(WAR로 패키징 했기 때문에 Tomcat 서버를 사용하였다. 따라서, 경로 및 환경은 자신에 맞게 설정하면 된다.)
정상적으로 동작함을 확인했다.
Ansible 서버에서는 이미지 빌드 및 Registry 저장, Docker 서버에서 컨테이너 구동을 하는 경우
우리는 위에서 도커 이미지 빌드 및 도커 컨테이너 실행과정을 전부 Ansible 서버에서 진행을 했다.
이렇게만 놓았을 때는 Ansible의 주요 기능인 다른 host들 관리라는 내용이 퇴색되기에 관련하여 구성해보자.
Item 생성과정은 거의 비슷하며 Exec Command 부분만 새롭게 생성한 playbook을 실행하도록 하면 된다.
playbook을 만들어보자.
이미지 빌드 및 Registry Push Playbook 생성
- hosts: all
# become: true
tasks:
- name: create a docker image with deployed waf file
command: docker build -t {username}/cicd-project-ansible .
args:
chdir: /root
- name: push the image on Docker Hub
command: docker push {username}/cicd-project-ansible
- name: remove the docker image from the ansible server
command: docker rmi {username}/cicd-project-ansible
ignore_errors: yes
Docker Hub에 올릴 본인의 계정 이름을 적절히 정해주면 된다.
다른 호스트에 실행시킬 도커 컨테이너 생성 Playbook
- hosts: all
# become: true
tasks:
- name: stop current running container
command: docker stop my_cicd_project
ignore_errors: yes
- name: remove stopped cotainer
command: docker rm my_cicd_project
ignore_errors: yes
- name: remove current docker image
command: docker rmi {username}/cicd-project-ansible
ignore_errors: yes
- name: pull the newest docker image from Docker Hub
command: docker pull {username}/cicd-project-ansible
- name: create a container using cicd-project-ansible image
command: docker run -d --name my_cicd_project -p 8080:8080 {username}/cicd-project-ansible
Exec Command 변경
ansible-playbook -i hosts create-cicd-project-image-playbook.yml --limit 172.17.0.3
ansible-playbook -i hosts create-cicd-devops-container-playbook.yml --limit 172.17.0.4
여기서 --limit 옵션은 hosts 인벤토리 파일에서 특정 IP 및 그룹으로 제한할 때 사용된다.
주의해야 할 점은 Ansible Server가 해당 호스트에 접근할 수 있어야 한다는 것이다.
(관련된 내용은 이전 포스팅을 참고하면 된다.)
https://hdbstn3055.tistory.com/131
[Jenkins] Docker 컨테이너로 Ansible 실행하기
Ansible 설치먼저 Ansible를 설치할 도커 리눅스 환경을 구성해야 한다.해당 리눅스 환경 구성과 관련해서는 다음 포스팅을 참고하면 된다 -> SSH, Docker 도커 이미지 구성 (후술할 내용은 나의 리눅
hdbstn3055.tistory.com
https://hdbstn3055.tistory.com/143
[Jenkins] Ansible 기본 명령어
이전 글우리는 이전 포스트에서 Ansible를 리눅스 서버에 설치해보았고 정상 동작함을 확인했다.Ansible에서 /etc/ansible/hosts 경로에 여러 호스트를 등록할 수 있었고,해당 호스트들에게 아직은 설명
hdbstn3055.tistory.com
정리
Jenkins와 Ansible을 연동하여 도커 이미지를 빌드하고 도커 컨테이너를 배포해보았다.
블로그 포스팅에서 딥하게 다루진 않았지만, Jenkins와 Ansible을 잘 연동하면 수많은 서비스들이 존재하는
큰 프로젝트에서 요긴하게 사용할 수 있을 것이라 생각한다.
- Ansible을 활용해서 도커 이미지만을 빌드하는 호스트에 요청
- 특정 서비스를 담당하는 호스트 CI/CD시 Jenkins로 CI 후 Ansible를 사용해 해당 호스트에 CD 작업
위의 예시뿐이 아니라 많은 작업이 가능하다고 생각한다.
참고
'Infra > Jenkins' 카테고리의 다른 글
[Jenkins] Jenkins + SonarQube 사용 (0) | 2024.08.01 |
---|---|
[Jenkins] Jenkins의 여러 Pipeline 작업 (0) | 2024.07.31 |
[Jenkins] Ansible Playbook 사용 (0) | 2024.07.30 |
[Jenkins] Ansible 기본 명령어 (0) | 2024.07.30 |
[Jenkins] Docker 컨테이너로 Ansible 실행하기 (0) | 2024.07.21 |