У сучасному світі хмарних додатків, масштабованість і стійкість є основними стовпами добре спроектованої системи. Але як можна забезпечити, щоб ваша інфраструктура дійсно масштабувалася під тиском? Ось тут і вступає в гру інженерія хаосу, яка допомагає вам змоделювати реальні стрес-сценарії та перевірити здатність вашої системи адаптуватися та відновлюватися.
У цьому пості ми розглянемо, як використовувати Chaos Mesh, потужний інструмент для інженерії хаосу, щоб виконати стрес-тести на кластері Amazon EKS, який працює в режимі Auto Mode. Створюючи навантаження на кластер за допомогою інтенсивних по CPU та пам’яті робочих навантажень, ми спостерігатимемо, як функціональність автоматичного масштабування EKS реагує на збільшення попиту. Цей практичний підхід не тільки перевірить надійність режиму Auto Mode в EKS, а й надасть вам інсайти для оптимізації ваших робочих навантажень у Kubernetes для високої доступності та економії витрат.
Чи ви ентузіаст Kubernetes, інженер з хаосу або архітектор хмарних рішень, який хоче забезпечити, щоб ваша інфраструктура могла впоратися з несподіваними ситуаціями, цей пост проведе вас через практичний експеримент, що поєднує хаос і контроль для перевірки масштабованості під тиском.
Створення кластера EKS
Щоб почати наші тести на масштабованість, необхідно налаштувати кластер Amazon EKS. Завдяки одному YAML конфігураційному файлу ми можемо визначити специфікації кластера та увімкнути режим Auto Mode в EKS, що спрощує управління вузлами та масштабування.
Наступний конфігураційний файл cluster.yaml визначає кластер з ім'ям scrumptious-classical-shark в регіоні eu-south-2 (Іспанія) з версією Kubernetes 1.31.
Увімкнувши Auto Mode через поле autoModeConfig, EKS автоматично управляє створенням та масштабуванням пулів вузлів, усуваючи потребу в ручному втручанні.
Конфігурація є гнучкою: ви можете налаштувати пули вузлів, визначити користувацьку IAM роль або залишити за замовчуванням, щоб EKS самостійно все налаштував. Для нашого випадку ми скористаємося стандартними налаштуваннями для простоти.
# cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: scrumptious-classical-shark
region: eu-south-2
version: '1.31'
autoModeConfig:
# за замовчуванням false
enabled: true
# опціонально, за замовчуванням [general-purpose, system].
# рекомендується не вказувати
# Щоб вимкнути створення nodePools, встановіть його в порожній масив ([]).
nodePools: []
# опціонально, eksctl створить нову роль, якщо це не вказано
# і якщо є nodePools.
# nodeRoleARN: string
eksctl create cluster -f cluster.yaml
Після завершення створення кластера у вас буде готове середовище EKS для проведення експериментів з хаосом і перевірки масштабованості під тиском. Для глибшого розуміння EKS Auto Mode та його налаштування через eksctl зверніться до офіційної документації AWS:
[
Створення кластера EKS у режимі Auto Mode за допомогою CLI eksctl
Цей розділ показує, як створити кластер Amazon EKS у режимі Auto Mode за допомогою командного інтерфейсу (CLI) eksctl. Ви…
docs.aws.amazon.com
](https://docs.aws.amazon.com/eks/latest/userguide/automode-get-started-eksctl.html?source=post_page-----d03deab5fd36--------------------------------)
Chaos Mesh
Chaos Mesh — це потужна платформа для інженерії хаосу з відкритим кодом, спеціально розроблена для середовищ Kubernetes. Вона надає багатий набір інструментів для впровадження різних типів відмов — таких як мережеві затримки, тиск на ресурси та аварії системи — в ваші додатки та інфраструктуру, допомагаючи вам виявляти слабкі місця та забезпечувати стійкість системи.
Завдяки моделюванню реальних відмов, Chaos Mesh дозволяє вам перевіряти здатність вашого додатку витримувати несподівані порушення, перевіряти його стійкість до відмов і покращувати загальну надійність.
Чи то ви готуєтесь до події з високим трафіком, чи забезпечуєте, щоб ваша архітектура відповідала цілям доступності, Chaos Mesh є інструментом для перевірки ваших припущень.
Розгортання
Containerd через те, що кластери базуються на цій технології
Щоб розгорнути Chaos Mesh у вашому кластері EKS, дотримуйтесь офіційної документації Chaos Mesh для продукційного розгортання з використанням Helm.
https://chaos-mesh.org/docs/production-installation-using-helm/
Однак важливо зазначити, що кластери EKS використовують containerd як стандартне середовище виконання, а не Docker. Тому при установці Chaos Mesh потрібно вказати середовище виконання та шлях до сокету відповідно. Використовуйте наступну команду Helm для інсталяції:
helm install chaos-mesh chaos-mesh/chaos-mesh -n=chaos-mesh --set chaosDaemon.runtime=containerd --set chaosDaemon.socketPath=/run/containerd/containerd.sock --version 2.7.0
Уникайте розгортання Chaos Mesh у Docker Mode на EKS
При розгортанні Chaos Mesh на кластері Amazon EKS важливо правильно налаштувати параметри середовища виконання, оскільки кластери EKS використовують containerd як стандартне середовище виконання, а не Docker. Якщо ви розгортаєте Chaos Mesh у Docker mode (без вказання середовища виконання та шляху до сокету для containerd), то Pods Chaos Mesh здаватимуться успішно запущеними, але при спробі виконати експерименти з хаосом виникатимуть внутрішні помилки.
Можливо, ви зіткнетесь з помилками, схожими на наступні в логах Chaos Mesh:
Warning Failed 56s records Failed to apply chaos: rpc error: code = Unknown desc = expected docker:// but got container
Ці помилки вказують на те, що Chaos Mesh намагається зв’язатись з Docker runtime, якого немає в середовищі EKS. Внаслідок цього експерименти з хаосом не будуть виконуватися, і ви матимете працюючі Pods без фактичного впровадження хаосу.
Стрес-симуляція
Щоб перевірити масштабованість вашого кластера EKS у режимі Auto Mode, ми почнемо з розгортання додатку, який буде виступати як жертва стрес-тестів. У цьому випадку ми використаємо NGINX як цільовий додаток, налаштований з конкретними запитами ресурсів, лімітаціями та політиками автоматичного масштабування.
Це налаштування дозволить нам спостерігати, як EKS Auto Mode реагує на збільшення навантажень.
Розгортання жертви
Виконайте наступну команду, щоб розгорнути NGINX Ingress Controller в кластері EKS:
# Створення простору імен
kubectl create namespace nginx
# Розгортання NGINX Ingress
helm upgrade nginx ingress-nginx/ing
--set-string controller.metrics.service.annotations."prometheus\.io/port"="10254" \
--set-string controller.metrics.service.annotations."prometheus\.io/scrape"="true" \
--set controller.resources.requests.cpu="500m" \
--set controller.resources.requests.memory="256Mi" \
--set controller.resources.limits.cpu="1000m" \
--set controller.resources.limits.memory="512Mi" \
--set controller.autoscaling.enabled=true \
--set controller.autoscaling.minReplicas=1 \
--set controller.autoscaling.maxReplicas=3 \
--set controller.autoscaling.targetCPUUtilizationPercentage=70 \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution\[0\].labelSelector.matchExpressions\[0\].key="app.kubernetes.io/name" \
--].labelSelector.matchExpressions\[0\].operator="In" \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution\[0\].labelSelector.matchExpressions\[0\].values\[0\]="ingress-nginx" \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution\[0\].labelSelector.matchExpressions\[1\].key="app.kubernetes.io/component" \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution\[0\].labelSelector.matchExpressions\[1\].operator="In" \
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution
--set controller.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution\[0\].topologyKey="kubernetes.io/hostname"Creación del escenario
Розуміння ключових параметрів
Давайте розглянемо найбільш важливі параметри в цій команді та пояснимо їх призначення.
Horizontal Pod Autoscaler (HPA)
Наступні параметри налаштовують HPA для контролера NGINX:
- controller.autoscaling.enabled=true: Увімкнення авто-масштабування для розгортання NGINX.
- controller.autoscaling.minReplicas=1: Встановлює мінімальну кількість реплік (Pods) на 1.
- controller.autoscaling.maxReplicas=3: Дозволяє розгортанню масштабуватися до максимуму 3 реплік.
- controller.autoscaling.targetCPUUtilizationPercentage=70: Вказує, що HPA має активувати масштабування, коли середнє використання CPU серед Pods перевищує 70%.
Ці налаштування забезпечують динамічне масштабування NGINX на основі використання ресурсів, що є критичним для спостереження за поведінкою EKS Auto Mode під час стресу.
Запити ресурсів та ліміти
Налаштування ресурсів забезпечують, щоб Kubernetes планував і масштабував Pods на основі визначеного використання ресурсів:
- controller.resources.requests.cpu=”500m” і controller.resources.requests.memory=”256Mi”: Кожен Pod запитує 0.5 vCPU і 256 MiB пам'яті. Kubernetes гарантує ці ресурси для Pod.
- controller.resources.limits.cpu=”1000m” і controller.resources.limits.memory=”512Mi”: Кожен Pod обмежений до 1 vCPU і 512 MiB пам'яті.
Якщо Pod перевищить ці ліміти, він може бути обмежений.
Ці налаштування моделюють навантаження, яке споживає значні ресурси, дозволяючи ефективно стресувати кластер.
Pod Anti-Affinity
Правила anti-affinity розподіляють Pods NGINX на різні вузли, щоб максимізувати високу доступність:
Як це працює: Правило забезпечує, що два Pods з однаковими мітками не можуть працювати на одному вузлі.
Ключова конфігурація:
- app.kubernetes.io/name=ingress-nginx: Орієнтується на Pods з цією міткою (специфічною для NGINX).
- app.kubernetes.io/component=controller: Забезпечує, що враховуються лише Pods контролера NGINX.
- topologyKey=kubernetes.io/hostname: Вказує, що правило anti-affinity застосовується до імені хоста кожного вузла.
Це налаштування гарантує, що кожен Pod буде розміщений на окремому вузлі, що забезпечить стійкість у разі відмови вузла. Це ретельно спроектовано, щоб:
- Запустити авто-масштабування: Комбінація запитів ресурсів, лімітів і HPA гарантує, що додаток буде масштабуватись динамічно під навантаженням.
- Максимізувати стійкість: Правила pod anti-affinity забезпечують розподіл Pods по різних вузлах, зменшуючи ризик простоїв через відмову вузла.
- Дозволити експерименти з хаосом: Передбачуване використання ресурсів і поведінка масштабування роблять це розгортання ідеальним для стресових симуляцій з Chaos Mesh.
Після того, як додаток-жертва розгорнуто і налаштовано, ми готові перейти до наступного етапу: симуляції стресу та спостереження, як EKS Auto Mode справляється з навантаженням.
Створення ресурсу StressChaos
Наступний крок у нашій стресовій симуляції — створення експерименту StressChaos. Цей експеримент застосує стрес на CPU і пам'ять до одного NGINX Pod, моделюючи сценарій важкого навантаження. Це дозволить нам спостерігати, як кластер EKS та його функції авто-масштабування реагують на додатковий тиск.
Нижче наведена YAML конфігурація для експерименту StressChaos:
#chaos-stress-nginx-test.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
name: nginx-stress-test
namespace: chaos-mesh
spec:
mode: one # Вплине лише на один pod з вказаною міткою
selector:
namespaces:
- nginx # Простір імен, де знаходиться NGINX pod
labelSelectors:
app.kubernetes.io/name: ingress-nginx # Вибір NGINX pod
stressors:
cpu:
workers: 4 # Кількість робітників для стресування CPU
load: 100 # Відсоток навантаження на кожного робітника
memory:
workers: 2 # Кількість робітників для стресування пам'яті
size: "100MB" # Кількість пам'яті, яку використовує кожен робітник
duration: "5m" # Тривалість стресового тесту
Збережіть файл YAML як chaos-stress-test.yaml і застосуйте його до кластера, виконавши наступну команду:
kubectl apply -f chaos-stress-test.yaml
Ви можете налаштувати цей експеримент або дослідити інші типи стресових тестів, підтримуваних Chaos Mesh. Для детальної інформації щодо параметрів та конфігурацій зверніться до офіційної документації Chaos Mesh:
[
Симулювати стресові сценарії | Chaos Mesh
Введення в StressChaos
chaos-mesh.org
](https://chaos-mesh.org/docs/simulate-heavy-stress-on-kubernetes/?source=post_page-----d03deab5fd36--------------------------------#create-experiments-using-the-yaml-file)
Помилковий випадок
При застосуванні експерименту StressChaos ви можете зіткнутися з такою помилкою:
Error from server (Forbidden): error when creating “chaos-stress-test.yaml”: admission webhook “vauth.kb.io” denied the request: arn:aws:iam::311141543661:user/bastion-user is forbidden on namespace nginx
Ця помилка виникає, тому що користувач (arn:aws:iam::311141543661:user/bastion-user) не має необхідних прав для створення ресурсів Chaos Mesh в просторі імен nginx.
RBAC (Role-Based Access Control) Kubernetes блокує запит.
Щоб вирішити цю проблему, створіть роль і RoleBinding в просторі імен nginx, щоб надати необхідні права доступу.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: nginx
name: chaos-mesh-role
rules:
- apiGroups: ["chaos-mesh.org"]
resources: ["stresschaos"]
verbs: ["create", "get", "list", "watch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
namespace: nginx
name: chaos-mesh-binding
subjects:
- kind: User
name: arn:aws:iam::311141543661:user/bastion-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: chaos-mesh-role
apiGroup: rbac.authorization.k8s.io
Застосуйте конфігурацію:
kubectl apply -f chaos-mesh-rbac.yaml
Результати
Конфігурація NodePool
Перед тим як розглядати результати нашого стресового тесту, важливо переглянути конфігурацію NodePool, яку керує Karpenter, оскільки це безпосередньо впливає на типи вузлів, що надаються, та їх масштабування. У кластері EKS Auto Mode Karpenter відповідає за динамічне надання вузлів на основі вимог навантаження та конфігурації, визначеної в NodePool.
Якщо ви новачок у Karpenter або хочете зрозуміти, як він оптимізує авто-масштабування Kubernetes, не соромтеся ознайомитися з моїм докладним постом: https://medium.com/@miguelangelchuecos/eks-auto-mode-how-karpenter-optimizes-kubernetes-autoscaling-d2ed666252d8
Для цього експерименту використовується наступна конфігурація NodePool, яку використовує Karpenter:
apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
annotations:
karpenter.sh/nodepool-hash: "4012513481623584108"
karpenter.sh/nodepool-hash-version: v3
creationTimestamp: "2025-01-08T11:59:16Z"
generation: 1
labels:
app.kubernetes.io/managed-by: eks
name: general-purpose
resourceVersion: "6493"
uid: c7925556-2019-4534-8395-79d4ed558a8a
spec:
disruption:
budgets:
- nodes: 10%
consolidateAfter: 30s
consolidationPolicy: WhenEmptyOrUnderutilized
template:
metadata: {}
spec:
expireAfter: 336h
nodeClassRef:
group: eks.amazonaws.com
kind: NodeClass
name: default
requirements:
- key: karpenter.sh/capacity-type
operator: In
values:
- on-demand
- key: eks.amazonaws.com/instance-category
operator: In
values:
- c
- m
- r
- key: eks.amazonaws.com/instance-generation
operator: Gt
values:
- "4"
- key: kubernetes.io/arch
operator: In
values:
- amd64
- key: kubernetes.io/os
operator: In
values:
- linux
terminationGracePeriod: 24h0m0s
Ключові моменти конфігурації NodePool:
Вимоги до вузлів: Karpenter буде надавати вузли, які відповідають наступним вимогам:
- Категорії інстансів: c, m та r.
- Покоління інстансів: більше ніж 4 (наприклад, c5, m5, r5).
- Архітектура: amd64.
- Операційна система: linux.
Бюджети відмов:
- Під час подій консолідації буде припинено не більше 10% вузлів у пулі.
Політика консолідації:
- Вузли будуть консолідовані (знищені, якщо використовуються неефективно) через 30 секунд, якщо вони є порожніми або недовикористаними.
Ви можете перевірити вузли, надані Karpenter, щоб впевнитись, що вони відповідають конфігурації NodePool.
# Виконайте наступну команду, щоб побачити всі вузли в кластері:
kubectl get nodes
# Виберіть один з вузлів і опишіть його деталі:
kubectl describe node
# Приклад: kubectl describe node i-070fdc8658e52cc8c
У виведенні ви побачите мітки, які відповідають вимогам NodePool.
Ці мітки підтверджують, що Karpenter надає вузли, які відповідають визначеним обмеженням.
Аналіз результатів
Результати стрес-тесту демонструють, як EKS Auto Mode та Karpenter динамічно обробляють обмеження ресурсів під час сильного навантаження на процесор та пам'ять. Ось детальний розбір спостережуваної поведінки та її значення:
Незабаром після застосування експерименту StressChaos використання процесора на вузлі, де розміщений NGINX Pod, різко зросло:
# Метрики вузлів до масштабування:
NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%)
i-070fdc8658e52cc8c 23m 1% 309Mi 9%
i-095283aeb46d58f76 14m 0% 690Mi 22%
# Метрики вузлів після масштабування:
NAME CPU(cores) CPU(%) MEMORY(bytes) MEMORY(%)
i-04bd9414783da9498 635m 32% 325Mi 10%
i-070fdc8658e52cc8c 19m 0% 305Mi 9%
i-095283aeb46d58f76 994m 51% 791Mi 25%
i-0cc17ba4217405624 16m 0% 373Mi 11%
- Було надано два нових вузли (i-04bd9414783da9498 та i-0cc17ba4217405624), щоб обробити збільшене навантаження.
- Ці вузли відповідають обмеженням, визначеним у NodePool (наприклад, типи інстансів, потужність і архітектура).
- Кожен NGINX Pod тепер розміщений на окремому вузлі, що забезпечується правилами Pod Anti-Affinity.
Кількість реплік для деплойменту NGINX збільшилась до максимального ліміту, визначеного в HPA:
machuecos@Miguels-MacBook-Pro Phantom % kubectl get pods -o wide -n nginx
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-ingress-nginx-controller-5f8c597494-fmk24 1/1 Running 0 73m 172.31.25.121 i-095283aeb46d58f76
nginx-ingress-nginx-controller-5f8c597494-vk6g4 1/1 Running 0 87s 172.31.25.96 i-04bd9414783da9498
nginx-ingress-nginx-controller-5f8c597494-wml4p 1/1 Running 0 118s 172.31.26.224 i-0cc17ba4217405624
Ключові спостереження:
- Досягнуто максимальну кількість реплік: Кількість реплік збільшилась до максимального ліміту 3, як це визначено в конфігурації HPA.
- Розподіл між вузлами: Pods розподілені між різними вузлами (i-095283aeb46d58f76, i-04bd9414783da9498, i-0cc17ba4217405624) завдяки правилам Pod Anti-Affinity.
Після 5 хвилин (тривалість тесту) почнеться зниження навантаження. Кількість подів буде зменшена до 1, знижуючи використання процесора та кількість вузлів, оптимізуючи ресурси і витрати.
Перекладено з: Scaling Under Pressure: Chaos Mesh Stress Tests on EKS Auto Mode