diff --git a/dockercoins/docker-compose.yml-scaled-rng b/dockercoins/docker-compose.yml-scaled-rng
index a8b06c8e..f1f5c9a4 100644
--- a/dockercoins/docker-compose.yml-scaled-rng
+++ b/dockercoins/docker-compose.yml-scaled-rng
@@ -7,7 +7,7 @@ rng2:
rng3:
build: rng
-rng0:
+rng:
image: jpetazzo/hamba
links:
- rng1
@@ -37,7 +37,7 @@ redis:
worker:
build: worker
links:
- - rng0:rng
- - hasher:hasher
+ - rng
+ - hasher
- redis
diff --git a/www/htdocs/index.html b/www/htdocs/index.html
index a31fa92c..42774d03 100644
--- a/www/htdocs/index.html
+++ b/www/htdocs/index.html
@@ -125,7 +125,7 @@ class: title
grep '^# ' index.html | grep -v '
-## Outline (1/2)
+## Outline (1/4)
- Pre-requirements
- VM environment
@@ -142,20 +142,37 @@ grep '^# ' index.html | grep -v '
`docker run -P redis`
-
`docker run -p 6379 redis`
-
`docker run -p 1234:6379 redis`
+
`docker run -d -p 8000:80 nginx`
+
`docker run -d -p 80 nginx`
+
`docker run -d -P nginx`
- With Docker Compose, in the `docker-compose.yml` file:
@@ -354,6 +369,8 @@ Let's get random bytes of data!
.exercise[
+- Open yet another terminal and SSH session
+
- Start the `hasher` service:
`docker-compose up hasher`
@@ -374,7 +391,7 @@ You can see the mapping in `docker-compose.yml`.
.exercise[
-- Open a third terminal window, and SSH to `node1`
+- Open one more terminal window, and SSH to `node1`
- Check that the `hasher` service is alive:
`curl localhost:8002`
@@ -890,7 +907,9 @@ WHY?!?
## The plan
+
- Create multiple identical `rng` containers
@@ -898,7 +917,7 @@ WHY?!?
- Point other services to the load balancer
----
+???
## Stopping `rng`
@@ -955,9 +974,9 @@ Shortcut: `docker-compose.yml-scaled-rng`
- Load balancer based on HAProxy
- Expects the following arguments:
-
`FE-port BE1-addr BE1-port BE2-addr BE2-port ...`
+
`FE-port BE1-addr:BE1-port BE2-addr:BE2-port ...`
*or*
-
`FE-addr:FE-port BE1-addr BE1-port BE2-addr BE2-port ...`
+
`FE-addr:FE-port BE1-addr:BE1-port BE2-addr:BE2-port ...`
- FE=frontend (the thing other services connect to)
@@ -967,7 +986,7 @@ Shortcut: `docker-compose.yml-scaled-rng`
Example: listen to port 80 and balance traffic on www1:1234 + www2:2345
```
-docker run -d -p 80 jpetazzo/hamba 80 www1 1234 www2 2345
+docker run -d -p 80 jpetazzo/hamba 80 www1:1234 www2:2345
```
]
@@ -982,7 +1001,7 @@ Let's add our load balancer to the Compose file.
- Add the following section to the Compose file:
```
- rng0:
+ rng:
image: jpetazzo/hamba
links:
- rng1
@@ -997,7 +1016,7 @@ Let's add our load balancer to the Compose file.
Shortcut: `docker-compose.yml-scaled-rng`
----
+???
## Point other services to the load balancer
@@ -1036,12 +1055,14 @@ Shortcut: `docker-compose.yml-scaled-rng`
`docker-compose logs worker`
- Check load balancer logs:
-
`docker-compose logs rng0`
+
`docker-compose logs rng`
]
+
---
@@ -1122,10 +1143,11 @@ faster for a well-behaved application.*
redis: 192.168.1.2
```
-- This creates entries in `/etc/hosts` in the container
- (in Engine 1.10, a local DNS server is used instead)
+- Docker exposes a DNS server to the container,
+
with a private view where `redis` resolves to `192.168.1.2`
+ (Before Engine 1.10, it created entries in `/etc/hosts`)
-???
+---
## The plan
@@ -1147,7 +1169,7 @@ faster for a well-behaved application.*
Note: the code stays on the first node!
(We do not need to copy the code to the other nodes.)
-???
+---
## Making Redis available on its default port
@@ -1169,7 +1191,7 @@ There are two strategies.
Choose wisely!
-???
+---
## Deploy Redis
@@ -1195,7 +1217,7 @@ Choose wisely!
To exit a telnet session: `Ctrl-] c ENTER`
-???
+---
## Update `docker-compose.yml` (1/3)
@@ -1210,7 +1232,7 @@ To exit a telnet session: `Ctrl-] c ENTER`
]
-???
+---
## Update `docker-compose.yml` (2/3)
@@ -1235,7 +1257,7 @@ Replace `A.B.C.D` with the IP address noted earlier.
Shortcut: `docker-compose.yml-extra-hosts`
(But you still have to replace `A.B.C.D`!)
-???
+---
## Update `docker-compose.yml` (3/3)
@@ -1260,7 +1282,7 @@ Shortcut: `docker-compose.yml-extra-hosts`
.icon[] Don't forget to comment out the `volumes` section!
-???
+---
## Why did we comment out the `volumes` section?
@@ -1281,7 +1303,7 @@ Shortcut: `docker-compose.yml-extra-hosts`
- This specific volume is used in development
(not in production)
-???
+---
## Start the stack on the first machine
@@ -1297,7 +1319,7 @@ Shortcut: `docker-compose.yml-extra-hosts`
- Check in the web browser that it's running correctly
-???
+---
## Start the stack on another machine
@@ -1320,7 +1342,7 @@ Shortcut: `docker-compose.yml-extra-hosts`
]
-???
+---
## Scale!
@@ -1333,7 +1355,7 @@ Shortcut: `docker-compose.yml-extra-hosts`
]
-???
+---
## Cleanup
@@ -1401,9 +1423,9 @@ Shortcut: `docker-compose.yml-extra-hosts`
.exercise[
-
- Restore `links` as they were before in `webui` and `worker`
--->
+
- Replace `redis` with an ambassador using `jpetazzo/hamba`:
@@ -1425,7 +1447,7 @@ Shortcut: `docker-compose.yml-extra-hosts`
Shortcut: `docker-compose.yml-ambassador`
(But you still have to update `AA.BB.CC.DD EEEE`!)
----
+???
## Why did we comment out the `volumes` section?
@@ -2132,6 +2154,23 @@ of this workshop.
---
+## Logging in production
+
+- If we were using an ELK stack:
+
+ - scale ElasticSearch
+ - scale Logstash
+ - (probably) switch away from GELF+UDP
+
+- Configure your Engines to send all logs to the stack by default
+
+- Start the logging containers with a different logging system
+
(to avoid a logging loop)
+
+- Make sure you don't end up writing *all logs* on the nodes running Logstash!
+
+---
+
# Security upgrades
- This section is not hands-on
@@ -2975,18 +3014,57 @@ So, what do‽
---
-# Network plumbing on Swarm
+## Connecting containers with Swarm (1/2)
+
+- Implement service discovery in the application
+
+ - requires extensive code changes
+
+ - doesn't require extra services or containers
+
+ - provides load balancing and failover
+
+- Inject service addresses in environment variables
+
+ - requires minimal code changes
+
+ - doesn't require extra services or containers
+
+ - doesn't provide load balancing and failover
+
+---
+
+## Connecting containers with Swarm (2/2)
+
+- Ambassadors
+
+ - don't require code changes
+
+ - require additional containers
+
+ - provide load balancing and failover
+
+- Overlay networks
+
+ - don't require code changes
+
+ - don't require extra services or containers
+
+ - doesn't provide load balancing and failover (yet)
+
+---
+
+# Connecting containers with ambassadors
- We will use one-tier, dynamic ambassadors
-
(as seen before)
-- Other available options:
+- Each link to a service will be replaced by an ambassador
- - injecting service addresses in environment variables
+- Each ambassador will be placed in the network namespace
+ of the service using the ambassador
- - implementing service discovery in the application
-
- - use an overlay network
+- Ambassadors will be dynamically reconfigured when
+ linked services are updated
---
@@ -3225,96 +3303,25 @@ Then it configures all ambassadors with all found backends.
---
-# Going further
+## Clean up
-Scaling the application (difficulty: easy)
+- Before moving on, stop and remove all containers
-- Run `docker-compose scale`
+.exercise[
-- Re-create ambassadors
+- Terminate all containers:
+ ```
+ docker-compose kill
+ ```
-- Re-configure ambassadors
+- Remove them:
+ ```
+ docker-compose rm -f
+ ```
-- No downtime
+]
----
-
-## Going further
-
-Deploying a new version (difficulty: easy)
-
-- Just re-run all the steps!
-
-- However, Compose will re-create the containers
-
-- You will have to re-create ambassadors
-
(and configure them)
-
-- You will have to cleanup old ambassadors
-
(left as an exercise for the reader)
-
-- You will experience a little bit of downtime
-
----
-
-## Going further
-
-Zero-downtime deployment (difficulty: medium)
-
-- Isolate stateful services
-
(like we did earlier for Redis)
-
-- Do blue/green deployment:
-
- - deploy and scale version N
-
- - point a "top-level" load balancer to the app
-
- - deploy and scale version N+1
-
- - put both apps in the "top-level" balancer
-
- - slowly switch traffic over to app version N+1
-
----
-
-## Going further
-
-Use the new networking features (difficulty: medium)
-
-- Create a key/value store (e.g. Consul cluster)
-
-- Reconfigure all Engines to use the key/value store
-
-- Load balancers can use DNS for backend discovery
-
-Note: this is really easy to do with a 1-node Consul cluster.
-
----
-
-## Going further
-
-Harder projects:
-
-- Two-tier or three-tier ambassador deployments
-
-- Deploy to Mesos or Kubernetes
-
----
-
-class: pic
-
-
-
----
-
-# Here be dragons
-
-- So far, we've used stable products (versions 1.X)
-
-- We're going to explore experimental software
-
-- **Use at your own risk**
+Note: we also need to remove the ambassadors.
---
@@ -3729,105 +3736,162 @@ docker run -d --name palpatine --net darkside -m 3G redis
---
-# Compose and multi-host networking
+# Using overlay networks with Compose
-.icon[] Here be 7-headed flame-throwing hydras!
+- Compose 1.5 had `--x-networking` flag
+
(enabling experimental support for overlay networks)
-- This is super experimental
+- Compose 1.6 has a new Compose file format
+
(using the new format enables overlay networks support)
-- Your cluster is likely to blow up to bits
+- Compose will remain backward compatible with old files
-- Situation is much better in Engine 1.10 and Compose 1.6
-
(currently in RC; to be released circa February 2016!)
+- Converting to new files is (ridiculously) easy
---
-## Revisiting DockerCoins
+## Converting from Compose file v1 to v2
-.exercise[
+- Services are no longer at the top level,
+
but under a `services` section
-- Go back to the `dockercoins` app:
+- There has to be a `version` key at the top level,
+
with value `"2"` (as a string, not an integer)
- ```
- cd ~/orchestration-workshop/dockercoins
- ```
+- Links should be removed
-- Re-execute `build-tag-push` to get a fresh Compose file:
+- Fixed port mappings should be removed
+
(until [docker/compose#2866](
+ https://github.com/docker/compose/issues/2866) is fixed)
- ```
- eval $(docker-machine env -u)
- ../build-tag-push.py
- export COMPOSE_FILE=docker-compose.yml-XXX
- ```
-
-]
+- There are other minor differences, but for our sample
+ app, that's all we have to worry about!
---
-## Add `container_name` to Compose file
+## Our new Compose file
-.exercise[
+.small[
+```
+version: '2'
-- Edit the Compose file
+services:
+ rng:
+ build: rng
+ ports:
+ - 80
-- In the `hasher`, `rng`, and `redis` sections, add:
-
`container_name: XXX`
-
(where XXX is the name of the section)
+ hasher:
+ build: hasher
+ ports:
+ - 80
-- Also, comment out the `volumes` section
+ webui:
+ build: webui
+ ports:
+ - 80
+ redis:
+ image: redis
+
+ worker:
+ build: worker
+```
]
-Note: by default, containers will be named `dockercoins_XXX_1`
-(instead of `XXX`) and links will not work.
+Note: `build-tag-push.py` doesn't support v2 format yet.
-*This is no longer necessary with Compose 1.6!*
+
---
-## Run the app
+## Manually edit out Compose file
+
+- If we try to start the app like that, containers will only
+ run on nodes with the appropriate images
+
+- We need to replace each `build:` section with an `image:` section
.exercise[
-- Add two custom experimental flags:
+- Merge `docker-compose.yml-v2` and `docker-compose.yml-12345678`
+ that was generated earlier
- ```
- docker-compose \
- --x-networking --x-network-driver=overlay \
- up -d
- ```
+- Start the application
-- Check the `webui` endpoint address:
-
- ```
- docker-compose ps webui
- ```
-
-- Go to the webui with your browser!
+- Observe that it's running on multiple nodes
]
+Alternate solution: live code a patch for `build-tag-push.py`.
+
---
-## Scale the app
+## Going further
-.exercise[
+Adding load balancers (difficulty: easy)
-- Don't forget the custom experimental flags:
+- Replace each service by:
- ```
- docker-compose \
- --x-networking --x-network-driver=overlay \
- scale worker=2
- ```
+ - multiple copies of itself
-- Look at the graph in your browser
+ - a load balancer
-]
+- This is what we did with `rng` earlier
-Note: with Compose 1.6 and Engine 1.10, you can have
-multiple containers with the same DNS name, thus
-achieving "natural" load balancing through DNS round robin.
+- Traffic will follow suboptimal paths
+
+---
+
+## Going further
+
+Deploying a new version (difficulty: easy)
+
+- Just re-run all the steps!
+
+- However, Compose will re-create the containers
+
+- You will have to re-create ambassadors
+
(and configure them)
+
+- You will have to cleanup old ambassadors
+
(left as an exercise for the reader)
+
+- You will experience a little bit of downtime
+
+---
+
+## Going further
+
+Zero-downtime deployment (difficulty: medium)
+
+- Isolate stateful services
+
(like we did earlier for Redis)
+
+- Do blue/green deployment:
+
+ - deploy and scale version N
+
+ - point a "top-level" load balancer to the app
+
+ - deploy and scale version N+1
+
+ - put both apps in the "top-level" balancer
+
+ - slowly switch traffic over to app version N+1
+
+---
+
+## Going further
+
+Harder projects:
+
+- Two-tier or three-tier ambassador deployments
+
+- Deploy to Mesos or Kubernetes
---
@@ -3844,14 +3908,21 @@ achieving "natural" load balancing through DNS round robin.
]
-Note: Compose 1.5 doesn't support changes to an
-existing app (except basic scaling).
+---
-When trying to do `docker-compose -x-... up` on existing
-apps, you might get errors like this one:
-
.small[`ERROR: unable to find a node that satisfies container==38aac...`]
+class: pic
-If that happens, just kill+rm the app and try again.
+
+
+---
+
+# Here be dragons
+
+- So far, we've used stable products (versions 1.X)
+
+- We're going to explore experimental software
+
+- **Use at your own risk**
---
@@ -4190,6 +4261,7 @@ Check that the container is up and running.
- I will deliver this workshop about twice a month
- Check out the GitHub repo for updated content!
+
(there is a tag for each big round of updates)
---