Jenkins, NAVER Cloud Platform, Docker로 CI/CD 무중단 배포 환경 구축하기 - 2편

Doyun Geum·2020년 1월 2일
4

DevOps

목록 보기
2/2

2편에서는 CD에서 무중단 배포까지 구축한다.

(1편에서는 Github Push 후에 Jenkins가 자동으로 빌드되도록 설정하였다.)

2. Jenkins로 Node.js기반 프로젝트 배포 설정하기

배포를 위해 scp를 사용하여 Jenkins에 있는 프로젝트 코드를 NAVER Cloud 서버에 복사해야 한다.
Node.js 기반의 프로젝트는 Tomcat과 같은 WAS(웹 서버+웹 컨테이너)가 존재하지 않아 ssh로 접속, scp로 파일을 주고 받는 작업으로 비교적 간단히 배포할 수 있다.

2-1. NAVER Cloud 서버에도 ssh 키를 생성한다.

ssh-keygen -t rsa

키가 생성되면 authorized_keys, id_rsa, id_rsa.pub, known_hosts 가 생성되어 있는 것을 볼 수 있다.

scp로 파일을 주고 받는다 하였는데 이때 복사 받을 서버의 접속 비밀번호를 알아야 한다. 그렇게되면 복사할 때마다 매번 비밀번호를 요구하여 자동화 배포는 불가능하게 된다.

이를 해결하기 위해 위의 4개의 키를 이용한다.
Jenkins에서는 NAVER Cloud 서버를 호스트로, NAVER Cloud 서버에서는 Jenkins 서버의 공개 키를 허가받은 키로 등록한다. 이러면 비밀번호를 요구하지 않고 자동화 배포가 가능하다.

2-2. Jenkins 서버에서 NAVER Cloud 서버를 known_hosts로 등록한다.

ssh-keyscan -H (NAVER CLOUD 서버)ip >> ~/.ssh/known_hosts

2-3. Jenkins에서 생성한 키 중에 공개 키(id_rsa.pub)를 NAVER Cloud 서버에서 생성한 authorized_keys에 입력한다.

  • Jenkins 서버의 공개 키

  • NAVER Cloud 서버의 authorized_keys

    vi ~/.ssh/authorized_keys

  • scp로 테스트하기
    접속 비밀번호를 요구하지 않았다면 성공이다.

  1. Jenkins 서버에서 test.txt 파일을 생성한다.
  2. Jenkins 서버에서 scp를 사용해 test.txt를 NAVER Cloud 서버의 /root/test 폴더에 복사한다.
    비밀번호를 요구하지 않으면 성공.
  3. NAVER Cloud 서버에서 복사된 파일을 확인한다.

3. NAVER Cloud 서버에 Docker, NGINX 설정하기

이제 프로젝트가 배포되는 NAVER Cloud 서버에서 설정해야 할 부분이다.
(*Docker 및 NGINX 설치는 생략한다.)

3-1. Dockerfile 작성.

ssh로 서버에 접속하고 Dockerfile을 다음과 같이 작성한다.

FROM 이미지 환경

MAINTAINER 개발자

VOLUME 호스트와 공유할 폴더

RUN mkdir -p /app

WORKDIR /app

COPY ./프로젝트 소스코드 폴더/ /app

RUN npm install

CMD npm start
  • FROM: Node 이미지(Node version 명시)
  • MAINTAINER: 개발자(팀명)
  • VOLUME: host와 컨테이너가 공유할 폴더 경로
  • RUN: 해당 명령어 실행( 위에선 app 폴더 생성 )
  • WORKDIR: 작업 디렉토리 설정(위에서 만든 app 폴더로 설정)
  • COPY: NAVER Cloud 서버에 있는 파일을 컨테이너 폴더에 복사
    서버에 있는 파일은 Dockerfile이 존재하는 현재 경로 내에 존재하는 것만 가능하다.
    (즉, 절대 경로는 Dockerfile이 있는 경로 이내가 아니라면 불가능)

그 다음은 패키지 파일들을 설치하고 서버를 실행한다.

docker image build -t 도커이미지이름 .를 입력하여 이미지를 빌드한다.

3-2. Docker-compose 작성하기

docker-compose(컨테이너 관리)를 설치하여 편하게 컨테이너를 설정한다.
여기서 blue-green 배포 방식이 사용되는데, 이는 무중단 배포 구축을 위함이다.

  • Dockerfile이 있는 곳에 docker-compose.blue.yml을 다음과 같이 작성한다.

version: '2'

services:
  linking-server:
     image: 빌드한 도커 이미지
     volumes:
          - ./deploy:/deploy/linking
     ports:
          - "NAVER Cloud 서버 포트:컨테이너 포트"

image: 아까 빌드한 이미지 이름을 작성한다.

volumes: host 폴더와 컨테이너 폴더를 설정하여 공유한다.(심볼릭 링크와 비슷한 개념이라고 한다.)

ports: host 포트와 컨테이너 포트 순으로 작성하여 포트 포워딩 설정을 한다.

  • 같은 곳에 docker-compose.green.yml을 다음과 같이 작성한다.
    host 포트만 다르다.

3-3. deploy script 작성하기.

  • 같은 곳에 deploy.sh를 다음과 같이 작성한다.

#!/bin/bash

DOCKER_APP_NAME=linking-server

EXIST_BLUE=$(docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep Up)

if [ -z "$EXIST_BLUE" ]; then
    echo "blue up"
    docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d

    sleep 10

    docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml down
else
    echo "green up"
    docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d

    sleep 10

    docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml down
fi
  • 지금까지 잘 따라 했다면 아래와 비슷한 디렉토리 구조를 볼 수 있을 것이다.

  • 컨테이너 생성하기

docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d를 입력하여 blue 컨테이너를 먼저 생성해준다.

docker ps -a로 컨테이너가 잘 실행되고 있는지 확인할 수 있다.

3-4. NGINX 설정하기.

다음은 NGINX로 blue, green의 로드밸런싱을 설정해 주어야 한다.

  • vi /etc/nginx/sites-available/linking-server를 입력하여 다음과 같이 작성한다.
    linking-server는 필자가 정한 이름이다.

# Load Balancing
upstream linking-server {
        least_conn;
        server 127.0.0.1:1025 weight=5 max_fails=3 fail_timeout=10s;
        server 127.0.0.1:1026 weight=10 max_fails=3 fail_timeout=10s;
}
server {
  listen 1024;
  server_name NAVER Cloud 서버 아이피;
  location / {
    proxy_pass http://linking-server;
  }
}

그런 다음 아래 명령어로 이 파일을 /etc/nginx/sites-enabled 디렉터리에 링크해준다.

sudo ln -fs /etc/nginx/sites-available/linking-server /etc/nginx/sites-enabled/

마지막으로 sudo nginx -t 명령어로 문법 이상 유무를 확인하고 이상이 없을 경우, systemctl stop nginx 명령어로 NGINX를 종료한 후에 systemctl start nginx 로 다시 시작한다.

3-5. NAVER Cloud Platform ACG 설정하기.

여기서 마지막으로 한 가지 해야할 것은 ACG 설정이다.

  • ACG 설정하기

NAVER Cloud Platform 콘솔에서 1024포트를 열어준다. 위에서 blue, green 모두 다른 포트지만 NGINX를 통해 1024 포트로 로드 밸런싱 되기에 사용자는 이를 통해 접근할 수 있다.
(보통 백엔드와 프론트엔드를 분리하면서 프로젝트를 진행하고 있다면 프론트엔드는 80포트를 사용하는게 좋다. 80이 기본 포트라 생략 가능하므로)

이것으로 NAVER Cloud 서버에서의 설정은 끝났다.

4. 마지막 작업

이제 마지막 Jenkins에서 빌드할 때 설정을 해주어야 위에서 설정한 무중단 배포가 자동화된다.

  • Jenkins 프로젝트 관리에서 "Execute managed script"를 클릭한다.
    다만, 아직 작성한 스크립트가 없기에 Jenkins 관리 > Managed files > Add a new Config를 통해 스크립트를 작성한다.

  • 다음과 같이 작성한다.

#!/bin/sh
ssh -T root@서버 아이피 <<EOF
 rm -rf /home/docker-image/deploy/*
 exit
EOF

scp -r /var/lib/jenkins/jobs/LinkingCI/workspace/* root@서버 아이피:/home/docker-image/deploy/

#!/bin/sh
ssh -T root@서버 아이피 <<EOF
 cd /home/docker-image
 docker image build -t linking-server-docker-image .
 ./deploy.sh
 exit
EOF

1) Jenkins가 빌드 동안 해당 서버에 접속하여 원래 있던 애플리케이션 코드를 삭제한다.

2) 빌드된 파일을 해당 서버에 복사한다.

3) 해당 서버에 다시 접속하여 새로 복사된 파일을 토대로 도커 이미지를 빌드한다.

4) 배포 스크립트를 실행한다.

위와 같은 과정이 일어나고 지금까지 설정한 것들이 모두 자동화되어 무중단 배포까지 진행된다. 이를 이제 Jenkins 프로젝트 관리에서 실행하도록 한다.

5. 빌드 상태 표시, Slack 알림

추가로 프로젝트에서 보이는 Embeddable Build Status를 클릭하면 마크다운 형식으로 Github 레포지토리에 빌드 상태바를 보이게 할 수 있다.

마지막으로 팀원들이 빌드 상태(시작, 실패, 성공)을 알고 싶을 때 Slack을 통해 알림을 받도록 할 수도 있다.
1편에서 이미 관련 플러그인을 설치하였기에 바로 설정이 가능하다.

  • Slack에 채널을 만들었다면 Apps에서 Jenkins를 검색 후 클릭한다.

  • 알림을 받을 채널을 설정하면 Jenkins에서 어떻게 설정해야 하는지 친절하게 나온다.

설정을 하고 나면 Jenkins 프로젝트에서 빌드 후 조치에 알림 받을 내역을 설정할 수가 있게 된다.

  • 빌드 시작부터 끝까지 알림이 날라온다.

이것으로 CI/CD 무중단 배포 환경 구축을 마친다.

-끝-

profile
안녕하세요, 서버 개발자 도유니입니다.

2개의 댓글

comment-user-thumbnail
2023년 1월 10일

Its critical to be honest and have a great time and not stress excessively. The objective isnt to converse with ladies on the however meet them face to face. In the event that youve made up a dream life brimming with lies you must tell the using headshots on tinder truth sooner or later. Distortion is fine however through and through lies are simply futile.

답글 달기
comment-user-thumbnail
2023년 5월 24일

애플리케이션 개발을 위한 새로운 프로세스 geometry dash lite

답글 달기