지금까지 우리는 Jenkins Server 1개를 생성하여 jenkins-server 측에서 모든 Build 및 배포 작업을 수행하였다.
이렇다 보니 Jenkins Server는 Poll SCM, Build, Test, Packaging, Deploy 등 모든 CI/CD 과정을 혼자 처리해야 했다.
Jenkins를 사용하는 사람이 1명이고 관리하는 Project도 1개라면 큰 문제가 없겠지만, 실제로는 그렇지 않다.
여러 명의 사람이 1개의 Jenkins Server에 접근하여 CI/CD 절차를 수행할 것이며 Jenkins 측에서 관리해야 하는 Project들도 매우 많을 것이다.
이렇게 1개의 Jenkins Server가 여러 명의 개발자와 여러 개의 프로젝트에 대한 이벤트 처리를 수행하다 보면 당연히 서버 측에 큰 과부하가 올 것이다.
그래서 이전에 Jenkins Server의 부하를 줄이도록 Master-Slave Architecture로 Jenkins를 구축한다고 언급했다.
Master는 Jenkins가 설치되어 있는 Jenkins Server를 의미하며 Jenkins Slave는 Jenkins가 설치되어 있지 않지만 Master가 처리해야 할 CI/CD 절차를 실제로 수행하는 Sub Node들을 말한다.
즉, Jenkins Slave란 Jenkins Master 원격에 존재하면서 Jenkins Master가 가지고 있는 요청 작업(Job)을 분배받아 실제로 Job을 수행하는 Server를 의미하는 것이다.
Jenkins Slave Server는 OS에 제한 사항이 없기 때문에 다양한 운영체제를 활용하여 Jenkins Slave를 구축할 수 있다.
그래서 A 작업이 Windows 특화, B 작업이 Linux 특화라면 A 작업은 Windows Slave에서, B 작업은 Linux Slave에서 수행하게 만들 수 있다.
※ 이번 실습은 다른 실습과는 다르게 Jenkins Server가 Docker Desktop 위의 Container로 구동되고 있음을 알고 있자.
docker run -itd --name jenkins-node1 -p 30022:22 ^
-e container=docker --tmpfs /run --tmpfs /tmp -v /sys/fs/cgroup:/sys/fs/cgroup:ro ^
-v /var/run/docker.sock:/var/run/docker.sock edowon0623/docker:latest /usr/sbin/init
우리는 docker-server Conatiner 생성 시 활용했던 Docker Image를 활용해 Slave Server를 구축할 것이다.
Port Number는 사용하지 않는 아무 값이나 입력해도 된다. 필자는 30022 Port Number를 활용했다.
Jenkins Master에서 Jenkins Slave에 접속할 때마다 Username & Password를 입력하도록 만드는 것은 효율적이지 않기에 ssh-keygen을 활용하여 Master에서 Slave에 바로 접속 가능하도록 만들자.
마지막으로 Java를 설치해줘야 한다.
Jenkins에서 처리해야 하는 Build 작업을 대신 수행할 수도 있는 Slave Server다 보니 Java가 설치되어 있지 않다면 아예 연결되지 않도록 Jenkins 측에서 막아놨다.
3번 과정에서 지정했던 Name으로 자동 입력됨
필수 입력값은 아님
Jenkins Master에서 Jenkins Slave에 접속하기 위한 방법 지정
Jekins Master에서 Slave로 SSH를 통해 접속하도록 방법을 지정해주는 것이다.
고급 버튼을 클릭하면 Port Number나 Java Path 등을 추가로 설정할 수 있다.
위에 띄웠던 Section 데이터를 채운 이미지는 Docker Desktop에 Jenkins Server Container를 구동시킨 상황에서의 설정이다.
우리는 Docker Desktop 위에서 여러 개의 Container를 만들었었다. 즉 1개의 Host 위에 여러 개의 Container가 존재하는 상황이었고 Jenkins Container와 Jenkins Slave Container도 같은 Host에 위치하고 있었다.
이런 상황이다 보니 Jenkins Container는 "ssh root@[slave Container IP Address]"를 통해서 바로 접속이 가능했다.
또한 이렇게 접속할 경우 내부 Container 사이의 이동이므로 Port Number를 22로 지정해도 문제없었다.
하지만 Windows 위에서 Jenkins를 구동시키고 있다면 위와 같이 설정했을 때 에러가 발생할 것이다.
만약 Windows 상에서 Jenkins를 구동시키고 있다면 Docker Desktop 내부의 Container와 Jenkins 실행 환경(Windows)은 분리된 공간에 존재하므로 "ssh root@[slave Container IP Address]"를 통한 접속이 불가하다.
우리는 이런 상황에서 "ssh root@localhost -p [Port Number]"를 통해 Container에 접속하였다.
즉, 만약 Windows 위에서 Jenkins가 구동하고 있다면 Host를 localhost(혹은 실행 환경의 IP Address), Port Number를 30022(Container 생성 시 설정했던 접속 Port Number)로 설정해야 정상적으로 Slave Node를 추가할 수 있을 것이다.
위 사진과 같이 Slave1의 Architecture 및 다른 Section에 값이 정상적으로 채워졌다면 성공이다.
이전에 생성했던 Item 중 빌드 작업만 수행하는 Item을 활용해보자.
Restrict where this project can be run이란 해당 Item 작업이 수행될 Slave Server를 직접 명시해주는 것이다.
아까 생성했던 "slave1"이라는 Label을 입력하자.
이후 Apply & 저장 버튼을 클릭해 설정을 수정한 뒤 빌드시켜보자.
이전에 우리는 Remote root directory를 "/root/slave1"이라는 Directory로 설정했었다.
만약 설정이 제대로 적용되었다면 "/root/slave1" 디렉터리 내에 빌드 결과물이 존재할 것이다.
정상적으로 빌드되었음을 확인할 수 있다.
마찬가지로 빌드 작업만 수행하게 만든 Pipeline Item을 활용하자.
새로 빌드되었음을 확실히 확인하기 위해서 slave1 Directory 안의 모든 내용을 삭제한 뒤 실습을 진행하자.
pipeline {
agent {
label 'slave1'
# 변경된 부분
# 'slave1'이라는 Label이 붙은 Node가 Pipeline 작업을 실행함을 명시
}
tools {
maven 'Maven3.8.6'
}
stages {
stage('github clone') {
steps {
git branch: 'main', url: 'https://github.com/idj7183/CI-CD-project';
}
}
stage('build') {
steps {
sh '''
echo build start
mvn clean compile package -DskipTests=true
'''
}
}
}
}
Apply & 저장 버튼 클릭 후 Item을 빌드시켜보자.
성공적으로 hello-world.war 파일이 빌드되었음을 알 수 있다.
(기존에 빌드된 파일들은 삭제했기 때문에 새로 빌드되었음이 확실하다)
이렇게 Jenkins에 대한 기본적인 사용 방법 및 개념은 학습이 끝났다.
마지막으로 Jenkins에서 수행할 수 있는 여러 가지 설정 방법들에 대해 알아보고 AWS 및 AWS에 Jenkins Server를 사용하는 법에 대해 새로 알아보자.