Swarm czy Kubernetes na produkcji?

1

Mamy już nowy serwer pod 4programmers.net. Cały projekt od dawna działa w oparciu o Dockera jednak nie na produkcji (na localu oraz serwerze CI). Zatem zastanawiam się (zakładając że mamy do dyspozycji tylko jedną maszynę) czy pójść w stronę Docker Swarm czy Kubernetes? Jakie jest wasze zdanie na ten temat?

Zależałoby mi na "zero downtime deployment" czyli usługi musiałyby się móc replikować (ale to akurat i swam i k8s potrafi). Jakie jest Wasze zdanie na ten temat?

1

Nikt (normalny) nie udzieli Ci jednoznacznej czy poprawnej odpowiedzi na podstawie tak małej ilości danych, które tu podałeś.

Pod uwagę trzeba wziąć (m.in):

  • czy sam stack w ogóle potrzebuje tego 1/100, co oferuje swarm/k8s, dla PROSTEGO przykładu: restart po padzie to prosty supervisord może być czasem lepszym rozwiązaniem lub skrypt w cronie, monitorowanie - milion film robi na tym biznesy, rozwiązania opensource od trywialnych po nietrywialne - masz monitoring+supervisord najczęściej, autoskalowanie - AWS czy inne cloudy mają proste reguły i nie zrujnują budżetu przy minimum ostrożności, a się tylko suwaki poprzesuwa, zamiast grzebać w yamlach.
    To tylko najprostsze przykłady.
  • znajomość tych narzędzi przez ludzi zajmujących się tym (używanie rozwiązania bo jest modne, może się skończyć większymi kłopotami niż w przypadku zaniechania użycia). To też ważne, bo kubernetes-jak-usługa w cloudach jest droższy niż gdyby go samemu skonfigurować, a samemu, można zepsuć na 1000 razy, zanim się skonfiguruje (poprawnie)
  • nawet jak weźmiesz usługę kubernetesa - to, że dostawca Ci go postawił nie znaczy, że go poprawnie użyjesz (patrz: punkty poprzednie)
  • te technologie wprowadzają swoje własne gotchas, które lubią kopać po tyłku tych, co wychowani na monolitach i bare metalach
  • na swarm/k8s najlepiej działają apki, które są pisane od samego początku na te technologie i od początku są z nimi testowane. Z innymi trzeba bardzo uważać, bo można nieźle wdepnąć.

//edit: jeszcze dla przykładu, co IMHO dobrze robi k8s - jak masz sporo mikroserwisów >10, które zajmują się swoimi, jak najbardziej okrojonymi odpowiedzialnościami, są bezstanowe (najprościej) i występuje między nimi kaskada zależności, że np. A powinien wstać, gdy B już działa, a B gdy C i D działają, z kolei C potrzebuje X, pod warunkiem, że D jeszcze nie działa, bo potem go nie potrzebuje itp. Ogarnianie takiej pajęczyny jest ułatwione przy użyciu k8s, pod warunkiem, że mikroserwisy były pisane z myślą o odpalaniu na czymś takim. Pewnie są inne jeszcze ciekawe use casy, ale nie wiem czy zwykłe forum się do nich zalicza.

0

Tak jak napisałem, mamy własny dedykowany serwer więc rozwiązania takie jak AWS odpadają bo są po prostu za drogie. Z kubernetesm mam jakieś doświadczenie i wydaje mi się że na potrzeby 4programmers.net jest to zbyt duża kobyła. Ze Swarmem nie miałem jednak do czynienia ale wydaje się o wiele prostsze.

Tak jak napisałem: potrzebna jest funkcjonalność rolling update co wiąże się oczywiście z możliwością skalowania serwisów. Cały projekt jest dostosowany do tego aby był stateless, docker-compose.yaml jest gotowy i działa.

Stack wygląda tak: serwer WWW to nginx oraz PHP-FPM. Baza PostgreSQL. Serwer websocket w Pythonie. Cache, sesje w Redis. Jest jeszcze RabbitMQ oraz Elasticsearch. To właściwie wszystko. Ewentualnie jak będzie konieczność to można dołożyć kolejny dedykowany serwer i postawić kolejnego noda.

0

Ostatnio w pracy bawiłem się OpenShiftem i rolling update znacznie ułatwiło wszystkim życie i dumałem właśnie o 4p, że skoro już mamy Dockera... :)

0
Adam Boduch napisał(a):

Tak jak napisałem, mamy własny dedykowany serwer więc rozwiązania takie jak AWS odpadają bo są po prostu za drogie. Z kubernetesm mam jakieś doświadczenie i wydaje mi się że na potrzeby 4programmers.net jest to zbyt duża kobyła. Ze Swarmem nie miałem jednak do czynienia ale wydaje się o wiele prostsze.

Tak jak napisałem: potrzebna jest funkcjonalność rolling update co wiąże się oczywiście z możliwością skalowania serwisów. Cały projekt jest dostosowany do tego aby był stateless, docker-compose.yaml jest gotowy i działa.

Stack wygląda tak: serwer WWW to nginx oraz PHP-FPM. Baza PostgreSQL. Serwer websocket w Pythonie. Cache, sesje w Redis. Jest jeszcze RabbitMQ oraz Elasticsearch. To właściwie wszystko. Ewentualnie jak będzie konieczność to można dołożyć kolejny dedykowany serwer i postawić kolejnego noda.

Swarm jest prostszy i można od niego zacząć, skoro już część rzeczy działa w dockerze.

Natomiast zastanawia mnie jedno: piszesz o jednym serwerze dedykowanym, z tego mam rozumieć, że to wszystko, czyli nginx, php, pgsql redis etc działa tylko na tym jednym serwerze?

0

Natomiast zastanawia mnie jedno: piszesz o jednym serwerze dedykowanym, z tego mam rozumieć, że to wszystko, czyli nginx, php, pgsql redis etc działa tylko na tym jednym serwerze?

Tak, działa na jednym serwerze :) W takim razie w swarm byłby tylko jeden node.

0
Adam Boduch napisał(a):

Natomiast zastanawia mnie jedno: piszesz o jednym serwerze dedykowanym, z tego mam rozumieć, że to wszystko, czyli nginx, php, pgsql redis etc działa tylko na tym jednym serwerze?

Tak, działa na jednym serwerze :) W takim razie w swarm byłby tylko jeden node.

No to teraz wyobraź sobie, co stanie się z Twoim "rolling update", jak ktoś popchnie zmianę, która zabije ten serwer (jakiś babol, 100% cpu, load w kosmos i cześć, łącz się do woli).

Stawianie tego wszystkiego na 1 serwerze, nawet mocnym, to total antypattern, do tego jeszcze chcesz tam wstawić soft typu swarm/k8s - no super, ale IMHO zysk tu niemal żaden, ale będzie tam dodatkowy software, który skomplikuje Ci stack, zwiększy prawdopodobieństwo faila (bo doda własne) i pożre trochę zasobów, a w zamian praktycznie nic nie zyskasz.

0

Tak też robimy to obecnie :) Też jest jeden serwer. Tyle, że bez dockera :) Serwer CD tworzy nowy folder, tam ściąga kod, wykonuje migracje itp itd, po czym przepina katalog (symbolic link) który wystawiony jest przez nginxa na świat. Każdy zmiana teoretycznie też może wywalić serwer. Mając k8s i koszmarnego babola w kodzie, jaką mamy pewność że nie wywalimy np. 2 workery kubernetestowe? Przecież rolling update aktualizuje od razu wszystkie pody z aplikacją.

Jaką zatem alternatywę proponujesz?

0

co stanie się z Twoim "rolling update", jak ktoś popchnie zmianę, która zabije ten serwer

Ale nie tylko może paść system, równie dobrze może się trafić fizyczna awaria typu przepięcie w zasilaczu i spalona MB+CPU+RAM.

W wypadku wirtualek (przynajmniej dobrze zbackupowanych) to jest chwila przerwy (można oczywiście dyskutować, jaka jest definicja "chwili"). W przypadku dedykowanego serwera to trzeba go fizycznie podmienić, postawić system, przenieść usługi i bazy, a to trochę może potrwać.

0

Wobec braku alternatywnej propozycji zabrałem się za tego swarma. Powiem szczerze że myślałem że będzie to prostsze jako że docker-compose.yaml był już dawno napisany.

Podstawową trudnością było to, że nginx oraz php-fpm muszą mieć dostęp do tych samych plików kodu źródłowego. Niektórzy sugerują aby utworzyć obraz Dockera który zawierałby w sobie zarówno nginx jak i php-fpm. Trochę przeczy to idei samego dockera gdzie uslugi powinny być rozdzielane na kontenery. Dodatkowo kiepsko ze skalowaniem takiego rozwiązania bo jednocześnie skalujemy nginxa który nie potrzebuje być skalowany.

Alternatywą jest użycie dockerowego volume i współdzielenie kodu pomiędzy dwoma kontenerami. I tutaj pojawił się problem ponieważ podgrywanie nowej wersji obrazu z kodem źródłowym nie powodowało nadpisania starego kodu w volume.

Docker secret wymagało również drobnych modyfikacji w samym kodzie bo hasła nie są przekazywane w zmiennych środowiskowych jak w k8s, Na szczęście chyba się już z tym uporałem i niedługo będzie można konfiguracje swarma dać do review ;)

1

Tzn, jak pytasz mnie, to ja osobiście poszedłbym w k8s, bo go lepiej znam, ale stawianie tego nie uznaję na 1 maszynie. ;-)

Ja bym poszedł w 4 instancje, gdzie byłyby master (1) + node (3). Na tych samych 4 jeszcze klaster etcd dla k8s (antypattern to jest, ale żeby nie było, że nowe instancje chcę tu dorzucić).
Do tego wpiąć jakiś HA system plików dla plików strony, np. od dostawcy clouda czy coś, a klaster MySQL załatwiamy tym: https://github.com/helm/charts/tree/master/incubator/mysqlha i powiedzmy od dużej biedy to przejdzie.

Jak koniecznie musi to być ta sama maszyna, to poszedłbym prędzej w microk8s: https://microk8s.io/docs/clustering i spiął je razem, ale to wyeksponuje "zalety" k8s tak jak braki w uzębieniu eksponują uśmiech.

0

Tez wolałbym k8s i nie wykluczam że w końcu uda się go postawić :)

Problemem rozwiązań cloudowych jest ich cena obecnie. Obecnie mamy serwer dedykowany 64 GB oraz 12 CPU. Weźmy pod uwagę najtańszy cloud czyli hetzner. Czyli 3 potrzebowalibyśmy min 3 nody po 32 GB, prawda? Na każdej instanacja Postgresa (na jednej mater, na 2 slave), bo nie używamy MySQL. Taki hetzner nadrabia ceną bo nie oferuje takich bajerów jak dynamiczna alokacja RAM czy CPU. Niestety to będzie kilkukrotnie drożej niż przy zwykłym serwerze dedykowanym :((

1

A jakie masz doświadzcenie z Kubernetesem i Swarmem?

Generalnie (przepraszam za porównanie) to tak jakby pytać czy lepiej Python czy Java na serwerze. Tzn. oba rozwiązania mają jakieś zalety, ale skoro ktoś o to pyta to znaczy że jest na dość wczesnym etapie planowania projektu. Tymczasem kubernetes to gigantyczny framework i mimo pracy z nim od ~2 lat, stawiania i zarządzania około 5 klastrami, a nawet doświadczenia od środka "u źródła" nie czuję się ekspertem w tym temacie :P. Swarm jest trochę prostszy, ale to dalej kombajn. Przede wszystkim, oba mają inne podejście do zarządzania niż adminowanie "bare metal".

Zatem zastanawiam się (zakładając że mamy do dyspozycji tylko jedną maszynę) czy pójść w stronę Docker Swarm czy Kubernetes?

Pierwszy problem - klaster z jedną maszyną to kiepski klaster :P. Można wiedzieć czemu takie założenie? Nie mówię że to na pewno zły pomysł (np. moja prywatna strona i usługi tak stoją), ale może się nie ograniczać tak od razu na etapie planowania. Bo np. czemu nie rozważyć k8s hostowanego zewnętrznie? To naprawdę fajne rozwiązanie jak ktoś nie chce za dużo się martwić adminowaniem - czyli np dobre dla 4p :P).

Zależałoby mi na "zero downtime deployment" czyli usługi musiałyby się móc replikować (ale to akurat i swam i k8s potrafi).

"To skomplikowane". I swarm i k8s potrafią bez problemu zrobić update (i nawet rollback jeśli się je dobrze skonfiguruje). Ale w przypadku jednej maszyny będzie downtime chociażby przy aktualizacji paczek na hoście.

W ogóle, @TurkucPodjadek ładnie problemy wylistował. K8s to naprawdę nie jest coś co się stawia w jeden wieczór z zerową wiedzą i "samo działa" :P. Swarm trochę lepszy, ale też ciężki.

Z kubernetesm mam jakieś doświadczenie i wydaje mi się że na potrzeby 4programmers.net jest to zbyt duża kobyła. Ze Swarmem nie miałem jednak do czynienia ale wydaje się o wiele prostsze.

Hmm, skoro tak to sam sobie odpowiedziałeś trochę. To prawda, swarm jest znacznie prostszy. Jest też gorzej wspierany (k8s wygrał tę wojnę), ale na potrzeby 4p powinno wystarczyć.

Stack wygląda tak: serwer WWW to nginx oraz PHP-FPM. Baza PostgreSQL. Serwer websocket w Pythonie. Cache, sesje w Redis. Jest jeszcze RabbitMQ oraz Elasticsearch. To właściwie wszystko

No i usługi poboczne (z głowy: certbot, postfix z całym otoczeniem, etc). Chyba że one zostają "natywnie"?

Podstawową trudnością było to, że nginx oraz php-fpm muszą mieć dostęp do tych samych plików kodu źródłowego.

Hmm, czemu to problem? W sensie, chyba buduje się obraz z plikami, wrzuca na jakiegoś dockerhuba (ew. prywatne registry) i jakoś działa. Tzn. nginx i php-fpm mają osobne obrazy, ale zbudowane z tych samych plików? Chyba że pliki się muszą zmieniac, ale to wtedy nie uciekniesz przed jakimś volumem (chociażby dla perzystencji).

Jak koniecznie musi to być ta sama maszyna, to poszedłbym prędzej w microk8s

Proszę, nie. Microk8s na produkcji to rak i czarna plama na powierzchni świata. Microk8s sam z siebie zbyt stabilny nie jest, ale powiedzmy jako coś służącego do developmentu się sprawdza. Ale błagam, nie na produkcji, bo jest:

    1. dziurawy jak sito pod względem bezpieczeństwa
    1. niestabilny (autoaktualizacje regularnie niszczą wsteczną kompatybilność)
    1. wolny (YMMV)
    1. słabo debugowalny (niektóre rzeczy robi się przez microk8s.enable, które jest wygodne, ale robi rzeczy w automagiczny sposób i naciąłem się parę razy próbując dociec niskopoziomowo czemu coś działa tak jak działa)
0

O jakich danych mówimy, w szczególności chodzi mi o (mogą być +- wartości):

  • wielkość bazy danych, w tym jej dzienny/miesięczny przyrost
  • ilość zapytań do bazy (np. na sekunde) i jakie to są zapytania, czy np. zdecydowana większość to SELECT, czy w ogóle nie ma takich danych obecnie?
  • jak często vacuum się odpala
  • ilość requestów do serwera http (na sek, dziennie?)
  • ilość requestów do php (na sek, dziennie?)
0
msm napisał(a):

Pierwszy problem - klaster z jedną maszyną to kiepski klaster :P. Można wiedzieć czemu takie założenie?

Jedyny powód to finansowy :P

Zależałoby mi na "zero downtime deployment" czyli usługi musiałyby się móc replikować (ale to akurat i swam i k8s potrafi).

"To skomplikowane". I swarm i k8s potrafią bez problemu zrobić update (i nawet rollback jeśli się je dobrze skonfiguruje). Ale w przypadku jednej maszyny będzie downtime chociażby przy aktualizacji paczek na hoście.

Tak, niestety w takim przypadku będzie downtime :(

No i usługi poboczne (z głowy: certbot, postfix z całym otoczeniem, etc). Chyba że one zostają "natywnie"?

Myślałem aby zostały "natywnie".

Podstawową trudnością było to, że nginx oraz php-fpm muszą mieć dostęp do tych samych plików kodu źródłowego.

Hmm, czemu to problem? W sensie, chyba buduje się obraz z plikami, wrzuca na jakiegoś dockerhuba (ew. prywatne registry) i jakoś działa. Tzn. nginx i php-fpm mają osobne obrazy, ale zbudowane z tych samych plików? Chyba że pliki się muszą zmieniac, ale to wtedy nie uciekniesz przed jakimś volumem (chociażby dla perzystencji).

Hmm, w sumie o tym nie pomyślałem. Póki co stanęło na jednym obrazie z kodem źródłowym oraz php-fpm oraz nginxem (oba dzielą ten sam volumen w kodem). Obraz jest na hubie: https://hub.docker.com/r/4programmers/coyote

Mógłbyś rzucić okiem na https://github.com/adam-boduch/coyote/blob/master/swarm.yaml i ocenić jak to póki co wygląda?

TurkucPodjadek napisał(a):

O jakich danych mówimy, w szczególności chodzi mi o (mogą być +- wartości):

  • wielkość bazy danych, w tym jej dzienny/miesięczny przyrost
  • ilość zapytań do bazy (np. na sekunde) i jakie to są zapytania, czy np. zdecydowana większość to SELECT, czy w ogóle nie ma takich danych obecnie?
  • jak często vacuum się odpala
  • ilość requestów do serwera http (na sek, dziennie?)
  • ilość requestów do php (na sek, dziennie?)

Z 50 mln requestów miesięcznie. Część z tego jest jednak cachowana przez cloudflare więc rzeczywista liczba jest mniejsza. Baza 15 GB. Dokładnych danych nie podam na razie (bo nie wiem) ale tak - zdecydowana większość to SELECT-y.

Obecnie mamy również 64 GB (czyli tak jak na planowanym nowym serwerze), 8 CPU.

0

O tym pytaniu zapomniałem: ile jesteś w stanie miesięcznie przeznaczyć na utrzymanie tego? Chodzi mi o koszty związane czysto z infrastrukturą (w sensie, gdyby używać jakiegoś clouda i usług/instancji w nim)

0

Jestem otwarty na propozycje :) Póki co płacimy 60 euro.

0
Adam Boduch napisał(a):

Jestem otwarty na propozycje :) Póki co płacimy 60 euro.

No to przykładowo, nie mówię, że to coś optymalnego:

Ceny i instancje biorę z tego hetznera, który jest najtańszy:

Load Balancery + ew. jakiś klaster redisa na nich i poczta (do nich lecą requesty, których CF nie "przechwycił"): 2 x CX31 (pracuje jeden, drugi to jego backup + dodatkowy node do klastra redis)
Klaster PostgreSQL: 2 x CX31 (można łatwo dokładać jak wydajność, po tuningowaniu, będzie niewystarczająca)
php-fpm+serwer www+jakieś minio na współdzielony system plików: 3 x CX21
Jak instancje CX21 na dystrybucyjny system plików będą za słabe to np. można na zapasowym load balancerze zrobić NFSa i im podmontować

To daje 4xCX31 + 3xCX21 czyli według aktualnych cen równe 60 EUR

Bez k8s/swarm, utworzysz sobie obrazy instancji, w hetznerze masz API, więc można dorzucić coś małego co będzie "z boku" monitorować całość (np. CX11) i szturchać ew. słać maile
Na http lub php 3 instancje dostają obciążenie, na postgresql osobne 2 więc masz w miarę backup każdej usługi, nie jesteś uzależniony od hetznera - ceny staną się nieatrakcyjne, to się przeniesiesz do innego clouda szybko.

Trzymałem się kwoty 60 EUR, ale oczywiście lepiej np. współdzielony system plików zrobić na osobnych instancjach, dołożyć dodatkową CX31 dla PostgreSQL itp.

//edit: bo byłbym zapomniał, no i taką całość można ochędożyć terraform+packer+ansible, że całość będzie się stawiać i autospinać jedną komendą.

0

Ciekawe zestawienie. Mam jedynie obawy co do tego, że 2 CPU oraz 8 GB RAM starczą na bazę. Trzeba by to postawić i przetestować. Chyba że na jeden serwer Postgresa (master) wziąć lepszy serwer a dla slave słabszy.

1 użytkowników online, w tym zalogowanych: 0, gości: 1