SlideShare a Scribd company logo
Microservices blue-green-deployment-with-docker
Book
●
DevOps 개발관련 HOWTO 를 잘 설명하였고 이문서의 근간이 된 책
●
https://www.amazon.com/DevOps-2-0-Toolkit-Containerized-Microservices/dp/B01FEK2HFQ/ref=sr_1_7?
ie=UTF8&qid=1477957713&sr=8-7&keywords=devops+2.0
Motive
Blue/Green Deployment 는 Service Upgrade 시 Service Downtime 없이 이전 Version(Blue) 에서 새로운
Version(Green) 으로 Seamless 하게 Deploy 하는 방법.
대부분의 Microservice 들은 Proxy(예를들어 nginx) 에 연결되어 Service 를 제공.
Proxy 의 Blue Service 연결을 Green Service 연결로 바로 전환할수 있다면 가능.
그런데 효율적 Resource 사용을 위해 Microservice 들은 Docker Container 안에서 실행,
그리고 Docker Container 들은 Swarm Cluster 위에 실행.
Microservice Docker Container 를 자동 Scale Out 하기 위해 Swarm Cluster 기반으로 Docker Compose
사용.
Configuration Management Tool 은 Ansible 사용.
그외 필요한 Tool 들은 Docker Private Registry, Consul, Consul-Registrator, Consul-Template 등.
Proxy
(nginx)
Blue Service
(Collection Handler v1)
Green Service
(Collection Handler v2)
Architecture
Consul Docker
Consul-Template
Docker
Registry
Blue Service
Collection Handler
Green Service
Collection Handler
Docker-Compose
Consul Docker
Consul-Template
Docker-Compose
Consul Docker
Consul-Template
Docker-Compose
Swarm
Master
Consul
Registrator
Swarm
Node
Consul
Registrator
Blue Service
Collection Handler
Green Service
Collection Handler
Consul Docker
Consul-Template
Docker-Compose
Swarm
Node
Consul
Registrator
Consul-TemplateConsulDocker Docker-Compose
Swarm
Node
Consul
Registrator
Proxy
nginx
Blue Service
Collection Handler
Green Service
Collection Handler
Green Service
Collection Handler
Blue Service
Collection Handler
Swarm Master Swarm Slave Swarm Slave
Swarm Slave
Architecture 2
●
사각형모양중 각이 둥근 사각형은 Docker Container, 각이 진 사각형은 Library 혹은 Process 를 의미.
●
Swarm Cluster 는 크게 Swarm Master 와 여러 Swarm Slave 로 구분.
●
모든 Docker Container 는 Swarm Cluster 위에 Deploy 됨.
●
Serivce 들은 Docker Registry 에 등록됨.
●
Docker Compose 를 통해 Swarm Cluster 에 Service Deploy 시 Docker Registry 를 lookup 하여
Service Image 를 Pull 함.
●
Service Discovery Consul 을 통해 Blue 혹은 Green Service 들의 IP, Port 정보가 등록.
●
이때 Consul-Registrator 가 이 Service 들의 IP, Port 정보를 자동으로 Consul 에 등록 해줌.
●
Consul-Template 을 통해 등록된 Service 들의 IP, Port 정보를 얻어 Proxy nginx configuration 을 변경.
●
Proxy nginx 는 restart 없이 configuration reload 를 하여 downtime 없이 blue 에서 green service 로 자
동 switching 됨.
설치 Pipeline
설치 순서는 다음과 같음:
1. Consul
2. Docker
3. Consul-Registrator
4. Swarm
5. Proxy nginx
6. Service Collection Handler
설치 Pipeline: Consul
- name: Start Consul Servers
shell: "nohup {{ consul_binary }} agent -server -bootstrap-expect=1 
-data-dir={{ consul_data_dir }} 
-config-dir={{ consul_config_dir }} 
-client=0.0.0.0 
-bind={{ private_ip }} 
-node={{ inventory_hostname }} 
-ui -ui-dir={{ consul_ui_dir }} 
-pid-file={{ consul_pid_file }} 
> {{ consul_log_dir }}/consul.log 2>&1 &"
args:
executable: /bin/bash
when: (inventory_hostname == hostvars[groups['consul-server-hosts'][0]]['inventory_hostname'])
- name: Start Consul Agents
shell: "nohup {{ consul_binary }} agent -join={{ hostvars[groups['consul-server-hosts'][0]]['inventory_hostname'] }} 
-data-dir={{ consul_data_dir }} 
-config-dir={{ consul_config_dir }} 
-client=0.0.0.0 
-bind={{ private_ip }} 
-node={{ inventory_hostname }} 
-ui -ui-dir={{ consul_ui_dir }} 
-pid-file={{ consul_pid_file }} 
> {{ consul_log_dir }}/consul.log 2>&1 &"
args:
executable: /bin/bash
when: (inventory_hostname != hostvars[groups['consul-server-hosts'][0]]['inventory_hostname'])
Ansible Script 를 통해 Consul Server 와 Agent 들을 설치.
설치 Pipeline: Docker
- name: Install Docker Engine
yum:
name: docker-engine
state: latest
- name: Set docker configuration for swarm
lineinfile:
dest: /usr/lib/systemd/system/docker.service
state: present
regexp: "^ExecStart"
line: "ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 
-H unix:///var/run/docker.sock 
--insecure-registry {{ registry_url }}"
- name: Reload Daemon
shell: "systemctl daemon-reload"
- name: Restart Docker
service:
name: docker
enabled: yes
state: restarted
- name: Run Docker Registry
docker:
name: registry
image: registry:2
state: started
ports:
- "5000:5000"
volumes:
- "{{ registry_volume }}"
when: (inventory_hostname == hostvars[groups['docker-registry-host'][0]]['inventory_hostname'])
- name: Install Docker Compose
pip:
name: docker-compose
state: present
Docker Engine 설치후 dockerd line 을 변경.
Docker Registry 설치.
Docker-Compose 설치.
설치 Pipeline: Consul-Registrator
- name: Run Consul Registrator Docker Container
shell: "docker run -d --name=registrator --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest
consul://localhost:8500"
args:
executable: /bin/bash
- name: Run Consul KV Registrator Docker Container
shell: "docker run -d --name=registrator-consul-kv --net=host --volume=/var/run/docker.sock:/tmp/docker.sock
gliderlabs/registrator:latest consulkv://localhost:8500/services"
args:
executable: /bin/bash
Docker Container 로 감싼 Service 의 IP, Port 를 자동 인식하여 Consul 에 등록할수 있도록 Consul-Registrator 설치.
설치 Pipeline: Swarm
- name: Run swarm node
docker:
name: swarm-node
image: swarm
command: "join --advertise={{ private_ip }}:2375 consul://{{ private_ip }}:8500"
env:
SERVICE_NAME: swarm-node
when: inventory_hostname in groups['swarm-node-hosts']
- name: Run swarm master
shell: "docker run -d -p 4000:4000 --name swarm-master 
--env SERVICE_NAME=swarm-master 
swarm manage -H :4000 --advertise {{ private_ip }}:4000 consul://{{ private_ip }}:8500"
when: inventory_hostname in groups['swarm-master-host']
Swarm Master, Slave 설치.
전체 Swarm Cluster 의 정보를 얻으려면:
sudo docker -H <swarm-master>:4000 info;
설치 Pipeline: Proxy nginx
- name: Run nginx container
docker:
image: nginx:alpine
name: nginx
state: running
ports: "{{ ports }}"
volumes: "{{ volumes }}"
- name: Copy conf file
copy:
src: "{{ item }}"
dest: "{{ nginx_conf_dir }}"
with_items:
- "{{ playbook_dir }}/roles/{{ role_name }}/files/{{ services_conf_file }}"
register: result
- name: Reload nginx container
shell: docker kill -s HUP nginx
when: result|changed
Proxy nginx 설치.
Configuration copy 후 restart 없이 nginx reload 함.
설치 Pipeline: Service Collection Handler
Service Collection Handler Dockerfile:
FROM java:8-jre
ENV COLLECTION_HANDLER_HOME "{{ collection_handler_home }}"
RUN mkdir -p "$COLLECTION_HANDLER_HOME"
WORKDIR $COLLECTION_HANDLER_HOME
ENV VERSION "{{ collection_handler_version }}"
ENV REPOSITORY "{{ maven_repo_type }}"
ENV NEXUS_CONTEXT "{{ nexus_context }}"
ENV ZIP_URL http://$NEXUS_CONTEXT/service/local/artifact/maven/redirect?r=$REPOSITORY&g=crochet&a=crochet-collection-collection-
handler&v=$VERSION&c=stand-alone&e=zip
RUN set -x 
&& curl -fSL "$ZIP_URL" -o crochet-collection-collection-handler-$VERSION-stand-alone.zip 
&& unzip -oq *.zip 
&& chmod a+x -R bin 
&& rm -rf crochet-collection-collection-handler-$VERSION-stand-alone.zip
EXPOSE "{{ collection_handler_port }}"
Docker Container Build 후 Docker Registry 에 image 등록:
- name: Build Collection Handler Docker Image
shell: "docker build --tag {{ docker_name }}:{{ docker_version }} {{ docker_file_path }}"
args:
executable: /bin/bash
when: (inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname'])
- name: Tag and Push Collection Handler Docker Image to Registry
shell: "{{ item }}"
args:
executable: /bin/bash
with_items:
- "docker tag {{ docker_name }}:{{ docker_version }} {{ registry_tag }}"
- "docker push {{ registry_tag }}"
when: (inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname'])
설치 Pipeline: Service Collection Handler 2
- name: Run and scale Collection Handler with Compose
shell: "{{ item }}"
with_items:
- "docker-compose -f {{ docker_file_path }}/docker-compose.yml 
-p collection-handler-project 
pull {{ container_name }}"
- "docker-compose -f {{ docker_file_path }}/docker-compose.yml 
-p collection-handler-project 
up -d {{ container_name }}"
- "export DOCKER_HOST=tcp://{{ swarm_master_host }}:4000 && 
docker-compose -f {{ docker_file_path }}/docker-compose.yml 
-p collection-handler-project 
scale {{ container_name }}=3"
when:
- run_compose == "true"
- inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname']
register: output
- debug: var=output
Service Collection Handler 는 Docker Compose 를 통해 pull, up 된후 swarm cluster 에 3개의 container
가 deploy 됨.
Blue/Green Deployment: Blue
Nginx includes configuration:
location /event/v1 {
proxy_pass http://collection-handler/event/v1;
proxy_next_upstream error timeout invalid_header http_500;
}
Nginx includes configuration file 을 nginx 설정 directory 에 copy.
Nginx upstreams configuration consul template:
upstream collection-handler {
{{range service "collection-handler-blue" "any"}}
server {{.Address}}:{{.Port}};
{{end}}
}
Service Collection Handler blue 에 대한 Consul Template 으로 다음과 같은 실행을 통해 Consul 에서 Service
collection-handler-blue 의 IP, Port 정보를 얻어 Template file 을 치환한후 nginx 설정 directory 로 copy:
- name: Run Consul Template for Collection Handler Service and move it to nginx upstreams directory
shell: "{{ item }}"
args:
executable: /bin/bash
with_items:
- "{{ consul_template_binary }} 
-consul localhost:8500 
-template {{ consul_template_temp_dir }}/{{ upstreams_file }}.ctmpl:{{ consul_template_temp_dir }}/
{{ nginx_collection_handler_upstreams_base }}.conf 
-once"
- "cp {{ consul_template_temp_dir }}/{{ nginx_collection_handler_upstreams_base }}.conf {{ nginx_upstreams_dir }}/
{{ nginx_collection_handler_upstreams_base }}.conf"
register: result
그리고 nginx restart 없이 configuration reload 실행:
- name: Reload nginx container
shell: docker kill -s HUP nginx
when:
- result|changed
Blue/Green Deployment: Green
Service Collection Handler blue Deployment 와 유사하게 Green Service Deployment 역시 nginx upstreams
configuration consul template 은 아래와 같음:
upstream collection-handler {
{{range service "collection-handler-green" "any"}}
server {{.Address}}:{{.Port}};
{{end}}
}
Service Collection Handler green 역시 마찬가지로 Consul 로 부터 IP, Port 정보를 얻어 Template file 을 치환한후
nginx 설정 upstreams configuration file 을 덮어쓰기함.
그리고 nginx restart 없이 configuration reload 실행함:
- name: Reload nginx container
shell: docker kill -s HUP nginx
when:
- result|changed
이로서 blue service 에서 downtime 없이 seamless 하게 green service 로 자동 switching 되었음.
Green service 가 원활히 돌아가는것을 확인한후 blue service docker container 를 stop 시키고 삭제함:
- name: Remove Collection Handler with Compose
shell: "{{ item }}"
with_items:
- "export DOCKER_HOST=tcp://{{ swarm_master_host }}:4000 && 
docker-compose -f {{ docker_file_path }}/docker-compose.yml 
-p collection-handler-project 
stop {{ container_name }}"
- "export DOCKER_HOST=tcp://{{ swarm_master_host }}:4000 && 
docker-compose -f {{ docker_file_path }}/docker-compose.yml 
-p collection-handler-project 
rm -f {{ container_name }}"
when:
- run_compose == "true"
- inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname']
register: output
ignore_errors: true
- debug: var=output
맺음말
●
Containerization, 예를들어 Docker 는 Microservice 에 있어서 필요요소.
●
복잡한 Microservices Deployment 에는 Service Discovery(예를들어 Consul), Resource Management(예를들어
Swarm), Configuration Management(예를들어 Ansible) 등이 필요함.
●
이러한 Tool 들은 이문서의 예와 같은 DevOps Practice 를 통해 잘 활용됨으로서 가치가 드러남. 결과적으로
CI/CD 를 적용할수 있음.

More Related Content

PDF
Heat optimization
PDF
Altitude SF 2017: Nomad and next-gen application architectures
PDF
Altitude SF 2017: Advanced VCL: Shielding and Clustering
PDF
The Good Parts / The Hard Parts
PPTX
Heat and its resources
PDF
Consul - service discovery and others
PDF
Workshop Consul .- Service Discovery & Failure Detection
PDF
I can't believe it's not a queue: Kafka and Spring
Heat optimization
Altitude SF 2017: Nomad and next-gen application architectures
Altitude SF 2017: Advanced VCL: Shielding and Clustering
The Good Parts / The Hard Parts
Heat and its resources
Consul - service discovery and others
Workshop Consul .- Service Discovery & Failure Detection
I can't believe it's not a queue: Kafka and Spring

What's hot (20)

PPTX
So I Wrote a Manifest
PDF
PuppetConf 2016: An Introduction to Measuring and Tuning PE Performance – Cha...
PDF
[오픈소스컨설팅] EFK Stack 소개와 설치 방법
PDF
Kubernetes at Datadog the very hard way
PPTX
Dockerizing Windows Server Applications by Ender Barillas and Taylor Brown
PDF
Scripting Embulk Plugins
PDF
AWS와 Docker Swarm을 이용한 쉽고 빠른 컨테이너 오케스트레이션 - AWS Summit Seoul 2017
PDF
Terraform 0.9 + good practices
PDF
Fargate 를 이용한 ECS with VPC 1부
PPTX
Final terraform
PDF
From Kubernetes to OpenStack in Sydney
PDF
Setup 3 Node Kafka Cluster on AWS - Hands On
PDF
GCPUG meetup 201610 - Dataflow Introduction
PPTX
Openstack study-nova-02
PDF
TIAD : Automating the aplication lifecycle
PDF
[OpenInfra Days Korea 2018] Day 2 - E6 - OpenInfra monitoring with Prometheus
PDF
How to improve ELK log pipeline performance
KEY
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
PDF
Beyond static configuration
PDF
Fluentd at Bay Area Kubernetes Meetup
So I Wrote a Manifest
PuppetConf 2016: An Introduction to Measuring and Tuning PE Performance – Cha...
[오픈소스컨설팅] EFK Stack 소개와 설치 방법
Kubernetes at Datadog the very hard way
Dockerizing Windows Server Applications by Ender Barillas and Taylor Brown
Scripting Embulk Plugins
AWS와 Docker Swarm을 이용한 쉽고 빠른 컨테이너 오케스트레이션 - AWS Summit Seoul 2017
Terraform 0.9 + good practices
Fargate 를 이용한 ECS with VPC 1부
Final terraform
From Kubernetes to OpenStack in Sydney
Setup 3 Node Kafka Cluster on AWS - Hands On
GCPUG meetup 201610 - Dataflow Introduction
Openstack study-nova-02
TIAD : Automating the aplication lifecycle
[OpenInfra Days Korea 2018] Day 2 - E6 - OpenInfra monitoring with Prometheus
How to improve ELK log pipeline performance
modern module development - Ken Barber 2012 Edinburgh Puppet Camp
Beyond static configuration
Fluentd at Bay Area Kubernetes Meetup
Ad

Viewers also liked (20)

PDF
Lesson Learned from Using Docker Swarm at Pronto
PDF
Blue Green Deploy: Entrega continua e rollback imediato - QCon Rio / 2014
PDF
Introduction to Docker
PDF
High Volume Monitoring with Graphite
PDF
Spring boot
DOCX
PRACTICA DE CONTROL DE MEDICAMENTOS
PPTX
Dropwizard
PPTX
Continuous deployment of polyglot microservices: A practical approach
PDF
COSCUP 2016: Project 52 每週一個小專案來學習 Golang
PDF
CF WebUI - CloudFoundry User Group DACH
PPTX
Golang 入門初體驗
PPTX
CloudStack - Apache's best kept secret
PDF
CloudStack Container Service
PPTX
CloudStack EU user group - CloudStack news
PPTX
CloudStack EU user group - Trillian
ODP
Publishing RDF SKOS with microservices
PPTX
Jenkins vs gogs
PPTX
Dropwizard Introduction
PPTX
What's New in NGINX Plus R10?
PPTX
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Lesson Learned from Using Docker Swarm at Pronto
Blue Green Deploy: Entrega continua e rollback imediato - QCon Rio / 2014
Introduction to Docker
High Volume Monitoring with Graphite
Spring boot
PRACTICA DE CONTROL DE MEDICAMENTOS
Dropwizard
Continuous deployment of polyglot microservices: A practical approach
COSCUP 2016: Project 52 每週一個小專案來學習 Golang
CF WebUI - CloudFoundry User Group DACH
Golang 入門初體驗
CloudStack - Apache's best kept secret
CloudStack Container Service
CloudStack EU user group - CloudStack news
CloudStack EU user group - Trillian
Publishing RDF SKOS with microservices
Jenkins vs gogs
Dropwizard Introduction
What's New in NGINX Plus R10?
Continuous Deployment into the Unknown with Artifactory, Bintray, Docker and ...
Ad

Similar to Microservices blue-green-deployment-with-docker (20)

PDF
Deploying and Scaling a Rails Application with Docker and Friends
PPTX
Running Docker in Development & Production (#ndcoslo 2015)
PPTX
Simple docker hosting in FIWARE Lab
PPTX
Microservices with docker swarm and consul
PPTX
Docker Security workshop slides
PDF
Easy Cloud Native Transformation using HashiCorp Nomad
PDF
Fullstack conf 2017 - Basic dev pipeline end-to-end
PPTX
Software Defined Datacenter
PDF
Things I've learned working with Docker Support
PPTX
An intro to Docker, Terraform, and Amazon ECS
PDF
Cloud-native applications with Java and Kubernetes - Yehor Volkov
PDF
JDO 2019: Tips and Tricks from Docker Captain - Łukasz Lach
PDF
Docker summit 2015: 以 Docker Swarm 打造多主機叢集環境
PPTX
Amazon Web Services and Docker: from developing to production
PDF
MeaNstack on Docker
PDF
Infrastructure = code - 1 year later
PDF
Docker for Ruby Developers
PDF
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
PDF
Challenges of container configuration
PDF
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview
Deploying and Scaling a Rails Application with Docker and Friends
Running Docker in Development & Production (#ndcoslo 2015)
Simple docker hosting in FIWARE Lab
Microservices with docker swarm and consul
Docker Security workshop slides
Easy Cloud Native Transformation using HashiCorp Nomad
Fullstack conf 2017 - Basic dev pipeline end-to-end
Software Defined Datacenter
Things I've learned working with Docker Support
An intro to Docker, Terraform, and Amazon ECS
Cloud-native applications with Java and Kubernetes - Yehor Volkov
JDO 2019: Tips and Tricks from Docker Captain - Łukasz Lach
Docker summit 2015: 以 Docker Swarm 打造多主機叢集環境
Amazon Web Services and Docker: from developing to production
MeaNstack on Docker
Infrastructure = code - 1 year later
Docker for Ruby Developers
PuppetConf 2016: The Challenges with Container Configuration – David Lutterko...
Challenges of container configuration
[EXTENDED] Ceph, Docker, Heroku Slugs, CoreOS and Deis Overview

Recently uploaded (20)

PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Electronic commerce courselecture one. Pdf
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
MYSQL Presentation for SQL database connectivity
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Encapsulation theory and applications.pdf
PPTX
Cloud computing and distributed systems.
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
Understanding_Digital_Forensics_Presentation.pptx
Chapter 3 Spatial Domain Image Processing.pdf
Electronic commerce courselecture one. Pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
MYSQL Presentation for SQL database connectivity
NewMind AI Monthly Chronicles - July 2025
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Spectral efficient network and resource selection model in 5G networks
Review of recent advances in non-invasive hemoglobin estimation
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
20250228 LYD VKU AI Blended-Learning.pptx
Encapsulation theory and applications.pdf
Cloud computing and distributed systems.
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Mobile App Security Testing_ A Comprehensive Guide.pdf
“AI and Expert System Decision Support & Business Intelligence Systems”

Microservices blue-green-deployment-with-docker

  • 2. Book ● DevOps 개발관련 HOWTO 를 잘 설명하였고 이문서의 근간이 된 책 ● https://www.amazon.com/DevOps-2-0-Toolkit-Containerized-Microservices/dp/B01FEK2HFQ/ref=sr_1_7? ie=UTF8&qid=1477957713&sr=8-7&keywords=devops+2.0
  • 3. Motive Blue/Green Deployment 는 Service Upgrade 시 Service Downtime 없이 이전 Version(Blue) 에서 새로운 Version(Green) 으로 Seamless 하게 Deploy 하는 방법. 대부분의 Microservice 들은 Proxy(예를들어 nginx) 에 연결되어 Service 를 제공. Proxy 의 Blue Service 연결을 Green Service 연결로 바로 전환할수 있다면 가능. 그런데 효율적 Resource 사용을 위해 Microservice 들은 Docker Container 안에서 실행, 그리고 Docker Container 들은 Swarm Cluster 위에 실행. Microservice Docker Container 를 자동 Scale Out 하기 위해 Swarm Cluster 기반으로 Docker Compose 사용. Configuration Management Tool 은 Ansible 사용. 그외 필요한 Tool 들은 Docker Private Registry, Consul, Consul-Registrator, Consul-Template 등. Proxy (nginx) Blue Service (Collection Handler v1) Green Service (Collection Handler v2)
  • 4. Architecture Consul Docker Consul-Template Docker Registry Blue Service Collection Handler Green Service Collection Handler Docker-Compose Consul Docker Consul-Template Docker-Compose Consul Docker Consul-Template Docker-Compose Swarm Master Consul Registrator Swarm Node Consul Registrator Blue Service Collection Handler Green Service Collection Handler Consul Docker Consul-Template Docker-Compose Swarm Node Consul Registrator Consul-TemplateConsulDocker Docker-Compose Swarm Node Consul Registrator Proxy nginx Blue Service Collection Handler Green Service Collection Handler Green Service Collection Handler Blue Service Collection Handler Swarm Master Swarm Slave Swarm Slave Swarm Slave
  • 5. Architecture 2 ● 사각형모양중 각이 둥근 사각형은 Docker Container, 각이 진 사각형은 Library 혹은 Process 를 의미. ● Swarm Cluster 는 크게 Swarm Master 와 여러 Swarm Slave 로 구분. ● 모든 Docker Container 는 Swarm Cluster 위에 Deploy 됨. ● Serivce 들은 Docker Registry 에 등록됨. ● Docker Compose 를 통해 Swarm Cluster 에 Service Deploy 시 Docker Registry 를 lookup 하여 Service Image 를 Pull 함. ● Service Discovery Consul 을 통해 Blue 혹은 Green Service 들의 IP, Port 정보가 등록. ● 이때 Consul-Registrator 가 이 Service 들의 IP, Port 정보를 자동으로 Consul 에 등록 해줌. ● Consul-Template 을 통해 등록된 Service 들의 IP, Port 정보를 얻어 Proxy nginx configuration 을 변경. ● Proxy nginx 는 restart 없이 configuration reload 를 하여 downtime 없이 blue 에서 green service 로 자 동 switching 됨.
  • 6. 설치 Pipeline 설치 순서는 다음과 같음: 1. Consul 2. Docker 3. Consul-Registrator 4. Swarm 5. Proxy nginx 6. Service Collection Handler
  • 7. 설치 Pipeline: Consul - name: Start Consul Servers shell: "nohup {{ consul_binary }} agent -server -bootstrap-expect=1 -data-dir={{ consul_data_dir }} -config-dir={{ consul_config_dir }} -client=0.0.0.0 -bind={{ private_ip }} -node={{ inventory_hostname }} -ui -ui-dir={{ consul_ui_dir }} -pid-file={{ consul_pid_file }} > {{ consul_log_dir }}/consul.log 2>&1 &" args: executable: /bin/bash when: (inventory_hostname == hostvars[groups['consul-server-hosts'][0]]['inventory_hostname']) - name: Start Consul Agents shell: "nohup {{ consul_binary }} agent -join={{ hostvars[groups['consul-server-hosts'][0]]['inventory_hostname'] }} -data-dir={{ consul_data_dir }} -config-dir={{ consul_config_dir }} -client=0.0.0.0 -bind={{ private_ip }} -node={{ inventory_hostname }} -ui -ui-dir={{ consul_ui_dir }} -pid-file={{ consul_pid_file }} > {{ consul_log_dir }}/consul.log 2>&1 &" args: executable: /bin/bash when: (inventory_hostname != hostvars[groups['consul-server-hosts'][0]]['inventory_hostname']) Ansible Script 를 통해 Consul Server 와 Agent 들을 설치.
  • 8. 설치 Pipeline: Docker - name: Install Docker Engine yum: name: docker-engine state: latest - name: Set docker configuration for swarm lineinfile: dest: /usr/lib/systemd/system/docker.service state: present regexp: "^ExecStart" line: "ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --insecure-registry {{ registry_url }}" - name: Reload Daemon shell: "systemctl daemon-reload" - name: Restart Docker service: name: docker enabled: yes state: restarted - name: Run Docker Registry docker: name: registry image: registry:2 state: started ports: - "5000:5000" volumes: - "{{ registry_volume }}" when: (inventory_hostname == hostvars[groups['docker-registry-host'][0]]['inventory_hostname']) - name: Install Docker Compose pip: name: docker-compose state: present Docker Engine 설치후 dockerd line 을 변경. Docker Registry 설치. Docker-Compose 설치.
  • 9. 설치 Pipeline: Consul-Registrator - name: Run Consul Registrator Docker Container shell: "docker run -d --name=registrator --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest consul://localhost:8500" args: executable: /bin/bash - name: Run Consul KV Registrator Docker Container shell: "docker run -d --name=registrator-consul-kv --net=host --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest consulkv://localhost:8500/services" args: executable: /bin/bash Docker Container 로 감싼 Service 의 IP, Port 를 자동 인식하여 Consul 에 등록할수 있도록 Consul-Registrator 설치.
  • 10. 설치 Pipeline: Swarm - name: Run swarm node docker: name: swarm-node image: swarm command: "join --advertise={{ private_ip }}:2375 consul://{{ private_ip }}:8500" env: SERVICE_NAME: swarm-node when: inventory_hostname in groups['swarm-node-hosts'] - name: Run swarm master shell: "docker run -d -p 4000:4000 --name swarm-master --env SERVICE_NAME=swarm-master swarm manage -H :4000 --advertise {{ private_ip }}:4000 consul://{{ private_ip }}:8500" when: inventory_hostname in groups['swarm-master-host'] Swarm Master, Slave 설치. 전체 Swarm Cluster 의 정보를 얻으려면: sudo docker -H <swarm-master>:4000 info;
  • 11. 설치 Pipeline: Proxy nginx - name: Run nginx container docker: image: nginx:alpine name: nginx state: running ports: "{{ ports }}" volumes: "{{ volumes }}" - name: Copy conf file copy: src: "{{ item }}" dest: "{{ nginx_conf_dir }}" with_items: - "{{ playbook_dir }}/roles/{{ role_name }}/files/{{ services_conf_file }}" register: result - name: Reload nginx container shell: docker kill -s HUP nginx when: result|changed Proxy nginx 설치. Configuration copy 후 restart 없이 nginx reload 함.
  • 12. 설치 Pipeline: Service Collection Handler Service Collection Handler Dockerfile: FROM java:8-jre ENV COLLECTION_HANDLER_HOME "{{ collection_handler_home }}" RUN mkdir -p "$COLLECTION_HANDLER_HOME" WORKDIR $COLLECTION_HANDLER_HOME ENV VERSION "{{ collection_handler_version }}" ENV REPOSITORY "{{ maven_repo_type }}" ENV NEXUS_CONTEXT "{{ nexus_context }}" ENV ZIP_URL http://$NEXUS_CONTEXT/service/local/artifact/maven/redirect?r=$REPOSITORY&g=crochet&a=crochet-collection-collection- handler&v=$VERSION&c=stand-alone&e=zip RUN set -x && curl -fSL "$ZIP_URL" -o crochet-collection-collection-handler-$VERSION-stand-alone.zip && unzip -oq *.zip && chmod a+x -R bin && rm -rf crochet-collection-collection-handler-$VERSION-stand-alone.zip EXPOSE "{{ collection_handler_port }}" Docker Container Build 후 Docker Registry 에 image 등록: - name: Build Collection Handler Docker Image shell: "docker build --tag {{ docker_name }}:{{ docker_version }} {{ docker_file_path }}" args: executable: /bin/bash when: (inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname']) - name: Tag and Push Collection Handler Docker Image to Registry shell: "{{ item }}" args: executable: /bin/bash with_items: - "docker tag {{ docker_name }}:{{ docker_version }} {{ registry_tag }}" - "docker push {{ registry_tag }}" when: (inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname'])
  • 13. 설치 Pipeline: Service Collection Handler 2 - name: Run and scale Collection Handler with Compose shell: "{{ item }}" with_items: - "docker-compose -f {{ docker_file_path }}/docker-compose.yml -p collection-handler-project pull {{ container_name }}" - "docker-compose -f {{ docker_file_path }}/docker-compose.yml -p collection-handler-project up -d {{ container_name }}" - "export DOCKER_HOST=tcp://{{ swarm_master_host }}:4000 && docker-compose -f {{ docker_file_path }}/docker-compose.yml -p collection-handler-project scale {{ container_name }}=3" when: - run_compose == "true" - inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname'] register: output - debug: var=output Service Collection Handler 는 Docker Compose 를 통해 pull, up 된후 swarm cluster 에 3개의 container 가 deploy 됨.
  • 14. Blue/Green Deployment: Blue Nginx includes configuration: location /event/v1 { proxy_pass http://collection-handler/event/v1; proxy_next_upstream error timeout invalid_header http_500; } Nginx includes configuration file 을 nginx 설정 directory 에 copy. Nginx upstreams configuration consul template: upstream collection-handler { {{range service "collection-handler-blue" "any"}} server {{.Address}}:{{.Port}}; {{end}} } Service Collection Handler blue 에 대한 Consul Template 으로 다음과 같은 실행을 통해 Consul 에서 Service collection-handler-blue 의 IP, Port 정보를 얻어 Template file 을 치환한후 nginx 설정 directory 로 copy: - name: Run Consul Template for Collection Handler Service and move it to nginx upstreams directory shell: "{{ item }}" args: executable: /bin/bash with_items: - "{{ consul_template_binary }} -consul localhost:8500 -template {{ consul_template_temp_dir }}/{{ upstreams_file }}.ctmpl:{{ consul_template_temp_dir }}/ {{ nginx_collection_handler_upstreams_base }}.conf -once" - "cp {{ consul_template_temp_dir }}/{{ nginx_collection_handler_upstreams_base }}.conf {{ nginx_upstreams_dir }}/ {{ nginx_collection_handler_upstreams_base }}.conf" register: result 그리고 nginx restart 없이 configuration reload 실행: - name: Reload nginx container shell: docker kill -s HUP nginx when: - result|changed
  • 15. Blue/Green Deployment: Green Service Collection Handler blue Deployment 와 유사하게 Green Service Deployment 역시 nginx upstreams configuration consul template 은 아래와 같음: upstream collection-handler { {{range service "collection-handler-green" "any"}} server {{.Address}}:{{.Port}}; {{end}} } Service Collection Handler green 역시 마찬가지로 Consul 로 부터 IP, Port 정보를 얻어 Template file 을 치환한후 nginx 설정 upstreams configuration file 을 덮어쓰기함. 그리고 nginx restart 없이 configuration reload 실행함: - name: Reload nginx container shell: docker kill -s HUP nginx when: - result|changed 이로서 blue service 에서 downtime 없이 seamless 하게 green service 로 자동 switching 되었음. Green service 가 원활히 돌아가는것을 확인한후 blue service docker container 를 stop 시키고 삭제함: - name: Remove Collection Handler with Compose shell: "{{ item }}" with_items: - "export DOCKER_HOST=tcp://{{ swarm_master_host }}:4000 && docker-compose -f {{ docker_file_path }}/docker-compose.yml -p collection-handler-project stop {{ container_name }}" - "export DOCKER_HOST=tcp://{{ swarm_master_host }}:4000 && docker-compose -f {{ docker_file_path }}/docker-compose.yml -p collection-handler-project rm -f {{ container_name }}" when: - run_compose == "true" - inventory_hostname == hostvars[groups['collection-handler-hosts'][0]]['inventory_hostname'] register: output ignore_errors: true - debug: var=output
  • 16. 맺음말 ● Containerization, 예를들어 Docker 는 Microservice 에 있어서 필요요소. ● 복잡한 Microservices Deployment 에는 Service Discovery(예를들어 Consul), Resource Management(예를들어 Swarm), Configuration Management(예를들어 Ansible) 등이 필요함. ● 이러한 Tool 들은 이문서의 예와 같은 DevOps Practice 를 통해 잘 활용됨으로서 가치가 드러남. 결과적으로 CI/CD 를 적용할수 있음.