mirror of
https://github.com/slurm-personal/school-dev-k8s.git
synced 2026-06-27 13:50:24 +00:00
Add 17th practice
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
### 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-<TAB>
|
||||
```
|
||||
|
||||
* Проверяем, что метрики доступны
|
||||
|
||||
Для проверки доступности метрик выполним команду:
|
||||
|
||||
```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)
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: php-apache
|
||||
name: php-apache
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: php-apache
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: php-apache
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/hpa-example
|
||||
name: hpa-example
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
...
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: system:aggregated-metrics-reader
|
||||
labels:
|
||||
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
||||
rules:
|
||||
- apiGroups: ["metrics.k8s.io"]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: metrics-server:system:auth-delegator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:auth-delegator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: metrics-server-auth-reader
|
||||
namespace: kube-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: extension-apiserver-authentication-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
apiVersion: apiregistration.k8s.io/v1beta1
|
||||
kind: APIService
|
||||
metadata:
|
||||
name: v1beta1.metrics.k8s.io
|
||||
spec:
|
||||
service:
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
group: metrics.k8s.io
|
||||
version: v1beta1
|
||||
insecureSkipTLSVerify: true
|
||||
groupPriorityMinimum: 100
|
||||
versionPriority: 100
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: metrics-server
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: metrics-server
|
||||
template:
|
||||
metadata:
|
||||
name: metrics-server
|
||||
labels:
|
||||
k8s-app: metrics-server
|
||||
spec:
|
||||
serviceAccountName: metrics-server
|
||||
volumes:
|
||||
# mount in tmp so we can safely use from-scratch images and/or read-only containers
|
||||
- name: tmp-dir
|
||||
emptyDir: {}
|
||||
containers:
|
||||
- name: metrics-server
|
||||
args:
|
||||
- --kubelet-preferred-address-types=InternalIP
|
||||
- --kubelet-insecure-tls=true
|
||||
image: k8s.gcr.io/metrics-server-amd64:v0.3.3
|
||||
imagePullPolicy: Always
|
||||
volumeMounts:
|
||||
- name: tmp-dir
|
||||
mountPath: /tmp
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
labels:
|
||||
kubernetes.io/name: "Metrics-server"
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
selector:
|
||||
k8s-app: metrics-server
|
||||
ports:
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
targetPort: 443
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: system:metrics-server
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- nodes
|
||||
- nodes/stats
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: system:metrics-server
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: system:metrics-server
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: metrics-server
|
||||
namespace: kube-system
|
||||
Reference in New Issue
Block a user