Easy Docker Orchestration With Docker 1.12, AWS EFS And The Swarm Mode

Docker is a powerful tool, however learning how to use it the right way could take a long time especially with the rapidly growing ecosystem of containers which could be confusing, that is why I had the idea to start writing Painless Docker.

Painless Docker is a complete and detailed guide (for beginners and intermediate levels) to create, deploy, optimize, secure, trace, debug, log,orchestrate & monitor Docker and Docker clusters in order to create a good quality microservices applications.

This article is more detailed in this book.

I already wrote about this in a recent post ( MicroServices From Development To Production Using Docker, Docker Compose & Docker Swarm ), but I was using the candidate release. So I couldn’t really talk about using it in production.

Now that the stable version is out, I started already using it in production.

This is a tutorial about the basics if using Docker in Swarm mode.

What’s New

You can see all of the new features here, but the most important are may be:

  • Support for UTF-8 in Dockerfiles
  • An additional syslog-format option rfc5424micro to allow microsecond resolution in syslog timestamp
  • New plugin command to manager plugins with install, enable, disable, rm, inspect, set subcommand
  • ..etc
  • And of course the Swarm Mode !

Docker Installation

For the latest Docker engine, just type:

curl -fsSL https://get.docker.com/ | sh

Be sure you are on the right version:

docker -v
Docker version 1.12.0, build 8eab29e

The Amazon Elastic File System

Amazon EFS is a scalable file storage for use with Amazon EC2 instances in the AWS Cloud.

EFS is 10x more expensive than S3 and 3x more expensive that EBS General Purpose SSD (gp2) volumes but it has multiple advantages.

I needed to use and share disk volumes in several times, but EBS are not intended to be used by two EC2 instances and it is probably a bad idea to do it. So I was simply waiting for an AWS built-in solution and EFS was what I needed: Sharing one volumes between multiples instances, in my case it was docker containers sharing the same file system.

EFS storage capacity is elastic and it shrinks automatically as you add or remove files.

It’s designed for

  • High availability
  • Big Data and analytics
  • Media processing
  • And of course sharing FS between multiples instances

EFS clusters can be created using a wizard:

https://eu-west-1.console.aws.amazon.com/efs/home?region=[YourRegion]

To create a “high available” EFS cluster, you should choose two distinct availability zones.

EFS Wizard — Creation & Configuration of VPC/Availability Zones/Security Groups ..etc

Now it’s time to set up the EC2 instance, for this example, I created two VMs.

iron-1 : 10.0.1.226
iron-2 : 10.0.2.99

Using the EC2 console, associate your EC2 instance with a VPC security group that enables access to your mount target

Open an SSH client and connect to your EC2 instance.

Install the nfs client on both two machines:

  • For Amazon Linux, Red Hat Enterprise Linux, or SuSE:
sudo yum install -y nfs-utils
  • For Ubuntu :

sudo apt-get install nfs-common

Create a directory that will host the data of our containers.

sudo mkdir /data

Mount your file system using the Elastic File System DNS name + the availability zone.

An example:

eu-west-1.fs-51d03998.efs.eu-west-1.amazonaws.com

We can use the EC2 instance metadata URI 169.254.169.254, to get the availability zone, then mounts the file system using the DNS name for that AZ.

sudo mount -t nfs4 -o nfsvers=4.1 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).fs-51d03998.efs.eu-west-1.amazonaws.com:/ /folder

in my case:

sudo mount -t nfs4 -o nfsvers=4.1 $(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone).fs-51d03998.efs.eu-west-1.amazonaws.com:/ /data

and what I generally do is :

sudo chown -R ubuntu /data

Using Docker In Swarm Mode

Here we come. Using Docker in Swarm Mode means having a cluster of generally two or more machines forming a distributed system where there is a leader and once it is down, there is always an election of a new leader.

Start by creating the cluster by typing the following command on the first machine:

ubuntu@iron-1:~$ docker swarm init --listen-addr 10.0.1.226
Swarm will generate a command that you should type on the other node VMs in order to join the cluster.

In the second machine:

ubuntu@iron-2:~$ sudo docker swarm join --token SWMTKN-1–5es9crb3syr59ad9d70nhhb3js5co83fd22n288trbt8owy3bw-1vb89cqsunoslvihqve1moygk 10.0.1.226:2377

In order to verify if everything is fine, list the nodes using this command:

ubuntu@iron-1:~$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
2spdpr7hi9dbjfxomhb8ba8tw * iron-1 Ready Active Leader
6z5ef8jyiomc7oq8aecgg68kj iron-2 Ready Active Reachable

Before moving to anything else, we need the driver used by Docker in order to access EFS, and we will use docker-volume-netshare.

You can follow the instructions in the Github Readme for more details and for the installation, but what we need here is a container running another container.

wget https://github.com/ContainX/docker-volume-netshare/releases/download/v0.18/docker-volume-netshare_0.18_amd64.deb
sudo dpkg -i docker-volume-netshare_0.18_amd64.deb

Modify the startup options in

/etc/default/docker-volume-netshare

Start the service

service docker-volume-netshare start

Then

sudo docker-volume-netshare efs
docker run -i -t --volume-driver=efs -v fs-51d03998:/mount ubuntu /bin/bash

Our cluster is set up, let’s launch a container (in one of the nodes)and map its file system to our directory (already mounted to the EFS).

root@iron-1:/apps/vote# docker service create --name vote -p 8080:80 --mount type=bind,source=/app,target=/data/vote/ eon01/vote:v1
2564e444d8kbjjcuf28hacce2

Scaling has never been easier, just type the following line to scale up to 10 instances.

docker service scale vote=10

Note that you can see all of the active services by typing:

root@iron-1:/apps/vote# docker service ls
ID            NAME  REPLICAS  IMAGE          COMMAND
2564e444d8kb vote 10/10 eon01/vote:v1

After scaling up to 10 docker containers (running the same application called vote), you can notice that those 10 containers are dynamically distributed into the two nodes:

Machine 1 (iron-1)

root@iron-1:/apps/vote# docker service ps vote
ID                         NAME     IMAGE          NODE    DESIRED STATE  CURRENT STATE          ERROR
7kt2lnhjxjmk3hgko30iqhuiv vote.1 eon01/vote:v1 iron-2 Running Running 4 minutes ago
98ncz4hv688gmz8x31r5jdcjx vote.2 eon01/vote:v1 iron-2 Running Running 2 minutes ago
defsak5k5ycyd9ftww4xgbnuj vote.3 eon01/vote:v1 iron-1 Running Running 2 minutes ago
016bdk8ax3ne8uwt8hhm3b85e vote.4 eon01/vote:v1 iron-2 Running Running 2 minutes ago
agccdrx156wguvbp4iu24vmyt vote.5 eon01/vote:v1 iron-1 Running Running 2 minutes ago
de2yhodyqffjl9utyz5m8zyf2 vote.6 eon01/vote:v1 iron-2 Running Running 2 minutes ago
9ayr2t979o6onupy114wl9mgb vote.7 eon01/vote:v1 iron-2 Running Running 2 minutes ago
03t5dz4ghyvtdz27xdojsgotd vote.8 eon01/vote:v1 iron-1 Running Running 2 minutes ago
cgoa7i3zpxi9kkngn5cpnmkun vote.9 eon01/vote:v1 iron-1 Running Running 2 minutes ago
9bzjrnsynn6if5nh2aflqaacp vote.10 eon01/vote:v1 iron-2 Running Running 2 minutes ago

Machine 2 (iron-2)

root@iron-2:/apps/vote# docker service ps vote
ID                         NAME     IMAGE          NODE    DESIRED STATE  CURRENT STATE          ERROR
7kt2lnhjxjmk3hgko30iqhuiv vote.1 eon01/vote:v1 iron-2 Running Running 4 minutes ago
98ncz4hv688gmz8x31r5jdcjx vote.2 eon01/vote:v1 iron-2 Running Running 3 minutes ago
defsak5k5ycyd9ftww4xgbnuj vote.3 eon01/vote:v1 iron-1 Running Running 3 minutes ago
016bdk8ax3ne8uwt8hhm3b85e vote.4 eon01/vote:v1 iron-2 Running Running 3 minutes ago
agccdrx156wguvbp4iu24vmyt vote.5 eon01/vote:v1 iron-1 Running Running 3 minutes ago
de2yhodyqffjl9utyz5m8zyf2 vote.6 eon01/vote:v1 iron-2 Running Running 3 minutes ago
9ayr2t979o6onupy114wl9mgb vote.7 eon01/vote:v1 iron-2 Running Running 3 minutes ago
03t5dz4ghyvtdz27xdojsgotd vote.8 eon01/vote:v1 iron-1 Running Running 3 minutes ago
cgoa7i3zpxi9kkngn5cpnmkun vote.9 eon01/vote:v1 iron-1 Running Running 3 minutes ago
9bzjrnsynn6if5nh2aflqaacp vote.10 eon01/vote:v1 iron-2 Running Running 3 minutes ago

We can also use the classic docker ps to list the containers:

Machine 1 (iron-1)

root@iron-1:/apps/vote# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
972c90437f8c eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.9.cgoa7i3zpxi9kkngn5cpnmkun
564cd8289a5f eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.5.agccdrx156wguvbp4iu24vmyt
380b206412de eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.8.03t5dz4ghyvtdz27xdojsgotd
dfcb4d8f3d46 eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.3.defsak5k5ycyd9ftww4xgbnuj

Machine 2 (iron-2)

root@iron-2:/apps/vote# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
939c05de5b46 eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.6.de2yhodyqffjl9utyz5m8zyf2
6172a27de93c eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.4.016bdk8ax3ne8uwt8hhm3b85e
5340dfcd8118 eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.2.98ncz4hv688gmz8x31r5jdcjx
dbd059bba9e0 eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.7.9ayr2t979o6onupy114wl9mgb
6ae1bb5d1351 eon01/vote:v1 "gunicorn app:app -b " 4 minutes ago Up 4 minutes 80/tcp vote.10.9bzjrnsynn6if5nh2aflqaacp
6a1d92277257 eon01/vote:v1 "gunicorn app:app -b " 5 minutes ago Up 5 minutes 80/tcp vote.1.7kt2lnhjxjmk3hgko30iqhuiv
a4a6fd75ec91 instavote/vote "gunicorn app:app -b " 27 minutes ago Up 27 minutes 0.0.0.0:80->80/tcp vote

Scaling Up To 100 Container

To scale up to 100 container, just type:

docker service scale vote=10

Another way to inspect the list of running containers is listing the scheduler tasks:

Machine 1 (iron-1)

root@iron-1:/apps/vote# docker node ps self
ID                         NAME     IMAGE          NODE    DESIRED STATE  CURRENT STATE           ERROR
defsak5k5ycyd9ftww4xgbnuj vote.3 eon01/vote:v1 iron-1 Running Running 34 minutes ago
agccdrx156wguvbp4iu24vmyt vote.5 eon01/vote:v1 iron-1 Running Running 34 minutes ago
03t5dz4ghyvtdz27xdojsgotd vote.8 eon01/vote:v1 iron-1 Running Running 34 minutes ago
cgoa7i3zpxi9kkngn5cpnmkun vote.9 eon01/vote:v1 iron-1 Running Running 34 minutes ago
8f687kw6ejjrhtwhyalx1fg6d vote.11 eon01/vote:v1 iron-1 Running Running 24 minutes ago
1ohwgoneeqziagof5365yennf vote.14 eon01/vote:v1 iron-1 Running Running 24 minutes ago
8ov6prf0o7cex3ya4nwm53l0f vote.15 eon01/vote:v1 iron-1 Running Running 24 minutes ago
7hx1dvftkoeed38xeu1y3xm4l vote.16 eon01/vote:v1 iron-1 Running Running 24 minutes ago
d9ki2233hkuzsa16faub7jvzw vote.21 eon01/vote:v1 iron-1 Running Running 24 minutes ago
eetr0ctspz8c4dm7qsobjyr1b vote.23 eon01/vote:v1 iron-1 Running Running 24 minutes ago
1pbhmcvaunzmylpsl8ex9s3er vote.27 eon01/vote:v1 iron-1 Running Running 24 minutes ago
da7yhdgdsqvuk2dde3xer143n vote.28 eon01/vote:v1 iron-1 Running Running 24 minutes ago
6dc09ptadcsk7y7kycd4qm06e vote.29 eon01/vote:v1 iron-1 Running Running 24 minutes ago
0569wp4x8batv9pt7ioioebi4 vote.30 eon01/vote:v1 iron-1 Running Running 24 minutes ago
4eqgtoclas4i2079sst2ttx0z vote.32 eon01/vote:v1 iron-1 Running Running 24 minutes ago
4jz0vew0r4uanycw0ugj8l1z3 vote.35 eon01/vote:v1 iron-1 Running Running 24 minutes ago
3pfeh4p2da5i95pdj8k7bcqpe vote.36 eon01/vote:v1 iron-1 Running Running 24 minutes ago
96x91gkjk8zysts6w760xmp9y vote.37 eon01/vote:v1 iron-1 Running Running 24 minutes ago
8sbad4r19o1bdn3gw115gwdmv vote.39 eon01/vote:v1 iron-1 Running Running 24 minutes ago
841339bcq3pczx0fhyyde880y vote.41 eon01/vote:v1 iron-1 Running Running 24 minutes ago
caql2o62odmtj6qqzidpuf3vy vote.45 eon01/vote:v1 iron-1 Running Running 24 minutes ago
41v7vciwoskkzzbdth9mrq6cd vote.47 eon01/vote:v1 iron-1 Running Running 24 minutes ago
9vf5wki2jr2d85wdx43w0iylp vote.49 eon01/vote:v1 iron-1 Running Running 24 minutes ago
48u8ha1nzu9abgpfvg1vi8z5v vote.53 eon01/vote:v1 iron-1 Running Running 24 minutes ago
0ql4thk1u5dvaq3sx5ykioq3s vote.54 eon01/vote:v1 iron-1 Running Running 24 minutes ago
canyadfycoxju2b7azliz6pbn vote.55 eon01/vote:v1 iron-1 Running Running 24 minutes ago
eqpwyux96bkzdksg6l5riaz5j vote.56 eon01/vote:v1 iron-1 Running Running 24 minutes ago
e8jujdv446ct321eemo5uzaxm vote.60 eon01/vote:v1 iron-1 Running Running 24 minutes ago
ba5nhqzop930y0dvgj1jc6be5 vote.61 eon01/vote:v1 iron-1 Running Running 24 minutes ago
3hjjs62qyd1k5eqttumpms7cy vote.62 eon01/vote:v1 iron-1 Running Running 24 minutes ago
ahwkbbfqzunc8jbxdz89y30bf vote.66 eon01/vote:v1 iron-1 Running Running 24 minutes ago
04d91yxhlv001c9ypj2ha8al3 vote.68 eon01/vote:v1 iron-1 Running Running 24 minutes ago
89j1pmwwel6v8yzuedg0rw0ap vote.69 eon01/vote:v1 iron-1 Running Running 24 minutes ago
6vyul61kcu8ussw7tyy2hdqa1 vote.71 eon01/vote:v1 iron-1 Running Running 24 minutes ago
1iea4nfwlq7fpna35gkw5jzn6 vote.72 eon01/vote:v1 iron-1 Running Running 24 minutes ago
09tjq2efvo6hu5bya4du72a9p vote.73 eon01/vote:v1 iron-1 Running Running 24 minutes ago
31922gluj6bvnszgpi7y8mneh vote.74 eon01/vote:v1 iron-1 Running Running 24 minutes ago
6o3v2qa0ax92145fwcv7yuc7j vote.75 eon01/vote:v1 iron-1 Running Running 24 minutes ago
9b9am8a743m0kahfg1mrx47tj vote.76 eon01/vote:v1 iron-1 Running Running 24 minutes ago
416cy3i237l78rg3uoyhpge9p vote.78 eon01/vote:v1 iron-1 Running Running 24 minutes ago
a2zqcn0bsg7lrom4z3777f4ul vote.80 eon01/vote:v1 iron-1 Running Running 24 minutes ago
ao5tv81kdkfyvplttn3bcohie vote.81 eon01/vote:v1 iron-1 Running Running 24 minutes ago
dci9ju9iowtixpnlmfl7ybkqe vote.82 eon01/vote:v1 iron-1 Running Running 24 minutes ago
0wtoly59eyjk7a4r3kvy5uyo1 vote.83 eon01/vote:v1 iron-1 Running Running 24 minutes ago
bo6pa9onhnpchsg4u6744clxu vote.84 eon01/vote:v1 iron-1 Running Running 24 minutes ago
7axevdfwv1bp7li54s72kz0di vote.85 eon01/vote:v1 iron-1 Running Running 24 minutes ago
95mp1uqezyj1b98xauk980ay6 vote.86 eon01/vote:v1 iron-1 Running Running 24 minutes ago
e6fysp6xolxvaenl097t38u6p vote.90 eon01/vote:v1 iron-1 Running Running 24 minutes ago
2sqx69qvlf1ona9z13xk78tnx vote.97 eon01/vote:v1 iron-1 Running Running 24 minutes ago
6cnsgfwow88vizop6cfmcdt91 vote.98 eon01/vote:v1 iron-1 Running Running 24 minutes ago

Machine 2(iron-2)

root@iron-2:/apps/vote# docker node ps self
ID                         NAME      IMAGE          NODE    DESIRED STATE  CURRENT STATE           ERROR
7kt2lnhjxjmk3hgko30iqhuiv vote.1 eon01/vote:v1 iron-2 Running Running 32 minutes ago
98ncz4hv688gmz8x31r5jdcjx vote.2 eon01/vote:v1 iron-2 Running Running 30 minutes ago
016bdk8ax3ne8uwt8hhm3b85e vote.4 eon01/vote:v1 iron-2 Running Running 30 minutes ago
de2yhodyqffjl9utyz5m8zyf2 vote.6 eon01/vote:v1 iron-2 Running Running 30 minutes ago
9ayr2t979o6onupy114wl9mgb vote.7 eon01/vote:v1 iron-2 Running Running 30 minutes ago
9bzjrnsynn6if5nh2aflqaacp vote.10 eon01/vote:v1 iron-2 Running Running 30 minutes ago
9a2gdw4phd9iypcam2e6o88wv vote.12 eon01/vote:v1 iron-2 Running Running 21 minutes ago
97dc9qv6ig29otqlp16o575mi vote.13 eon01/vote:v1 iron-2 Running Running 21 minutes ago
4mdt1tekz9j7ptkyffwi6uey9 vote.17 eon01/vote:v1 iron-2 Running Running 20 minutes ago
ermm0xgwmztq1foevi7fgs90q vote.18 eon01/vote:v1 iron-2 Running Running 20 minutes ago
db9hrpbfrzeye59mh4tvwklwd vote.19 eon01/vote:v1 iron-2 Running Running 21 minutes ago
34zp56cju6b5725yn8e7kjtuc vote.20 eon01/vote:v1 iron-2 Running Running 21 minutes ago
54zndo1vtinxk1cn5zy1hzsjs vote.22 eon01/vote:v1 iron-2 Running Running 21 minutes ago
85ne3vzjyr965lgxvfw5wrwc2 vote.24 eon01/vote:v1 iron-2 Running Running 21 minutes ago
bp7grjvvol6cc3c34kmjqbk4w vote.25 eon01/vote:v1 iron-2 Running Running 20 minutes ago
9oe8gnrjj241fdkk7luoyw6cq vote.26 eon01/vote:v1 iron-2 Running Running 21 minutes ago
dl7c0ece7fchovty6spa95rly vote.31 eon01/vote:v1 iron-2 Running Running 21 minutes ago
a0zz7f27mawjzmz18xtpse670 vote.33 eon01/vote:v1 iron-2 Running Running 20 minutes ago
eb7c088yeg5dotg068g9g3c3u vote.34 eon01/vote:v1 iron-2 Running Running 20 minutes ago
3jyuv9s75bar7zit85cqf8hg4 vote.38 eon01/vote:v1 iron-2 Running Running 20 minutes ago
esp4wosgfyzbqddus74896bdg vote.40 eon01/vote:v1 iron-2 Running Running 21 minutes ago
7v8oxu9nmiyyi9ulvd3u3cd3z vote.42 eon01/vote:v1 iron-2 Running Running 20 minutes ago
1z5nppvgjjhdl0kzyxl16ony5 vote.43 eon01/vote:v1 iron-2 Running Running 20 minutes ago
a3x9ykg5zfpdq182barf0ezh3 vote.44 eon01/vote:v1 iron-2 Running Running 21 minutes ago
80nl6pet0cw3l8er1wjr3ejc1 vote.46 eon01/vote:v1 iron-2 Running Running 20 minutes ago
cpxnbxolvjxjf0zpmaawwbcg0 vote.48 eon01/vote:v1 iron-2 Running Running 20 minutes ago
cbd9ir2x7r3vpudysokm9dh8e vote.50 eon01/vote:v1 iron-2 Running Running 20 minutes ago
4g5dpdg6zy1188aqa7b45pd20 vote.51 eon01/vote:v1 iron-2 Running Running 20 minutes ago
3g2mvguwk0ny8klppsws5frgj vote.52 eon01/vote:v1 iron-2 Running Running 20 minutes ago
5vw7tu19gbpi3e6k8alp96dsk vote.57 eon01/vote:v1 iron-2 Running Running 21 minutes ago
3cgjlmq2le7vp69y93suwq2fr vote.58 eon01/vote:v1 iron-2 Running Running 20 minutes ago
57an0ss67y45ytp3cztsaxrow vote.59 eon01/vote:v1 iron-2 Running Running 20 minutes ago
4a1au1xd8olvvzwpb1zp28ei8 vote.63 eon01/vote:v1 iron-2 Running Running 21 minutes ago
28zzmt9tufc9vfu58fza5fvnx vote.64 eon01/vote:v1 iron-2 Running Running 21 minutes ago
70btxz2r6zg9ji2pfo573hllg vote.65 eon01/vote:v1 iron-2 Running Running 20 minutes ago
ep27gvvpda9bogzof9za9gvav vote.67 eon01/vote:v1 iron-2 Running Running 21 minutes ago
5hzq8eqlp2qrxb3zkukxh9vm8 vote.70 eon01/vote:v1 iron-2 Running Running 20 minutes ago
5axsu6jrlk4e16wzgq2cxxts9 vote.77 eon01/vote:v1 iron-2 Running Running 20 minutes ago
4x4r14hj9thceuvcgjsv6ldtl vote.79 eon01/vote:v1 iron-2 Running Running 20 minutes ago
eojymechpx7vlu0h04uhrzhvg vote.87 eon01/vote:v1 iron-2 Running Running 20 minutes ago
a880pvnffz6yvue8bc62dz7t8 vote.88 eon01/vote:v1 iron-2 Running Running 20 minutes ago
e3cwkod6pvvlkqfbjxmd8torq vote.89 eon01/vote:v1 iron-2 Running Running 21 minutes ago
07ndhjrzul2vzg74n9rzi1vuy vote.91 eon01/vote:v1 iron-2 Running Running 21 minutes ago
0o2vd8xv4crtkyy485l3pw0fr vote.92 eon01/vote:v1 iron-2 Running Running 20 minutes ago
dk2xx9z24k9ktogzdwok6m1ik vote.93 eon01/vote:v1 iron-2 Running Running 21 minutes ago
2pdhwmfivyg6lgj9luqna503a vote.94 eon01/vote:v1 iron-2 Running Running 20 minutes ago
4pocywnwr9h17wng3sztev8d9 vote.95 eon01/vote:v1 iron-2 Running Running 20 minutes ago
7j1tke117l9cime5qk86njhoz vote.96 eon01/vote:v1 iron-2 Running Running 21 minutes ago
4of8hk7rev9lauhwrvrsmjiqd vote.99 eon01/vote:v1 iron-2 Running Running 21 minutes ago
er8ln77g2p5nz298srd3e6hek vote.100 eon01/vote:v1 iron-2 Running Running 20 minutes ago

The inspect command could be also useful:

oot@iron-1:/apps/vote# docker service inspect vote
[
{
"ID": "2564e444d8kbjjcuf28hacce2",
"Version": {
"Index": 60
},
"CreatedAt": "2016-08-01T15:14:01.677451672Z",
"UpdatedAt": "2016-08-01T15:25:09.471121175Z",
"Spec": {
"Name": "vote",
"TaskTemplate": {
"ContainerSpec": {
"Image": "eon01/vote:v1",
"Mounts": [
{
"Type": "bind",
"Source": "/app",
"Target": "/data/vote/"
}
]
},
"Resources": {
"Limits": {},
"Reservations": {}
},
"RestartPolicy": {
"Condition": "any",
"MaxAttempts": 0
},
"Placement": {}
},
"Mode": {
"Replicated": {
"Replicas": 100
}
},
"UpdateConfig": {
"Parallelism": 1,
"FailureAction": "pause"
},
"EndpointSpec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 8080
}
]
}
},
"Endpoint": {
"Spec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 8080
}
]
},
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 8080
}
],
"VirtualIPs": [
{
"NetworkID": "cbx9gvbvaocokn4135djlghaf",
"Addr": "10.255.0.4/16"
}
]
},
"UpdateStatus": {
"StartedAt": "0001-01-01T00:00:00Z",
"CompletedAt": "0001-01-01T00:00:00Z"
}
}
]

Upgrading Production Apps Using Swarm

Deploying a new version of a containerized application is quite simple.

Moving the Vote app from version 1 to the 2nd one, could be done like this:

root@iron-1:~# docker service update --image eon01/vote:v2 vote
vote

You can see how things are managed by Swarm by using grep on v1 or v2 and see how containers changes from v1 to v2.

root@iron-1:/apps/vote# docker node ps self|grep v1
defsak5k5ycyd9ftww4xgbnuj  vote.3       eon01/vote:v1  iron-1  Running        Running 37 minutes ago          
agccdrx156wguvbp4iu24vmyt vote.5 eon01/vote:v1 iron-1 Running Running 37 minutes ago
03t5dz4ghyvtdz27xdojsgotd vote.8 eon01/vote:v1 iron-1 Shutdown Shutdown 41 seconds ago
cgoa7i3zpxi9kkngn5cpnmkun vote.9 eon01/vote:v1 iron-1 Running Running 37 minutes ago
8f687kw6ejjrhtwhyalx1fg6d vote.11 eon01/vote:v1 iron-1 Running Running 27 minutes ago
1ohwgoneeqziagof5365yennf \_ vote.14 eon01/vote:v1 iron-1 Shutdown Shutdown 23 seconds ago
8ov6prf0o7cex3ya4nwm53l0f vote.15 eon01/vote:v1 iron-1 Running Running 27 minutes ago
7hx1dvftkoeed38xeu1y3xm4l vote.16 eon01/vote:v1 iron-1 Running Running 27 minutes ago
d9ki2233hkuzsa16faub7jvzw vote.21 eon01/vote:v1 iron-1 Running Running 27 minutes ago
eetr0ctspz8c4dm7qsobjyr1b vote.23 eon01/vote:v1 iron-1 Running Running 27 minutes ago
1pbhmcvaunzmylpsl8ex9s3er \_ vote.27 eon01/vote:v1 iron-1 Shutdown Shutdown 21 seconds ago
da7yhdgdsqvuk2dde3xer143n vote.28 eon01/vote:v1 iron-1 Running Running 27 minutes ago
6dc09ptadcsk7y7kycd4qm06e vote.29 eon01/vote:v1 iron-1 Running Running 27 minutes ago
0569wp4x8batv9pt7ioioebi4 \_ vote.30 eon01/vote:v1 iron-1 Shutdown Shutdown 36 seconds ago
4eqgtoclas4i2079sst2ttx0z vote.32 eon01/vote:v1 iron-1 Running Running 27 minutes ago
4jz0vew0r4uanycw0ugj8l1z3 vote.35 eon01/vote:v1 iron-1 Running Running 27 minutes ago
3pfeh4p2da5i95pdj8k7bcqpe \_ vote.36 eon01/vote:v1 iron-1 Shutdown Shutdown 1 seconds ago
96x91gkjk8zysts6w760xmp9y vote.37 eon01/vote:v1 iron-1 Running Running 27 minutes ago
8sbad4r19o1bdn3gw115gwdmv vote.39 eon01/vote:v1 iron-1 Running Running 27 minutes ago
841339bcq3pczx0fhyyde880y vote.41 eon01/vote:v1 iron-1 Running Running 27 minutes ago
caql2o62odmtj6qqzidpuf3vy vote.45 eon01/vote:v1 iron-1 Running Running 27 minutes ago
41v7vciwoskkzzbdth9mrq6cd vote.47 eon01/vote:v1 iron-1 Running Running 27 minutes ago
9vf5wki2jr2d85wdx43w0iylp vote.49 eon01/vote:v1 iron-1 Running Running 27 minutes ago
48u8ha1nzu9abgpfvg1vi8z5v vote.53 eon01/vote:v1 iron-1 Running Running 27 minutes ago
0ql4thk1u5dvaq3sx5ykioq3s \_ vote.54 eon01/vote:v1 iron-1 Shutdown Shutdown 28 seconds ago
canyadfycoxju2b7azliz6pbn vote.55 eon01/vote:v1 iron-1 Running Running 27 minutes ago
eqpwyux96bkzdksg6l5riaz5j vote.56 eon01/vote:v1 iron-1 Running Running 27 minutes ago
e8jujdv446ct321eemo5uzaxm vote.60 eon01/vote:v1 iron-1 Running Running 27 minutes ago
ba5nhqzop930y0dvgj1jc6be5 vote.61 eon01/vote:v1 iron-1 Running Running 27 minutes ago
3hjjs62qyd1k5eqttumpms7cy vote.62 eon01/vote:v1 iron-1 Shutdown Shutdown 5 seconds ago
ahwkbbfqzunc8jbxdz89y30bf vote.66 eon01/vote:v1 iron-1 Running Running 27 minutes ago
04d91yxhlv001c9ypj2ha8al3 vote.68 eon01/vote:v1 iron-1 Shutdown Shutdown 38 seconds ago
89j1pmwwel6v8yzuedg0rw0ap vote.69 eon01/vote:v1 iron-1 Running Running 27 minutes ago
6vyul61kcu8ussw7tyy2hdqa1 vote.71 eon01/vote:v1 iron-1 Running Running 27 minutes ago
1iea4nfwlq7fpna35gkw5jzn6 \_ vote.72 eon01/vote:v1 iron-1 Shutdown Shutdown 25 seconds ago
09tjq2efvo6hu5bya4du72a9p \_ vote.73 eon01/vote:v1 iron-1 Shutdown Shutdown 32 seconds ago
31922gluj6bvnszgpi7y8mneh vote.74 eon01/vote:v1 iron-1 Shutdown Shutdown 12 seconds ago
6o3v2qa0ax92145fwcv7yuc7j vote.75 eon01/vote:v1 iron-1 Running Running 27 minutes ago
9b9am8a743m0kahfg1mrx47tj vote.76 eon01/vote:v1 iron-1 Running Running 27 minutes ago
416cy3i237l78rg3uoyhpge9p vote.78 eon01/vote:v1 iron-1 Shutdown Running less than a second ago
a2zqcn0bsg7lrom4z3777f4ul vote.80 eon01/vote:v1 iron-1 Running Running 27 minutes ago
ao5tv81kdkfyvplttn3bcohie vote.81 eon01/vote:v1 iron-1 Running Running 27 minutes ago
dci9ju9iowtixpnlmfl7ybkqe vote.82 eon01/vote:v1 iron-1 Running Running 27 minutes ago
0wtoly59eyjk7a4r3kvy5uyo1 vote.83 eon01/vote:v1 iron-1 Shutdown Shutdown 26 seconds ago
bo6pa9onhnpchsg4u6744clxu vote.84 eon01/vote:v1 iron-1 Running Running 27 minutes ago
7axevdfwv1bp7li54s72kz0di vote.85 eon01/vote:v1 iron-1 Running Running 27 minutes ago
95mp1uqezyj1b98xauk980ay6 vote.86 eon01/vote:v1 iron-1 Running Running 27 minutes ago
e6fysp6xolxvaenl097t38u6p vote.90 eon01/vote:v1 iron-1 Running Running 27 minutes ago
2sqx69qvlf1ona9z13xk78tnx vote.97 eon01/vote:v1 iron-1 Shutdown Shutdown 14 seconds ago
6cnsgfwow88vizop6cfmcdt91 vote.98 eon01/vote:v1 iron-1 Running Running 27 minutes ago

Some seconds later, I started to see that many of the containers are already in V2.

root@iron-1:/apps/vote# docker node ps self|grep v2
2rkgm7r4iyds4jz0fmem73vh7  vote.4       eon01/vote:v2  iron-1  Running        Running 44 seconds ago            
en2w6sbvq0re6cuk011p1pmil vote.14 eon01/vote:v2 iron-1 Running Running 24 seconds ago
1sei4t9729thq7tpyhe7nv6q9 vote.20 eon01/vote:v2 iron-1 Running Running 11 seconds ago
7ucugqku8i0zv8hdlo9b0frja vote.27 eon01/vote:v2 iron-1 Running Running 22 seconds ago
dkx5os069wx2evcat2pxlvbbi vote.30 eon01/vote:v2 iron-1 Running Running 37 seconds ago
d8z8a19dttm2ccludkogu90m0 vote.36 eon01/vote:v2 iron-1 Running Running 2 seconds ago
25dfat5thxo40mx9hy5b3sykq vote.43 eon01/vote:v2 iron-1 Running Running 20 seconds ago
2e5e69sknw27vyiiuw06xghg4 vote.47 eon01/vote:v2 iron-1 Ready Preparing less than a second ago
7l7lru1b9ew6i02ct6sbpe9c7 vote.54 eon01/vote:v2 iron-1 Running Running 30 seconds ago
717ne41wlug7w86dqtgqj6vju vote.58 eon01/vote:v2 iron-1 Running Running 10 seconds ago
d39wj0grgun6mx5ibur3ed5qo vote.64 eon01/vote:v2 iron-1 Running Running 18 seconds ago
bjvg6b825c9v2qjrku4bh2ipv vote.72 eon01/vote:v2 iron-1 Running Running 26 seconds ago
6tsu2s5dnonwdls1808zkv8ey vote.73 eon01/vote:v2 iron-1 Running Running 33 seconds ago
6o3v2qa0ax92145fwcv7yuc7j vote.75 eon01/vote:v1 iron-1 Running Running 27 minutes ago
3403dn9ao57ozo47blpv4y40z vote.91 eon01/vote:v2 iron-1 Running Running 35 seconds ago

And in almost 15 seconds, I got 50% of the containers updated:

root@iron-1:/apps/vote# docker node ps self|grep v2|wc -l && echo "/" && docker node ps self|grep v1|wc -l
50
/
50

The upgrade from the V1 to the V2 of 100 container was relatively fast and without any errors or downtimes.

Nothing to notice for now about over usage of the resources, but this depends also on your application, not just the number of the containers you started:

What We Learned

Scaling up to 100 container from the same server and attaching one file system to those 100 container is what we have done during this tutorial.

Docker 1.2, used in Swarm Mode will simplify many operations, it is scalable and seems to be stable. The Elastic File System solves and simplifies also many other problems like sharing the same file system between one or more containers.

For more information, other details are explained in my previous post Microservices From Development To Production Using Docker/Docker-compose & Docker Swarm

Connect Deeper

If you resonated with this article, please subscribe to DevOpsLinks : An Online Community Of Diverse & Passionate DevOps, SysAdmins & Developers From All Over The World.

You can find me on Twitter, Clarity or my blog and you can also check my books: SaltStack For DevOps,The Jumpstart Up & Painless Docker.

If you liked this post, please recommend and share it to your followers.