From 169d1085a10d51b5fda267ce6b0513b51ffe9c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Petazzoni?= Date: Wed, 13 Apr 2016 22:23:35 +0000 Subject: [PATCH] Update slides for automated testing --- www/htdocs/index.html | 477 ++++++++++++++++++++++++++++-------------- 1 file changed, 315 insertions(+), 162 deletions(-) diff --git a/www/htdocs/index.html b/www/htdocs/index.html index c0aa2d43..5723d6d2 100644 --- a/www/htdocs/index.html +++ b/www/htdocs/index.html @@ -252,22 +252,50 @@ grep '^# ' index.html | grep -v ' + - Log into the first VM (`node1`) -- Check that you can SSH (without password) to `node2` -- Check the version of docker with `docker version` +- Check that you can SSH (without password) to `node2`: + ```bash + ssh node2 + ``` +- Type `exit` or `^D` to come back to node1 + + ] -Note: from now on, unless instructed, **all commands must -be run from the first VM, `node1`**. +--- + +## We will (mostly) interact with node1 only + +- Unless instructed, **all commands must be run from the first VM, `node1`** + +- We will only checkout/copy the code on `node1` + +- When we will use the other nodes, we will do it mostly through the Docker API + +- We will use SSH only for a few "out of band" operations (mass-removing containers...) --- @@ -305,13 +333,22 @@ If you want to use screen or whatever, you're welcome! ## Brand new versions! - Engine 1.11-rc3 - - Compose 1.7-rc1 - - Swarm 1.2-rc1 - - Machine 0.7-rc1 +.exercise[ + +- Check all installed versions: + ```bash + docker version + docker-compose -v + docker run --rm swarm -version + docker-machine -v + ``` + +] + --- # Our sample application @@ -327,6 +364,10 @@ If you want to use screen or whatever, you're welcome! .exercise[ + + - Clone the repository on `node1`:
`git clone git://github.com/jpetazzo/orchestration-workshop` @@ -373,7 +414,7 @@ Without further ado, let's start our application. - Go to the `dockercoins` directory, in the cloned repo: ```bash - cd orchestration-workshop/dockercoins + cd ~/orchestration-workshop/dockercoins ``` - Use Compose to build and run all containers: @@ -402,7 +443,7 @@ and displays aggregated logs. - Stop the application by hitting `^C` @@ -477,7 +518,7 @@ and displays aggregated logs. ``` @@ -522,17 +563,17 @@ Tip: use `^S` and `^Q` to pause/resume log output. docker-compose logs --tail 10 --follow ``` + + ] We will let Compose stream the logs, and open a new terminal. - - --- ## Compose file location @@ -563,7 +604,7 @@ and open a new terminal. ## Locating port numbers for `rng` and `hasher` - We can see the port mapping for our services with: - ``` + ```bash docker-compose ps ``` @@ -630,11 +671,10 @@ Let's get random bytes of data! - Get 10 bytes of random data:
`curl localhost:8001/10` -- If the binary data output messed up your terminal, fix it: -
`reset` - ] +If the binary data output messed up your terminal, fix it with `reset`. + --- ## Testing the `hasher` service @@ -642,22 +682,37 @@ Let's get random bytes of data! .exercise[ - Check that the `hasher` service is alive: -
`curl localhost:8002` + ```bash + curl localhost:8002 + ``` - Posting binary data requires some extra flags: ```bash - curl \ - -H "Content-type: application/octet-stream" \ - --data-binary hello \ - localhost:8002 + curl -H "Content-type: application/octet-stream" \ + --data-binary hello localhost:8002 ``` -- Check that it computed the right hash: -
`echo -n hello | sha256sum` +] + +--- + +## Verifying the computed hash + +- This web service is essentially implementing `sha256sum` over HTTP + +.exercise[ + +- Check that `sha256sum` yields the same result: + ```bash + echo -n hello | sha256sum + ``` ] +- We specify `-n` to prevent `echo` from adding a trailing `\n` +
(which would change the SHA digest) + --- ## Checking logs @@ -719,6 +774,13 @@ We have available resources. - See the impact on CPU load (with top/htop), and on compute speed (with web UI) + + ] .red[*]With some limitations, as we'll see later. @@ -965,7 +1027,7 @@ WHY?!? - We could try to scale with Compose: - ``` + ```bash docker-compose scale rng=3 ``` @@ -999,7 +1061,7 @@ WHY?!? - Use `docker-compose` to stop `rng`: - ``` + ```bash docker-compose stop rng ``` @@ -1081,31 +1143,11 @@ Let's add our load balancer to the Compose file. - "8001:80" ``` -] - -Shortcut: `docker-compose.yml-scaled-rng` - -??? - -## Point other services to the load balancer - -- The only affected service is `worker` - -- We have to replace the `rng` link with a link to `rng0`, - but it should still be named `rng` (so we don't change the code) - -.exercise[ - -- Update the `worker` section as follows: - - ``` - worker: - build: worker - links: - - rng0:rng - - hasher - - redis - ``` + ] @@ -1178,6 +1220,21 @@ faster for a well-behaved application.* --- +## Cleaning up + +- Before moving forward, let's clean up all those containers + +.exercise[ + +- Use the `down` command to stop and remove containers: + ```bash + docker-compose down + ``` + +] + +--- + # Connecting to containers on other hosts - So far, our whole stack is on a single machine @@ -1205,13 +1262,13 @@ faster for a well-behaved application.* - With the CLI: - ``` + ```bash docker run --add-host redis:192.168.1.2 myservice... ``` - In a Compose file: - ``` + ```yaml myservice: image: myservice extra_host: @@ -1274,7 +1331,7 @@ Choose wisely! - Start a new redis container, mapping port 6379 to 6379: - ``` + ```bash docker run -d -p 6379:6379 redis ``` @@ -1284,7 +1341,7 @@ Choose wisely! - Try to connect to it (from anywhere): - ``` + ```bash curl node1:6379 ``` @@ -1300,7 +1357,7 @@ The `ERR` messages are normal: Redis speaks Redis, not HTTP. - Comment out `redis`: - ``` + ```yaml #redis: # image: redis ``` @@ -1315,7 +1372,7 @@ The `ERR` messages are normal: Redis speaks Redis, not HTTP. - Update `worker`: - ``` + ```yaml worker: build: worker extra_hosts: @@ -1340,7 +1397,7 @@ Shortcut: `docker-compose.yml-extra-hosts` - Update `webui`: - ``` + ```yaml webui: build: webui extra_hosts: @@ -1403,7 +1460,7 @@ Shortcut: `docker-compose.yml-extra-hosts` - Keep an eye on the web UI - Create 20 workers on both nodes: - ``` + ```bash for NODE in node1 node2; do export DOCKER_HOST=tcp://$NODE:55555 docker-compose scale worker=20 @@ -1424,7 +1481,7 @@ Note: of course, if we wanted, we could run on all five nodes. - You can use the following scriptlet: - ``` + ```bash for N in $(seq 1 5); do export DOCKER_HOST=tcp://node$N:55555 docker ps -qa | xargs docker rm -f @@ -1445,10 +1502,16 @@ Note: of course, if we wanted, we could run on all five nodes. .exercise[ - See what happens if we run: - ``` + ```bash docker run --add-host redis:1.2.3.4 alpine ping redis ``` + + ] There is a Compose file option for that: `extra_hosts`. @@ -1526,6 +1589,12 @@ class: pic command: 6379 `AA.BB.CC.DD EEEEE` ``` + + ] Shortcut: `docker-compose.yml-ambassador` @@ -1543,13 +1612,13 @@ Shortcut: `docker-compose.yml-ambassador` - Just tell Compose to do its thing: - ``` + ```bash docker-compose up -d ``` - Check that the stack is up and running: - ``` + ```bash docker-compose ps ``` @@ -1677,6 +1746,7 @@ Let's celebrate our success! export DOCKER_HOST=tcp://node$N:55555 docker-compose down & done + wait ``` ] @@ -1860,10 +1930,16 @@ class: title - Make sure you're talking to the initial host: - ``` + ```bash unset DOCKER_HOST ``` + + - Start the container: ```bash @@ -1916,6 +1992,12 @@ class: title - Look into `/tmp/myredis` (on the host) + + ] --- @@ -1970,14 +2052,18 @@ With containers, what are our options? .exercise[ - Get a stream of events: - ``` + ```bash docker events ``` - + - In a new terminal, do *anything*: - ``` + ```bash docker run --rm alpine sleep 10 ``` @@ -2000,7 +2086,7 @@ to the default `bridge` network. .exercise[ - Start two containers, with and without a `backup` label: - ``` + ```bash docker run -d --name leweb nginx docker run -d --name ledata --label backup=please redis ``` @@ -2016,13 +2102,13 @@ to the default `bridge` network. .exercise[ - List only containers that have a `backup` label: - ``` + ```bash docker ps --filter label=backup ``` - List only containers where the `backup` label has a specific value: - ``` + ```bash docker ps --filter label=backup=please ``` @@ -2040,14 +2126,18 @@ to the default `bridge` network. .exercise[ - Show events only for containers with a "backup" label: - ``` + ```bash docker events --filter label=backup ``` - + - In a different terminal, terminate our containers: - ``` + ```bash docker kill leweb ledata ``` @@ -2101,14 +2191,14 @@ Only the events for `ledata` will be shown. - To check logs, run e.g. - ``` + ```bash docker run --volumes-from ... ubuntu sh -c \ "grep WARN /logs/*.log" ``` - Or just go interactive: - ``` + ```bash docker run --volumes-from ... -ti ubuntu ``` @@ -2148,7 +2238,7 @@ Only the events for `ledata` will be shown. - The flags are identical for `docker daemon` and `docker run` Tip #1: when provisioning with Docker Machine, use: -``` +```bash docker-machine create ... --engine-opt log-driver=... ``` @@ -2243,12 +2333,12 @@ What we will do: .exercise[ - Go to the `elk` directory: - ``` + ```bash cd ~/orchestration-workshop/elk ``` - Start the ELK stack: - ``` + ```bash docker-compose up -d ``` @@ -2267,7 +2357,7 @@ What we will do: .exercise[ - Look at Logstash stdout: - ``` + ```bash docker-compose logs logstash ``` @@ -2286,7 +2376,7 @@ in the output. .exercise[ - Check the port number for the Kibana UI: - ``` + ```bash docker-compose ps kibana ``` @@ -2331,11 +2421,19 @@ in the output. .exercise[ - Check the port number for the GELF socket: -
`docker-compose ps logstash` + ```bash + docker-compose ps logstash + ``` - Start a one-off container, overriding its logging driver:
(make sure to update the port number, of course) + + ```bash docker run --rm --log-driver gelf \ --log-opt gelf-address=udp://127.0.0.1:`EEEEE` \ @@ -2405,6 +2503,12 @@ in the output. gelf-address: "udp://`AA.BB.CC.DD:EEEEE`" ``` + + ] Shortcut: `docker-compose.yml-logging` @@ -2417,7 +2521,7 @@ Shortcut: `docker-compose.yml-logging` .exercise[ - Use Compose normally: - ``` + ```bash docker-compose up -d ``` @@ -2484,14 +2588,14 @@ of this workshop. ## In practice - Keep track of running containers before stopping the Engine: - ``` + ```bash docker ps --no-trunc -q | tee /tmp/running | xargs -n1 -P10 docker stop ``` - Restart those containers after the Engine is running again: - ``` + ```bash xargs docker start < /tmp/running ```
(Run this multiple times if you have linked containers!) @@ -2540,7 +2644,7 @@ of this workshop. ## Upgrading with Compose Compose makes this particularly easy: -``` +```bash docker-compose build --pull --no-cache docker-compose up -d ``` @@ -2579,6 +2683,12 @@ Ngrep uses libpcap (like tcpdump) to sniff network traffic. .exercise[ + + - Start a container with the same network namespace:
`docker run --net container:myredis -ti alpine sh` @@ -2588,6 +2698,12 @@ Ngrep uses libpcap (like tcpdump) to sniff network traffic. - Run ngrep:
`ngrep -tpd eth0 -Wbyline . tcp` + + ] You should see a stream of Redis requests and responses. @@ -2944,7 +3060,7 @@ in the discovery service hosted by Docker Inc. - Create your token, saving it preciously to disk as well: - ``` + ```bash TOKEN=$(docker run swarm create | tee token) ``` @@ -2984,6 +3100,12 @@ in the discovery service hosted by Docker Inc. - Provision a node with Docker Machine: + + ```bash docker-machine create --driver generic \ --swarm --swarm-master --swarm-discovery token://$TOKEN \ @@ -3021,13 +3143,13 @@ Let's connect to the node *individually*. - Select the node with Machine - ``` + ```bash eval $(docker-machine env node1) ``` - Execute some Docker commands - ``` + ```bash docker version docker info docker ps @@ -3047,13 +3169,13 @@ Let's connect to the manager instead. - Select the Swarm manager with Machine - ``` + ```bash eval $(docker-machine env node1 --swarm) ``` - Execute some Docker commands - ``` + ```bash docker version docker info docker ps @@ -3148,6 +3270,12 @@ Name: node1 - Add another node with Docker Machine + + ```bash docker-machine create --driver generic \ --swarm --swarm-discovery token://$TOKEN \ @@ -3164,19 +3292,26 @@ Repeat for all 4 nodes. (Pro tip: look for name/address mapping in `/etc/hosts`! ## Scripting -To help you a little bit: +- We can automate the remaining nodes with a little shell script -```bash -grep node[2345] /etc/hosts | grep -v ^127 | -while read IPADDR NODENAME -do docker-machine create --driver generic \ - --swarm --swarm-discovery token://$TOKEN \ - --generic-ssh-user docker \ - --generic-ip-address $IPADDR $NODENAME -done -``` +.exercise[ -Then check with `docker info` that all the nodes are there. +- Deploy nodes 3, 4, and 5: + ```bash + grep node[345] /etc/hosts | grep -v ^127 | + while read IPADDR NODENAME + do docker-machine create --driver generic \ + --swarm --swarm-discovery token://$TOKEN \ + --generic-ssh-user docker \ + --generic-ip-address $IPADDR $NODENAME + done + ``` + +- Check that all nodes are here: + ```bash + docker info + ``` +] --- @@ -3260,7 +3395,7 @@ Before trying to build our app, we will remove previous images. - Delete all images with "dockercoins" in the name: - ``` + ```bash docker images | grep dockercoins | awk '{print $1}' | @@ -3281,7 +3416,7 @@ Before trying to build our app, we will remove previous images. - Run `docker-compose build` - Try to start and scale the application: - ``` + ```bash docker-compose up -d docker-compose scale worker=10 docker-compose scale webui=2 @@ -3408,6 +3543,12 @@ Before trying to build our app, we will remove previous images. .exercise[ + + - Set the following environment variable:
`export DOCKER_REGISTRY=jpetazzo` @@ -3416,6 +3557,12 @@ Before trying to build our app, we will remove previous images. - Log into the Docker Hub:
`docker login` + + ] --- @@ -3481,17 +3628,17 @@ If we wanted to use DTR, we would: .exercise[ - Make sure we have the busybox image: - ``` + ```bash docker pull busybox ``` - Retag the busybox image: - ``` + ```bash docker tag busybox localhost:5000/busybox ``` - Push it: - ``` + ```bash docker push localhost:5000/busybox ``` @@ -3507,7 +3654,7 @@ If we wanted to use DTR, we would: .exercise[ - Set the `DOCKER_REGISTRY` variable: - ``` + ```bash export DOCKER_REGISTRY=localhost:5000 ``` @@ -3528,7 +3675,7 @@ Let's inspect the source code of `build-tag-push.py` and run it. .exercise[ - Run `build-tag-push.py`: - ``` + ```bash eval $(docker-machine env node1) git checkout docker-compose.yml ../bin/build-tag-push.py @@ -3685,13 +3832,13 @@ So, what do‽ - It can be started without configuration: - ``` + ```bash docker run --name amba jpetazzo/hamba run ``` - There is a helper to inject a new configuration: - ``` + ```bash docker run --rm --volumes-from amba jpetazzo/hamba \ reconfigure 80 backend1 port1 backend2 port2 ... ``` @@ -3966,7 +4113,7 @@ class: pic .exercise[ - Scale worker and rng: - ``` + ```bash docker-compose scale worker=5 rng=10 ``` @@ -3994,7 +4141,7 @@ class: pic .exercise[ - Create the missing ambassadors with the script: - ``` + ```bash ../bin/create-ambassadors.py ``` @@ -4022,7 +4169,7 @@ class: pic .exercise[ - Run the last script one more time: - ``` + ```bash ../bin/configure-ambassadors.py ``` @@ -4048,12 +4195,12 @@ class: pic .exercise[ - Terminate and remove all containers: - ``` + ```bash docker-compose down ``` - Remove ambassadors: - ``` + ```bash ../bin/delete-ambassadors.sh ``` @@ -4163,6 +4310,12 @@ Note: our Swarm cluster is now broken. - Re-provision the manager node: + + ```bash docker-machine create --driver generic \ --engine-opt cluster-store=consul://localhost:8500 \ @@ -4203,7 +4356,7 @@ Note: our Swarm cluster is now broken. - Directly point the CLI to a node and check configuration: - ``` + ```bash eval $(docker-machine env node1) docker info ``` @@ -4212,7 +4365,7 @@ Note: our Swarm cluster is now broken. - Try to talk to the Swarm cluster: - ``` + ```bash eval $(docker-machine env node1 --swarm) docker info ``` @@ -4307,12 +4460,12 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V .exercise[ - Ask Consul the list of members it knows: - ``` + ```bash docker run --net host --rm jpetazzo/consul members ``` - Ask Consul which node is the current leader: - ``` + ```bash curl localhost:8500/v1/status/leader ``` @@ -4326,7 +4479,7 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V - Try again the `docker info` from earlier: - ``` + ```bash eval $(docker-machine env --swarm node1) docker info ``` @@ -4361,7 +4514,7 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V .exercise[ - Create two networks, *blue* and *green*: - ``` + ```bash docker network create --driver overlay blue docker network create --driver overlay green docker network ls @@ -4369,7 +4522,7 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V - Create containers with names of blue and green things, on their respective networks: - ``` + ```bash docker run -d --name sky --net blue -m 3G redis docker run -d --name navy --net blue -m 3G redis docker run -d --name grass --net green -m 3G redis @@ -4386,19 +4539,19 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V - Check that our containers are on different networks: - ``` + ```bash docker ps ``` - This will work: - ``` + ```bash docker exec -ti sky ping navy ``` - This will not: - ``` + ```bash docker exec -ti navy ping grass ``` @@ -4413,12 +4566,12 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V .exercise[ - Create a container that we want to be on both networks: - ``` + ```bash docker run -d --net blue --name turquoise nginx ``` - Check connectivity: - ``` + ```bash docker exec -ti turquoise ping -c1 navy docker exec -ti turquoise ping -c1 grass ``` @@ -4436,12 +4589,12 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V .exercise[ - Dynamically connect to the green network: - ``` + ```bash docker network connect green turquoise ``` - Check connectivity: - ``` + ```bash docker exec -ti turquoise ping -c1 navy docker exec -ti turquoise ping -c1 grass ``` @@ -4460,7 +4613,7 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V .exercise[ - View interfaces in our `turquoise` container: - ``` + ```bash docker exec -ti turquoise ip addr ls ``` @@ -4476,13 +4629,13 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V - Disconnect the *turquoise* container from *blue* (its original network): - ``` + ```bash docker network disconnect blue turquoise docker network connect green turquoise ``` - Check connectivity: - ``` + ```bash docker exec -ti turquoise ping -c1 navy docker exec -ti turquoise ping -c1 grass ``` @@ -4498,13 +4651,13 @@ Note: good guy ~~Stevedore~~ Docker will start without K/V - Destroy containers: - ``` + ```bash docker rm -f sky navy grass forest turquoise ``` - Destroy networks: - ``` + ```bash docker network rm blue docker network rm green ``` @@ -4543,7 +4696,7 @@ There is a `"disconnect -f"` if needed. .exercise[ - Go to the `registry` directory in the repository: - ``` + ```bash cd ~/orchestration-workshop/registry ``` @@ -4588,12 +4741,12 @@ and network aliases. .exercise[ - Make sure that `COMPOSE_FILE` is not set: - ``` + ```bash unset COMPOSE_FILE ``` - Start the registry: - ``` + ```bash docker-compose up -d ``` @@ -4691,7 +4844,7 @@ Copy-paste this into `docker-compose.yml` - Set `DOCKER_REGISTRY` to use our local registry,
then build, tag, and push the application: - ``` + ```bash export DOCKER_REGISTRY=localhost:5000 ../bin/build-tag-push.py ``` @@ -4709,13 +4862,13 @@ Copy-paste this into `docker-compose.yml` .exercise[ - Start the application: - ``` - export COMPOSE_FILE=docker-compose.yml-NNN + ```bash + export COMPOSE_FILE=docker-compose.yml-`NNN` docker-compose up -d ``` - Observe that it's running on multiple nodes: - ``` + ```bash docker ps ``` @@ -4732,7 +4885,7 @@ Each container name is prefixed with the node it's running on. .exercise[ - Check the `webui` service address and port: - ``` + ```bash docker-compose port webui 80 ``` @@ -4750,7 +4903,7 @@ Each container name is prefixed with the node it's running on. .exercise[ - Scale `worker`: - ``` + ```bash docker-compose scale worker=10 ``` @@ -4790,7 +4943,7 @@ How can we scale that service? -- - In a perfect world, we would like to do: - ``` + ```bash docker-compose scale rng=10 ``` @@ -4927,12 +5080,12 @@ Load-balanced DockerCoins .exercise[ - Bring up DockerCoins: - ``` + ```bash docker-compose up -d ``` - See that `worker` is complaining: - ``` + ```bash docker-compose logs worker ``` ] @@ -4970,7 +5123,7 @@ The application should now be working correctly. .exercise[ - Scale `rng`: - ``` + ```bash docker-compose scale rng=10 ``` @@ -5091,7 +5244,7 @@ Harder projects: - Terminate containers and remove them: - ``` + ```bash docker-compose down ``` @@ -5167,7 +5320,7 @@ class: pic .exercise[ - Be lazy and use the Docker image: - ``` + ```bash sudo docker run --rm -v /usr/local/bin:/target jpetazzo/consulfs ``` ] @@ -5192,12 +5345,12 @@ the host (yet). .exercise[ - Create a mount point: - ``` + ```bash mkdir ~/consul ``` - Mount Consul as a local filesystem: - ``` + ```bash consulfs localhost:8500 ~/consul ``` @@ -5217,12 +5370,12 @@ Leave this running in the foreground. .exercise[ - Check that Consul key/values are visible: - ``` + ```bash ls -l ~/consul/ ``` - Copy Machine credentials into Consul: - ``` + ```bash cp -r ~/.docker/machine/. ~/consul/machine/ ``` @@ -5239,7 +5392,7 @@ Leave this running in the foreground. .exercise[ - Connect to node2: - ``` + ```bash ssh node2 ``` @@ -5427,7 +5580,7 @@ reconfigured and restarted. .exercise[ - Talk to a random node, and ask its view of the cluster: - ``` + ```bash eval $(docker-machine env node3 --swarm) docker info | grep -e ^Name -e ^Role -e ^Primary ``` @@ -5453,7 +5606,7 @@ debugging. .exercise[ - Kill the primary manager: - ``` + ```bash ssh node`N` docker kill swarm-agent-master ``` @@ -5490,7 +5643,7 @@ Look at the output of `docker info` every few seconds.
(Machine adds flags *after* the Swarm command) - Instead, we will use the Swarm image `jpetazzo/swarm:experimental`: - ``` + ```dockerfile FROM swarm ENTRYPOINT ["/swarm", "--experimental"] ```