Base/CI, CD

Jenkins Master/Slave 연동

findmypiece 2021. 6. 5. 01:16
728x90

SSH 방식

https://wiki.kicco.com/pages/viewpage.action?pageId=9732396

 

JNLP 방식

https://wiki.kicco.com/pages/viewpage.action?pageId=9732892


실제 Jenkins가 설치된 서버를 Master라 칭하고 이곳에서 모든 CI/CD를 담당할 경우 부하가 심해질 수 있으므로 Master에서는 전체적인 Job에 대한 관리만 하고 실제 CI/CD는 별도 Slave 서버에서 수행되도록 부하분산 처리를 할 수 있다. 이때 Slave 서버는 일반적으로 실제 서비스가 배포되어야 할 서버가 된다.

 

이 경우 Master 와 Slave 연동이 필요하게 되고 일반적으로 SSH 방식을 많이 사용하고 Master 에서 Slave 로 접근할 수 없는 환경이라면 JNLP 방식을 차선책으로 사용한다. 일단 둘다 Slave 로 사용할 서버에 Java가 설치되어 있어야 하고 Master 의 요청을 처리할 Agent 가 띄워져 있어야 한다. Java는 직접 설치하면 되고 Agent 는 어떤 방식을 사용하느냐에 따라 다르게 띄울 수 있다.

 

SSH 방식의 경우 Master 에서 SSH를 이용해 Slave로 접속한 뒤 필요한 Agent 파일을 전송하고 그걸 실행키는 구조이다. 즉, Master에서 모든 걸 처리한다. 처리과정을 간단하게 정리해보면 아래와 같다.

 

  1. Master 에서 ssh-keygen 으로 ssh 키 생성
  2. 1번에서 생성된 privateKey 로 Master 서버에 설치된 Jenkins 에 credentials 등록 
    이제 username은 접속하려는 Slave에서 허용하는 username을 지정하면 된다.
  3. 1번에서 생성된 publicKey를 Slave 서버 ~/.ssh/authorized_keys 파일에 저장
    기존에 authorized_keys 파일이 이미 있고 등록된 publicKey가 있다면 그냥 가장 밑에 개행처리한 후 저장하면 된다.
  4. Slave 서버에 Master에서 사용할 작업 디렉토리 생성
    이는 Master 에서 Agent 파일을 전송하고 CI/CD 작업 등을 위해 사용할 디렉토리 이고
    2번에서 지정한 username이 접근가능한 디렉토리여야 한다.
  5. 최종적으로 Jenkins 에서 Slave 를 바라보는 신규노드를 생성한다.
    Remote root directory 는 4번에서 생성한 디렉토리를 지정하면 된다.
    Launch method는 Launch agent via SSH를 선택하면 된다.(SSH Build Agents 플러그인이 필요하다)
    Credentials 은 2번에서 등록한 것을 지정하면 된다.
    Host Key Verification Strategy 는 Non verifying Verification Strategy 를 선택하면 된다.

중요한 것은 아래와 같이 "고급" 버튼을 클릭할 경우 JavaPath 를 설정할수 있는데  Slave 에 설치된 Java 경로를 이곳에 반드시 지정해줘야 한다. 

오해하지 말아야 할 것은 여기에서 설정하는  jdk는 빌드에 사용되는 것은 아니다. Jenkins 는 java기반 툴이므로 jdk 가 필요할 뿐이다. 빌드에서 사용할 jdk는 Jenkins Job 구성시 다양한 방법으로 지정할 수 있다.

 

일반적으로 빌드는 Slave 노드에서 수행하게 되는데 빌드에서 사용할 jdk 는 마스터에서 관리하고 Slave에서는 그것을 참조하도록 하는 것이 일반적이다.

 

그런데 이걸 Slave 구성시 Node Properties 로 지정을 해줘야 할까? 그렇지 않다. 툴도 그렇고 환경변수도 그렇고 기본적으로 Master에만 설정하면 Slave 에서는 추가적인 작업이 없더라도 기본적으로 이를 상속받는다. 

 

즉, Master 에서 Global properties 에 환경변수를 지정하고 Global Tool Configuration 에 툴을 지정할 경우 아무런 추가작업 없이 Slave 에서는 이를 참조할 수 있기 때문에 Master 에서 작성하는 것과 동일한 스크립트를 작성하면 된다.

 

JNLP 방식의 경우 Master에서 제공하는 Agent 파일을 직접 Slave 로 옮긴 뒤에 실행시켜줘야 한다. SSH와 마찬가지로 신규노드를 생성해줘야 하는데 SSH 방식의 4번 과정처럼 Slave 에 작업 디렉토리를 선택해서 Remote root directory 에 지정하고 Launch method 는 Launch agent by connecting it to the master 로 지정하면 된다.

 

이렇게 하고 노드 등록을 완료하면 해당 노드 상세페이지에서 agent.jar 를 다운로드 할 수 있는 링크와 Slave에서 agent를 실행할 수 있는 java -jar ... 명령이 제공될 것이다. agent.jar를 다운로드 받아서  Slave 에 생성한 작업디렉토리로 옮긴 뒤에 제공되는 java -jar ... 명령을 수행하면 Master와 연결이 완료된다.

 

주의할 점은 java -jar ... 는 기본적으로 foreground 로 실행되는데 계속 콘솔창을 열어놓을 수는 없기 때문에 systemctl service 등을 활용해서 background 로 실행시켜놓아야 한다. 해보면 알겠지만 Master에서 모든 것을 처리하는 SSH 방식이 기본적으로 간단하고 추후 관리도 편하다.

 

참고
https://jonnung.dev/devops/2018/08/15/jenkins-distributed-builds/
728x90