pi@pi01:~ $ curl -sSL https://get.docker.com | sh # Executing docker install script, commit: 26ff363bcf3b3f5a00498ac43694bf1c7d9ce16c Warning: the "docker" command appears to already exist on this system.
If you already have Docker installed, this script can cause trouble, which is why we're displaying this warning and provide the opportunity to cancel the installation.
If you installed the current Docker package using this script and are using it again to update Docker, you can safely ignore this message.
You may press Ctrl+C now to abort this script. + sleep 20 + sudo -E sh -c apt-get update -qq >/dev/null + sudo -E sh -c DEBIAN_FRONTEND=noninteractive apt-get install -y -qq apt-transport-https ca-certificates curl >/dev/null + sudo -E sh -c curl -fsSL "https://download.docker.com/linux/raspbian/gpg" | apt-key add -qq - >/dev/null Warning: apt-key output should not be parsed (stdout is not a terminal) + sudo -E sh -c echo "deb [arch=armhf] https://download.docker.com/linux/raspbian buster stable" > /etc/apt/sources.list.d/docker.list + sudo -E sh -c apt-get update -qq >/dev/null + [ -n ] + sudo -E sh -c apt-get install -y -qq --no-install-recommends docker-ce >/dev/null + sudo -E sh -c docker version Client: Docker Engine - Community Version: 19.03.11 API version: 1.40 Go version: go1.13.10 Git commit: 42e35e6 Built: Mon Jun 1 09:20:15 2020 OS/Arch: linux/arm Experimental: false
Server: Docker Engine - Community Engine: Version: 19.03.11 API version: 1.40 (minimum version 1.12) Go version: go1.13.10 Git commit: 42e35e6 Built: Mon Jun 1 09:14:09 2020 OS/Arch: linux/arm Experimental: false containerd: Version: 1.2.13 GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683 If you would like to use Docker as a non-root user, you should now consider adding your user to the "docker" group with something like:
sudo usermod -aG docker pi
Remember that you will have to log out and back in for this to take effect!
WARNING: Adding a user to the "docker" group will grant the ability to run containers which can be used to obtain root privileges on the docker host. Refer to https://docs.docker.com/engine/security/security/#docker-daemon-attack-surface for more information.
pi@pi01:~ $ docker pull arm64v8/alpine Using default tag: latest latest: Pulling from arm64v8/alpine b538f80385f9: Pull complete Digest: sha256:3b3f647d2d99cac772ed64c4791e5d9b750dd5fe0b25db653ec4976f7b72837c Status: Downloaded newer image for arm64v8/alpine:latest docker.io/arm64v8/alpine:latest pi@pi01:~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE arm64v8/alpine latest 62ee0e9f8440 11 days ago 5.32MB pi@pi01:~ $ docker run -it -d arm64v8/alpine 4deed42b3a29231bde40176c5c385d9f04bbf5188383b2ede4a09383360d69bb pi@pi01:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4deed42b3a29 arm64v8/alpine "/bin/sh" 49 seconds ago Restarting (159) 8 seconds ago inspiring_mendeleev pi@pi01:~ $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4deed42b3a29 arm64v8/alpine "/bin/sh" 51 seconds ago Up 2 seconds inspiring_mendeleev pi@pi02:~ $
pi@pi01:~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE alpine latest 3ddac682c5b6 12 days ago 4.77MB arm64v8/alpine latest 62ee0e9f8440 12 days ago 5.32MB arm64v8/ubuntu latest dbc66a3d7b82 6 weeks ago 66.7MB aarch64/ubuntu latest 5227400055a2 3 years ago 122MB pi@pi01:~ $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e06eaba12e82 alpine "/bin/sh" 2 hours ago Up 2 hours relaxed_cerf ba8d858d36f0 aarch64/ubuntu "/bin/bash" 2 hours ago Exited (159) 2 hours ago nifty_sutherland 08346701599a arm64v8/ubuntu "/bin/bash" 2 hours ago Exited (159) 2 hours ago jolly_fermi ccda6c95f81d arm64v8/alpine "/bin/sh" 4 hours ago Exited (159) 4 hours ago nifty_gates
pi@pi02:~ $ docker pull arm32v6/alpine Using default tag: latest latest: Pulling from arm32v6/alpine Digest: sha256:71465c7d45a086a2181ce33bb47f7eaef5c233eace65704da0c5e5454a79cee5 Status: Image is up to date for arm32v6/alpine:latest docker.io/arm32v6/alpine:latest pi@pi02:~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE arm32v6/alpine latest 3ddac682c5b6 3 weeks ago 4.77MB pi@pi02:~ $ docker run -it -d arm32v6/alpine 66b813b4c07426294e01f3c7b2ff03f6608f6be10f8f7bf9fde581f605e6a5bc pi@pi02:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 66b813b4c074 arm32v6/alpine "/bin/sh" 10 seconds ago Up 5 seconds intelligent_gates pi@pi02:~ $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 66b813b4c074 arm32v6/alpine "/bin/sh" 12 seconds ago Up 8 seconds intelligent_gates pi@pi02:~ $ docker exec -it 66b813b4c074 /bin/sh / # cat /etc/os-release NAME="Alpine Linux" ID=alpine VERSION_ID=3.12.0 PRETTY_NAME="Alpine Linux v3.12" HOME_URL="https://alpinelinux.org/" BUG_REPORT_URL="https://bugs.alpinelinux.org/" / # uname -a Linux 66b813b4c074 4.19.118-v7l+ #1311 SMP Mon Apr 27 14:26:42 BST 2020 armv7l Linux / # exit pi@pi02:~ $
, where X=1, or 2, or 3, or 4.
Now, we can see docker0 is UP. And
a wired connection is running as the additional interface
vethc6e4f97, which is actually just eth0 running in docker image arm32v6/alpine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
pi@pi02:~ $ ip -c address ... 4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:0e:a2:30:0d brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:eff:fea2:300d/64 scope link valid_lft forever preferred_lft forever 6: vethc6e4f97@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 3e:cf:32:5f:92:e8 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 169.254.108.166/16 brd 169.254.255.255 scope global noprefixroute vethc6e4f97 valid_lft forever preferred_lft forever inet6 fe80::f8c1:6d4c:aa67:11af/64 scope link valid_lft forever preferred_lft forever
3.3.2 Docker Login & Docker
Commit
In order to avoid issues about registry, we can run
docker login, so that a configuration file
/home/pi/.docker/config.json will also be automatically
generated.
1 2 3 4 5 6 7 8 9 10 11
pi@pi01:~ $ docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: jiapei100 Password: WARNING! Your password will be stored unencrypted in /home/pi/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store
From the above command docker info, you can see clearly
that Swarm: inactive. Docker now has a Docker Swarm Mode. Now,
let's begin playing with Docker Swarm.
If you've got both Wired and Wifi
enabled at the same time, without specifying with connection you are
going to use for initializing your docker swarm, you'll
meet the following ERROR message.
1 2
pi@pi01:~ $ docker swarm init Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on different interfaces (192.168.1.253 on eth0 and 192.168.1.252 on wlan0) - specify one with --advertise-addr
By specifying the argument --advertise-addr, docker swarm can be
successfully initialized as:
1 2 3 4 5 6 7 8
pi@pi01:~ $ docker swarm init --advertise-addr 192.168.1.253 Swarm initialized: current node (q7w8gwf9z6keb86rltvqx0f7z) is now a manager.
To add a worker to this swarm, run the following command:
On each worker, just run the following command to
join docker swarm
created by master.
1 2
pi@pi0X:~ $ docker swarm join --token SWMTKN-1-5ivkmmwk8kfw92gs0emkmgzg78d4cwitqmi827ghikpajzvrjt-6i326au3t4ka3g1wa74n4rhe4 192.168.1.253:2377 This node joined a swarm as a worker.
, where X=2, or 3, or 4.
4.3 List Docker Nodes In
Leader
Come back to pi01, namely, docker swarmmaster, also the leader, and list all
nodes:
1 2 3 4 5 6
pi@pi01:~ $ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION q7w8gwf9z6keb86rltvqx0f7z * pi01 Ready Active Leader 19.03.11 sdiwqlawhfjobfsymmp38xivn pi02 Ready Active 19.03.11 97h11ixu7nvce4p64td2o5one pi03 Ready Active 19.03.11 tzrqp2fcj4yht20j84r83s5ps pi04 Ready Active 19.03.11
In our test, we ONLY designate a single
leader. You can of course have the option to designate
multiple leaders by using command
docker node promote.
Create the service on leader with 4 replicas on both
the master and 3 workers.
1 2 3 4 5 6 7 8
pi@pi01:~ $ docker service create --name ping1 --replicas=4 alexellis2/arm-pingcurl ping google.com 63n31w2jyr6uuqg2670r985h6 overall progress: 4 out of 4 tasks 1/4: running [==================================================>] 2/4: running [==================================================>] 3/4: running [==================================================>] 4/4: running [==================================================>] verify: Service converged
Then, we can list the created docker service on the
leader.
1 2 3 4 5 6 7 8 9
pi@pi01:~ $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS 63n31w2jyr6u ping1 replicated 4/4 alexellis2/arm-pingcurl:latest pi@pi01:~ $ docker service ps ping1 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS xqjxus8ayetx ping1.1 alexellis2/arm-pingcurl:latest pi02 Running Running 2 hours ago 9lemwgls6hp6 ping1.2 alexellis2/arm-pingcurl:latest pi03 Running Running 2 hours ago b2y2muif9h2x ping1.3 alexellis2/arm-pingcurl:latest pi04 Running Running 2 hours ago 2uqbcrn0j7et ping1.4 alexellis2/arm-pingcurl:latest pi01 Running Running 2 hours ago
4.4.1.1 On Master
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
pi@pi01:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7d72a046d2f4 alexellis2/arm-pingcurl:latest "ping google.com" 41 minutes ago Up 41 minutes ping1.4.2uqbcrn0j7ettnqndxfq6s44b 71ef4e0107a7 arm32v6/alpine "/bin/sh" 9 hours ago Up 9 hours great_saha pi@pi01:~ $ docker logs 7d72a046d2f4 | tail -n 10 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42461 ttl=119 time=5.98 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42462 ttl=119 time=5.53 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42463 ttl=119 time=5.69 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42464 ttl=119 time=5.98 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42465 ttl=119 time=5.97 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42466 ttl=119 time=5.65 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42467 ttl=119 time=6.22 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42468 ttl=119 time=6.33 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42469 ttl=119 time=9.93 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42470 ttl=119 time=5.82 ms
4.4.1.2 On Worker
This time, let's take pi04 as our example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
pi@pi04:~/Downloads $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2520e1ea0ea8 alexellis2/arm-pingcurl:latest "ping google.com" 44 minutes ago Up 44 minutes ping1.3.b2y2muif9h2xa847rlibcv5nz 746386fce983 arm32v6/alpine "/bin/sh" 11 days ago Up 9 hours serene_chebyshev pi@pi04:~ $ docker logs 2520e1ea0ea8 | tail -n 10 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42491 ttl=119 time=7.22 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42492 ttl=119 time=9.10 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42493 ttl=119 time=6.97 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42494 ttl=119 time=6.76 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42495 ttl=119 time=6.74 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42496 ttl=119 time=7.03 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42497 ttl=119 time=7.06 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42498 ttl=119 time=6.17 ms 64 bytes from sea15s12-in-f14.1e100.net (172.217.3.206): icmp_seq=42499 ttl=119 time=6.74 ms 64 bytes from sea15s12-in-f206.1e100.net (172.217.3.206): icmp_seq=42500 ttl=119 time=6.23 ms
4.4.2 Scenario 2 - Replicate
Webservice
In this example, we will create 2 replicas only for
fun.
1 2 3 4 5 6
pi@pi01:~ $ docker service create --name hello1 --publish 3000:3000 --replicas=2 alexellis2/arm-alpinehello pe19as7evzmgi5qiq36z2pk63 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
Again, let's list our created services.
1 2 3 4 5 6 7 8
pi@pi01:~ $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS pe19as7evzmg hello1 replicated 2/2 alexellis2/arm-alpinehello:latest *:3000->3000/tcp 63n31w2jyr6u ping1 replicated 4/4 alexellis2/arm-pingcurl:latest pi@pi01:~ $ docker service ps hello1 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS z9k8a10hkxqv hello1.1 alexellis2/arm-alpinehello:latest pi02 Running Running about an hour ago 7xuhpuru0r5u hello1.2 alexellis2/arm-alpinehello:latest pi01 Running Running about an hour ago
4.4.2.1 On Master and Worker
pi02
On masterpi01 and
workerpi02, there are 3 running
docker images:
1 2 3 4 5
pi@pi02:~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE arm32v6/alpine latest 3ddac682c5b6 3 weeks ago 4.77MB alexellis2/arm-pingcurl <none> 86a225e3a07b 3 years ago 6.19MB alexellis2/arm-alpinehello <none> 2ad6d1f9b6ae 3 years ago 33.8MB
, and 3 running docker containers.
1 2 3 4 5
pi@pi02:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 918e211b5784 alexellis2/arm-alpinehello:latest "npm start" 22 minutes ago Up 22 minutes 3000/tcp hello1.1.z9k8a10hkxqvsovuu6omw4axy a92acd03471a alexellis2/arm-pingcurl:latest "ping google.com" About an hour ago Up About an hour ping1.1.xqjxus8ayetxiip2cmw4fm54x 66b813b4c074 arm32v6/alpine "/bin/sh" 11 hours ago Up 11 hours intelligent_gates
4.4.2.2 On Worker pi03 and
Worker pi04
On masterpi03 and
workerpi04, there are
only 2 running docker images:
1 2 3 4
pi@pi03:~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE arm32v6/alpine latest 3ddac682c5b6 3 weeks ago 4.77MB alexellis2/arm-pingcurl <none> 86a225e3a07b 3 years ago 6.19MB
, and 3 running docker containers.
1 2 3 4
pi@pi03:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5670e6944779 alexellis2/arm-pingcurl:latest "ping google.com" About an hour ago Up About an hour ping1.2.9lemwgls6hp6wnpyg14aeyeva f3d1670dfc7a arm32v6/alpine "/bin/sh" 11 days ago Up 9 hours infallible_cerf
Afterwards, a redis database service is created and runs on a
single node, here, masterpi01.
1 2 3 4 5
pi@pi01:~ $ docker service create --replicas=1 --network=armnet --name redis alexellis2/redis-arm:v6 kmk663ad1t88nfjf567tkctmr overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged
Finally, 2 replicas of docker service counter are
created in this created subnetwork armnet and listening
to port 3333.
1 2 3 4 5 6
pi@pi01:~ $ docker service create --name counter --replicas=2 --network=armnet --publish 3333:3333 alexellis2/arm_redis_counter ivdubq3vzdil3r2i5z0r1d2va overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
Now, let's list all created docker service on the leader.
1 2 3 4 5 6 7 8 9 10 11 12 13
pi@pi01:~ $ docker service ls ID NAME MODE REPLICAS IMAGE PORTS ivdubq3vzdil counter replicated 2/2 alexellis2/arm_redis_counter:latest *:3333->3333/tcp pe19as7evzmg hello1 replicated 2/2 alexellis2/arm-alpinehello:latest *:3000->3000/tcp 63n31w2jyr6u ping1 replicated 4/4 alexellis2/arm-pingcurl:latest kmk663ad1t88 redis replicated 1/1 alexellis2/redis-arm:v6 pi@pi01:~ $ docker service ps counter ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ip6z9yacmjbz counter.1 alexellis2/arm_redis_counter:latest pi04 Running Running about an hour ago nzhx6q1vugm9 counter.2 alexellis2/arm_redis_counter:latest pi02 Running Running about an hour ago pi@pi01:~ $ docker service ps redis ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS z1tqve759bh6 redis.1 alexellis2/redis-arm:v6 pi03 Running Running 2 hours ago
It's interesting that this time: - the 2 replicas of service
counter are automatically created on node
pi02 and pi04 - the unique replica of
service redis is allocated for node
pi03
I've got no idea how the created services are
distributed to different nodes. The ONLY thing I can do
is to run docker ps and show the distribution
results:
pi01
1 2 3 4 5
pi@pi01:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b2c313ac8200 alexellis2/arm-alpinehello:latest "npm start" 3 hours ago Up 3 hours 3000/tcp hello1.2.7xuhpuru0r5ujkyrp4g558ehu 7d72a046d2f4 alexellis2/arm-pingcurl:latest "ping google.com" 3 hours ago Up 3 hours ping1.4.2uqbcrn0j7ettnqndxfq6s44b 71ef4e0107a7 arm32v6/alpine "/bin/sh" 11 hours ago Up 11 hours great_saha
pi02
1 2 3 4 5 6
pi@pi02:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES da2452b474af alexellis2/arm_redis_counter:latest "node ./app.js" 2 hours ago Up 2 hours 3000/tcp counter.2.nzhx6q1vugm9w7ouqyots5x43 918e211b5784 alexellis2/arm-alpinehello:latest "npm start" 3 hours ago Up 3 hours 3000/tcp hello1.1.z9k8a10hkxqvsovuu6omw4axy a92acd03471a alexellis2/arm-pingcurl:latest "ping google.com" 3 hours ago Up 3 hours ping1.1.xqjxus8ayetxiip2cmw4fm54x 66b813b4c074 arm32v6/alpine "/bin/sh" 14 hours ago Up 14 hours intelligent_gates
pi03
1 2 3 4 5
pi@pi03:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5fd9a0b8dd08 alexellis2/redis-arm:v6 "redis-server" 2 hours ago Up 2 hours 6379/tcp redis.1.z1tqve759bh6hdw2udnk6hh7t 5670e6944779 alexellis2/arm-pingcurl:latest "ping google.com" 3 hours ago Up 3 hours ping1.2.9lemwgls6hp6wnpyg14aeyeva f3d1670dfc7a arm32v6/alpine "/bin/sh" 12 days ago Up 11 hours infallible_cerf
pi04
1 2 3 4 5
pi@pi04:~ $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES aca52fdaf2d4 alexellis2/arm_redis_counter:latest "node ./app.js" 2 hours ago Up 2 hours 3000/tcp counter.1.ip6z9yacmjbzjaeax45tuh2oa 2520e1ea0ea8 alexellis2/arm-pingcurl:latest "ping google.com" 3 hours ago Up 3 hours ping1.3.b2y2muif9h2xa847rlibcv5nz 746386fce983 arm32v6/alpine "/bin/sh" 12 days ago Up 11 hours serene_chebyshev
Clearly, - servicealexellis2/arm_redis_counter is running on both nodes
pi02 and pi04, but
not on nodes pi01 or pi03 -
servicealexellis2/arm-alpinehello is
running on both nodes pi01 and pi02,
but not on nodes pi03 or
pi04 - servicealexellis2/arm-pingcurl is running on all 4 nodes
pi01, pi02. pi03, and
pi04
So far, curl localhost:3333/incr
is NOT running. Why?
What's more: -
without touching anything for a whole night, servicealexellis2/arm_redis_counter seems to automatically
shundown with the ERROR:
task: non-zero exit (1) for multiple times. -
alexellis2/arm_redis_counter is now running on nodes
masterpi01 and
workerpi04, instead of original
masterpi02 and
workerpi04. - it's interesting that
alexellis2/redis-arm is still running on node
pi03.