🐳 Docker를 이용한 배포
Dockerizing
Application 을 Docker Image로 Wrapping
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "node", "index.js" ]
Docker Registry
Docker Image에 대한 저장소
기본적으로 Docker Hub를 사용
Application 배포시에는 Private Registry를 사용
version: "3"
services:
registry:
container_name: registry
image: registry:2.6
ports:
- 5000:5000
volumes:
- "./registry-data:/var/lib/registry"Docker Image로 제공
ECR, Quay.io ...
Docker Registry
# docker image build
docker build -t test-server .
# docker image tagging
docker tag test-server localhost:5000/test-server
# docker image push
docker push localhost:5000/test-serverDocker Image Push 과정
docker tag <옵션> <이미지 이름>:<태그> <저장소 주소, 사용자명>/<이미지 이름>:<태그>
Docker Tag 형식
이제 배포
다른 머신에 배포하려면 ?
App Dockerizing & Build
Image Registry Push
Image Pull & Run
Node-01
Node-02
Docker Daemon
- Container를 관리하는 Background 프로세스
Docker Socket
- 실행시 옵션을 받거나 혹은 daemon.json 파일을 통해서 관리
- Docker Daemon 은 Docker Engine API를 요청해서 사용
- Docker Engine API는 unix, tcp, fd 세가지 Socket을 사용 가능
$ sudo dockerd -H unix:///var/run/docker.sock -H tcp://192.168.59.106 -H tcp://10.10.10.2
example
DOCKER_HOST 환경 변수
Docker Remote API 를 요청하는 소켓을 지정할 수 있음
$ export DOCKER_HOST="tcp://0.0.0.0:2375"
Node01
Node02
192.168.0.1
192.168.0.2
DOCKER_HOST=192.168.0.1
$ docker run echo -d
echo
Shell Script를 통한 Deploy
LOCAL_IMAGE=test-server
REMOTE_IMAGE=registry:5000/test-server
echo "Build Image"
docker build -t ${LOCAL_IMAGE} .
docker tag ${LOCAL_IMAGE} ${REMOTE_IMAGE}
docker push ${REMOTE_IMAGE}
echo "Deploy node02"
export DOCKER_HOST="tcp://node02:3000"
docker pull ${REMOTE_IMAGE}
docker rm -f test-server || true
docker run -p 4000:3000 --name test-server -d ${REMOTE_IMAGE}
Node 1번에서 2번으로 배포하는 스크립트
Blue - Green 배포

Load Balancer를 이용해서 무중단 배포
Nginx load balancing config
http {
upstream app {
server localhost:4000;
server localhost:4001;
}
server {
listen 80;
location / {
proxy_pass http://app;
}
}
}
Helth check를 통해서 살아있는 쪽으로 트래픽 전달
컨테이너를 순차적으로 업데이트 가능
Blue-Green Script
#!/bin/sh
export DOCKER_HOST=...
if [ $(docker ps -f name=blue -q) ]
then
ENV="green"
PORT=4000
OLD="blue"
else
ENV="blue"
PORT=4001
OLD="green"
fi
echo "Starting "$ENV" container"
PORT=${PORT} docker-compose --project-name=$ENV up -d
echo "Waiting..."
sleep 5s
echo "Stopping "$OLD" container"
docker-compose --project-name=$OLD down
Nginx load balancing 단점
물리 노드가 추가될시 자동으로 인식 불가능 (설정파일 수정)
고정적인 IP & Port
Docker Swarm
Docker 에 기본적으로 내장된 컨테이너 오케스트레이션 툴
오케스트레이션 ?
컨테이너 스케쥴링
클러스터링
서비스 디스커버리
멀티 호스트 네트워크 지원 (Overlay)
매니저 노드와 워커 노드
스웜 클러스터 상태 관리를 위한 노드
$ docker swarm init
초기에 스웜을 initialize 한 노드가 매니저 노드
$ docker swarm join <token>
매니저 노드에 조인한 다른 노드들
워커 노드
서비스
스웜 모드에서의 기본적인 배포 단위
Compose와 비슷하지만 Multi Host에 배포가 가능하고 Scale 설정
$ docker service create --replicas 1 --publish 8000:8000 --name echo registry/echo
replicas 는 배포될 container 개수를 의미
service scale 명령을 통해 추후에 scale 조정 가능
Ingress Network

서비스가 publish 한 port를 모든 Host가 해당 port를 open
현재 살아있는 node에 알아서 전달
Rolling Update
$ docker service update --image <최신이미지> ip-server
docker swarm이 알아서 순차적으로 이미지를 업데이트

상황에따라서 중단될수도 그렇지 않을수도 있음
스택
하나의 이상의 서비스를 그룹으로 묶은 단위
version: "3"
services:
nginx:
image: gihyodocker/nginx-proxy:latest
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
environment:
SERVICE_PORTS: 80
BACKEND_HOST: echo_api:8080
depends_on:
- api
networks:
- ch03
api:
image: registry:5000/example/echo:latest
deploy:
replicas: 3
placement:
constraints: [node.role != manager]
networks:
- ch03
Reverse Proxy 이용하기(traefik)

Swarm mode traefik
version: "3.3"
services:
traefik:
image: traefik
command: --web \
--docker \
--docker.swarmmode \
--docker.domain=test.com \
--docker.watch \
--logLevel=DEBUG
ports:
- "80:80"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- ch03
deploy:
placement:
constraints: [node.role==manager]
networks:
ch03:
external: true
Docker Event 감시 host 추가되면 도메인 연결
Jenkins를 이용한 CI / CD
Jenkins Setup
Dockerfile
FROM jenkinsci/jenkins:latest
USER root
RUN apt-get update -qq
RUN apt-get install -qqy apt-transport-https ca-certificates
RUN apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
RUN echo deb https://apt.dockerproject.org/repo debian-jessie main > /etc/apt/sources.list.d/docker.list
RUN apt-get update -qq
RUN apt-get install -qqy docker-engine
USER jenkinsJenkins 이미지 내부에서 Docker 사용을 위해 Docker-Engine 셋업
Jenkins Setup

귀찮다면 추천 플러그인 모두 설치
Docker를 이용한 배포
By y0c
Docker를 이용한 배포
- 580