-
NCP(Naver Cloud Platform)와 Jenkins -3) CD 환경 구축기술 이야기/CI&CD 2020. 11. 2. 16:24반응형
Jenkins, Nginx, docker를 활용한 무중단 CD
-
보통은 Jenkins 서버와 배포하는 서버를 따로 두지만, NCP에서는 Jenkins가 탑재된 Server를 생성할 수 있고 프로젝트의 규모가 크지 않기 때문에, 하나의 서버에서 진행하는 것으로 전제한다.
-
Docker 설치
- 패키지 저장소 추가 (도커의 공식 GPG 키와 저장소를 추가)
-
sudo apt-get update && sudo apt-get install \ sudo apt-transport-https \ sudo ca-certificates \ curl \ sudo software-properties-common
- sudo: unable to resolve host라는 값이 console에 찍힌다면, /etc/hostname이 /etc/hosts에 등록되어있지 않아서 그렇다.
- /etc/hosts에 hostname을 등록해주자
-
[/etc/hosts] 127.0.1.1 host_name
- docker 패키지가 검색되는지 확인하기
- sudo apt-get update && sudo apt-cache search docker-ce
- docker-ce - Docker: the open-source application container engine 이렇게 표시된다면 설치패키지가 검색된다는 의미
- 도커 CE 설치 (무료버전)
- sudo apt-get update && sudo apt-get install docker-ce
-
Nginx 설치
- apt-get install nginx 명령어로 Nginx서버 설치
- Nginx 웹 서버 수동으로 재실행하고 상태 확인하기
-
service nginx restart service nginx status
-
Dockerfile 작성
-
/home/docker-image에서 작업. server와 client를 구분하여 server만 도커 이미지화 해준다.
-
server 디렉토리 아래 작업
-
vi Dockerfile로 Dockerfile 생성 및 내부를 설정하기
-
FROM node:12.19.0 MAINTAINER zin0 VOLUME /deploy/issue-tracker/server RUN mkdir -p /app WORKDIR /app COPY ./deploy/ /app RUN npm install CMD npm start
-
-
docker image build -t 도커이미지이름 . 으로 이미지를 빌드한다.
- docker image build -t issue-tracker-server .
- .은 현재 path를 의미
-
docker-compose 작성 (blue, green)
-
docker-compose.blue.yml 작성
-
version: '2'
services:
issue-tracker-server:image: issue-tracker-server-docker-image volumes: - ./deploy:/deploy/issue-tracker/server ports: - "3001:3000"
-
-
docker-compose.green.yml 작성
-
version: '2'
services:
issue-tracker-server:image: issue-tracker-server-docker-image volumes: - ./deploy:/deploy/issue-tracker/server ports: - "3002:3000"
-
-
deploy.sh 작성
-
#!/bin/bash DOCKER_APP_NAME=issue-tracker-server EXIST_BLUE=$(sudo docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep Up) if [ -z "$EXIST_BLUE" ]; then echo "blue up" sudo docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d sleep 10 sudo docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml down else echo "green up" sudo docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d sleep 10 sudo docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml down fi
-
deploy.sh에 권한 추가
- chmod 755 ./deploy.sh
-
-
client
-
client는 nginx를 통해 띄워주는 것으로 결정, build를 통해 webpack을 적용
-
deploy.sh 작성 #!/bin/bash cd ./deploy npm install npm run build
-
-
compose 파일에서 port:port 이 부분은 외부 port를 도커 컨테이너 내부 port로 바인딩해준다는 뜻이다.
-
Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running? 에러
-
검색 결과, docker가 정상적으로 실행되는지에 대한 에러라고 한다.
-
그래서 docker socket을 이용하는 권한추가 sudo chown $USER /var/run/docker.sock나 docker 그룹에 유저를 추가하는 sudo usermod -aG docker $USER나 여러가지 방법을 해봤지만 똑같았다. 마지막으로, docker 컨테이너를 띄울 때, 권한 문제가 있지 않을까 싶어서 deploy.sh의 명령어에 sudo를 붙였다.
-
#!/bin/bash DOCKER_APP_NAME=issue-tracker-server EXIST_BLUE=$(sudo docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml ps | grep Up) if [ -z "$EXIST_BLUE" ]; then echo "blue up" sudo docker-compose -p ${DOCKER_APP_NAME}-blue -f docker-compose.blue.yml up -d sleep 10 sudo docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml down else echo "green up" sudo docker-compose -p ${DOCKER_APP_NAME}-green -f docker-compose.green.yml up -d sleep 10 sudo 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
- docker-compose가 없다는 메세지가 출력돼서, apt install docker-compose를 통해 설치했다.
- yaml.scanner.ScannerError: while scanning for the next token found character '\t' that cannot start any token 에러가 뜬다면, yaml 파일에서는 탭('\t')을 지원하지 않는다는 에러다. 따라서, tab으로 작성을 한 부분을 space(' ')로 변경해줘야한다.
- docker ps -a로 컨테이너가 정상 작동 중인지 확인해준다.
-
Nginx 설정하기
- Nginx로 blue와 green의 로드밸런싱을 설정
- vi /etc/nginx/sites-available/issue-tracker-server로 서버 로드밸런싱 설정
-
# Load Balancing upstream issue-tracker-server { least_conn; server 127.0.0.1:3001 weight=5 max_fails=3 fail_timeout=10s; server 127.0.0.1:3002 weight=10 max_fails=3 fail_timeout=10s; } server { listen 3000; server_name Naver Cloud 주소; location / { proxy_pass http://issue-tracker-server; } }
- vi /etc/nginx/sites-available/issue-tracker-client로 클라이언트 배포 설정
-
server { listen 80; location / { root /home/docker-image/client/deploy/dist; autoindex on; set $fallback_file /index.html; if ($http_accept !~ text/html) { set $fallback_file /null; } if ($uri ~ /$) { set $fallback_file /null; } index index.html server_name $url try_files $uri /index.html; } error_page 404 /index.html; }
- nginx 기본 설정 값들을 삭제해준다.
-
$ sudo rm /etc/nginx/sites-available/default $ sudo rm /etc/nginx/sites-enabled/default
- 그런 다음 아래 명령어로 이 파일을 /etc/nginx/sites-enabled 디렉터리에 링크
-
sudo ln -fs /etc/nginx/sites-available/issue-tracker-server /etc/nginx/sites-enabled/ sudo ln -fs /etc/nginx/sites-available/issue-tracker-client /etc/nginx/sites-enabled/
- sudo nginx -t 명령어로 문법 이상 유무를 체크해주고, successful이 뜨면 됐다.
- systemctl stop nginx, systemctl start nginx로 재실행을 해준다.
-
ACG 설정하기
- 1024 포트(Nginx)를 열어준다.
- Nginx는 1024포트를 통해 로드 밸런싱을 하기 때문(설정을 1024로 했음)
-
Jenkins Script 작성
-
#!/bin/sh ## docker container image를 만들 디렉토리를 비운다. sudo rm -rf /home/docker-image/server/deploy/* sudo rm -rf /home/docker-image/client/deploy/* ## jenkins에서 받아온 파일을 docker image 작업 디렉토리에 복사 sudo cp -r /var/lib/jenkins/workspace/issue-tracker/server/* /home/docker-image/server/deploy/ sudo cp -r /var/lib/jenkins/workspace/issue-tracker/client/* /home/docker-image/client/deploy/ ## server 단에서, config를 구성하는 파일이 필요하기 때문에, 미리 저장해둔 파일 복사 sudo mkdir /home/docker-image/server/deploy/config sudo cp /home/docker-image/server/config.json /home/docker-image/server/deploy/config/ #!/bin/sh cd /home/docker-image/server sudo docker image build -t issue-tracker-server-docker-image . ./deploy.sh #!/bin/sh cd /home/docker-image/client ./deploy.sh exit EOF
-
하나의 서버에서 작업하기 때문에, ssh 접속이 필요가 없었다.
-
대신, deploy 스크립트를 실행할 때 권한 문제가 생겨서 권한을 주가해줬다.
-
chmod +x deploy.sh
-
server와 client를 각각 docker를 띄워 nginx로 로드 밸런싱해준다.
-
server에 config 디렉토리와 json 파일이 필요하기 때문에, 서버에 저장해뒀다가 docker를 image화 하는 디렉토리 아래 복사해주는 명령어를 추가했다.
-
-
sequilze connection error
- GRANT ALL PRIVILEGES ON . TO root@'ip주소' IDENTIFIED BY '비밀번호'' WITH GRANT OPTION;
- DB 접근 권한이 없기 때문에 localhost로는 접근이 가능하지만, 다른 ip로 접근했을 때 나오는 오류다. HOST에게 DB를 접근할 권한을 부여해서 해결하는 방법이다.
- [nginx에서 세부 경로를 조회했을 때 React Router로 넘어가지 않는 오류](https://github.com/boostcamp-2020/IssueTracker-35/issues/10)
- react는 SPA형식으로 index.html만을 사용하지만, nginx의 경우는 URL에 맞는 html파일을 찾으려고 하는 문제가 원인.
- 설정 파일의 location 하단에 `server_name $url` 설정 파일에 url로 호스트를 설정해줘서 해결
- 에러메세지는 사라졌는데 왜일까..? 파일을 찾는게 아닌, spa 내에서 처리하게 되는걸까??
- 기타
- NodeJS 설치
- PPA 추가
- curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
- NodeJS 설치
- sudo apt-get install -y nodejs
- build-essential 설치
- sudo apt-get install build-essential
- PPA를 통해서 NodeJS를 설치하면 npm도 함께 설치가 되는데, npm install시 에러가 발생하는 것을 방지하기 위해 build-essential을 설치해준다.
- 설치가 완료되면 node -v로 버전을 확인해준다.
- server forever 구동
- forever start는 background 명령이기 때문에 도커 컨테이너가 계속 죽음 ~> forever app.js로 도커 컨테이너가 죽지 않도록 설정
- 문제점
- 동일 서버에서 클라이언트 배포, API 서버 배포, docker image화 및 jenkins, nginx를 한번에 돌리기 때문에 메모리 부하 및 용량이 걱정된다.
- 하지만, 토이 프로젝트기 때문에 큰 문제가 없을 것으로 판단되고 서버당 요금이 무시할 수준은 아니기 때문에 하나에서 진행
- 지원받는 크레딧이 있긴 하지만, 12월 까지 다른 프로젝트도 돌려야하므로 서버 한대로 진행하기로 결정했다.
Reference
- https://docs.ncloud.com/ko/devtools/devtools-1-1.html
- https://docs.ncloud.com/ko/devtools/devtools-1-2.html
- https://velog.io/@doyuni/Jenkins-NAVER-Cloud-Platform-Docker%EB%A1%9C-CICD-%EB%AC%B4%EC%A4%91%EB%8B%A8-%EB%B0%B0%ED%8F%AC-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0-1%ED%8E%B8-khk4w6hrm0
- https://velog.io/@doyuni/Jenkins-NAVER-Cloud-Platform-Docker%EB%A1%9C-CICD-%EB%AC%B4%EC%A4%91%EB%8B%A8-%EB%B0%B0%ED%8F%AC-%ED%99%98%EA%B2%BD-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0-2%ED%8E%B8-7rk4w9eynh#3-naver-cloud-%EC%84%9C%EB%B2%84%EC%97%90-docker-nginx-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0
- https://hiseon.me/linux/ubuntu/install-docker/
- https://itexpert.tips/ko/nginx-ko/%EC%9A%B0%EB%B6%84%ED%88%AC-%EB%A6%AC%EB%88%85%EC%8A%A4%EC%97%90-nginx-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0/
- https://docs.docker.com/compose/env-file/
- https://jeonghwan-kim.github.io/forever-and-docker/
- https://fishpoint.tistory.com/1406
- https://blog.naver.com/PostView.nhn?blogId=dilrong&logNo=221497936351
반응형'기술 이야기 > CI&CD' 카테고리의 다른 글
Docker Compose 한국 표준 시간 설정하기 (113) 2020.12.31 NCP와 Jenkins 글 보완 및 새로운 내용들 (0) 2020.12.19 NCP(Naver Cloud Platform)와 Jenkins -2) CI 환경 구축 (0) 2020.10.29 NCP(Naver Cloud Platform)와 Jenkins -1) 서버 구축 (0) 2020.10.27 -