I found docker interesting technology something about 2 years ago, at this point I want to use it on larger scale then one machine but not necessary using cloud or kubernetes. I just want to be able to create 3 physical machines cluster ( swarm ) and deploy applications ( services ) on it.
1. Installation Of Docker
First I will install latest docker version just by using those commands:
curl -X GET https://get.docker.com/ > get-docker.sh
sudo sh get-docker.sh
then I will add my user to the docker by typing :
sudo usermod -aG docker USERNAME
2. Configuration Of Docker Deamon
Second I need to be able to run docker as deamon on public port and let it be 2375
.
To do it I will reconfigure docker daemon
sudo service docker stop
sudo vi /etc/docker/daemon.json
{
"debug":true,
"bip":"172.16.0.1/16",
"hosts":["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}
Also to get rid of -H fd://
in systemctl modify docker script
sudo systemctl edit docker
And paste:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
and finally start docker using
sudo service docker start
Probably I could also use some proxy since dockerd is simply http server with json api, or at least som environment variable, but this way I can learn something more about systemd shitty configurations.
3. Installation Of docker-compose And docker-machine
Third I want to also use docker-compose to manage my multiple docker container application and since it is python package I will install it with :
pip install docker-compose
Last but not least I want to setup docker-machine to maintain my cluster. I will grab latest version from https://github.com/docker/machine/releases and just apply some console magic (I am installing version for raspberry pi 3):
wget https://github.com/docker/machine/releases/download/v0.12.2/docker-machine-Linux-armhf
sudo cp docker-machine-Linux-armhf /usr/local/bin/docker-machine
sudo chmod +x /usr/local/bin/docker-machine
So now since I got all lame docker prefixed shit in place including docker,dockerd,docker-machine,docker-compose I can add some machines to maintain and finally start to swarm my machines with containers.
4. SSH Keys
So I will be adding 3 machines and I want to access to them without password.
I will create simple configuration in /etc/hosts
file for now:
192.168.1.101 pi01
192.168.1.102 pi02
192.168.1.103 pi03
First let's create key
ssh-keygen -t rsa -b 4096
I will add my key to my hosts using:
cat ~/.ssh/id_rsa.pub | ssh pi@pi01 'cat >> .ssh/authorized_keys'
cat ~/.ssh/id_rsa.pub | ssh pi@pi02 'cat >> .ssh/authorized_keys'
cat ~/.ssh/id_rsa.pub | ssh pi@pi03 'cat >> .ssh/authorized_keys'
5. Creation Of Docker Machine
then create one machine:
docker-machine create --driver=generic --generic-ssh-user=pi --generic-ssh-key=/home/pi/.ssh/id_rsa --generic-ip-address=pi01 --generic-engine-port=2375 pi01
the output for raspberry pi 3 should be something like this (first failure):
Detecting the provisioner...
Error creating machine: Error detecting OS: OS type not recognized
But it should be running so using docker-machine ls
I will get (second failure):
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
pi01 - generic Running tcp://pi01:2375 Unknown Unable to query docker version: Get https://pi01:2375/v1.15/version: http: server gave HTTP response to HTTPS client
Ok so I need to use https instead of http with my docker deamon to fix machine listings and also provision my machines manually.
6. Certificate Authority For HTTPS Traffic.
Let's start from locating cerfiticate authority (CA) and creating certificate for each machine. I am using docker-machine so files should be around here:
~/.docker/machine/certs/ca-key.pem
~/.docker/machine/certs/ca.pem
If I didn't have those files I can create them from command line:
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Ok so now I will create certificate for pi01 machine with ip 192.168.1.101 and 127.0.0.1:
openssl genrsa -out key.pem 4096
openssl req -subj "/CN=pi01" -sha256 -new -key key.pem -out server.csr
echo subjectAltName = DNS:pi01,IP:192.168.1.101,IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
openssl x509 -req -days 1000 -sha256 -in server.csr -CA ~/.docker/machine/certs/ca.pem -CAkey ~/.docker/machine/certs/ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
7. Docker Deamon With HTTPS Trafic
After that I can modify configuration of my docker daemon:
sudo vi /etc/docker/daemon.json
with configuration:
{
"debug":true,
"tls":true,
"tlsverify":true,
"tlscacert":"/home/pi/.docker/certs/ca.pem",
"tlscert":"/home/pi/.docker/certs/cert.pem",
"tlskey":"/home/pi/.docker/certs/key.pem",
"bip":"172.16.0.1/16",
"hosts":["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}
notice that I intentionally changed port from 2375
to 2376
so I need to change my docker-machine
config file:
vi ~/.docker/machine/machines/pi01/config.json
# change section :
"Driver": {
"EnginePort": 2376,
Now everything is all right (except active flag) with first machine:
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
pi01 - generic Running tcp://pi01:2376 v17.05.0-ce
8. Manual Provisioning Summary
Ok so since I cannot provision two other raspberry pi I will add certificates for each host and change systemctl manually. Again this could be done using environment variables
DOCKER_HOST="tcp://0.0.0.0:2376"
So for me it is (in short provisioning and certificates for pi02):
add machine
docker-machine create --driver=generic --generic-ssh-user=pi --generic-ssh-key=/home/pi/.ssh/id_rsa --generic-ip-address=pi02 --generic-engine-port=2376 pi02
add directory and create certs for ip 192.168.1.102 hostname pi02
cd ~/.docker/machine/machines/pi02
mkdir certs
cd certs
openssl genrsa -out key.pem 4096
openssl req -subj "/CN=pi02" -sha256 -new -key key.pem -out server.csr
echo subjectAltName = DNS:pi02,IP:192.168.1.102,IP:127.0.0.1 >> extfile.cnf
echo extendedKeyUsage = serverAuth >> extfile.cnf
openssl x509 -req -days 365 -sha256 -in server.csr -CA ~/.docker/machine/certs/ca.pem -CAkey ~/.docker/machine/certs/ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
cp ~/.docker/machine/certs/ca.pem .
copy to remote machine
rsync -Paz --rsync-path="mkdir -p /home/pi/.docker/certs && rsync" * pi@pi02:~/.docker/certs
to remote machine
docker-machine ssh pi02
edit daemon.json
sudo vi /etc/docker/daemon.json
{
"debug":true,
"tls":true,
"tlsverify":true,
"tlscacert":"/home/pi/.docker/certs/ca.pem",
"tlscert":"/home/pi/.docker/certs/cert.pem",
"tlskey":"/home/pi/.docker/certs/key.pem",
"bip":"172.16.0.1/16",
"hosts":["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}
edit systemctl
sudo systemctl edit docker
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd
restart docker service
sudo service docker restart
I won't repeat those steps for pi03. After running those commands I have something like this:
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
pi01 - generic Running tcp://pi01:2376 v17.05.0-ce
pi02 - generic Running tcp://pi02:2376 v17.05.0-ce
pi03 - generic Running tcp://pi03:2376 v17.05.0-ce
9. Configuration of docker-swarm
Now it's time for swarming. I will start with one host that will act as manager.
docker swarm init
I will add other hosts as guests by simply execute command printed to console on other hosts
docker swarm join --token tokenstring swarmip:port
This node joined a swarm as a worker.
And after that that to see my cluster I can run command:
docker node ls
So there it is.
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
xxx * pi01 Ready Active Leader
xxx pi02 Ready Active
xxx pi03 Ready Active
if someone want to add some machines to the swarm later or simply want to add more managers to retrieve specific command just invoke:
docker swarm join-token worker
docker swarm join-token manager
Next I will try to write about how to build docker applications, use docker-compose and deploy it against swarm cluster.