Jenkins Master-Slave Architecture

Violet_Evgadn·2023년 4월 25일
0

CI&CD 자동화

목록 보기
28/28

Master-Slave Architecture란?

지금까지 우리는 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에서 수행하게 만들 수 있다.


Master-Slave Architecture 구축

※ 이번 실습은 다른 실습과는 다르게 Jenkins Server가 Docker Desktop 위의 Container로 구동되고 있음을 알고 있자.

  1. 새로운 Server 추가
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에 바로 접속 가능하도록 만들자.

SSH Key 활용

마지막으로 Java를 설치해줘야 한다.

Jenkins에서 처리해야 하는 Build 작업을 대신 수행할 수도 있는 Slave Server다 보니 Java가 설치되어 있지 않다면 아예 연결되지 않도록 Jenkins 측에서 막아놨다.

2. Jenkins 관리 > 노드 관리 > New Node

3. 노드명 입력 & Permanent Agent 선택 후 Create

4. Section 의미에 맞게 값 입력

각 Section에 대한 설명

Node Name : Slave Node Name

3번 과정에서 지정했던 Name으로 자동 입력됨

Description : Slave Node에 대한 설명

필수 입력값은 아님

Number of executors

  • Jenkins Master에서 받아 동시에 처리할 수 있는 Job의 최대 개수
  • 값이 크면 많은 작업을 처리할 수 있으나 서버 과부하의 가능성이 증가함

Remote root directory

  • Build 결과 파일을 저장할 Directory
  • "Slave Server의 Directory"를 입력해줘야 한다. Slave Server에서 Build 작업이 수행되므로 당연히 결과물도 Slave Server에 저장되어야 하기 때문이다.
  • 미리 Slave Server에 해당 Directory가 존재해야 한다.

Labels

  • Server label
  • 이전에 Pipeline Script를 공부할 때 "agent"에 대해 언급한 적이 있는데 이때 "label"이라는 agnet Parmeter를 설명한 적이 있다. label [Lables]를 통해 CI/CD 절차를 실제로 수행할 Slave Node를 지정해줄 수 있다.

Usage

  • 언제 이 노드를 활용할 수 있는지 설정하는 Section
  • Only build jobs with lable expressions matching this node : Slave Node를 직접 지정한 작업에서만 사용 가능
  • User this node as much as possible : Slave Node가 사용 가능한 상황이라면 모든 작업에서 사용 가능

Launch Method

Jenkins Master에서 Jenkins Slave에 접속하기 위한 방법 지정

Launch Method > Launch agents via SSH

Jekins Master에서 Slave로 SSH를 통해 접속하도록 방법을 지정해주는 것이다.

Host : Jenkins Slave의 IP Address

Credentials : Jenkins Slave 접속을 위한 접속 정보

  • Add > Jenkins 버튼을 클릭해 접속 정보 추가 가능
  • 이전에 수행했던 Credentials 추가 방법과 동일하다

고급 버튼을 클릭하면 Port Number나 Java Path 등을 추가로 설정할 수 있다.

Host 및 Port Number에 대한 추가 설명

위에 띄웠던 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을 Slave1에서 동작시키도록 설정

이전에 생성했던 Item 중 빌드 작업만 수행하는 Item을 활용해보자.

1. 빌드 작업만 수행하는 Item > 구성 > Restrict where this project can be run 활성화

Restrict where this project can be run이란 해당 Item 작업이 수행될 Slave Server를 직접 명시해주는 것이다.

아까 생성했던 "slave1"이라는 Label을 입력하자.

이후 Apply & 저장 버튼을 클릭해 설정을 수정한 뒤 빌드시켜보자.

2. Jenkins Slave Server 접속 & 확인

이전에 우리는 Remote root directory를 "/root/slave1"이라는 Directory로 설정했었다.

만약 설정이 제대로 적용되었다면 "/root/slave1" 디렉터리 내에 빌드 결과물이 존재할 것이다.

정상적으로 빌드되었음을 확인할 수 있다.


Pipeline을 Slave1에서 동작시키도록 설정

마찬가지로 빌드 작업만 수행하게 만든 Pipeline Item을 활용하자.

새로 빌드되었음을 확실히 확인하기 위해서 slave1 Directory 안의 모든 내용을 삭제한 뒤 실습을 진행하자.

1. Pipeline Item > 구성 > Pipeline Section의 Script 변경

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을 빌드시켜보자.

2. Jenkins Slave Server 접속 & 확인

성공적으로 hello-world.war 파일이 빌드되었음을 알 수 있다.

(기존에 빌드된 파일들은 삭제했기 때문에 새로 빌드되었음이 확실하다)


이렇게 Jenkins에 대한 기본적인 사용 방법 및 개념은 학습이 끝났다.

마지막으로 Jenkins에서 수행할 수 있는 여러 가지 설정 방법들에 대해 알아보고 AWS 및 AWS에 Jenkins Server를 사용하는 법에 대해 새로 알아보자.

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글