Giter VIP home page Giter VIP logo

docker-swarm-blue-green's Introduction

Blue-Green Deployment to the Docker Swarm Cluster

Prerequisites

  • VirtualBox
  • Vagrant

Steps

# TODO: git clone

cd docker-swarm-blue-green

vagrant up

# Configures Ansible on the swarm-master node

vagrant ssh swarm-master

ansible-playbook /vagrant/ansible/swarm.yml -i /vagrant/ansible/hosts/dev

curl 10.100.192.200:8500/v1/catalog/nodes | jq '.'
[
  {
    "Node": "swarm-master",
    "Address": "10.100.192.200"
  },
  {
    "Node": "swarm-node-1",
    "Address": "10.100.192.201"
  },
  {
    "Node": "swarm-node-2",
    "Address": "10.100.192.202"
  }
]
export DOCKER_HOST=tcp://10.100.192.200:2375

docker info
Containers: 6
Images: 6
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
Nodes: 2
 swarm-node-1: 10.100.192.201:2375
  └ Containers: 3
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.19.0-31-generic, operatingsystem=Ubuntu 15.04, storagedriver=devicemapper
 swarm-node-2: 10.100.192.202:2375
  └ Containers: 3
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.19.0-31-generic, operatingsystem=Ubuntu 15.04, storagedriver=devicemapper
CPUs: 2
Total Memory: 2.037 GiB
Name: 0b8218c618d2
docker ps --format "table {{.Names}}"
NAMES
swarm-node-2/registrator
swarm-node-2/consul
swarm-node-1/registrator
swarm-node-1/consul
cd /vagrant/books-ms

chmod +x *.sh

cat nginx-includes.conf
location /api/v1/books {
  proxy_pass http://books-ms/api/v1/books;
  proxy_next_upstream error timeout invalid_header http_500;
}
sudo cp nginx-includes.conf /data/nginx/includes/books-ms.conf

cat get-next-color.sh
#!/usr/bin/env bash

CURR_COLOR=`curl http://localhost:8500/v1/kv/books-ms/color?raw`

if [ "$CURR_COLOR" == "blue" ]; then
    echo "green"
else
    echo "blue"
fi
cat docker-compose.yml
app:
  image: vfarcic/books-ms
  ports:
    - 8080
  environment:
    - SERVICE_NAME=books-ms
    - DB_HOST=books-ms-db

app-blue:
  environment:
    - SERVICE_NAME=books-ms-blue
  extends:
    service: app

app-green:
  environment:
    - SERVICE_NAME=books-ms-green
  extends:
    service: app

db:
  container_name: books-ms-db
  image: mongo
  environment:
    - SERVICE_NAME=books-ms-db
NEXT_COLOR=$(./get-next-color.sh)

export DOCKER_HOST=tcp://10.100.192.200:2375

docker-compose pull app

docker-compose stop app-$NEXT_COLOR

docker-compose rm -f app-$NEXT_COLOR

docker-compose --x-networking up -d db

docker-compose --x-networking scale app-$NEXT_COLOR=2

docker ps --filter name=books --format "table {{.Names}}"

curl 10.100.192.200:8500/v1/catalog/service/books-ms-$NEXT_COLOR | jq '.'
[
  {
    "Node": "swarm-node-2",
    "Address": "10.100.192.202",
    "ServiceID": "swarm-node-2:booksms_app-blue_1:8080",
    "ServiceName": "books-ms-blue",
    "ServiceTags": null,
    "ServiceAddress": "10.100.192.202",
    "ServicePort": 32769
  },
  {
    "Node": "swarm-node-1",
    "Address": "10.100.192.201",
    "ServiceID": "swarm-node-1:booksms_app-blue_2:8080",
    "ServiceName": "books-ms-blue",
    "ServiceTags": null,
    "ServiceAddress": "10.100.192.201",
    "ServicePort": 32769
  }
]
# Pre-Integration Testing

ADDRESS=`curl \
    localhost:8500/v1/catalog/service/books-ms-$NEXT_COLOR \
    | jq -r '.[0].ServiceAddress + ":" + (.[0].ServicePort | tostring)'`

curl http://$ADDRESS/api/v1/books | jq '.'

# Integration

cat nginx-upstreams-$NEXT_COLOR.ctmpl
upstream books-ms {
    {{range service "books-ms-blue" "any"}}
    server {{.Address}}:{{.Port}};
    {{end}}
}
sudo consul-template -consul localhost:8500 -template "nginx-upstreams-$NEXT_COLOR.ctmpl:/data/nginx/upstreams/books-ms.conf:docker kill -s HUP nginx" -once

cat /data/nginx/upstreams/books-ms.conf
upstream books-ms {

    server 10.100.192.201:32769;

    server 10.100.192.202:32769;

}
# Post-Integration Testing

curl http://10.100.192.200/api/v1/books | jq '.'

curl http://10.100.192.200/api/v1/books | jq '.'

curl http://10.100.192.200/api/v1/books | jq '.'

sudo docker logs nginx
... "GET /api/v1/books HTTP/1.1" 200 201 "-" "curl/7.38.0" "-" 10.100.192.201:32769
... "GET /api/v1/books HTTP/1.1" 200 201 "-" "curl/7.38.0" "-" 10.100.192.202:32769
... "GET /api/v1/books HTTP/1.1" 200 201 "-" "curl/7.38.0" "-" 10.100.192.201:32769
curl -X PUT -d $NEXT_COLOR localhost:8500/v1/kv/books-ms/color

NEXT_COLOR=$(./get-next-color.sh)

docker-compose stop app-$NEXT_COLOR

# Second Release

NEXT_COLOR=$(./get-next-color.sh)

docker-compose pull app

docker-compose stop app-$NEXT_COLOR

docker-compose rm -f app-$NEXT_COLOR

docker-compose --x-networking up -d db

docker-compose --x-networking scale app-$NEXT_COLOR=2

docker ps --filter name=books --format "table {{.Names}}"
NAMES
swarm-node-1/booksms_app-green_2
swarm-node-2/booksms_app-green_1
swarm-node-1/booksms_app-blue_2
swarm-node-1/books-ms-db
swarm-node-2/booksms_app-blue_1

# Pre-Integration Testing

ADDRESS=`curl \
    localhost:8500/v1/catalog/service/books-ms-$NEXT_COLOR \
    | jq -r '.[0].ServiceAddress + ":" + (.[0].ServicePort | tostring)'`

curl http://$ADDRESS/api/v1/books | jq '.'

# Integration

sudo consul-template -consul localhost:8500 -template "nginx-upstreams-$NEXT_COLOR.ctmpl:/data/nginx/upstreams/books-ms.conf:docker kill -s HUP nginx" -once

# Post-Integration Testing

curl http://10.100.192.200/api/v1/books | jq '.'

curl http://10.100.192.200/api/v1/books | jq '.'

curl http://10.100.192.200/api/v1/books | jq '.'

sudo docker logs nginx
... "GET /api/v1/books HTTP/1.1" 200 201 "-" "curl/7.38.0" "-" 10.100.192.201:32770
... "GET /api/v1/books HTTP/1.1" 200 201 "-" "curl/7.38.0" "-" 10.100.192.202:32770
... "GET /api/v1/books HTTP/1.1" 200 201 "-" "curl/7.38.0" "-" 10.100.192.201:32770
curl -X PUT -d $NEXT_COLOR localhost:8500/v1/kv/books-ms/color

NEXT_COLOR=$(./get-next-color.sh)

docker-compose stop app-$NEXT_COLOR

docker ps -a --filter name=books --format "table {{.Names}}\t{{.Status}}"
NAMES                              STATUS
swarm-node-1/booksms_app-green_2   Up 4 minutes
swarm-node-2/booksms_app-green_1   Up 4 minutes
swarm-node-1/booksms_app-blue_2    Exited (137) About a minute ago
swarm-node-1/books-ms-db           Up 16 minutes
swarm-node-2/booksms_app-blue_1    Exited (137) About a minute ago

Open http://10.100.192.200:8500/

TODO

  • Change Compose to latest version

docker-swarm-blue-green's People

Contributors

vfarcic avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.