Docker Swarm

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.

Referències

Continua a:

Arquitectura

En Docker Swarm disposem de 2 tipus de nodes (VMs):

  • managers: gestionen el Swarm.
  • workers: executen els contenidors.

Stack

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.


Crear un Swarm mínim amb Vagrantfile

Aquest Vagrantfile et crearà un Docker Swarm amb 1 manager i 2 workers (el manager també accepta tasques de worker).

Vagrantfile
$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

Posada en marxa del Docker Swarm amb Vagrant

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


Crear un swarm manualment

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.


Llençant un servei simple

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.

Escalant el servei

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

Exercici

Inspecciona els nodes per veure com s'han repartit les instàncies.

  • Quin node en té més?
  • Us surt la mateixa distribució amb els altres companys?
  • El node manager executa alguna instància o només fa de manager?

Accedeix a la web del servei hello amb un browser, a través del port que t'hagi marcat Docker Swarm.

  • Quina és la IP del container?
  • Canvia la IP si fem CTRL+F5 repetidament ?
  • Què passa si accedeixes a través d'un curl enlloc de amb el browser? Es comporta igual?
  • Perquè creus que es comporten diferentment per browser i amb la comanda curl?

Tot en una línia

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

Serveis amb restriccions

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


Exercici

Anem a simular que un contenidor cau (per exemple per un error d'execució):

  • Tomba un contenidor amb docker rm -f

Comprova com es comporta el sistema.

  • Quantes rèpliques hi ha actualment?
  • S'ha mantingut el nombre de rèpliques o no?


Treballant amb stacks

Pots seguir treballant amb Stacks de Docker Swarm docker swarm stacks.