Środowisko dla Docker Swarm
Odświeżałem ostatnio wiadomości z podstaw używania Docker Swarm. Do stworzenia klastra do ćwiczeń zdecydowałem się użyć Vagrant-a. To narzędzie dzięki któremu w prosty sposób mogę szybko stworzyć kilka maszyn wirtualnych, połączyć się z nimi itd. - Vagrant zadba o stworzenie kluczy SSH i całą resztę. Nie trzeba “przeklikiwać” się przez każdą z nich indywidualnie.
Trochę bardziej nietypową częścią było to, że te vm-ki były uruchamiane… w innej vm-ce (zagnieżdżona wirtualizacja). To może operacja nieco na wyrost - ale przyznaję, że do ćwiczeń lubię to podejście. Dzięki temu ucząc się nie mam obaw, że zrobię coś głupiego i uziemię swoją stację roboczą - w razie czego mogę usunąć “popsutą” maszynę wirtualną i odtworzyć ją na nowo. W mojej ocenie prowadzi to do zdecydowanie odważniejszych ćwiczeń - a tym samym lepszej sesji treningowej.
Przygotowanie maszyny do ćwiczeń
Jako system do ćwiczeń wybrałem Rocky Linuxa z pulpitem Gnome. Wybór wirtualizatora to kwestia indywidualna - stąd też nie ma sensu, żebym rozpisywał się na ten temat. Ważne żeby umożliwiał uruchamianie vm-ek wewnątrz vm-ek. W większości wypadków wystarczy pobrać obraz instalacyjny i przeklikać się przez konfigurator (w moim wypadku KVM i Virt-Manger jako GUI). Po uruchomieniu zaktualizowałem system i przeszedłem do właściwej pracy (i od tego momentu reszta kroków wykonywana jest bezpośrednio na vm-ce).
- Sprawdzenie czy jest aktywana zagnieżdżona wirtualizacja
https://docs.fedoraproject.org/en-US/quick-docs/using-nested-virtualization-in-kvm/
- Dodanie narzędzi do wirtualizacji.
sudo dnf group install -y "virtualization hypervisor"
sudo dnf group install -y "virtualization tools"
sudo systemctl enable --now libvirtd
Uruchomiono też libvirt-a i dodano użytkownika do grupy libvirt.
sudo systemctl enable libvirtd --now
sudo usermod -aG libvirt <UŻYTKOWNIK>
Instalacja Dockera
- Dodano repozytorium dla Dockera
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
- Instalacja
sudo dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- Uruchomiono usługę
systemctl enable docker --now
- Dodano użytkownika do grupy docker
usermod -aG docker <UŻYTKOWNIK>
Vagrant do startowania dodatkowych węzłów
- Dodano repozytorium z Vagrant-em i zainstalowano go.
sudo dnf config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo dnf install -y vagrant
- Zainstalowano plugin dla libvirt - wymagało to dodanie libvirt-devel i development tools
sudo dnf config-manager --set-enabled crb
sudo dnf groupinstall 'Development Tools'
sudo dnf install -y libvirt-devel
vagrant plugin install vagrant-libvirt
Definicja Vagrant
Wykorzystany został box:
https://portal.cloud.hashicorp.com/vagrant/discover/formationgpa/r9docker
Zawiera on od razu zainstalowanego Dockera. Jest to jednak box dostarczony przez społeczność, więc w jakiś poważniejszych zastosowaniach warto by było bliżej się mu przyjrzeć.
Stworzono folder dla projektu i przygotowano następujacy Vagrantfile:
Vagrant.configure("2") do |config|
swarm = [
{
hostname: "node1",
box: "formationgpa/r9docker",
ip: "10.20.30.10"
},
{
hostname: "node2",
box: "formationgpa/r9docker",
ip: "10.20.30.20"
},
{
hostname: "node3",
box: "formationgpa/r9docker",
ip: "10.20.30.30"
},
{
hostname: "node4",
box: "formationgpa/r9docker",
ip: "10.20.30.40"
}
]
swarm.each do |machine|
config.vm.define machine[:hostname] do |node|
node.vm.box = machine[:box]
node.vm.hostname = machine[:hostname]
node.vm.network "private_network",
ip: machine[:ip]
node.vm.synced_folder ".", "/vagrant", disabled: true
node.vm.provider "libvirt" do |lv|
lv.cpu_mode = "host-passthrough"
lv.cpus = 2
lv.memory = 2048
end
end
end
end
To nic innego jak krótki skrypt napisany w Ruby - na pewno dałoby radę go zoptymalizować. Jednak z racji tego, że nie znam tego języka zapoznałem się jedynie z podstawową składnią i strukturami danych, tak aby być w stanie stworzyć taką podstawową konfigurację. Z racji tego, że ilość węzłów nie idzie w setki, dodatkowe VM-ki mogę dodać poprzez kopiowanie i dodawanie nowych wpisów w liście swarm
.
Oczywiście dla innych wirtualizatorów należałoby wprowadzić odpowiednie modyfikacje w sekcji provider
.
Taki plik można zweryfikować poprzez:
vagrant validate
Jeśli wszystko jest ok to pozostaje stworzyć i uruchomić vmk-ki poprzez:
vagrant up
Chcąc wyłączyć je należy:
vagrant halt
A usunąć je można poprzez:
vagrant destroy
Status można podejrzeć z pomocą:
vagrant global-status
Swarm w działaniu
Po uruchomieniu VM-ek można było się do nich zalogować poprzez vagrant ssh <NAZWA>
i uruchomić lidera swarma na jednej z nich poprzez:
docker swarm init --adverise-addr <ADRES_IP>
Na kolejnych wystarczy użyć wyświetlonego linka żeby dołączyć do swarm-a.
Przy okazji - do podzielenia terminala na części wykorzystuję Zellij. Ten multiplexer daje też możliwość zapisywania sesji - więc upraszcza pracę. Równie dobrze można by było użyć Tmuxa - wymaga jednak on wg. mnie nieco więcej pracy w konfiguracji. W Zellij-u musiałem jedynie zadbać o to, żeby poprawnie działało kopiowanie tekstu:
https://zellij.dev/documentation/faq#copy--paste-isnt-working-how-can-i-fix-this
Pozostaje zacząć zabawę - uruchomić jakąś usługę np.
docker service create alpine ping 8.8.8.8
Spróbować “ubić” kontener na którymś z węzłów i zobaczyć jak swarm go przywraca itd. (a finalnie usunąć poprzez docker service rm <NAZWA>
).
Gorąco też polecam ten kurs na Udemy:
https://www.udemy.com/course/docker-mastery
- to właśnie on ułatwił mi zapoznanie się z tymi zagadnieniami.
Odnośniki
https://vagrant-libvirt.github.io/vagrant-libvirt/configuration.html
https://developer.hashicorp.com/vagrant/docs/networking/basic_usage
https://developer.hashicorp.com/vagrant/docs/
https://www.youtube.com/watch?v=a9pHnOkhcds
https://reintech.io/blog/working-with-data-structures-in-ruby