This document discusses application delivery in a container world. It summarizes using Docker from development to production, including local development, continuous integration, deploying to servers using schedulers like Kubernetes and ECS, service discovery using tools like Consul, and updating applications safely using blue-green deployments and feature toggling. It then demonstrates these concepts using Docker, AWS ECS, Consul, and Consul Template to deploy a voting application.
2. # TIAD@ tiadparis
Who am I?
2
Laurent Bernaille @d2si
• Linux background
• Cloud enthousiast
• Opensource advocate
• Love discovering, building (and breaking…) new things
• Passionate about the ongoing IT transformations
@lbernail
3. # TIAD@ tiadparis
Docker from development to production
3
• Local development
• Docker and Continuous integration
• Deploying to servers: scheduling containers
• Multi-server setup: service discovery
• Updating my application safely: Blue green deployment
• Dynamically enable/disable features: Feature toggling
4. # TIAD@ tiadparis
Demo
• Local Build
• Run locally (docker-compose)
• Update code
• Commit
• Intregration with travis to publish image to ECR registry
docker build -t demotiad/vote:0.1 --build-arg version=0.1 vote
docker tag demotiad/vote:0.1 demotiad/vote:latest
specific version tag ARG for label
Alias image to latest
ARG version
ADD Dockerfile /Dockerfile
LABEL eu.d2-si.python_version="2.7"
LABEL eu.d2-si.application="vote"
LABEL eu.d2-si.version="${version}"
Metadata about the image
Amazon
ECR
5. # TIAD@ tiadparis 5
Bastion
eu-west-1a
Public subnets
Let’s create an environment in AWS to deploy
Private subnets
NAT
GW
Public subnets
Private subnets
eu-west-1b
Public subnets
Private subnets
eu-west-1c
6. # TIAD@ tiadparis
Scheduling
How do I run my containers?
• Manual : ssh / docker run
• Automated: ansible
How do I choose a host?
• Static (see before)
• With a generic scheduler (Mesos, Nomad)
• With a specialized scheduler (Kubernetes, ECS, Swarm)
Choosing your scheduler
• Most complete: Kubernetes
• Kubernetes and Swarm provide more than scheduling
- Higher level of abstraction
- Control networking
- Really worth looking into once if you have run production workloads for a while
- hosts: redis
tasks:
- name: Run redis
docker_container:
name: redis
image: redis
- hosts: app
tasks:
- name: Run app
docker
name: vote
image: demotiad/vote
Demo: ECS (good integration with AWS / terraform, simple)
7. # TIAD@ tiadparis
Service discovery
How do my containers find each other when I have multiple hosts?
• Static: set up /etc/hosts entries in containers
• Rely on service discovery from scheduler
* Kubernetes
* Swarm
> Big assumptions on the nework, intrusive (overlay, proxy, iptables)
• Use a separate tool for service discovery
+ More control
+ Can be used for non-containers workloads (and for communication with them)
- An additional tool to manage
app redis
redis ?
- hosts: redis
tasks:
- name: Run redis
docker_container:
name: redis
image: redis
- hosts: app
tasks:
- name: Run app
docker
name: vote
image: demotiad/vote
etc_hosts:
redis: 10.0.0.4
Demo: Consul (one of the reference standalone solution)
8. # TIAD@ tiadparis 8
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
CAg
(UI)
CS CS CS
Let’s create a consul cluster
9. # TIAD@ tiadparis
ECS
9
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
ECS ECS
EFS file system
EFS Mount target EFS Mount target EFS Mount target
/mnt/efs /mnt/efs /mnt/efs
Deploy ECS servers
CAg
(UI)
CS CS CS
10. # TIAD@ tiadparis
ECS
10
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
CAg
(UI)
CS CS CS
ECS ECS
EFS file system
EFS Mount target EFS Mount target EFS Mount target
/mnt/efs /mnt/efs /mnt/efs
CAg RG Cad CAg RG Cad CAg RG Cad
docker events
We need some services on all nodes
11. # TIAD@ tiadparis
ECS
11
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
CAg
(UI)
CS CS CS
ECS ECS
EFS file system
EFS Mount target EFS Mount target EFS Mount target
/mnt/efs /mnt/efs /mnt/efs
CAg RG Cad CAg RG Cad CAg RG Cad
docker events
Let’s start two containers
Rd Ash
redis?
12. # TIAD@ tiadparis
ECS
12
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
CAg
(UI)
CS CS CS
ECS ECS
EFS file system
EFS Mount target EFS Mount target EFS Mount target
/mnt/efs /mnt/efs /mnt/efs/redis
CAg RG Cad CAg RG Cad CAg RG Cad
Let’s deploy our application: backends
Red
Ctmpl+Nginx Ctmpl+Nginx
13. # TIAD@ tiadparis
A few notes on ECS
ECS tasks
• run « manually » (part of ECS servers bootstrap here)
• Consist of one or several related containers (« pod »)
• Consul Agent / Registrator / cAdvisor
ECS services
• Run a given number of tasks on the cluster
• Ensure they remain running
• Scheduling
* find host with capacity
* try to run tasks of the same service on different nodes / AZ
- Redis : 1
- Haproxy + Consul Template : 2
Persistency
• No solution for dynamic volume migration
• We use EFS and mount an EFS sub-directory inside containers with data
14. # TIAD@ tiadparis
Consul template
• Watch for entries in consul
• Generate configuration based on these entries
• Here
* Generate nginx configuration
* Start nginx as a child process
* Reload nginx when configuration as changed
server {
location / {
proxy_pass http://{{key_or_default "routes/vote" "blue”}};
}
}
server {
location / {
proxy_pass http://blue;
}
}
key routes/vote ?
• Let’s create routes/vote and set it to green
15. # TIAD@ tiadparis
ECS
15
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
CAg
(UI)
CS CS CS
ECS ECS
EFS file system
EFS Mount target EFS Mount target EFS Mount target
/mnt/efs /mnt/efs /mnt/efs/redis
CAg RG Cad CAg RG Cad CAg RG Cad
Red
Ctmpl+Nginx Ctmpl+Nginx
Deploy our app Vote: http://tiad.awsdemo.d2-si.eu
AppApp
16. # TIAD@ tiadparis
How did nginx find the containers?
upstream green {
{{ range service "votegreen" }}
server {{.Address}}:{{.Port}};{{end}}
}
upstream green {
server 10.255.128.166:32769;
server 10.255.129.118:32770;
}
service votegreen ?
17. # TIAD@ tiadparis
ECS
17
Bastion
Public subnets
NAT
GW
Public subnets Public subnets
CAg
(UI)
CS CS CS
ECS ECS
EFS file system
EFS Mount target EFS Mount target EFS Mount target
/mnt/efs /mnt/efs /mnt/efs/redis
CAg RG Cad CAg RG Cad CAg RG Cad
Red
Ctmpl+Nginx Ctmpl+Nginx
AppApp
What about a new version?
App App
18. # TIAD@ tiadparis
Blue Green deployment
HA
P
HA
P
AppApp App App
routes/vote: green
Test before switching
Acces blue containers directly
Use custom header: X-Color
map $http_x_color $color {
"green" "green";
"blue" "blue";
default "{{= key_or_default "routes/vote" "blue”}}";
}
server {
location / {
proxy_pass http://$color;
}
}
X-color = blue?
19. # TIAD@ tiadparis
When ok switch
HA
P
HA
P
AppApp App App
routes/vote: blue
Dynamic parameters
Get title from consul
params/title/blue
title=get_param("title",color,"Hello TIAD")
20. # TIAD@ tiadparis
Feature toggling
HA
P
HA
P
AppApp App App
routes/vote: blue
features/containerid/blue
Switch on/off features
Release code not validated yet
Simplify branch management (always ship trunk)
Advanced use cases
Canary deployment (x% users)
Specific users only
if is_enabled_feature("containerid",color):
message=message+" on container "+ hostname
« Always Ship Trunk » (Paul Hammond, Velocity 2010)
« Feature Toggles » (Martin Fowler 2016: http://martinfowler.com/articles/feature-toggles.htm)
21. # TIAD@ tiadparis
Conclusion and perspectives
Going into production with docker
• With containers OPS and DEV are closer than ever
• Continuous Integration as a source for images
• Service discovery will be a challenge
=> Not specific to containers but to microservices in general
A few other (somewhat unrelated) notes
• Docker in production will require experienced sysadmins
• Avoid putting stateful (db) services in containers
• Security (image sources, container permissions)
22. # TIAD@ tiadparis
Thank you
@lbernail
Look at / Fork the code of this demo on github
https://github.com/lbernail/demotiad
Questions ?