2) "как дебажить vmrule?"
Например чтобы отправить собственную метрику для проверки каких-то кондишнов
- коннектимся к vmagent
- отправляем придуманное событие в vmagent
- проверяем что этот алёрт ок в виктории метрикс, например нам важно какой северити у него стал/есть (этот кусок прям в Prometheus/VM/Grafana explore вводить)
- не забываем потушить алёрт, иначе он будет висеть вечно
Удаление нужно в том случае, когда вы не хотите, чтобы это попало в алёртменеджер. Вам же просто протестировать
3) "как проверить рулесы алертменеджера"
отправить курл запрос типа
#alertmanager
Например чтобы отправить собственную метрику для проверки каких-то кондишнов
- коннектимся к vmagent
>k port-forward svc/vmagent-tratata-prod-aks-us-1 8429
- отправляем придуманное событие в vmagent
curl -X POST http://localhost:8429/api/v1/import/prometheus \
-d 'kube_pod_status_phase{phase="Pending",exported_namespace="test-namespace",pod="logical-backup-pgsql-test-pod",cluster="test-prod-cluster"} 1'
- проверяем что этот алёрт ок в виктории метрикс, например нам важно какой северити у него стал/есть (этот кусок прям в Prometheus/VM/Grafana explore вводить)
ALERTS{alertname="KubernetesPodNotHealthy", pod="logical-backup-pgsql-test-pod"}- не забываем потушить алёрт, иначе он будет висеть вечно
curl -X POST http://localhost:8429/api/v1/import/prometheus \
-d 'kube_pod_status_phase{phase="Pending",exported_namespace="test-namespace",pod="logical-backup-pgsql-test-pod",cluster="test-prod-cluster"} 0'
Удаление нужно в том случае, когда вы не хотите, чтобы это попало в алёртменеджер. Вам же просто протестировать
vmrules.❕vmalert происходит ДО попадания в alertmanager.3) "как проверить рулесы алертменеджера"
отправить курл запрос типа
curl -X POST https://alertmanager.domain.com/api/v1/alerts \
-H "Content-Type: application/json" \
-d '[
{
"labels": {
"alertname": "KubernetesPodNotHealthy",
"cluster": "test-prod-cluster",
"exported_namespace": "test-namespace",
"pod": "logical-backup-pgsql-test-pod",
"phase": "Pending",
"emoji": "🔥",
"incident_type": "outage"
},
"annotations": {
"summary": "POD'"'"'s state is `Pending` for `test-prod-cluster`/`test-namespace`/`logical-backup-pgsql-test-pod`",
"description": "Pod test-namespace/logical-backup-pgsql-test-pod has been in a non-running state for longer than 15 minutes.\n VALUE = 1\n LABELS = map[cluster:test-prod-cluster exported_namespace:test-namespace phase:Pending pod:logical-backup-pgsql-test-pod]"
},
"startsAt": "'$(date -u +"%Y-%m-%dT%H:%M:%SZ")'",
"endsAt": "'$(date -u -d "+3 minutes" +"%Y-%m-%dT%H:%M:%SZ")'"
}
]'
#alertmanager
✍4
Bottlerocket, storage.
Ну а куда без боттлрокета.
Допустим вы решили перейти на боттлрокет после моих постов - https://xn--r1a.website/makebreakreflect/35
Сразу споткнувшись про пустой дефолтный конфиг кублета читаете и тут
https://xn--r1a.website/makebreakreflect/38
Готово.
У вас и кластер AWS EKS и нод группа(ы) и лаунчтемплейт.
Всё работает, всё круто, но спустя время вы замечаете, что у вас участились алёрты
Так же в ивентах у вас нечто типа
"Какогох*ра рожна" думаете вы, ведь у меня диск как был 200 гигабайт, так и остался.
Смотрите свой код, видите там нечто типа
"ну да, двести гигов" говорите вы вслух самому себе и идёте проверять терраформ/террагрант план.
Всё ок. Никаких
Лезете в кубер, смотрите а чо там рили.
Внезапно там ну вообще ни 200 гигов, там 20.
Начинаете перепроверять код, лаунчемплейт, ласт вершн и issue github.
А нет ничего.
У вас желаемое 200 гигов, а реально видно 20.
И тут подстава, откуда вы не ждали.
У
Чтобы ноде под поды выделить больше места дефолта с 20 гигами, вам надо выдать отдельный маунт на побольше.
Терраформ план, терраформ апплай, проверяем
Отлично, теперь под эфемерку у нас 200 гигов, а не дефолтные 20(или 30, я не помню если честно) гигабайт.
Разуемся, алёрты пропадают, эфемерки всем хватает, кластер снова сладкий как яблочки с огорода у бабушки.
Кому интересно могут почитать на официальном сайте детальнейшее описание причин, но там на самом деле скукота.
#aws #eks #bottlerocket
Ну а куда без боттлрокета.
Допустим вы решили перейти на боттлрокет после моих постов - https://xn--r1a.website/makebreakreflect/35
Сразу споткнувшись про пустой дефолтный конфиг кублета читаете и тут
https://xn--r1a.website/makebreakreflect/38
Готово.
У вас и кластер AWS EKS и нод группа(ы) и лаунчтемплейт.
Всё работает, всё круто, но спустя время вы замечаете, что у вас участились алёрты
DiskPressure.Так же в ивентах у вас нечто типа
The node had condition: [DiskPressure].
The node was low on resource: ephemeral-storage. Threshold quantity: 4281126156, available: 3438556Ki
"Какого
Смотрите свой код, видите там нечто типа
resource "aws_launch_template" "node-launch-template" {
...
block_device_mappings {
device_name = "/dev/xvda"
ebs {
volume_size = 200
volume_type = "gp3"
}
}
..."ну да, двести гигов" говорите вы вслух самому себе и идёте проверять терраформ/террагрант план.
Всё ок. Никаких
lifecycle {
ignore_changes Лезете в кубер, смотрите а чо там рили.
kubectl get nodes -o yaml | grep -i -A6 ephemeral-storage
Внезапно там ну вообще ни 200 гигов, там 20.
Начинаете перепроверять код, лаунчемплейт, ласт вершн и issue github.
А нет ничего.
У вас желаемое 200 гигов, а реально видно 20.
И тут подстава, откуда вы не ждали.
У
bottlerocket не совсем типичный подход к монтированию томов.Чтобы ноде под поды выделить больше места дефолта с 20 гигами, вам надо выдать отдельный маунт на побольше.
resource "aws_launch_template" "node-launch-template" {
...
# !!! вот тут много не надо, это для самой ноды, операционка, можно хоть 10
block_device_mappings {
device_name = "/dev/xvda"
ebs {
volume_size = 20
volume_type = "gp3"
}
}
# !!! вот это добавляем, для POD-ов
block_device_mappings {
device_name = "/dev/xvdb"
ebs {
volume_size = 200
volume_type = "gp3"
}
}Терраформ план, терраформ апплай, проверяем
kubectl get nodes -o yaml | grep -i -A6 ephemeral-storage
Отлично, теперь под эфемерку у нас 200 гигов, а не дефолтные 20(или 30, я не помню если честно) гигабайт.
Разуемся, алёрты пропадают, эфемерки всем хватает, кластер снова сладкий как яблочки с огорода у бабушки.
Кому интересно могут почитать на официальном сайте детальнейшее описание причин, но там на самом деле скукота.
#aws #eks #bottlerocket
👍6
#начинающим #docker
Контекст(context).
Мне понадобилось некоторое время на этапе моего обучения несколько лет назад, чтобы поесть всякого, чтобы осознать существование контекста.
Основной пример буду пояснять на примере Docker.
Например, когда вы пишете😈 .
Допустим мы собираем имадж так:
Вот точка это и есть контекст. Точка это наша директория нашего проекта.
Что же нам надо знать о контексте?
- нельзя выйти за пределы контекста
Например у нас есть такая структура
Находясь в директории
Так как shared находится выше по иерархии и не входит в контекст текущей директории "."
- докер(и другие известные мне утилиты) сканирует все файлы контекста( то есть в текущей директории)
То есть условно если у вас есть 50000 файлов по мегабайту или один файл 50 гигабайт в гит репозитории в контексте, то это замедлит сборку
Даже если мы НЕ используем
Не думаю, что этот случай для всех, с этим можно столкнутся при не совсем корректных воркфлоу и при монолит приложениях.
Например у вас npm build идёт ВНЕ сборки докера, а потом вы копируете файлы(я видел и такое).
Проблема с переполнением контекста решается через
В этом файле мы указываем те директории/файлы, которые НЕ должны попасть в контекст, по аналогии с
- контекст в
Контекст доступен для всех этапов сборки, однако при использовании
Концепция контекста применима не только к Docker, но и к другим инструментам, например, к Helm - менеджеру пакетов для кубера.
Некоторые инженеры сталкиваются с ситуацией, когда во время деплоя секрет Helm не удаётся сохранить в ETCD, потому что его размер превышает ограничение в 1 МБ(ограничение ETCD).
Чаще всего это происходит из-за того, что в директорию случайно попадают ненужные файлы: логи, бинарники, архивы или другие "левые" данные. Да, прям внутри кубера в секрете хелма по релизу помимо манифестов yaml валяются бинари/файлы, которые мы по незнанию туда засунули.
Чтобы избежать таких проблем, стоит использовать файл
Контекст - это не просто техническая деталь, а инструмент, который нужно понимать и оптимизировать.
Используйте
Контекст(context).
Мне понадобилось некоторое время на этапе моего обучения несколько лет назад, чтобы поесть всякого, чтобы осознать существование контекста.
Основной пример буду пояснять на примере Docker.
Контекст сборки - это архив (по сути tar-файл), который Docker создаёт из указанной директории и отправляет демону для обработки. Например, когда вы пишете
docker build -t image ., Docker упаковывает все файлы из текущей директории (.) и передаёт их демонуДопустим мы собираем имадж так:
docker build -t image .
Вот точка это и есть контекст. Точка это наша директория нашего проекта.
Что же нам надо знать о контексте?
- нельзя выйти за пределы контекста
Например у нас есть такая структура
/home/user/projects/
├── my_project/
│ ├── Dockerfile
│ ├── app.py
└── shared/
└── library.so
Находясь в директории
my_project мы не сможем собрать имадж типа такогоFROM ubuntu:20.04
COPY ../shared/library.so /usr/lib/
Так как shared находится выше по иерархии и не входит в контекст текущей директории "."
- докер(и другие известные мне утилиты) сканирует все файлы контекста( то есть в текущей директории)
То есть условно если у вас есть 50000 файлов по мегабайту или один файл 50 гигабайт в гит репозитории в контексте, то это замедлит сборку
Даже если мы НЕ используем
COPY . . , докер всё равно сканирует эти файлы(точнее Docker демон сканирует и упаковывает файлы для передачи) и мы собираем дольше по времени.Не думаю, что этот случай для всех, с этим можно столкнутся при не совсем корректных воркфлоу и при монолит приложениях.
Например у вас npm build идёт ВНЕ сборки докера, а потом вы копируете файлы(я видел и такое).
Проблема с переполнением контекста решается через
.dockerignore файл.В этом файле мы указываем те директории/файлы, которые НЕ должны попасть в контекст, по аналогии с
.gitignore.- контекст в
multi-stage билдахКонтекст доступен для всех этапов сборки, однако при использовании
COPY --from=build копирование идет из предыдущего этапа, а не из исходного контекста.Концепция контекста применима не только к Docker, но и к другим инструментам, например, к Helm - менеджеру пакетов для кубера.
Некоторые инженеры сталкиваются с ситуацией, когда во время деплоя секрет Helm не удаётся сохранить в ETCD, потому что его размер превышает ограничение в 1 МБ(ограничение ETCD).
Чаще всего это происходит из-за того, что в директорию случайно попадают ненужные файлы: логи, бинарники, архивы или другие "левые" данные. Да, прям внутри кубера в секрете хелма по релизу помимо манифестов yaml валяются бинари/файлы, которые мы по незнанию туда засунули.
Чтобы избежать таких проблем, стоит использовать файл
.helmignore, который позволяет исключить лишние файлы из контекста чарта - примерно так же, как .dockerignore помогает в Docker.Контекст - это не просто техническая деталь, а инструмент, который нужно понимать и оптимизировать.
Используйте
.dockerignore/.helmignore и следите за содержимым директорий, чтобы сборка была быстрой и эффективной.Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥7💯2
#aws #eks #sqs #CostOptimization
Материал уровня middle.
Снова про экономию.
У нас есть AWS SQS.
В него прилетает миллион вебхуков с полезным и важным payload.
Бывают пики, бывают нет.
У нас есть AWS EKS и приложение в POD-e, который вычитывает SQS, процессит и всё ок.
Нам надо настроить масштабирование не за счёт CPU/memory usage, а за счёт количества сообщений.
В этом нам помогает KEDA. Опустим этапы установки/настройки/прав и авторизации.
У нас есть готовый манифест
Всё работает, всё скейлится, всё ок.
В HPA некрасиво выглядят цифры, хочется видеть точное количество мессаджем. Добавляем
И теперь в
Этого нам мало, нужна точная подстройка.
Читаем дальше доку, у нас есть адвансед настройки.
Теперь у нас всё динамически скейлится, прописаны все триггеры, трешхолды.
Всё отлично и бизнес ликует(не вру, прям ликует, сильно помогло).
Однако меня, как рьяного и верного пса девопс церкви, напрягает, что в период высокой нагрузки всё упирается в максимум реплик. Да, можно поставить не 50, а 100, но я думаю, что настройка неверная.
Углубляемся дальше в доку(вру, я ничо не понял и просто спросил ребят-гуру-AWS-технологий в телеге) и вспоминаем про визибл/анвизибл настройки у sqs.
https://keda.sh/docs/2.14/scalers/aws-sqs/
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
Окончательно пилим манифест.
Отлично. Теперь самая точная и потрясающая настройка.
Материал уровня middle.
Снова про экономию.
У нас есть AWS SQS.
В него прилетает миллион вебхуков с полезным и важным payload.
Бывают пики, бывают нет.
У нас есть AWS EKS и приложение в POD-e, который вычитывает SQS, процессит и всё ок.
Нам надо настроить масштабирование не за счёт CPU/memory usage, а за счёт количества сообщений.
В этом нам помогает KEDA. Опустим этапы установки/настройки/прав и авторизации.
У нас есть готовый манифест
scaledobject.---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
...
spec:
cooldownPeriod: 300
maxReplicaCount: 50
minReplicaCount: 2
pollingInterval: 30
scaleTargetRef:
name: application
triggers:
- authenticationRef:
name: keda-aws-credentials
metadata:
awsRegion: us-east-1
identityOwner: operator
queueLength: "500"
queueURL: https://sqs.us-east-1.amazonaws.com/123456789/sqsname
type: aws-sqs-queue
Всё работает, всё скейлится, всё ок.
В HPA некрасиво выглядят цифры, хочется видеть точное количество мессаджем. Добавляем
metricType---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
...
spec:
...
metricType: Value
И теперь в
kubectl get hpa blablabla видим точное количество мессаджей в TARGETS(а не системы счисления инопланетян).Этого нам мало, нужна точная подстройка.
Читаем дальше доку, у нас есть адвансед настройки.
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
...
spec:
advanced:
horizontalPodAutoscalerConfig:
behavior:
scaleDown:
policies:
- periodSeconds: 15
type: Pods
value: 1
stabilizationWindowSeconds: 300
scaleUp:
policies:
- periodSeconds: 15
type: Pods
value: 1
selectPolicy: Max
stabilizationWindowSeconds: 60
... (остальное так же)
Теперь у нас всё динамически скейлится, прописаны все триггеры, трешхолды.
Всё отлично и бизнес ликует(не вру, прям ликует, сильно помогло).
Однако меня, как рьяного и верного пса девопс церкви, напрягает, что в период высокой нагрузки всё упирается в максимум реплик. Да, можно поставить не 50, а 100, но я думаю, что настройка неверная.
Углубляемся дальше в доку(вру, я ничо не понял и просто спросил ребят-гуру-AWS-технологий в телеге) и вспоминаем про визибл/анвизибл настройки у sqs.
https://keda.sh/docs/2.14/scalers/aws-sqs/
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html
Окончательно пилим манифест.
---
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
...
spec:
advanced:
...(тут тоже самое)
metadata:
...
scaleOnInFlight: "false" << - - вот это вот важное нам
...
Отлично. Теперь самая точная и потрясающая настройка.
🔥5
#aws #eks #sqs #CostOptimization
Благодаря точной настройке мы неслабо экономим:
- во время нагрузки мы не скейлим так много реплик
- нет большого лишнего скейла реплик - нет и скейла нод кластера AWS EKS
- нет скейла нод - платим серьёзно меньше
Всего один параметр и в разы снижаем нагрузку и косты.
❕Прежде чем делать подобное, уточните у девелоперов и бизнеса - подойдёт ли это вам и продукту.
Не все процессинги можно переключить только на инфлайт режим.
Полный пример манифеста(код в телеге неудобно читать).
https://gist.github.com/kruchkov-alexandr/e6328137107e49c6a5e7c05c40851680
scaleOnInFlight - Indication of whether or not to include in-flight messages when calculating the number of SQS messages. (default: true, Optional)Благодаря точной настройке мы неслабо экономим:
- во время нагрузки мы не скейлим так много реплик
- нет большого лишнего скейла реплик - нет и скейла нод кластера AWS EKS
- нет скейла нод - платим серьёзно меньше
Всего один параметр и в разы снижаем нагрузку и косты.
❕Прежде чем делать подобное, уточните у девелоперов и бизнеса - подойдёт ли это вам и продукту.
Не все процессинги можно переключить только на инфлайт режим.
Полный пример манифеста(код в телеге неудобно читать).
https://gist.github.com/kruchkov-alexandr/e6328137107e49c6a5e7c05c40851680
👍8
#aws #opensearch
"Алекс, у нас какая-то штука, логи в OpenSearch недоступны. да просто белая страница крутится и всё. Да, мы помним, что ты давно говорил перейти на локи, но пока нет бюджета. Глянь, пожалуйста, что там может быть, да, прайс почасовой такой же."
Да блин, я так себе мастер с опенсёрче, на этом проекте он просто дефолтный.
Файлбит собирает с кубера с дефолт конфигом и пушит в опенсёрч.
У опенсёрча 2 инстанса в кластере на продакшне.
Ок, деньги не пахнут, а за спасибо супруге новую сумку не купить🤣
Заходим в веб - да, тормозит, белая страница по дискавери.
Но статус кластер - грин, всё ок по мнению амазона😂 .
Смотрим в дашборды графаны - видим 100% нагрузка CPU и она началась 15 числа (ага, можно поклянчить денег на новые алёрты ЦПУ юсадж опенсёрча).
Пробуем делать рестарт нод/дашбордов.
Получаем неожиданную ошибку
Ну спасибо, амазон, ну молодцы. Лллллллогика железная.
Заходим в dev tools и смотрим "а чо там".
Ого, все запросы в среднем по 180 секунд висят.
Видим что всё упирается в опендистро
Пробуем не глядя (а что вы мне сделаете?)
Ждём 10 минут и.. и лучше не стало.
Запуливаем снова что там с процессами - там всё ещё всё висит.
Ок. Логи то нужны девелоперам.
Спрашиваем лида проекта "могу ли всё хард ресетнуть?". Ничего не понимая он с лицом осла из Шрека кивает и мы пуляем
Ждём 10 минут и ничего.
Ладно.
Ищем мануалы типа
https://repost.aws/knowledge-center/opensearch-troubleshoot-high-cpu
Проходим всё, и вот эта шабола показывает нам всякое
по 50 и 52 часов пользовательские (игнорируем системные).
Ну а какие варианты -
Ии.. и ничего не происходит.
Опенсёрч ставит в очередь на удаление и всё.
Ждём ещё полчаса и нет результата.
Пробуем точечно и родительские и дочерние процессы кильнуть - ноль на массу.
Ну то есть по моему личному мнению по анализу запросов, дебагу и прочему я понимаю, что "подвисли" запросы по 50+ часов с 15 числа.
Убить их не удаётся. Нет, не так описал: то есть их убивает, при повторной попытке убить он пишет "already deleted" но всё равно тратит память и такты ЦПУ. Очередь на удаление на часы.
Пишем тикет в саппорт "дяденьки спасити памагити", ставим system impaired.
Спустя час вижу, что нагрузка стала меньше, 95% запросов таки убило.
Остался один максимально всратый.
Оставил его всем на сладенькое.
https://gist.githubusercontent.com/kruchkov-alexandr/3d28e37918dbf6c844c020b286a062df/raw/28a6ac4b2a5b6584c1f77ed51d2d9b3189f2344c/parasha.json
Да, я вот так же это читал и реагировал🤣 🤣 🤣 🤣 🤣
Слегка заорал чайкой от
Получаю ответ
- "used Cursor AI and multi cursor to build it up lol"
😂 😂 😂
и взвизгнул гиеной на весь город, это в мемы.
Ну то есть девелопер выполнил буквально такой запрос:
https://gist.github.com/kruchkov-alexandr/bb6b2bb2ce46828e26b9c5feb6af878d
Собственно этот запроси был причиной проблемы.
Спустя 45-60 минут этот цирк заканчивается, все квери удалены, нагрузка на CPU снижается, интерфейс оживает для девелоперов.
Трекаем время (Не, ну я же ждал всё это время, да? Ждал же? Трекаем!🤣 ) и закрываем таску.
Закрываем таску в саппорт амазона, на 3 часа так и не ответили ничего, даже ассайна не было с систем импайрд, ну ладно.
Как положить кластер опенсёрча при помощи AI помошников и фич IDE "Алекс, у нас какая-то штука, логи в OpenSearch недоступны. да просто белая страница крутится и всё. Да, мы помним, что ты давно говорил перейти на локи, но пока нет бюджета. Глянь, пожалуйста, что там может быть, да, прайс почасовой такой же."
Да блин, я так себе мастер с опенсёрче, на этом проекте он просто дефолтный.
Файлбит собирает с кубера с дефолт конфигом и пушит в опенсёрч.
У опенсёрча 2 инстанса в кластере на продакшне.
Ок, деньги не пахнут, а за спасибо супруге новую сумку не купить
Заходим в веб - да, тормозит, белая страница по дискавери.
Но статус кластер - грин, всё ок по мнению амазона
Смотрим в дашборды графаны - видим 100% нагрузка CPU и она началась 15 числа (ага, можно поклянчить денег на новые алёрты ЦПУ юсадж опенсёрча).
Пробуем делать рестарт нод/дашбордов.
Получаем неожиданную ошибку
Operation disabled for domains with less than three nodes.
Ну спасибо, амазон, ну молодцы. Лллллллогика железная.
Заходим в dev tools и смотрим "а чо там".
GET _tasks?detailed=true
Ого, все запросы в среднем по 180 секунд висят.
Видим что всё упирается в опендистро
ISMПробуем не глядя (а что вы мне сделаете?)
POST .opendistro-ism-config/_forcemerge?max_num_segments=1
{
"_shards" : {
"total" : 10,
"successful" : 10,
"failed" : 0
}
}
Ждём 10 минут и.. и лучше не стало.
Запуливаем снова что там с процессами - там всё ещё всё висит.
Ок. Логи то нужны девелоперам.
Спрашиваем лида проекта "могу ли всё хард ресетнуть?". Ничего не понимая он с лицом осла из Шрека кивает и мы пуляем
PUT .opendistro-ism-config-optimized
{
"settings": {
"index.number_of_shards": 1,
"index.number_of_replicas": 1
}
}
POST _reindex
{
"source": {"index": ".opendistro-ism-config"},
"dest": {"index": ".opendistro-ism-config-optimized"}
}
Ждём 10 минут и ничего.
Ладно.
Ищем мануалы типа
https://repost.aws/knowledge-center/opensearch-troubleshoot-high-cpu
Проходим всё, и вот эта шабола показывает нам всякое
GET _tasks?actions=*search&detailed
по 50 и 52 часов пользовательские (игнорируем системные).
Ну а какие варианты -
Kill 'Em AllPOST _tasks/bDFfq7RrRyGGnzfHPBy14g:794713665/_cancel
POST _tasks/bDFfq7RrRyGGnzfHPBy14g:817036855/_cancel
Ии.. и ничего не происходит.
Опенсёрч ставит в очередь на удаление и всё.
Ждём ещё полчаса и нет результата.
Пробуем точечно и родительские и дочерние процессы кильнуть - ноль на массу.
Ну то есть по моему личному мнению по анализу запросов, дебагу и прочему я понимаю, что "подвисли" запросы по 50+ часов с 15 числа.
Убить их не удаётся. Нет, не так описал: то есть их убивает, при повторной попытке убить он пишет "already deleted" но всё равно тратит память и такты ЦПУ. Очередь на удаление на часы.
Пишем тикет в саппорт "дяденьки спасити памагити", ставим system impaired.
Спустя час вижу, что нагрузка стала меньше, 95% запросов таки убило.
Остался один максимально всратый.
Оставил его всем на сладенькое.
https://gist.githubusercontent.com/kruchkov-alexandr/3d28e37918dbf6c844c020b286a062df/raw/28a6ac4b2a5b6584c1f77ed51d2d9b3189f2344c/parasha.json
Да, я вот так же это читал и реагировал
Слегка заорал чайкой от
multi_match на 200+ вэльюсов, я отправляю коллегам с текстом are you okhueli there?!!?Получаю ответ
- "used Cursor AI and multi cursor to build it up lol"
и взвизгнул гиеной на весь город, это в мемы.
Ну то есть девелопер выполнил буквально такой запрос:
https://gist.github.com/kruchkov-alexandr/bb6b2bb2ce46828e26b9c5feb6af878d
Собственно этот запроси был причиной проблемы.
Спустя 45-60 минут этот цирк заканчивается, все квери удалены, нагрузка на CPU снижается, интерфейс оживает для девелоперов.
Трекаем время (Не, ну я же ждал всё это время, да? Ждал же? Трекаем!
Закрываем таску в саппорт амазона, на 3 часа так и не ответили ничего, даже ассайна не было с систем импайрд, ну ладно.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁9👍3🔥2
#aws #aurora #terraform #finops
Материал уровня senior
Мы умеем определять тип инстанса - по нагрузке на CPU/Memory и другим факторам.
Но насколько эффективно мы выбрали
Эффективно ли это спустя год или два?
А никто не знает, давайте разбираться.
- сперва пилим Dashboard к нашему существующему кластеру
https://gist.github.com/kruchkov-alexandr/d9335d7927e58d06557b994dc9f194de
- применяем, видим панель в CloudWatch
Сверху у нас панель чтения/записи хранилища, снизу размер базы данных (+снепшоты?).
Разделение нужно из-за разницы масштабов и удобства экспорта.
- выбираем период три месяца и кликаем на трех точках у обоих панелей и выбираем
- заходим в cost explorer и экспортируем дату за три месяца по кластеру
- заходим в вашу любимую AI(я спрашивал у клаудии, перплексити и грок3, все платные) и пилим промт нечто типа(можете писать свой, если мой вам кажется тупым):
"Help me decide if we should switch to Amazon Aurora I/O-Optimized. Use the attached billing screenshot/csv, three-month IOPS data from the CSV, and the IOPS/storage graphs to analyze our costs. Calculate our current I/O expenses, compare them to I/O-Optimized costs and check if our I/O costs exceed AWS’s 25% threshold for switching. Look at IOPS and storage trends, then recommend whether to switch, including specific cost figures. I’ve attached all files (billing, CSV, graphs).
based on this article
https://aws.amazon.com/blogs/database/estimate-cost-savings-for-the-amazon-aurora-i-o-optimized-feature-using-amazon-cloudwatch/"
- ждём ответа и все 4 нейронки мне выдали на 95% одинаковый подробнейший расчёт ответ. Вкратце "
- пишем менеджеру/боссу
I've analyzed our infrastructure costs over the last three months billing and IOPS data, to see if switching to Amazon Aurora I/O-Optimized makes sense. Right now, it's not cost-effective. Our I/O costs an average of $******* monthly (************ I/Os at $**** per million). Moving to I/O-Optimized would increase instance costs by ***%, from $******* to $******* - a $******* jump, which is $415.21 more than our current I/O expenses.
Our IOPS trends show peaks up to *** but no major growth, averaging ~** Write and ~**** Read IOPS hourly in February. Storage usage is growing at *** GB/month, but that doesn't impact the I/O-Optimized cost comparison. AWS suggests I/O-Optimized when I/O costs exceed **% of total Aurora spend, but ours ($******) are only **% of the $******* total, so we're below that threshold.
I recommend sticking with our standard configuration for now. We should keep monitoring I/O activity -if it exceeds **** I/Os monthly or I/O costs reach **% of our Aurora spend, we can revisit I/O-Optimized.
Прикладываем все файлы,скрины,расчёты.
- закрываем таску и трекаем время
Всё вышеописанное заняло у меня минут 15, а вот подготовительные работы(чтение про фичу, особенности, лимиты, как считать, написание борды, особенности биллинга и тп) почти половину дня.
* Если не верите ИИ, можете пересчитать вручную🐒
Дополнительные полезные ссылки(а вдруг вы мне не верите):
- анонс фичи
https://aws.amazon.com/about-aws/whats-new/2023/05/amazon-aurora-i-o-optimized/
- обзор менеджер уровня
https://aws.amazon.com/awstv/watch/b9bfc040ac5/
- пример расчётов (там руками считают, без ИИ)
https://aws.amazon.com/blogs/database/estimate-cost-savings-for-the-amazon-aurora-i-o-optimized-feature-using-amazon-cloudwatch/
Материал уровня senior
Мы умеем определять тип инстанса - по нагрузке на CPU/Memory и другим факторам.
Но насколько эффективно мы выбрали
Cluster storage configuration Авроры вашего проекта?Эффективно ли это спустя год или два?
А никто не знает, давайте разбираться.
- сперва пилим Dashboard к нашему существующему кластеру
https://gist.github.com/kruchkov-alexandr/d9335d7927e58d06557b994dc9f194de
- применяем, видим панель в CloudWatch
Сверху у нас панель чтения/записи хранилища, снизу размер базы данных (+снепшоты?).
Разделение нужно из-за разницы масштабов и удобства экспорта.
- выбираем период три месяца и кликаем на трех точках у обоих панелей и выбираем
Download as .csv и качаем оба файла- заходим в cost explorer и экспортируем дату за три месяца по кластеру
- заходим в вашу любимую AI(я спрашивал у клаудии, перплексити и грок3, все платные) и пилим промт нечто типа(можете писать свой, если мой вам кажется тупым):
"Help me decide if we should switch to Amazon Aurora I/O-Optimized. Use the attached billing screenshot/csv, three-month IOPS data from the CSV, and the IOPS/storage graphs to analyze our costs. Calculate our current I/O expenses, compare them to I/O-Optimized costs and check if our I/O costs exceed AWS’s 25% threshold for switching. Look at IOPS and storage trends, then recommend whether to switch, including specific cost figures. I’ve attached all files (billing, CSV, graphs).
based on this article
https://aws.amazon.com/blogs/database/estimate-cost-savings-for-the-amazon-aurora-i-o-optimized-feature-using-amazon-cloudwatch/"
- ждём ответа и все 4 нейронки мне выдали на 95% одинаковый подробнейший расчёт ответ. Вкратце "
Переходить пока рано".- пишем менеджеру/боссу
I've analyzed our infrastructure costs over the last three months billing and IOPS data, to see if switching to Amazon Aurora I/O-Optimized makes sense. Right now, it's not cost-effective. Our I/O costs an average of $******* monthly (************ I/Os at $**** per million). Moving to I/O-Optimized would increase instance costs by ***%, from $******* to $******* - a $******* jump, which is $415.21 more than our current I/O expenses.
Our IOPS trends show peaks up to *** but no major growth, averaging ~** Write and ~**** Read IOPS hourly in February. Storage usage is growing at *** GB/month, but that doesn't impact the I/O-Optimized cost comparison. AWS suggests I/O-Optimized when I/O costs exceed **% of total Aurora spend, but ours ($******) are only **% of the $******* total, so we're below that threshold.
I recommend sticking with our standard configuration for now. We should keep monitoring I/O activity -if it exceeds **** I/Os monthly or I/O costs reach **% of our Aurora spend, we can revisit I/O-Optimized.
Прикладываем все файлы,скрины,расчёты.
- закрываем таску и трекаем время
Всё вышеописанное заняло у меня минут 15, а вот подготовительные работы(чтение про фичу, особенности, лимиты, как считать, написание борды, особенности биллинга и тп) почти половину дня.
* Если не верите ИИ, можете пересчитать вручную
Дополнительные полезные ссылки(а вдруг вы мне не верите):
- анонс фичи
https://aws.amazon.com/about-aws/whats-new/2023/05/amazon-aurora-i-o-optimized/
- обзор менеджер уровня
https://aws.amazon.com/awstv/watch/b9bfc040ac5/
- пример расчётов (там руками считают, без ИИ)
https://aws.amazon.com/blogs/database/estimate-cost-savings-for-the-amazon-aurora-i-o-optimized-feature-using-amazon-cloudwatch/
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8😁1
#kubernetes #azure #troubleshooting
Материал уровень крепкий джун(на который я тут не потянул, лол, самоуверенное овно)
Никого не трогаю, прилетает алёрт.
"Лаг между репликами на Patroni кластере в кубере".
А я дежурный, блин. Ладно.
Сам алёрт вида
Делаю свич на кластер кубера, NS, вижу поды.
Никаких рестартов, никаких ООМираний.
Лезу внутрь пода, смотрю
0 - мастер, 1 и 2 - реплики. Лаг в 900 мегабайт на каждой реплике.
Пытаюсь сделать реинит для 1 реплики.
Впервые в жизни вижу ошибку - нет соединения, спустя минут 15 ретраев всё отваливается питоновскими ошибками.
Ок, пытаюсь повторить со второй репликой, через 15 минут тот же ответ.
Ладно, семь бед - один ресет.
Мастер трогать нельзя, ребутаю POD-ы c репликами.
После рестарта снова попытка реинициализации - таймаут.
Хм. Просто так делать failover с 0 инстанса на 1 или 2 нельзя в данном случае - у нас везде лаг и мы может грохнуть то, что не надо.
Мастер так же не хочется рестартовать, я уже с этой ложки ел.
Окунаемся в логи: да, прям внутри каждого пода смотрю журналы, ошибки, файлики.
Нет ничего. Таймаут. Да как так-то.
Ныряю выше, на уровень кластера: ивенты кубера, состояние нод, на каких нодах данные поды запустились.
Смотрим нетворк полиси и прочие типичные радости кубера. Нет ничего, что мешало бы.
Да все ок, ивенты пустые, все поды патрони кластера с БД на одной нод группе.
Проверял даже наличие свободных IP адресов в кластере AKS. Всё есть.
Посидел ещё минут 20 с логами и пошёл писать в общий чат "спасити памагити".
Спустя время коллега пишет "сорри аймсорри, это я".
Оказалось вот что у нас было разделение на нод группы. Часть прожорливого перенесли на отдельные нод группы (Trino, AirFlow etc).
По стечению обстоятельств туда, на эту "edge" нод группу, по аффинити прилетел тот кластер Patroni.
Делаем быстро исправление типа такого(это внутренний модуль террагранта)
План, апплай(а что вы мне сделаете?), МР, аппрув, мерж.
Трафик начал ходить между подами внутри нод группы, лаг мгновенно пропадает, проверяем через
Алёрт через минуту окрашивается зеленым
Итог:
- не стоит быть самоуверенным "синёром", если мне белым по чёрному пишут, что нет сетевой связности между подами - ну проверь, блин, дебаг контейнер кто-то отменял? Ну кто виноват, что я селюк и не знал про существование asg rules между подами в одной нод группе AKS, только я сам и виноват.
- девопс это не всегда про пайплайны, иногда это про общение. Надо общаться с коллегами и знать про подобные изменения.
* Да, у нас 99% баз данных в кубере и мы с этим живёмхорошо .
Материал уровень крепкий джун(на который я тут не потянул, лол, самоуверенное овно)
Никого не трогаю, прилетает алёрт.
"Лаг между репликами на Patroni кластере в кубере".
А я дежурный, блин. Ладно.
Сам алёрт вида
- alert: PostgreSQLlaggingbehind
expr: pg_replication_lag_seconds{} > 7200
for: 5m
labels:
severity: warning
annotations:
summary: "PSQLDB `{{ $labels.pod }}`/`{{ $labels.cluster }}`/`{{ $labels.namespace }}` has lag of `{{ $value }}`"
Делаю свич на кластер кубера, NS, вижу поды.
Никаких рестартов, никаких ООМираний.
Лезу внутрь пода, смотрю
patronictl list
0 - мастер, 1 и 2 - реплики. Лаг в 900 мегабайт на каждой реплике.
Пытаюсь сделать реинит для 1 реплики.
patronictl reinit clustername instancename
Впервые в жизни вижу ошибку - нет соединения, спустя минут 15 ретраев всё отваливается питоновскими ошибками.
Ок, пытаюсь повторить со второй репликой, через 15 минут тот же ответ.
Ладно, семь бед - один ресет.
Мастер трогать нельзя, ребутаю POD-ы c репликами.
После рестарта снова попытка реинициализации - таймаут.
Хм. Просто так делать failover с 0 инстанса на 1 или 2 нельзя в данном случае - у нас везде лаг и мы может грохнуть то, что не надо.
Мастер так же не хочется рестартовать, я уже с этой ложки ел.
Окунаемся в логи: да, прям внутри каждого пода смотрю журналы, ошибки, файлики.
Нет ничего. Таймаут. Да как так-то.
Ныряю выше, на уровень кластера: ивенты кубера, состояние нод, на каких нодах данные поды запустились.
Смотрим нетворк полиси и прочие типичные радости кубера. Нет ничего, что мешало бы.
Да все ок, ивенты пустые, все поды патрони кластера с БД на одной нод группе.
Проверял даже наличие свободных IP адресов в кластере AKS. Всё есть.
Посидел ещё минут 20 с логами и пошёл писать в общий чат "спасити памагити".
Спустя время коллега пишет "сорри аймсорри, это я".
Оказалось вот что у нас было разделение на нод группы. Часть прожорливого перенесли на отдельные нод группы (Trino, AirFlow etc).
По стечению обстоятельств туда, на эту "edge" нод группу, по аффинити прилетел тот кластер Patroni.
Делаем быстро исправление типа такого(это внутренний модуль террагранта)
# Allow Security rule in NSG (allows communication between pods on edge node pool)
resource "azurerm_network_security_rule" "edge_asg_allow_pod_to_pod_rule" {
count = local.edge_node_pool_exists ? 1 : 0
name = "allow-pod-to-pod-edge-asg"
priority = 960
direction = "Outbound"
access = "Allow"
protocol = "*"
source_address_prefixes = azurerm_subnet.edge.address_prefixes
source_port_range = "*"
destination_address_prefixes = azurerm_subnet.edge.address_prefixes
destination_port_range = "*"
resource_group_name = "${var.kubernetes_cluster.name}-nrg"
network_security_group_name = data.azurerm_resources.nsg[0].resources.0.name
}
План, апплай(а что вы мне сделаете?), МР, аппрув, мерж.
Трафик начал ходить между подами внутри нод группы, лаг мгновенно пропадает, проверяем через
patronictl list
Алёрт через минуту окрашивается зеленым
resolved.Итог:
- не стоит быть самоуверенным "синёром", если мне белым по чёрному пишут, что нет сетевой связности между подами - ну проверь, блин, дебаг контейнер кто-то отменял? Ну кто виноват, что я селюк и не знал про существование asg rules между подами в одной нод группе AKS, только я сам и виноват.
- девопс это не всегда про пайплайны, иногда это про общение. Надо общаться с коллегами и знать про подобные изменения.
* Да, у нас 99% баз данных в кубере и мы с этим живём
🔥12👍2❤1
#kubernetes #databases #azure #longread
Лонгрид на вечер.
Часть 1 из 4
Раз уж были вопросы, дополню своё мнение про базы в Kubernetes.
Не ради холивара, чисто технический разбор с моим взглядом на вещи.
Всё нижесказанное про базы данных в managed kubernetes (Azure/AWS).
С GCP опыта крайне мало и на него не буду ссылаться.
Мои тезисы строятся так - сама по себе идея "
- баз мало (ну, скажем, меньше 20 суммарно)
- размер их небольшой (допустим до гига)
- ops-команда шарит в бэкапах и ресторах на уровне профессионалов
В случае, когда баз становится больше, и даже команда вроде всё знает, вылезают проблемы, о которых ты раньше и не думал.
Что в AWS, что в Azure - везде свои сюрпризы, особенно неявные.
Ниже я опишу свой личный опыт большого количества баз в облачных куберах.
Зачем мы тащим базы в кубер?
Сделать себе больно? Потренироваться новыми достижениями?
Потетешкать самолюбие и похвастать на конфе?
Галочка в CV? Нет.
Изначально идея держать базы в кубере часто про экономию и удобство менеджмента(через оператора).
Мелкие базы в простое почти не жрут CPU и памяти, и если у вас есть много мелких баз, то на стоимости compute в AKS/EKS можно прилично сэкономить. Очень и очень прилично.
Плюс операторы - автоматизация, управление, всё красиво.
Мы сразу договорились: каждая база живёт в своём кластере.
Это из-за требований аудита и простой логики - чтобы "коммунальные кластеры" не ломали "соседей", если одна база вдруг начнёт жрать ресурсы как не в себя + секьюрити + изоляция.
По три реплики на базу - это не просто так: здравый смысл, богатый опыт с факапами баз и рекомендация по кворуму, чтобы не терять данные и не ловить даунтайм/сплитбрейн(а вот это я зря сказал, сейчас кааак раскритикуете🤣).
Лонгрид на вечер.
Часть 1 из 4
Раз уж были вопросы, дополню своё мнение про базы в Kubernetes.
Не ради холивара, чисто технический разбор с моим взглядом на вещи.
Всё нижесказанное про базы данных в managed kubernetes (Azure/AWS).
С GCP опыта крайне мало и на него не буду ссылаться.
Мои тезисы строятся так - сама по себе идея "
тащить базы в кубер" отличная, но ровно до момента, когда:- баз мало (ну, скажем, меньше 20 суммарно)
- размер их небольшой (допустим до гига)
- ops-команда шарит в бэкапах и ресторах на уровне профессионалов
В случае, когда баз становится больше, и даже команда вроде всё знает, вылезают проблемы, о которых ты раньше и не думал.
Что в AWS, что в Azure - везде свои сюрпризы, особенно неявные.
Ниже я опишу свой личный опыт большого количества баз в облачных куберах.
Зачем мы тащим базы в кубер?
Сделать себе больно? Потренироваться новыми достижениями?
Потетешкать самолюбие и похвастать на конфе?
Галочка в CV? Нет.
Изначально идея держать базы в кубере часто про экономию и удобство менеджмента(через оператора).
Мелкие базы в простое почти не жрут CPU и памяти, и если у вас есть много мелких баз, то на стоимости compute в AKS/EKS можно прилично сэкономить. Очень и очень прилично.
Плюс операторы - автоматизация, управление, всё красиво.
Мы сразу договорились: каждая база живёт в своём кластере.
Это из-за требований аудита и простой логики - чтобы "коммунальные кластеры" не ломали "соседей", если одна база вдруг начнёт жрать ресурсы как не в себя + секьюрити + изоляция.
По три реплики на базу - это не просто так: здравый смысл, богатый опыт с факапами баз и рекомендация по кворуму, чтобы не терять данные и не ловить даунтайм/сплитбрейн(а вот это я зря сказал, сейчас кааак раскритикуете🤣).
👍9
#kubernetes #databases #azure #longread
Часть 2 из 4
Берём пример.
У нас есть AKS-кластер, инстансы
Заливаешь одну среднюю БД, смотришь нагрузочное тестирование - в простое совсем мелкий CPU/memory usage.
Включаешь арифметику с умножением и думаешь "Отлично, сейчас закину кучу баз на пару нод".
Вынужден расстроить, но так у тебя не получится сделать, давай разберёмся почему.
1. Количество дисков
Читаешь доки Azure - максимум 16 диска на наш инстанс. Patroni для HA просит 3 реплики, то есть 3 PV на базу. Считаем: 16 дисков - это 5 изолированных кластеров БД (комплаенс, привет), 1 в запасе или под мелочи.
Поднял 3 кластера по 3 реплики - и всё, приехали, больше некуда.
https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dasv5-series?tabs=sizestorageremote
Думаешь ладно. Денег много, возьму в этом же семействе инстанс дороже и мощнее, но и там ограничение 32 диска(10 кластеров + 2 диска под другие нужны).
2а. Максимальное количество подов на ноде (параметр
В Azure CNI дают до 250 подов на ноду, но по умолчанию нашего инстанса 80.
Считаем: апп с HPA (1 апп + 2 min HPA реплики) + Patroni (3 пода) = 6 подов на микросервис. Минус системные штуки (CNI, CSI, экспортёры, filebeat и так далее) - остаётся где-то 65.
То есть при привычных всем системным ресурсам и 3 репликам на бизнес микросервис апп + 3 реплики кластера БД, мы не сможем поднять больше 10 кластеров(да и не смогли бы, диски раньше нас тормознули бы).
https://learn.microsoft.com/en-us/azure/aks/azure-cni-overlay?tabs=kubectl#maximum-pods-per-node
2б. Резервирование памяти (параметр MAX_PODS)
Временно забудем про первый пункт с дисками и пофантазируем "Сейчас увеличу до 200 макс подс, в конфиге же легко и нам не будет мешать этот параметр".
AKS забирает память под ОС и kubelet: примерно 20 МБ на под + запас + операционная система +hard eviction.
Формула примерно такая, тут не буду топить за точность вычислений, на память пишу
(20 MB × 200(max_pods)) + 50 MB + 100 MB
Из ожидаемых тобой 32 гигабайт на ноде ты получаешь доступным для аллокации будет меньше.
С учётом hard eviction 100mb цифры примерно такие для нашего инстанса:
При
При
При
В попытке уместить не умещаемое ты теряешь драгоценную память на ноде.
Часть 2 из 4
Берём пример.
У нас есть AKS-кластер, инстансы
Standard_D8as_v5 - 8 ядер, 32 ГБ RAM. Заливаешь одну среднюю БД, смотришь нагрузочное тестирование - в простое совсем мелкий CPU/memory usage.
Включаешь арифметику с умножением и думаешь "Отлично, сейчас закину кучу баз на пару нод".
Вынужден расстроить, но так у тебя не получится сделать, давай разберёмся почему.
1. Количество дисков
Читаешь доки Azure - максимум 16 диска на наш инстанс. Patroni для HA просит 3 реплики, то есть 3 PV на базу. Считаем: 16 дисков - это 5 изолированных кластеров БД (комплаенс, привет), 1 в запасе или под мелочи.
Поднял 3 кластера по 3 реплики - и всё, приехали, больше некуда.
https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dasv5-series?tabs=sizestorageremote
Думаешь ладно. Денег много, возьму в этом же семействе инстанс дороже и мощнее, но и там ограничение 32 диска(10 кластеров + 2 диска под другие нужны).
2а. Максимальное количество подов на ноде (параметр
MAX_PODS)В Azure CNI дают до 250 подов на ноду, но по умолчанию нашего инстанса 80.
Считаем: апп с HPA (1 апп + 2 min HPA реплики) + Patroni (3 пода) = 6 подов на микросервис. Минус системные штуки (CNI, CSI, экспортёры, filebeat и так далее) - остаётся где-то 65.
То есть при привычных всем системным ресурсам и 3 репликам на бизнес микросервис апп + 3 реплики кластера БД, мы не сможем поднять больше 10 кластеров(да и не смогли бы, диски раньше нас тормознули бы).
https://learn.microsoft.com/en-us/azure/aks/azure-cni-overlay?tabs=kubectl#maximum-pods-per-node
2б. Резервирование памяти (параметр MAX_PODS)
Временно забудем про первый пункт с дисками и пофантазируем "Сейчас увеличу до 200 макс подс, в конфиге же легко и нам не будет мешать этот параметр".
AKS забирает память под ОС и kubelet: примерно 20 МБ на под + запас + операционная система +hard eviction.
Формула примерно такая, тут не буду топить за точность вычислений, на память пишу
(20 MB × 200(max_pods)) + 50 MB + 100 MB
Из ожидаемых тобой 32 гигабайт на ноде ты получаешь доступным для аллокации будет меньше.
С учётом hard eviction 100mb цифры примерно такие для нашего инстанса:
При
--max-pods=80: ~28.7 GB (28714 MB)При
--max-pods=200: ~26.3 GB (26314 MB)При
--max-pods=250: ~25.3 GB (25314 MB)В попытке уместить не умещаемое ты теряешь драгоценную память на ноде.
👍5
#kubernetes #databases #azure #longread
Часть 3 из 4
3. Сетевой стек
Azure CNI 250 IP на ноду, звучит неплохо. Но неявные проблемы - это отдельная песня. Первое: задержки между репликами. Думаешь, раз в одном кластере, сеть летает, а на деле CNI overlay добавляет 1-5 мс, и для синхронной репликации (типа Patroni) это уже ощутимо. Второе: подсеть кластера. Сотни баз, поды плодятся, и твоя дефолт /24 (256 IP) заканчивается на раз-два, а расширить - рестарт кластера и нервы. Третье: пропускная способность. NIC на ноде (12500 Mb/s) делится на всех, и 200 подов с трафиком - это бутылочное горлышко.
4. Бекапы
Мы разобрались(нет) с первыми болями и дошли до масштабирования.
Подняли dev кластер, развесили taints/toleration, скейлинг нод и подов, задеплоили оператора, на аппы повесили клеймы кластеров/БД, рассчитали, что вам надо, допустим по 4 кластера на ноду. Везде всё умещается.
Время учится делать бекапы. Допустим вы решили пойти путем через velero(а оно чертовски удобное).
Поставили расписание снепшотов, радостно проверили пару баз и ушли домой.
Утром приходите и видите - все запланированные бекапы не сработали. Копаясь в ивентах и логах вы поняли, что не хватило дисков.
с Azure Disk и VolumeSnapshot нюанс: для восстановления из снапшота нужен новый PVC, а дисков и так не хватает. Сами снапшоты PVC не требуют, но при развёртывании - да.
А если расписания в Velero, то без костылей никак: все снепшоты штатно запускаются разом - и по всему кластеру дисков не найти. Пока новые ноды в нужных зонах/регионах запустятся, джоба велеро просто упадёт по таймауту.
Разносишь по времени, ограничиваешь параллельность - выкручиваешься.
Уже на этих аргументах, подкрепленных моей болью, поеданием полной ложки коричневой субстанции я предлагаю завершить монолог "почему много баз в кубере это плохо", но мы идём дальше.
Часть 3 из 4
3. Сетевой стек
Azure CNI 250 IP на ноду, звучит неплохо. Но неявные проблемы - это отдельная песня. Первое: задержки между репликами. Думаешь, раз в одном кластере, сеть летает, а на деле CNI overlay добавляет 1-5 мс, и для синхронной репликации (типа Patroni) это уже ощутимо. Второе: подсеть кластера. Сотни баз, поды плодятся, и твоя дефолт /24 (256 IP) заканчивается на раз-два, а расширить - рестарт кластера и нервы. Третье: пропускная способность. NIC на ноде (12500 Mb/s) делится на всех, и 200 подов с трафиком - это бутылочное горлышко.
4. Бекапы
Мы разобрались(нет) с первыми болями и дошли до масштабирования.
Подняли dev кластер, развесили taints/toleration, скейлинг нод и подов, задеплоили оператора, на аппы повесили клеймы кластеров/БД, рассчитали, что вам надо, допустим по 4 кластера на ноду. Везде всё умещается.
Время учится делать бекапы. Допустим вы решили пойти путем через velero(а оно чертовски удобное).
Поставили расписание снепшотов, радостно проверили пару баз и ушли домой.
Утром приходите и видите - все запланированные бекапы не сработали. Копаясь в ивентах и логах вы поняли, что не хватило дисков.
с Azure Disk и VolumeSnapshot нюанс: для восстановления из снапшота нужен новый PVC, а дисков и так не хватает. Сами снапшоты PVC не требуют, но при развёртывании - да.
А если расписания в Velero, то без костылей никак: все снепшоты штатно запускаются разом - и по всему кластеру дисков не найти. Пока новые ноды в нужных зонах/регионах запустятся, джоба велеро просто упадёт по таймауту.
Разносишь по времени, ограничиваешь параллельность - выкручиваешься.
Уже на этих аргументах, подкрепленных моей болью, поеданием полной ложки коричневой субстанции я предлагаю завершить монолог "почему много баз в кубере это плохо", но мы идём дальше.
😁6👍3
#kubernetes #databases #azure #longread
Часть 4 из 4
5. Операторы и типы баз данных.
"ой, а ты же даже ничего не сказал про типы базы данных(MySQL, PostgreSQL, MongoDB etc), ты ничего не сказал про операторы и разницу между ними, как же так?".
Каждый из операторов, которые я трогал в 2024-2025 годах обладал своими минусами.
Пожалуй отдельно могу отметить только https://cloudnative-pg.io/. Он невероятно чертовски хорош и очень быстро развивается.
Остальные почти все не годятся вам с дефолтными параметрами.
Например zalando оператор по дефолту с выключенной фичей DCS.
https://github.com/zalando/postgres-operator/blob/master/charts/postgres-operator/values.yaml#L454
Это гарантирует вам регулярную проблему с
Почитать вам https://patroni.readthedocs.io/en/master/dcs_failsafe_mode.html
Другой дефолтный параметр вообще превратит ваш кластер в постоянно расползающийся лаг, который будет течь как красотки на концерте Энрике Иглесиаса.
6. IOPS
Потом в процессе эксплуатуации доходит, что IOPS в Azure (и в AWS EKS) от размера диска зависит.
Мелкий диск (допустим 128 ГБ) - 500 IOPS, и для активных баз это ни о чём.
Хочешь больше - бери 512 ГБ (2300 IOPS) или 1 ТБ (5000 IOPS).
База мелкая, а из-за трёх реплик платишь за объём втридорога.
То есть в том случае, если ваш тип базы данных потребляет много IOPS, то вам придётся брать большие скоростные диски, а это уже не так весело и совсем не так дёшево.
"Так каков итог?" - спросите вы. Можно или нельзя пихать БД в managed кубер AKS/EKS?
Мой ответ такой:
- когда много баз - нельзя. Аргументы выше.
- когда базы очень большие(размер, большое потребление ресурсов CPU/Memory) - совершенно нельзя. Аргумент мне не хватило времени написать, может позже накатаю пост. не обещаю, много работы.
- когда OPS команда неквалифицированная. При ресторах будут большие проблемы, а DRP вам не всегда сможет помочь.
Это основные тезисы и рекомендации.
Мы можем сделать фактор репликации 2 или даже 1 реплику, но это уже не про HA.
Мы можем сделать 1 кластер на все базы, но это уже не про изоляцию и безопасность.
Выбор за каждым.
Update:
Апдейтнул пост, добавив, что рекомендации только для AKS/EKS.
Ничего не смогу сказать за других облачных провайдеров, у меня нет этого опыта.
Там могут не быть этих корнер кейсов(но могут быть другие).
Ничего не могу сказать за managed k8s, меня вселенная бережёт от работы с ними.
Часть 4 из 4
5. Операторы и типы баз данных.
"ой, а ты же даже ничего не сказал про типы базы данных(MySQL, PostgreSQL, MongoDB etc), ты ничего не сказал про операторы и разницу между ними, как же так?".
Каждый из операторов, которые я трогал в 2024-2025 годах обладал своими минусами.
Пожалуй отдельно могу отметить только https://cloudnative-pg.io/. Он невероятно чертовски хорош и очень быстро развивается.
Остальные почти все не годятся вам с дефолтными параметрами.
Например zalando оператор по дефолту с выключенной фичей DCS.
https://github.com/zalando/postgres-operator/blob/master/charts/postgres-operator/values.yaml#L454
Это гарантирует вам регулярную проблему с
demoting self because DCS is not accessible and I was a leader и тем, что аппликейшны не смогут подключаться к кластеру (помогает рестарт аппликейшна, как ни странно).Почитать вам https://patroni.readthedocs.io/en/master/dcs_failsafe_mode.html
Другой дефолтный параметр вообще превратит ваш кластер в постоянно расползающийся лаг, который будет течь как красотки на концерте Энрике Иглесиаса.
6. IOPS
Потом в процессе эксплуатуации доходит, что IOPS в Azure (и в AWS EKS) от размера диска зависит.
Мелкий диск (допустим 128 ГБ) - 500 IOPS, и для активных баз это ни о чём.
Хочешь больше - бери 512 ГБ (2300 IOPS) или 1 ТБ (5000 IOPS).
База мелкая, а из-за трёх реплик платишь за объём втридорога.
То есть в том случае, если ваш тип базы данных потребляет много IOPS, то вам придётся брать большие скоростные диски, а это уже не так весело и совсем не так дёшево.
"Так каков итог?" - спросите вы. Можно или нельзя пихать БД в managed кубер AKS/EKS?
Мой ответ такой:
- когда много баз - нельзя. Аргументы выше.
- когда базы очень большие(размер, большое потребление ресурсов CPU/Memory) - совершенно нельзя. Аргумент мне не хватило времени написать, может позже накатаю пост. не обещаю, много работы.
- когда OPS команда неквалифицированная. При ресторах будут большие проблемы, а DRP вам не всегда сможет помочь.
Это основные тезисы и рекомендации.
Мы можем сделать фактор репликации 2 или даже 1 реплику, но это уже не про HA.
Мы можем сделать 1 кластер на все базы, но это уже не про изоляцию и безопасность.
Выбор за каждым.
Update:
Апдейтнул пост, добавив, что рекомендации только для AKS/EKS.
Ничего не смогу сказать за других облачных провайдеров, у меня нет этого опыта.
Там могут не быть этих корнер кейсов(но могут быть другие).
Ничего не могу сказать за managed k8s, меня вселенная бережёт от работы с ними.
👍11
Forwarded from Alexandr Kruchkov
Коллеги со связкой Azure AKS/ AWS EKS + ArgoCD.
У кого-то после последних апдейтов(просмто смена версии, автосесурити апдейт) поломал ли чего в кластере при взаимодействии ArgoCD -> k8s API?
Дикий бурст насилия.
Если кто сталкивался и решил - напишите плиз.
Всем любопытным: я искал на гитхабе, писал в саппорт, гуглил, смотрел на реддите, читал ивенты, смотрел логи и контроллера и аппликейшнсета, менял конфиги и джиттер и реконселейшн, и многое другое.
Или киданите киворд, если где-то рядом нашли решение.
У кого-то после последних апдейтов(просмто смена версии, автосесурити апдейт) поломал ли чего в кластере при взаимодействии ArgoCD -> k8s API?
Дикий бурст насилия.
Если кто сталкивался и решил - напишите плиз.
Всем любопытным: я искал на гитхабе, писал в саппорт, гуглил, смотрел на реддите, читал ивенты, смотрел логи и контроллера и аппликейшнсета, менял конфиги и джиттер и реконселейшн, и многое другое.
Или киданите киворд, если где-то рядом нашли решение.
👍2
Forwarded from Alexandr Kruchkov
Alexandr Kruchkov
Коллеги со связкой Azure AKS/ AWS EKS + ArgoCD. У кого-то после последних апдейтов(просмто смена версии, автосесурити апдейт) поломал ли чего в кластере при взаимодействии ArgoCD -> k8s API? Дикий бурст насилия. Если кто сталкивался и решил - напишите плиз.…
ТЛДР: ажур конченные спидораковые ублюдки свинособачьих шлюх.
После автоматического и не отключаемого обновления AKS в API-сервере появился строгий рейт-лимит, которого раньше либо не было, либо он был мягче. Это вызвало неожиданный эффект: ArgoCD стал чаще дёргать апи и это вызвало нагрузку на API до 40-80 тысяч RPS на каждом из кластеров, увеличив латентность и количество запросов.
Отключение контроллеров Argo не сразу спасло ситуацию - нагрузка держалась из-за накопившейся очереди.
Даже базовые операции (GET, PUT, PATCH) застревали, уходя в retry, а метрики показывали код 409 (Conflict) из-за одновременных попыток обновить ресурсы.
Admission-контроллеры тоже вставали в очередь, усугубляя хаос.
воркэраундсолюшн: отключить ArgoCD/Kyverno, вебхуки и другие активные компоненты, пока нагрузка не упадёт до 30–50 RPS. После этого можно постепенно включать их обратно - ArgoCD зальёт кучу watch-запросов, GET-ов и патчей для синхронизации(чего он там сперва пушит в апиху) и кластер стабилизируется.
Если же Argo и/или киверно не выключать, он уходит в бесконечный retry storm, перегрузка API сохраняется, а метрики с пикамиточёными ошибок 409.
Дольше всего ушло времени на трублшутинг, из-за моей тупости не было сразу понимания, что при вырубании просто арго/киверно и других говн, ещё и хуки ж насильничают апи и надо ещёёёёё время, чтобы всё рассосалось.
После автоматического и не отключаемого обновления AKS в API-сервере появился строгий рейт-лимит, которого раньше либо не было, либо он был мягче. Это вызвало неожиданный эффект: ArgoCD стал чаще дёргать апи и это вызвало нагрузку на API до 40-80 тысяч RPS на каждом из кластеров, увеличив латентность и количество запросов.
Отключение контроллеров Argo не сразу спасло ситуацию - нагрузка держалась из-за накопившейся очереди.
Даже базовые операции (GET, PUT, PATCH) застревали, уходя в retry, а метрики показывали код 409 (Conflict) из-за одновременных попыток обновить ресурсы.
Admission-контроллеры тоже вставали в очередь, усугубляя хаос.
воркэраундсолюшн: отключить ArgoCD/Kyverno, вебхуки и другие активные компоненты, пока нагрузка не упадёт до 30–50 RPS. После этого можно постепенно включать их обратно - ArgoCD зальёт кучу watch-запросов, GET-ов и патчей для синхронизации(чего он там сперва пушит в апиху) и кластер стабилизируется.
Если же Argo и/или киверно не выключать, он уходит в бесконечный retry storm, перегрузка API сохраняется, а метрики с пиками
Дольше всего ушло времени на трублшутинг, из-за моей тупости не было сразу понимания, что при вырубании просто арго/киверно и других говн, ещё и хуки ж насильничают апи и надо ещёёёёё время, чтобы всё рассосалось.
😁9🤯5👏1🌚1😎1
#aws #eks #kubernetes
Задача уровня
Ну вот подключил ты Karpenter/Cluster Autoscaler + SPOT инстансы через разные node group.
Всё даже работает, ты проверяешь в EKS web консоли.
Задача: как быстро и удобно понять когда/сколько у тебя
Для аналитики использования и вообще для удобства.
Перебираешь все метрики и не видишь ничего сходу.
А сходу их и нет. (а, ну или мне сейчас накидают горелых пирожков с гусятками в мою печурку в комментариях)
Прометей/VM не знает ничего про споты или не споты.
А давайте мы сделаем всё сами.
Сперва в наших существующих нод группах вешаем лейблы
Задеплоили, проверяем, есть ли лейблы
Видим свои лейблы:
-
- - spot
- - on-demand
Ок, лейбл повесили, теперь ноды с разных нод-групп имеют лейбл, по которому мы определяем кто есть кто.
А что же дальше?
Дальше нам нужно научить "какой-то" компонент обсервабилити кубернетиса собирать его.
У нас есть метрика с именем
Компонент
Смотрим в прометиусе/ВМ - метрика есть, но наших новых лейблов нет.
Как бы вы его не ставили, добавьте в его конфиг такой параметр
Тем самым, мы разрешаем обогащать метрику новыми лейблами из списка.
* Звездочку писать не рекомендую - этим вы лишь будете занимать сильно больше лишнего места в хранилище прометиуса/викиторииметрикс.
Применяем, смотрим в графане - красота(скриншот).
Результат: пару простых движений и у нас есть график в графане сколько каких нод у нас было в нужный момент времени.
Видим график и понимаем "ага, нам есть над чем работать, надо сделать тюнинг спот инстансов больше, чем он деманд, чтобы платить меньше", но об этом мы поговорим в следующий раз.
* параметр extraArgs может отличаться синтаксисом вашего чарта, читайте документацию по тому способу, как вы ставили куб стейт метрикс.
Задача уровня
junior+/middle-
Ну вот подключил ты Karpenter/Cluster Autoscaler + SPOT инстансы через разные node group.
Всё даже работает, ты проверяешь в EKS web консоли.
Задача: как быстро и удобно понять когда/сколько у тебя
on-demand нод, а когда spot нод?Для аналитики использования и вообще для удобства.
Перебираешь все метрики и не видишь ничего сходу.
А сходу их и нет.
Прометей/VM не знает ничего про споты или не споты.
А давайте мы сделаем всё сами.
Сперва в наших существующих нод группах вешаем лейблы
resource "aws_eks_node_group" "on-demand-group" {
...
labels = {
"node-type" = "on-demand"
...
}
...
}
resource "aws_eks_node_group" "spot-group" {
...
labels = {
"node-type" = "spot"
...
}
...
}Задеплоили, проверяем, есть ли лейблы
kubectl get nodes -L node-role,node-type
NAME STATUS ROLES AGE VERSION NODE-ROLE NODE-TYPE
ip-10-1-123-114.ec2.internal Ready <none> 70d v1.31.4-eks-aeac579 infrastructure on-demand
ip-10-1-14-194.ec2.internal Ready <none> 42m v1.31.6-eks-aad632c applications on-demand
ip-10-1-24-165.ec2.internal Ready <none> 52s v1.31.6-eks-aad632c applications spot
Видим свои лейблы:
-
NODE-TYPE, тип ноды - нам нужно как раз это- - spot
- - on-demand
Ок, лейбл повесили, теперь ноды с разных нод-групп имеют лейбл, по которому мы определяем кто есть кто.
А что же дальше?
Дальше нам нужно научить "какой-то" компонент обсервабилити кубернетиса собирать его.
У нас есть метрика с именем
kube_node_labels от компонента kube-state-metricsКомпонент
kube-state-metrics вы можете ставить разными способами: от оператора, отдельный манифест, стак набор, да не важно.Смотрим в прометиусе/ВМ - метрика есть, но наших новых лейблов нет.
Как бы вы его не ставили, добавьте в его конфиг такой параметр
kube-state-metrics:
...
extraArgs:
- --metric-labels-allowlist=nodes=[node-type,node-role]
Тем самым, мы разрешаем обогащать метрику новыми лейблами из списка.
* Звездочку писать не рекомендую - этим вы лишь будете занимать сильно больше лишнего места в хранилище прометиуса/викиторииметрикс.
Применяем, смотрим в графане - красота(скриншот).
sum(kube_node_labels) by (label_node_type)
Результат: пару простых движений и у нас есть график в графане сколько каких нод у нас было в нужный момент времени.
Видим график и понимаем "ага, нам есть над чем работать, надо сделать тюнинг спот инстансов больше, чем он деманд, чтобы платить меньше", но об этом мы поговорим в следующий раз.
* параметр extraArgs может отличаться синтаксисом вашего чарта, читайте документацию по тому способу, как вы ставили куб стейт метрикс.
👍11👏1