Также есть возможность дать возможность регулировать количество нод в автоматическом режиме в зависимости от нагрузки, например, количества контейнеров с установленными требованиями к ресурсам, с помощью ключей –enable-autoscaling –min-nodes=1 –max-nodes=2.
Простой кластер в GCP
Для создания кластера можно пойти двумя путями: через графический интерфейс Google Cloud Platform или через его API командой gcloud. Посмотрим, как это можно сделать через UI. Рядом с меню кликнем на выпадающей список и создадим отдельный проект. В разделе Kubernetes Engine выбираем создать кластер. Дадим название, 2CPU, зону europe-north-1 (дата-центр в Финляндии ближе всего к СПб) и последнюю версию Kubernetes. После создания кластера кликаем на подключиться и выбираем Cloud Shell. Для создания через API по кнопке в правом верхнем углу выведем консольную панель и введём в ней:
gcloud container clusters create mycluster –zone europe-north1-a
Через некоторое время, у меня это заняло две с половиной минуты, будут подняты 3 виртуальные машины, на них установлена операционная система и примонтирован диск. Проверим:
esschtolts@cloudshell:~ (essch)$ gcloud container clusters list –filter=name=mycluster
NAME LOCATION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
mycluster europe-north1-a 35.228.37.100 n1-standard-1 1.10.9-gke.5 3 RUNNING
esschtolts@cloudshell:~ (essch)$ gcloud compute instances list
NAME MACHINE_TYPE EXTERNAL_IP STATUS
gke-mycluster-default-pool-43710ef9-0168 n1-standard-1 35.228.73.217 RUNNING
gke-mycluster-default-pool-43710ef9-39ck n1-standard-1 35.228.75.47 RUNNING
gke-mycluster-default-pool-43710ef9-g76k n1-standard-1 35.228.117.209 RUNNING
Подключимся к виртуальной машине:
esschtolts@cloudshell:~ (essch)$ gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
agile-aleph-203917 My First Project 546748042692
essch app 283762935665
esschtolts@cloudshell:~ (essch)$ gcloud container clusters get-credentials mycluster \
–-zone europe-north1-a \
–-project essch
Fetching cluster endpoint and auth data.
kubeconfig entry generated for mycluster.
У нас пока нет кластера:
esschtolts@cloudshell:~ (essch)$ kubectl get pods
No resources found.
Создадим кластер:
esschtolts@cloudshell:~ (essch)$ kubectl run Nginx –image=Nginx –replicas=3
deployment.apps "Nginx" created
Проверим его состав:
esschtolts@cloudshell:~ (essch)$ kubectl get deployments –selector=run=Nginx
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
Nginx 3 3 3 3 14s
esschtolts@cloudshell:~ (essch)$ kubectl get pods –selector=run=Nginx
NAME READY STATUS RESTARTS AGE
Nginx-65899c769f-9whdx 1/1 Running 0 43s
Nginx-65899c769f-szwtd 1/1 Running 0 43s
Nginx-65899c769f-zs6g5 1/1 Running 0 43s
Удостоверимся, что все три реплики кластера распределились равномерно на все три ноды:
esschtolts@cloudshell:~ (essch)$ kubectl describe pod Nginx-65899c769f-9whdx | grep Node:
Node: gke-mycluster-default-pool-43710ef9-g76k/10.166.0.5
esschtolts@cloudshell:~ (essch)$ kubectl describe pod Nginx-65899c769f-szwtd | grep Node:
Node: gke-mycluster-default-pool-43710ef9-39ck/10.166.0.4
esschtolts@cloudshell:~ (essch)$ kubectl describe pod Nginx-65899c769f-zs6g5 | grep Node:
Node: gke-mycluster-default-pool-43710ef9-g76k/10.166.0.5
Теперь поставим балансировщик нагрузки:
esschtolts@cloudshell:~ (essch)$ kubectl expose Deployment Nginx –type="LoadBalancer" –port=80
service "Nginx" exposed
Проверим, что он создался:
esschtolts@cloudshell:~ (essch)$ kubectl expose Deployment Nginx –type="LoadBalancer" –port=80
service "Nginx" exposed
esschtolts@cloudshell:~ (essch)$ kubectl get svc –selector=run=Nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
Nginx LoadBalancer 10.27.245.187 pending> 80:31621/TCP 11s
esschtolts@cloudshell:~ (essch)$ sleep 60;
esschtolts@cloudshell:~ (essch)$ kubectl get svc –selector=run=Nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
Nginx LoadBalancer 10.27.245.187 35.228.212.163 80:31621/TCP 1m
Проверим его работу:
esschtolts@cloudshell:~ (essch)$ curl 35.228.212.163:80 2>\dev\null | grep h1
< h1>Welcome to Nginx!< /h1>
Чтобы каждый раз не копировать полные названия – сохраним их в переменных (подробнее о формате JSONpath в документации Go: https://golang.org/pkg/text/template/#pkg-overview):
esschtolts@cloudshell:~ (essch)$ pod1=$(kubectl get pods -o jsonpath={.items[0].metadata.name});
esschtolts@cloudshell:~ (essch)$ pod2=$(kubectl get pods -o jsonpath={.items[1].metadata.name});
esschtolts@cloudshell:~ (essch)$ pod3=$(kubectl get pods -o jsonpath={.items[2].metadata.name});
esschtolts@cloudshell:~ (essch)$ echo $pod1 $pod2 $pod3
Nginx-65899c769f-9whdx Nginx-65899c769f-szwtd Nginx-65899c769f-zs6g5
Изменим страницы в каждом POD, скопировав уникальные страницы в каждую реплику, и проверим балансировку, проверяя распределение запросов по POD:
esschtolts@cloudshell:~ (essch)$ echo 1 > test.html;
esschtolts@cloudshell:~ (essch)$ kubectl cp test.html ${pod1}:/usr/share/Nginx/html/index.html
esschtolts@cloudshell:~ (essch)$ echo 2 > test.html;
esschtolts@cloudshell:~ (essch)$ kubectl cp test.html ${pod2}:/usr/share/Nginx/html/index.html
esschtolts@cloudshell:~ (essch)$ echo 3 > test.html;
esschtolts@cloudshell:~ (essch)$ kubectl cp test.html ${pod3}:/usr/share/Nginx/html/index.html
esschtolts@cloudshell:~ (essch)$ curl 35.228.212.163:80 && curl 35.228.212.163:80 && curl 35.228.212.163:80
3
2
1
esschtolts@cloudshell:~ (essch)$ curl 35.228.212.163:80 && curl 35.228.212.163:80 && curl 35.228.212.163:80
3
1
1
Проверим отказоустойчивость кластера удалением одного POD:
esschtolts@cloudshell:~ (essch)$ kubectl delete pod ${pod1} && kubectl get pods && sleep 10 && kubectl get pods
pod "Nginx-65899c769f-9whdx" deleted
NAME READY STATUS RESTARTS AGE
Nginx-65899c769f-42rd5 0/1 ContainerCreating 0 1s
Nginx-65899c769f-9whdx 0/1 Terminating 0 54m
Nginx-65899c769f-szwtd 1/1 Running 0 54m
Nginx-65899c769f-zs6g5 1/1 Running 0 54m
NAME READY STATUS RESTARTS AGE
Nginx-65899c769f-42rd5 1/1 Running 0 12s
Nginx-65899c769f-szwtd 1/1 Running 0 55m
Nginx-65899c769f-zs6g5 1/1 Running 0 55m
Как мы видим, сразу после того, как POD стал недоступен (начался процесс его удаления) начала создаваться его замена. Вскоре, кластер полностью восстановит свою структуру. После того как мы закончили наши эксперименты, удалим виртуальные машины с кластером:
Читать дальше