Docker Swarm és el què es coneix com un orquestrador de contenidors, a l'igual que Kubernetes, només que aquest darrer és més potent (i més complicat). Els orquestradors ens permeten gestionar les instàncies de contenidors distribuïdes en diverses màquines físiques (o virtuals), pel què els orquestradors son una eina imprescindible per a la gestió de l'escalabilitat i alta disponibilitat de les aplicacions actuals.
Docker Swarm ve actualment inclosa dins el propi Docker Engine, així que no ens cal instal·lar res més que el propi motor de Docker per iniciar els nodes en mode Swarm, facilitant la posada en marxa.
Continua a:
En Docker Swarm disposem de 2 tipus de nodes (VMs):
El Swarm es basa en serveis que definirem mitjançant un docker-stack.yml, molt similar a docker-compose
, i replicarem segons convingui per augmentar les prestacions.
Cada node disposa d'un load balancer que ens permetrà accedir indistintament als serveis a través de qualsevol node. Els mateixos load balancers decidiran com redirigir el trànsit en base als valors interns de càrrega de la CPU dels nodes, etc.
Aquest Vagrantfile et crearà un Docker Swarm amb 1 manager i 2 workers (el manager també accepta tasques de worker).
$install_docker_script = <<SCRIPT
echo Installing Docker...
curl -sSL https://get.docker.com/ | sh
sudo usermod -aG docker vagrant
SCRIPT
$manager_script = <<SCRIPT
echo Swarm Init...
sudo docker swarm init --listen-addr 10.100.199.200:2377 --advertise-addr 10.100.199.200:2377
sudo docker swarm join-token --quiet worker > /vagrant/worker_token
SCRIPT
$worker_script = <<SCRIPT
echo Swarm Join...
sudo docker swarm join --token $(cat /vagrant/worker_token) 10.100.199.200:2377
SCRIPT
Vagrant.configure('2') do |config|
vm_box = 'ubuntu/focal64'
config.vm.define :manager, primary: true do |manager|
manager.vm.box = vm_box
manager.vm.box_check_update = true
manager.vm.network :private_network, ip: "10.100.199.200"
manager.vm.network :forwarded_port, guest: 8080, host: 8080
manager.vm.network :forwarded_port, guest: 5000, host: 5000
manager.vm.hostname = "manager"
manager.vm.synced_folder ".", "/vagrant"
manager.vm.provision "shell", inline: $install_docker_script, privileged: true
manager.vm.provision "shell", inline: $manager_script, privileged: true
manager.vm.provider "virtualbox" do |vb|
vb.name = "manager"
vb.memory = "1024"
end
end
(1..2).each do |i|
config.vm.define "worker0#{i}" do |worker|
worker.vm.box = vm_box
worker.vm.box_check_update = true
worker.vm.network :private_network, ip: "10.100.199.20#{i}"
worker.vm.hostname = "worker0#{i}"
worker.vm.synced_folder ".", "/vagrant"
worker.vm.provision "shell", inline: $install_docker_script, privileged: true
worker.vm.provision "shell", inline: $worker_script, privileged: true
worker.vm.provider "virtualbox" do |vb|
vb.name = "worker0#{i}"
vb.memory = "1024"
end
end
end
end
Aixequeu les màquines virtuals descarregant el Vagrantfile
amb
$ vagrant up
Per veure els nodes creats podem fer:
$ vagrant status
Connectar-se al manager:
$ vagrant ssh manager
Si teniu problemes amb les IPs que Vagrant vol assignar als nodes (10.100.199.x) probablement sigui perquè Virtualbox fa va fixar un rang per a xarxes privades que només permet de la 192.168.56.x a la 192.168.64.x).
Per poder superar aquesta limitació, la documentació indica que creem un arxiu a /etc/vbox/networks.conf
amb els rangs permesos (ni la carpeta ni l'arxiu existeixen a la instal·lació d'Ubuntu, pel què caldrà crear-los). El següent contingut (asterisc inclòs) permet qualsevol rang de IPs:
* 0.0.0.0/0 ::/0
Crea un Vagrantfile amb 3 nodes sense cap software afegit, els 3 amb una xarxa bridge i fixant les IPs segons la teva conveniència (xarxa del centre, casa, o on siguis).
Segueix la doc oficial per crear un Swarm per crear un node manager i dos workers.
Podem llençar un docker com el conegut nginxdemos/hello
que va molt bé per a les primeres passes.
$ docker service create --name hello nginxdemos/hello
Comprovem que ha arrencat correctament:
$ docker service ls
Mirem en quin node està exacutant-se:
$ docker node ps $ docker node ps worker01 $ docker node ps worker02
Potser és més fàcil veure-ho així:
$ docker service ps hello
Actualitzem la configuració del servei, publicant el port 80 del Nginx:
$ docker service update --publish-add 80 hello
Pots consultar les opcions disponibles per a la comanda docker service update.
Mirem a quin port del Swarm s'ha publicat:
$ docker service ls
Comprovem que podem veure la web apuntant el browser al port indicat (al meu Swarm em surt el 30000):
10.100.199.200:30000
Comproveu que mirant els altres nodes (IPs :201 i :202, amb el mateix port) també ens mostra la mateixa pàgina.
Ara escalarem el servei:
$ docker service scale hello=7
Inspecciona els nodes per veure com s'han repartit les instàncies.
Accedeix a la web del servei hello amb un browser, a través del port que t'hagi marcat Docker Swarm.
curl
enlloc de amb el browser? Es comporta igual?curl
?Destruïm el servei:
$ docker service rm hello
Tot junt:
$ docker service create --name hello --publish published=8888,target=80 --replicas 3 nginxdemos/hello
Podem veure les IPs de cada container amb inspect
:
$ docker ps $ docker inspect <id_container> | grep -i address $ docker inspect $(docker service ps -q hello) | grep -i -A 2 address
Si volem restringir els nodes on corre el contenidor als nodes worker (i que no corri als manager):
$ docker service create --name cluster1 --constraint "node.role == worker" -p:81:80/tcp --replicas 5 russmckendrick/cluster
Comprova-ho amb:
$ docker service ps cluster1
Per canviar les restriccions i permetre que corri en qualsevol node:
$ docker service update --constraint-rm "node.role == worker" cluster1 $ docker service scale cluster1=7
Comprova-ho amb:
$ docker service ps cluster1
Anem a simular que un contenidor cau (per exemple per un error d'execució):
docker rm -f
Comprova com es comporta el sistema.
Pots seguir treballant amb Stacks de Docker Swarm docker swarm stacks.