Jak postawić klaster Kubernetes w AWS na instancjach typu spot
Artykuł ukazał się pierwotnie na blogu Chmurowiska.
Kubernetes zagarnia co raz to większe obszary. Sporo firm już używa Kubernetesa, a jeszcze więcej chce poznać tą technologię. Najłatwiej zrobić to w chmurze, mamy tam dostępne zarządzane przez vendorów klastry. Nie musimy nic, no prawie nic, konfigurować, uaktualniać, backupować. Tu pewnie pojawia się obawa o koszty. I nie będę zaprzeczał, nieumiejętne korzystanie z dobrodziejstw chmury publicznej może finansowo zaboleć. Pokażę jak postawić klaster Kubernetes na instancjach spot i zaoszczędzić sporo pieniędzy. Do 90%. Zostanie więcej na lody lub kebaba 😉
EKS – Kubernetes w AWS
Można oczywiście korzystać z maszyn wirtualnych i samemu uruchomić klaster. Jest sporo narzędzi, które w tym pomogą:
Ale zostawmy to specjalistom i tym, którzy naprawdę potrzebują skrojonego dokładnie pod siebie klastra, wiedzą co robią i mogą poświęcić czas na konfigurowanie zamiast używania.
Siła chmur to usługi zarządzane i dlatego wykorzystamy Amazon EKS.
Kubernetes “składa” się z dwóch części, Control Plane i nodów, na których uruchamiamy nasze aplikacje.
Trzeba jakoś pokazać, że to obrazek ukradziony z https://kubernetes.io/pl/docs/concepts/overview/components/
Ciężko powiedzieć, która jest ważniejsza. Obie są potrzebne. Ale usługa EKS bierze na siebie połowę odpowiedzialności i wszystkie komponenty zarządzające naszym klastrem, czyli właśnie Control Plane, jest zarządzana przez AWS. Ufff… Połowa kłopotów mniej.
Dla nas zostają worker nodes, czyli miejsce(a) gdzie uruchamiamy nasze aplikacje. W przypadku EKS to maszyny wirtualne. Podzielone na grupy, tak zwane nodegroups. Możemy także uruchamiać aplikacje bez maszyn, ale o tym już pisałem. Dziś będzie o nodgroups. No, może na końcu pokażę jak taki klaster bez maszyn wirtualnych uruchomić. 🙂
Jak uruchomić klaster EKS
Można oczywiście przeklikać się przez konsolę AWS, ale my, profesjonaliści użyjemy eksctl. To oficjalne narzędzie, które umożliwia pracę z klastrami Kubernetesa w EKS.
Nie będę pisał jak je zainstalować. Instrukcję możesz znaleźć tu. Zakładam, że masz zainstalowane eksctl i kubectl.
Najprostszy sposób uruchomienia klastra to:
eksctl create cluster \
--name eks1 \
--nodegroup-name workers \
--node-type t3.medium \
--nodes 1 \
--nodes-min 1 \
--nodes-max 2 \
--node-ami auto \
--vpc-nat-mode Disable \
--region eu-west-1
Dostaniemy zasoby w Irlandii, do pliku /.kube/conf zapisze się nowy kontekst i będziesz mógł od razy rozpocząć pracę z klastrem. Będziesz miał dostępną autoscalinggroup, którą będziesz mógł skalować w miarę potrzeby. Za mało serwerów, dodajesz jeden lub kilka i jest dobrze. Zalety chmur. Możesz też oczywiście taką grupę zmniejszać.
Pracując z Kubernetesem, na pewno chcesz mieć możliwość definiowania zasobów na pomocą plików yaml. Prawda? 😉 Jest oczywiście też taka możliwość. Podobny klaster możesz zdefiniować za pomocą pliku yaml:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: basic-cluster
region: eu-west-1
version: "1.16"
vpc:
nat:
gateway: Disable # other options: Disable, Single (default)
nodeGroups:
- name: ng-1
instanceType: t3.medium
minSize: 1
maxSize: 2
desiredCapacity: 1
Znasz kubectl więc to co teraz napiszę nie będzie czymś dziwnym. Abu utworzyć klaster zdefiniowany za pomocą tego pliku wykonaj polecenie:
eksctl create cluster -f <NAZWAPLIKU>
Zróbmy więc sobie taki klaster. Odpalamy polecenie i… Czekamy kilkanaście minut.

Pod spodem eksctl, wykorzystując CloudFormation buduje dla nas dwa stacki. Jeden dla klastra EKS i drugi dla grupy grupy autoskalingowej z naszymi węzłami.

Jeżeli zaczniesz przyglądać się utworzonemu klastrowi, zauważysz, że nie masz dostępnych żadnych węzłów.

Ale polecenie kubectl get nodes jednak coś zwraca

O co chodzi? EKS pozwala na pracę zarówno z maszynami zarządzanymi przez samą usługę, jak i z maszynami pracującymi poza samym EKS. W naszym przypadku eksctl utworzył autoscaling group i podpiął ją pod nasz klaster.

Można ją oczywiście także skalować aby zwiększyć, bądź zmniejszyć liczbę pracujących w naszym klastrze maszyn

Managed groups
eksctl umożliwia oczywiście także uruchamianie zarządzanych przez EKS grup serwerów. Wystarczy sekcję nodeGroups w pliku opisującym nasz klaster zamienić na managedNodeGroups
Możesz też oczywiście dodać kolejną grupę serwerów do swojego klastra. Definicja może wyglądać tak:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: basic-cluster
region: eu-west-1
managedNodeGroups:
- name: managed-ng
instanceType: t3.medium
minSize: 1
desiredCapacity: 1
maxSize: 1
volumeSize: 20
labels: {role: worker}
Aby „zaaplikować” taką grupę do naszego klastra wykonujemy polecenie eksctl create nodegroup -f nodegroup.yaml
Po dosłownie chwili jest juz dostępna w klastrze.

Możesz także oczywiście przeglądać i usuwać istniejące grupy maszyn. Aby pobrać listę grup musisz wykonać polecenie eksctl get nodegroups --cluster=basic-cluster

a aby grupę usunąć eksctl delete nodegroup --cluster=basic-cluster --name=ng-1 eksctl get nodegroups --cluster=basic-cluster
Gdzie te spoty?
No właśnie. Miało być tanio. Na dziś, za control plane EKS płacimy 0,10$ za godzinę. Dużo? Mało? To zależy 🙂 Ale chcesz zaoszczędzić na maszynach, na których pracują aplikacje. Chcesz spotów!!! No OK. Przecież obiecałem.
Tylko spoty
Zakładam, że klaster już masz. Dodamy nową grupę. Konfiguracja wygląda następująco:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: basic-cluster
region: eu-west-1
nodeGroups:
- name: ng-spots-1
minSize: 1
maxSize: 5
instancesDistribution:
maxPrice: 1
instanceTypes: ["c5.large", "t3.medium"]
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 0
spotInstancePools: 2
- name: ng-spots-2
minSize: 1
maxSize: 5
instancesDistribution:
maxPrice: 1
instanceTypes: ["c5.large", "t3.medium"]
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 0
spotInstancePools: 2
Tworzysz dwie ASG z instancjami spot. Dlaczego dwie? Będzie większa szansa, że maszyny nam nie znikną. Warto też zajrzeć tutaj i sprawdzić jak często dany typ maszyny jest odbierany użytkownikowi.
Jak widzisz, zarówno onDemandBaseCapacity jak i onDemandPercentageAboveBaseCapacity są ustawione na zero. Oznacza to, że w danej grupie będą tylko maszyny typu spot. Możesz też oczywiście w jednej grupie maszyn umieścić obok instancji spot, także instancje typu od-demand.
No dobrze, pozostało tylko wywołać eksctl create nodegroup -f spot-ng.yaml
i chwilę poczekać.

Mamy już kilka grup
eksctl get nodegroups --cluster=basic-cluster

oraz kilka węzłów

Możesz usunąć grupy niespotowe:
eksctl delete nodegroup --cluster=basic-cluster --name=ng-1
eksctl delete nodegroup --cluster=basic-cluster --name=managed-ng
I po chwili mamy klaster pracujący tylko na spotach.
Oczywiście te wszystkie kroki nie są niezbędne aby otrzymać klaster na instancjach spot. Chciałem Ci pokazać więcej możliwości eksctl. Możesz oczywiście od razu utworzyć tak klaster. Na przykład wykorzystując poniższy plik z konfiguracją
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: basic-cluster-spot
region: eu-west-1
version: "1.16"
vpc:
nat:
gateway: Disable
nodeGroups:
- name: ng-spots-1
minSize: 2
maxSize: 2
instancesDistribution:
maxPrice: 1
instanceTypes: ["c5.large", "t3.medium"]
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 0
spotInstancePools: 2
- name: ng-spots-2
minSize: 2
maxSize: 2
instancesDistribution:
maxPrice: 1
instanceTypes: ["c5.large", "t3.medium"]
onDemandBaseCapacity: 0
onDemandPercentageAboveBaseCapacity: 0
spotInstancePools: 2
Tworzy klaster z 4 węzłami w dwóch grupach.

Nie zapomnij po wszystkim usunąć klastra za pomocą poleceniaeksctl delete cluster -f basic-cluster.yaml
A w ogóle bez serwerów?
Obiecałem więc i taka recepta będzie. Możesz uruchomić klaster EKS bez żadnych worker nodes i nadal uruchamiać na nim swoje aplikacje. Z odsieczą przychodzi Fargate. Bez wnikania w szczegóły, uruchomienie takiego klastra jest bardzo proste. Plik z konfiguracją wygląda następująco:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: fargate-cluster
region: eu-west-1
fargateProfiles:
- name: fp-default
selectors:
- namespace: default
- namespace: kube-system
Tylko jeden profil, ale wszystko co trafi do namespace default będzie uruchomione na Fargate.
Podsumowanie
eksctl pozwala oczywiści na o wiele więcej. W tym artykule chciałem pokazać, że uruchamianie i podstawowe zarządzanie klastrami EKS nie musi być skomplikowane.
Jeżeli ktoś zaczyna zabawę z Kubernetesem to podstawową potrzebą jest posiadanie klastra. Warto więc przygotować sobie plik z konfiguracją klastra i w łatwy sposób sobie takie klastry tworzyć i je usuwać.
Po więcej wiedzy o eksctl zapraszam na stronę projektu. Na GitHub dostępne są także przykładowe konfiguracje, które możesz wykorzystać.