본문 바로가기

Java/Deploy

[Docker] 젠킨스 SSH 키 생성 및 master-slave 컨테이너 설정

반응형

 

실제 관리 기능이나 작업 실행 지시등은 마스터(Leader) 인스턴스가 맡고,

작업을 실제로 진행하는 것은 슬레이브(Follower) 인스턴스가 담당한다.

 

이러한 구성의 컴포즈로 만들어 보겠다 !! :)

1 ) master 젠킨스 컨테이너에 접속할 수 있는 SSH 키 생성

- TERMINAL

% docker container exec -it master ssh-keygen -t rsa   

Generating public/private rsa key pair.
Enter file in which to save the key (/var/jenkins_home/.ssh/id_rsa):     
Created directory '/var/jenkins_home/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /var/jenkins_home/.ssh/id_rsa.
Your public key has been saved in /var/jenkins_home/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:****
The key's randomart image is:
+---[RSA 2048]----+
****
+----[SHA256]-----+

 

지금 만든 /var/jenkins_home/.ssh/id_rsa.pub 파일은 masger 젠킨스가 slave 젠킨스에 접속할 때 사용할 키(ssh-rsa ...)다.

이 키를 slave 를 추가할 때 설정할 것이다.

2 ) slave 젠킨스 컨테이너 설정 및 생성

- docker-compose.yml

version: "3"
services:
  master:
    container_name: master
    image: jenkinsci/jenkins:2.154-slim
    ports:
      - 8080:8080
    volumes:
      - ./jenkins_home:/var/jenkins_home
    links:
      - slave01

slave01:
  container_name: slave01
  image: jenkinsci/ssh-slave
  environment:
    - JENKINS_SLAVE_SSH_KEY=ssh-rsa AAAAB3NzaC1yc2E...

 

  • master 컨테이너는 master, slave 컨테이너는 slave01로 각각 이름을 붙인다.
  • links 요소를 사용해 mater 컨테이너가 slave 컨테이너로 통신할 수 있도록 설정한다.
  • slave 컨테이너를 만들때는 SSH로 접속하는 slave용도로 구성된 도커 이미지인 jenkinsci/ssh-slave를 사용하고,
    이 이미지에서 다시 환경변수인 JENKINS_SLAVE_SSH_KEY를 설정하는데, SSH로 접속하는 상대가 이 키를 보고 master 젠킨스임을 식별하게 된다.
  • JENKINS_SLAVE_SSH_KEY 는 아래와 같이 접근해 확인할 수 있다. (경로: ./jenkins_home/.ssh/id_rsa.pub)

- TERMINAL

## master jenkins 컨테이너 접근
% docker exec -it 8aa0b74952499a2dd13dd3b2717644313bc73aa185640cc65f883c252dac0d36 /bin/sh; exit

## ssh public key 확인
$ cd /var/jenkins_home/.ssh           
$ tail id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2E...

 

이후 docker-compose.yml을 다 설정한 후 아래의 명령어를 통해 설정 파일을 실행해봤다.

 

- TERMINAL

% docker-compose up -d

ERROR: The Compose file './docker-compose.yml' is invalid because:

Invalid top-level property "slave01". Valid top-level sections for this Compose file are: version, services, networks, volumes, and extensions starting with "x-".

You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the `services` key, or omit the `version` key and place your service definitions at the root of the file to use version 1.

For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

 

아니, 에러가 나는 것이 아닌가 🤯

알고 봤더니, slave01을 master와 같은 레벨의 띄어쓰기가 되어있지 않아 발생한 현상으로
아래와 같이 수정해서 다시 up 하니 정상적으로 설정되었다.

 

- docker-compose.yml

version: "3"
services:
  master:
    container_name: master
    image: jenkinsci/jenkins:2.154-slim
    ports:
      - 8080:8080
    volumes:
      - ./jenkins_home:/var/jenkins_home
    links:
      - slave01

  slave01:
    container_name: slave01
    image: jenkinsci/ssh-slave
    environment:
      - JENKINS_SLAVE_SSH_PUBKEY=ssh-rsa AAAAB3NzaC1yc2E...

 

- TERMINAL

% docker-compose up -d

WARNING: Found orphan containers (docker_echo_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Pulling slave01 (jenkinsci/ssh-slave:)...
latest: Pulling from jenkinsci/ssh-slave
146bd6a88618: Pull complete
9935d0c62ace: Pull complete
db0efb86e806: Pull complete
e705a4c4fd31: Pull complete
3d3bf7f7e874: Pull complete
49371c5b9ff6: Pull complete
e7873a7ca0fd: Pull complete
0d3a3f35f94b: Pull complete
baa86448071c: Pull complete
0ceaafd75f6e: Pull complete
c8e4cc898fde: Pull complete
Digest: sha256:8d9cc4f3d29fabe62e0e5ff11fb15276d673fb282c7684ca9cd7bcb5a484c517
Status: Downloaded newer image for jenkinsci/ssh-slave:latest
Creating slave01 ... done
Recreating master ... done

 % docker-compose ps
 
 Name                Command               State                 Ports              
------------------------------------------------------------------------------------
master    /sbin/tini -- /usr/local/b ...   Up      50000/tcp, 0.0.0.0:8080->8080/tcp
slave01   setup-sshd                       Up      22/tcp      

 

3 ) slave 젠킨스 컨테이너 노드 추가

두 컨테이너를 실행했다고 해서 master 젠킨스가 slave 젠킨스를 인식하지는 못한다. 

따라서 이를 인식할 수 있도록 slave 젠킨스를 추가하도록 하자.

  3-1 ) 'Jenkins 관리' 페이지 → '노드 관리' 선택 

  3-2 ) '신규 노드' 생성 항목에서 노드 추가

노드명은 slave01로 설정 후 OK 버튼 실행

  3-3 ) 노드 설정

slave jenkins node 설정 화면

  • Remote root directory : 디렉터리 경로(/home/jenkins도 가능) 아무거나 입력
  • Usage : 'Use this node as much as possible'로 선택
  • Launch method : 'Launch agent agents via SSH'로 선택
    ⇢ 이 선택지가 없는 경우, jenkins의 plug-in 중 'ssh-slaves(SSH Build Agents)' 가 정상적으로 설치되었는지 확인 필요
        * ssh-slaves(SSH Build Agents) : https://plugins.jenkins.io/ssh-slaves/
    ⇢ ssh-slaves 플러그인도 설치가 안된다면, 기존의 jenkins image를 제거 한 후 jenkins 버전을 상위 버전으로 재설치할 것을 권장
Host slave 젠킨스의 호스트명 = master 컨테이너에서 slave 컨테이너를 찾는 명칭
Credentials [Add] 버튼 ⇢ 'Jenkins' 선택
Host Key Verification Strategy 'Non Verifying Verification Strategy' 선택

 

Credentials(인증) Add 화면

SSH 의 아이디와 비밀키를 지정해서 master 컨테이너에서 slave01 컨테이너로 SSH 접속할 수 있게 한다.

* ID : jenkins

* Private Key : master 젠킨스 컨테이너에서의 /.ssh 의 Key로 설정

 

- TERMINAL

## master jenkins 컨테이너 접근
% docker exec -it 4b5f1a52f8b7bf8f6ba78468ed415cc94e08bb550d3a80628e08678208fbfe3e /bin/sh; exit

## ssh private key 확인
$ cd /var/jenkins_home/.ssh
$ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA2TS+t+UOke86fkfMigf/p52hUDQK4aQ70/UZXmf8Qln2FM5E
...
-----END RSA PRIVATE KEY-----

 

인증 정보(SSH Key)를 추가하고, 신규 노드 설정 화면에서 생성한 'jenkins'를 지정한다.

호스트 키 설정 방법도 'Non Verifying Verification Strategy' 선택 후 [Save] 버튼을 눌러 slave01 노드를 추가한다.

 

  3-3-1 ) 노드 설정 ERROR #1

그러고나면... 아름답게 설정된 모습을 볼 수가 없었고, slave01을 눌러보면 아래와 같은 ERROR 메시지를 확인할 수 있었다. 😬

[07/21/20 06:15:06] [SSH] WARNING: SSH Host Keys are not being verified. Man-in-the-middle attacks may be possible against this connection.

ERROR: Server rejected the 1 private key(s) for jenkins (credentialId:jenkins/method:publickey) [07/21/20 06:15:06]

[SSH] Authentication failed. Authentication failed. [07/21/20 06:15:06] Launch failed - cleaning up connection

 

이는 slave 젠킨스 컨테이너에 SSH Key에 접근 권한이 없어 발생하는 현상으로,

아래의 쉘 스크립트를 따라 slave 젠킨스 컨테이너에 SSH 파일 생성 및 권한을 확인해보자.

 

- TERMINAL

## slave jenkins 컨테이너 접근
% docker exec -it 1de4823aa7287d5054cc76ac63b56432994baf2c33906808baf97d58c32cfa5d /bin/sh; exit

## /.ssh/authorized_keys 폴더 확인 → 없음
# cd /home/jenkins
# ls -al
total 20
drwxr-xr-x 2 jenkins jenkins 4096 Jul 21 03:51 .
drwxr-xr-x 1 root    root    4096 Jan  1  2020 ..
-rw-r--r-- 1 jenkins jenkins  220 May 15  2017 .bash_logout
-rw-r--r-- 1 jenkins jenkins 3526 May 15  2017 .bashrc
-rw-r--r-- 1 jenkins jenkins  675 May 15  2017 .profile

## /.ssh 폴더 및 authorized_keys 파일 생성
## 이미 존재한다면, 접근 권한만 설정!!
# mkdir /home/jenkins/.ssh
# touch /home/jenkins/.ssh/authorized_keys

## master Jenkins에 있는 Key를 authorized_keys 파일에 작성
# echo 'ssh-rsa AAAAB3NzaC1yc2 ... jenkins@8aa0b7495249' >> authorized_keys

## authorized_keys 파일까지의 경로까지 접근 권한 설정
# chown -R jenkins /home/jenkins/.ssh
# chmod 600 /home/jenkins/.ssh/authorized_keys
# chmod 700 /home/jenkins/.ssh

  3-3-2 ) 노드 설정 ERROR #2

설정 한 후 Jenkins Node 설정화면에서 다시 slave 젠킨스를 실행해보면, 새로운 Error를 만날 수 있다. 🤐

 

slave01 노드의  [Launch agent] 버튼 실행

java.io.IOException: Java not found on hudson.slaves.SlaveComputer@65b529ea. Install a Java 8 version on the Agent. at hudson.plugins.sshslaves.JavaVersionChecker.resolveJava(JavaVersionChecker.java:82) at hudson.plugins.sshslaves.SSHLauncher$1.call(SSHLauncher.java:442) at hudson.plugins.sshslaves.SSHLauncher$1.call(SSHLauncher.java:412) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) [07/21/20 13:14:17] Launch failed - cleaning up connection

 

이는 java8의 path가 제대로 설정되지 않아 발생한 현상이였고, 해결방법은 아래와 같이 slave 젠킨스 설정을 하면 된다.

⇢ [참고] issues.jenkins-ci.org/browse/JENKINS-18767

 

 

java 경로(JavaPath)를 알기 위해서는 slave 젠킨스 컨테이너에서 확인해보자.

 

- TERMINAL

## slave 젠킨스 컨테이너 접근
% docker exec -it 7f800534fe3a342e0b1b72d27929e730dcd023dff7db064d10ca85fbfab52bba /bin/sh; exit

## JAVA 설치 여부
# java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-b09)
OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)

## JAVA 경로
# which java
/usr/local/openjdk-8/bin/java

 

4 ) master-slave 젠킨스 설정 완료

이후, 다시 Jenkins Node 설정 화면에서 slave01을 재실행한 후에는 정상적으로 설정된 화면을 볼 수 있다. ^0^

 

master-slave Jenkins 설정 완료 화면

 


[참고] : chati.tistory.com/128

 

[Docker] 도커 컴포즈로 여러 컨테이너 실행 및 젠킨스 연동

도커 컨테이너는 = 단일 애플리케이션 도커는 애플리케이션 배포에 특화된 컨테이너이다. 가상 서버와는 대상 단위의 크기 자체가 다르다. 즉 애플리케이션 간의 연동 없이는 실용적 수준의 시�

chati.tistory.com

 

반응형

❥ CHATI Github