tiad 2016 : application delivery in a container world
TRANSCRIPT
Application delivery in a container world4 octobre 2016 . #TIAD . @tiadparis
# 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
# 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
# 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 latestARG version
ADD Dockerfile /DockerfileLABEL 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
# 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
# TIAD@ tiadparis
SchedulingHow 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)
# TIAD@ tiadparis
Service discoveryHow 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 redisredis ?
- 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)
# TIAD@ tiadparis 8
Bastion
Public subnets
NAT GW
Public subnets Public subnets
CAg(UI)
CS CS CS
Let’s create a consul cluster
# 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
# 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
# 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?
# 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/re-dis
CAg RG Cad CAg RG Cad CAg RG Cad
Let’s deploy our application: backends
Red
Ctmpl+Nginx
watc
h
Ctmpl+Nginx
watc
h
# TIAD@ tiadparis
A few notes on ECSECS 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
# 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
# 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/re-dis
CAg RG Cad CAg RG Cad CAg RG Cad
Red
Ctmpl+Nginx
watc
h
Ctmpl+Nginx
Deploy our app Vote: http://tiad.awsdemo.d2-si.eu
AppApp
# 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 ?
# 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/re-dis
CAg RG Cad CAg RG Cad CAg RG Cad
Red
Ctmpl+Nginx
watc
h
Ctmpl+Nginx
AppApp
What about a new version?
App App
# TIAD@ tiadparis
Blue Green deployment
HAP HAP
AppApp App App
routes/vote: green
Test before switchingAcces blue containers directlyUse 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?
# TIAD@ tiadparis
When ok switch
HAP HAP
AppApp App App
routes/vote: blue
Dynamic parametersGet title from consul
params/title/blue
title=get_param("title",color,"Hello TIAD")
# TIAD@ tiadparis
Feature toggling
HAP HAP
AppApp App App
routes/vote: blue
features/containerid/blue
Switch on/off featuresRelease code not validated yetSimplify branch management (always ship trunk)
Advanced use casesCanary 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)
# 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)
# TIAD@ tiadparis
Thank you
@lbernail
Look at / Fork the code of this demo on githubhttps://github.com/lbernail/demotiad
Questions ?