### HPA v1 --- **1. Запускаем Metric server (!!! только при выполнении практики на собственном кластере - Minikube и тд)** * Применяем манифесты Metric server Поскольку Metric server не устанавливается в Kubernetes кластер по умолчанию, первое что необходимо сделать - это установить его. Все необходимые манифесты находятся в каталоге `for-minikube-only-metric-server` и их можно сразу применить в кластер. Для этого необходимо в консоли выполнить команду: ```bash kubectl apply -f for-minikube-only-metrics-server/ -n kube-system ``` * Проверяем работу Metric server Metric server собирает данные с kubelet c периодичностью 1 раз в минуту. После установки необходимо подождать 1-2 минуты и выполнить команду: ```bash kubectl top node ``` Данная команда выведет текущую нагрузку на ноды. В результате выполнения команды на экран будут выведены примерно следующие данные: ```bash NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% master-1.s000000.slurm.io 122m 12% 1693Mi 44% master-2.s000000.slurm.io 114m 11% 1489Mi 38% master-3.s000000.slurm.io 97m 9% 1423Mi 37% node-1.s000000.slurm.io 59m 5% 1505Mi 39% node-2.s000000.slurm.io 357m 35% 1389Mi 36% ``` Важной особенностью Metric Server является то, что он не хранит полученные данные, а только отображает последние полученные. По этому расценивать его как полноценную систему мониторинга нельзя. **2. Запускаем тестовое приложение** В качестве тестового приложения будет использоваться специальное приложение, предназначенное для тестирования HPA. Приложение написано на PHP, и при запросах генерирует высокую нагрузку. Для начала применим Deployment в кластер, выполнив команду: ```bash kubectl apply -f deploy/deployment.yml ``` Для работы HPA обязательным является наличие у Pod выставленных `request`. Обратите внимание на [deployment.yml](deploy/deployment.yml), в нем указано: ```yaml resources: requests: cpu: 100m ``` Теперь создадим Service. Для этого мы не будем использовать готовые манифесты, а воспользуемся ключом `expose` для kubectl. Данный ключ позволяет создать Service для Deployment без написания манифеста. В итоге получается следующая команда, которую необходимо выполнить в консоли: ```bash kubectl expose deployment php-apache --port 80 ``` **3. Устанавливаем HPA** Для запуска HPA так же воспользуемся возможностями kubectl. Для создания абстракции HPA без манифеста можно использовать ключ `autoscale`. Выполним команду: ```bash kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=5 ``` В результате выполнения команды будет создан HPA, который отслеживает состояние Deployment с именем `php-apache`. При достижении средней нагрузки на все Pod 50% (для расчетов суммируется процент нагрузки на каждый Pod и делится на их количество) scaling будет производиться в границах от 1-го Pod до 5 Pod. **4. Проверяем работу** * Смотрим на текущее количество Pod ```bash kubectl get pod ``` Должен быть запущен один Pod ```bash NAME READY STATUS RESTARTS AGE php-apache-566d7644df-z9dtt 1/1 Running 0 15s ``` * Смотрим на HPA ```bash kubectl get hpa ``` Видим созданный HPA ```bash NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE php-apache Deployment/php-apache 1%/50% 1 5 1 32s ``` Она будет скейлить Pod, как только их использование cpu начнет составлять 50% от request. * Создаем нагрузку Для генерации нагрузки создадим еще один Pod из образа busybox. Внутри Pod в цикле будет запущена утилита wget, которая будет обращаться к тестовому приложению по имени Service. В итоге получается следующая команда, которую необходимо выполнить в консоли: ```bash kubectl run load-generator --image=busybox -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done" ``` * Проверяем текущее потребление cpu Pod Metric server может отдавать не только нагрузку по Node, но и по Pod. Для вывода информации по нагрузке от Pod выполните команду: ``` kubectl top pod ``` Видим, что нагрузка начинает увеличиваться. ```bash NAME CPU(cores) MEMORY(bytes) php-apache-566d7644df-z9dtt 936m 11Mi ``` * Ждем когда начнет работать Autoscaling У kubectl есть ключ `-w`, который позволяет выводить в режиме реального времени все изменения для нашего текущего запроса. Выполним следующую команду в консоли, чтобы отслеживать изменения количества Pod: ```bash kubectl get pod -w ``` Спустя несколько минут количество Pod должно увеличиться до 5-ти. ```bash NAME READY STATUS RESTARTS AGE load-generator-6b9cf94758-5qmbx 1/1 Running 0 2m16s php-apache-566d7644df-4zvv7 1/1 Running 0 108s php-apache-566d7644df-kv662 1/1 Running 0 93s php-apache-566d7644df-tg8qw 1/1 Running 0 108s php-apache-566d7644df-z9dtt 1/1 Running 0 13m php-apache-566d7644df-zlwd7 1/1 Running 0 108s ``` Отлично, autoscaling сработал! * Проверяем работу в обратную сторону Удаляем Pod с тестовой нагрузкой выполнив команду: ```bash kubectl delete pod load-generator ``` * Проверяем нагрузку на поды ```bash kubectl top pod ``` Через какое-то время замечаем, что она упала ```bash NAME CPU(cores) MEMORY(bytes) php-apache-566d7644df-4zvv7 1m 11Mi php-apache-566d7644df-kv662 1m 11Mi php-apache-566d7644df-tg8qw 1m 11Mi php-apache-566d7644df-z9dtt 1m 11Mi php-apache-566d7644df-zlwd7 1m 11Mi ``` * Проверяем, как autoscaling отработает в обратную сторону ```bash kubectl get pod -w ``` Видим, что ненужные поды умирают (в течение 5 минут). После снижения нагрузки scale down не происходит слишком быстро, чтобы избежать ситуации, когда значения по потреблению находятся в пограничном состоянии. ```bash NAME READY STATUS RESTARTS AGE php-apache-566d7644df-4zvv7 0/1 Terminating 0 8m59s php-apache-566d7644df-kv662 0/1 Terminating 0 8m44s php-apache-566d7644df-tg8qw 0/1 Terminating 0 8m59s php-apache-566d7644df-z9dtt 1/1 Running 0 20m php-apache-566d7644df-zlwd7 0/1 Terminating 0 8m59s ``` Autoscaling вернул все к первоначальному варианту с одним Pod. **5. Чистим за собой кластер** ```bash kubectl delete all --all ``` #### Troubleshooting * Проверяем, что Metric server запущен ```bash kubectl get po -n kube-system | grep metrics-server ``` Поды должны быть в состоянии `STATUS: Running` и `READY 1/1`. Если Pod отсутствует, начинаем практику с первого пункта. Если состояние не `Running` или `0/1`, то смотрим причины, выполнив команду: ```bash kubectl describe po -n kube-system metrics-server- ``` * Проверяем, что метрики доступны Для проверки доступности метрик выполним команду: ```bash kubectl top node ``` Если не выводится потребления по Node, но в прошлом шаге не выявлено ошибок, то пробуем установить еще раз все абстракции, выполнив команду: ```bash kubectl apply -f ~/slurm/practice/8.hpa/v1/metrics-server -n kube-system ``` #### Полезные ссылки 1. [k8s doc: HPA v1](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/) 2. [Metric server](https://github.com/kubernetes-sigs/metrics-server)