이전 글에서 master 노드에 Jenkins를 설치하고 정적 web site와 docker 이미지를 각각 AWS S3와 AWS ECR에 배포하고 배포된 이미지를 AWS ECS에 올리는 작업을 하였다.
하지만 작업이 많아지고 무거워지는 경우 서버 한대에서 이를 처리하기에 버거워질 것이다.
오늘은 slave 서버를 추가하여 master 노드가 slave 노드와 작업을 분산할 수 있도록 구성을 해보자.
slave 노드에는 별도로 Jenkins를 설치하지 않고 ssh 통신으로 master 노드가 slave 노드에 작업을 지시하도록 할 것이다.
1. AWS EC2 slave node 생성
우선 master와 동일하게 AWS EC2로 Slave 서버를 생성한다.
2. slave 환경설정
master 서버와 동일하게 java, git, docker를 설치한다.
$ sudo yum install -y java-1.8.0-openjdk git docker
3. ssh connection
master에 ssh-keygen을 생성한 후
$ ssh-keygen
slave의 authorized_keys에 master의 public key를 추가한다.
$ vi ~/.ssh/authorized_keys
master → slave ssh 연결 확인!
4. Credential 추가
Jenkins에서 slave와의 ssh 연결을 위해 Credential을 추가한다.
Private Key 항목에는 master node의 private key를 입력한다.
$ cat ~/.ssh/id_rsa
생성된 Credentials 목록이다.
5. Node 추가
slave node를 추가할 차례이다.
테스트 용이므로 slave node에 일을 시켰을 때 동작되는 것을 확인하고자 Usage 항목에서 'Only build jobs with label expressions matching this node'를 선택한다.
slave node가 정상적으로 추가되었다.
node 목록에서 master와 slave를 확인할 수 있다.
6. Jenkinsfile 수정
default로 master node에서 빌드될 수 있도록 상단에서 agent
label을 'master'로 설정하고, 'Deploy Server' Stage는 slave node에서 빌드될 수 있도록 설정하였다.
def DEPLOY_TO
pipeline {
//agent any
agent {
label 'master'
}
parameters {
...
}
stages {
stage('Decide Deploy To') {
...
}
stage('Check deploy parameter') {
...
}
stage('Build website') {
...
}
stage('Deploy website') {
...
}
stage('Build Server') {
...
}
stage('Deploy Server') {
agent {
label 'slave'
}
steps {
script {
withAWS(region:'ap-northeast-2', credentials:'jenkinsaws') {
sh """
aws ecs update-service \
--region ap-northeast-2 \
--cluster ${DEPLOY_TO}-app \
--service ${DEPLOY_TO}-webserver \
--force-new-deployment \
--desired-count 2
aws ecs wait services-stable \
--cluster ${DEPLOY_TO}-app \
--services ${DEPLOY_TO}-webserver
"""
}
}
}
}
}
}
7. 배포 테스트
master 노드와 slave 노드에서 동시에 빌드되는 중이다.
정상적으로 빌드도 완료되었으며,
log를 봐도 'Deploy Server' Stage가 slvae 노드에서 빌드되었음을 확인할 수 있다.
ps. 이렇게 활용할 수도...
stage('Some Parallel Stage') {
parallel {
stage('frontend test') {
agent { label 'slave1' }
...
}
stage('backend test') {
agent { label 'slave2' }
...
}
stage('master job') {
agent { label 'master' }
...
}
}
}
위 Stage 처럼 Parallel 하게 3개의 Stage를 각각 다른 node에서 돌아가도록 설정할 수도 있다.