WeDoOps
43 subscribers
1 photo
8 links
Блог уставшего DevOps-инженера 💻

Это мой цифровой дневник. Сюда пишу о работе, автоматизации, облаках и о том, как не сойти с ума от YAML. Делюсь личным опытом, шишками и найденными граблями.
Download Telegram
Привет! Сегодня поговорим о том, как искать проблемы с PersistentVolumes (PV) и PersistentVolumeClaims (PVC) в Kubernetes, когда за ними стоит Ceph (Rook, ODF и т.п.). Тема объёмная, поэтому разобьём её на несколько постов)

🧭 Часть 1. С чего начинать диагностику?

Прежде чем лезть в дебри Ceph, всегда проверяем то, что видно глазами в Kubernetes.

❗️ Смотрим события пода
Если под не стартует:
kubectl describe pod <problem-pod>

В секции Events ищем FailedMount или FailedAttachVolume. Это даст первую зацепку.

❗️ Статус PVC
kubectl get pvc -n <namespace>
kubectl describe pvc <pvc-name>

PVC должен быть Bound. Если висит в Pending — проблема либо в StorageClass, либо в работе CSI-драйвера.

❗️ Логи CSI-драйверов (живут в namespace Rook, обычно `rook-ceph`)
Нас интересуют:
- Provisioner (создание/удаление томов):
csi-cephfsplugin-provisioner-* или csi-rbdplugin-provisioner-*
- Node plugin (монтирование на узлах):
csi-cephfsplugin-* или csi-rbdplugin-*

Просмотр логов провайдера:
kubectl -n rook-ceph logs -l app=csi-rbdplugin-provisioner --tail=50



💡 Вывод: прежде чем грешить на Ceph, убедись, что ошибка не на уровне Kubernetes или CSI.
В следующем посте разберём конкретные проблемы CephFS (RWX).

#k8s #ceph #pvc #troubleshooting #rook
👍21🔥1
🧭 Часть 2. Типовые проблемы CephFS (ReadWriteMany)

⚠️ Ошибка: mount error: no mds is up
Симптом: В логах пода видим, что нет доступного Metadata Server (MDS).
Причина: Либо MDS действительно не работают, либо клиент (kubelet) не может до них достучаться (сеть, авторизация).

Диагностика:
1. Заходим в тулбокс Rook:
   kubectl -n rook-ceph exec -it deploy/rook-ceph-tools -- bash

2. Проверяем статус Ceph:
   ceph status

Ищем строчку mds: 1/1 daemons up (или больше). Если MDS не встали — проблема в развёртывании Rook.
3. Проверяем права клиента:
   ceph auth ls | grep client.csi-cephfs-node

Должен быть allow rw для CephFS.

Решение:
- Если MDS не стартуют — проверяем ресурсы (CPU/RAM) на нодах MDS.
- В новых версиях Ceph (Squid+) может потребоваться параметр монтирования ms_mode: legacy в StorageClass или в CRD кластера Rook (если версии клиента и сервера не совпадают).

⚠️ Ошибка: NodeResizeError: failed to expand pvc with NodeExpand is not supported
Симптом: PVC расширили, размер в get pvc обновился, но висит эта ошибка.
Причина: Драйвер CephFS не поддерживает расширение файловой системы на узле (NodeExpandVolume), только на стороне хранилища. Ошибка часто косметическая — том работает с новым размером.

Решение: Убедитесь, что в kube-controller-manager включён --feature-gates=RecoverVolumeExpansionFailure=true. Ошибка может игнорироваться, если данные пишутся нормально.


➡️ В следующей части разберём проблемы с RBD (RWO): зависшие блокировки, multi-attach и шифрование.

#k8s #cephfs #pvc #troubleshooting
1👍1🔥1
🧭 Часть 3. Типовые проблемы RBD (ReadWriteOnce)

⚠️ Ошибка: rbd image <pool>/<image> is still being used
Симптом: Под не может смонтировать PVC после пересоздания.
Причина: Старый watcher (клиент Ceph) не отдал диск, образ считается занятым.

Диагностика и решение:
1. В тулбоксе Rook смотрим watcher'ов образа:
   rbd status <pool-name>/csi-vol-<volume-id>

Увидим IP-адрес "зависшего" клиента.
2. Самый простой способ разблокировки — перезапустить CSI node plugin на проблемном узле.
Можно также перезагрузить сам узел (если возможно).
3. Если не помогло, можно сбросить блокировку вручную через rbd lock list и rbd lock remove, но осторожно!

⚠️ Multi-Attach error для статических PV
Симптом: Два статических PV, ссылающихся на RBD-образы с одинаковым именем в разных пулах, конфликтуют. Второй под не стартует с ошибкой Multi-Attach error.

Причина: Kubernetes/CSI генерирует volumeHandle на основе имени образа. Если имена совпадают, система думает, что это один и тот же том.

Решение: При создании статического PV обязательно делайте volumeHandle уникальным, например, <pool-name>-<image-name>.

⚠️ Проблемы с шифрованием и OMAP
Редкие ошибки вида internal state inconsistent, omap names mismatch или cannot create encrypted volume from unencrypted volume.
Лечатся проверкой RBAC у CSI-провайдера и, в крайнем случае, ручной зачисткой OMAP-объектов (только для опытных!).


➡️ В следующей части поговорим о сетевых блокировках (blocklist) и дадим универсальный чек-лист.

#k8s #rbd #pvc #troubleshooting
🧭 Часть 4. Сетевые проблемы и чек-лист

⚠️ Blocklist
Симптом: PVC на RBD внезапно становятся ReadOnly, поды в CreateContainerError, в мониторинге видны заблокированные клиенты.
Причина: Ceph забанил клиента за некорректное поведение (например, проблемы сети на узле).

Диагностика:
ceph osd blocklist ls


Решение:
- Перезагрузить проблемный узел — блокировка снимется автоматически.
- Если нужно срочно, можно вручную удалить запись из blocklist, но это временно.


Универсальный чек-лист при проблемах с Ceph PVC

1. Kubernetes уровень
- kubectl describe pod – ищем ошибки монтирования.
- kubectl describe pvc – статус биндинга и события.

2. CSI уровень
- Логи csi-*plugin-provisioner – ошибки создания томов (RBAC, OMAP).
- Логи csi-*plugin (на узле) – ошибки монтирования.

3. Ceph уровень (через toolbox)
- ceph status – здоровье кластера, состояние MDS/MGR/OSD.
- ceph fs status – активность файловых систем.
- rbd status <image> – наблюдатели за RBD-образом.
- ceph osd blocklist ls – не забанен ли узел.

4. Нюансы
- Совместимость версий Ceph и CSI (ms_mode).
- Feature gates в Kubernetes (например, RecoverVolumeExpansionFailure).


📌 Главное: Ceph в Kubernetes — мощная, но сложная система. Всегда начинайте с верха (Kubernetes) и постепенно спускайтесь вглубь (Ceph). И помните: если том не монтируется, проверьте, не "висит" ли где-то старый клиент.


#k8s #ceph #pvc #troubleshooting
1👍1🔥1
⚙️ Движки сборки образов в 2025–2026: разбор

Сборка контейнеров — сердце любого CI/CD. Но чем именно собирать образы сегодня, когда ландшафт инструментов сильно изменился?

Разбираем все актуальные движки: от ветерана Docker BuildKit до новичка Kimia, который пришёл на смену «умершему» Kaniko. Сохраняйте, чтобы не потерять! 👇


🧱 Как это работает

Образ состоит из слоёв. Каждая команда в Dockerfile — новый слой.
- Кэш ускоряет сборку, переиспользуя неизменные слои.
- Современные движки строят граф зависимостей и выполняют этапы параллельно.


🛠 Основные игроки

🐳 Docker BuildKit
Стандарт де-факто. Встроен в Docker. Умеет параллелить независимые стадии, умно кэшировать в S3/Registry, монтировать секреты без сохранения в слоях и собирать multi-arch образы.
👉 *Выбор для большинства команд.*

🦭 Buildah
Инструмент от Red Hat. Работает без демона Docker. Полный rootless из коробки. Тесно дружит с Podman. Отлично подходит для строгих security-политик.
👉 *Максимальная безопасность без компромиссов.*

📦 Podman
Полная замена Docker CLI, но без демона. Для сборки под капотом использует код Buildah.
👉 *Если хочется Docker, но безопаснее.*

☁️ Kaniko (⚠️ Архив)
Google-инструмент для сборки в Kubernetes без демона и root-прав. Важно: проект переведён в архив в июне 2025. Для новых проектов использовать не рекомендуется.
👉 *Пора мигрировать на аналоги.*

🔥 Kimia (НОВИНКА)
Прямая замена Kaniko. Разработан как Kubernetes-native и 100% совместимый по аргументам с Kaniko. Фишка: под капотом использует либо BuildKit, либо Buildah. Обеспечивает полный rootless, сокращает поверхность атаки на 90% и умеет подписывать образы (Cosign).
👉 *Лучший выбор для безопасных сборок в K8s прямо сейчас.*

☕️ Jib
Специалист по Java (Maven/Gradle). Не требует Dockerfile. Сам раскладывает приложение по слоям (зависимости, ресурсы, классы) для супер-быстрых повторных сборок.
👉 *Мастхэв для Java-микросервисов.*

🧩 Cloud Native Buildpacks (CNB)
Сборка из исходников без Dockerfile. Buildpack сам определит язык и соберёт образ по best practices.
👉 *Идеально для платформенных команд, чтобы стандартизировать сборки.*

🧪 Другие
- Makisu (от Uber) — нишевый, почти не развивается.
- Bazel — мощно для монореп, но сложный порог входа.
- werf — CI/CD комбайн на базе Buildah.


💡 Лучшие практики (вне зависимости от движка)

1️⃣ Многоэтапная сборка: собираем в «жирном» образе, копируем только бинарник в минимальный alpine или scratch.
2️⃣ Порядок слоёв: сначала копируем файлы с зависимостями (package.json), потом ставим пакеты, и только в конце — код.
3️⃣ Секреты: никогда не через ENV. Используйте --mount=type=secret.
4️⃣ Безопасность: запускайте контейнер от USER 1000 и сканируйте образы Trivy/Grype.


🚀 Будущее

- BuildKit — король производительности.
- Kaniko уходит в прошлое, его место занимает Kimia.
- Rootless-сборки становятся обязательным стандартом безопасности.
- Все больше команд переходят на CNB, забывая о ручном написании Dockerfile.
1👏1🤔1
🚀 Cilium CNI и Cluster Mesh: единая сеть для всех ваших кластеров

Современный Kubernetes — это часто зоопарк из десятков кластеров. Как заставить их работать как единое целое, не теряя в скорости и безопасности? Ответ — Cilium и его режим Cluster Mesh.

⚡️ Что такое Cilium и при чём тут eBPF?

Cilium — это не просто сетевой плагин. Он основан на eBPF — технологии, которая запускает ваш сетевой код прямо в ядре Linux.

Результат:
* Пропускная способность значительно выше, чем у решений на базе iptables.
* Значительно меньшие задержки по сравнению с традиционными CNI.
* Полноценная замена kube-proxy без потери производительности.
* Глубокая наблюдаемость через Hubble.

🛡 Безопасность на уровнях L3–L7

Cilium понимает не только IP и порты, но и протоколы прикладного уровня: HTTP, Kafka, gRPC, DNS и другие. Можно написать политику: «фронтенду можно GET /api, но только если он из namespace production». И всё это без sidecar-прокси.

🌍 Cluster Mesh: когда один кластер — мало

Cluster Mesh связывает несколько независимых Kubernetes-кластеров в единую сеть. Поды из кластера А могут обращаться к подам в кластере Б так, будто они в одном пространстве имен.

Ключевые сценарии использования:
* Геораспределённые и высокодоступные сервисы
* Разделение stateful / stateless
* Общие сервисы (мониторинг, секреты) для всех команд

🧩 Как это работает

* В каждом кластере разворачивается компонент clustermesh-apiserver. Он отслеживает состояние локального кластера (сервисы, поды, идентификаторы) и синхронизирует его с общим etcd-хранилищем.
* Агенты Cilium на всех узлах читают это хранилище и программируют eBPF-маршруты напрямую к удалённым подам.
* Никаких дополнительных прокси или шлюзов — чистый pod-to-pod через туннели (VXLAN/Geneve) или нативную маршрутизацию.

💡 Ключевые возможности Cluster Mesh

Глобальные сервисы (Global Services): Один и тот же сервис, распределённый по всем кластерам. Балансировка нагрузки и автоматический фейловер «из коробки»:
metadata:
annotations:
service.cilium.io/global: "true"

Для этого сервис с одинаковыми именем и пространством имен должен быть создан во всех кластерах mesh-сети.

Сетевые политики на весь Mesh: Запрещаем доступ из кластера 3 к бекенду в кластере 1. Политики CiliumNetworkPolicy работают глобально, опираясь на криптографические идентификаторы, а не на IP-адреса.

Прозрачное шифрование (Transparent Encryption): Включается одной опцией, и весь трафик между узлами в разных ЦОД защищается с помощью IPsec или WireGuard.

Hubble обеспечивает наблюдаемость не только внутри одного, но и между несколькими кластерами в Cluster Mesh.

⚙️ Быстрый старт за 5 минут

1. Устанавливаем Cilium на каждом кластере с уникальными cluster-name и cluster-id и непересекающимися PodCIDR:
    cilium install \
--cluster-name eu-cluster \
--cluster-id 1 \
--kube-proxy-replacement strict

*Важно: Режим передачи данных (инкапсуляция или нативная маршрутизация) должен быть одинаковым на всех кластерах*.

2. Включаем Cluster Mesh на каждом из кластеров:
    cilium clustermesh enable


3. Соединяем кластеры:
    cilium clustermesh connect \
--context eu-cluster \
--destination-context us-cluster


📊 Cilium vs. Istio/Linkerd

Cilium — это подход без sidecar-контейнеров (sidecar-less). В отличие от Istio или Linkerd, которые внедряют дополнительный прокси-контейнер в каждый под, Cilium обрабатывает трафик на уровне ядра. Это даёт лучшую производительность и меньшее потребление ресурсов, особенно в крупных масштабах. При этом Cilium легко интегрируется с классическими Service Mesh, обеспечивая многоуровневую защиту.

🏁 Вывод

Связка Cilium + Cluster Mesh — это одна из самых производительных и безопасных альтернатив для построения мультикластерного Kubernetes. Без sidecar-контейнеров, с «плоской» сетью и сквозными политиками безопасности. Если вы ещё думаете, как объединить свои кластеры — попробуйте, оно того стоит.

Больше деталей и туториалов — на официальном сайте [cilium.io](https://cilium.io)

#kubernetes #cilium #ebpf #devops #networking
🔥1
🌍 Мультикластер и геораспределёнка: не просто «серверы в разных странах»

Современные сервисы должны работать быстро отовсюду и не падать при отказе целого дата-центра. Но поставить железо в нескольких локациях — лишь первый шаг. Разбираемся, чем отличается мультикластерная архитектура от настоящей геораспределёнки, и какие практики спасают от ночных кошмаров дежурных инженеров.

⚖️ Два понятия, которые часто путают
Мультикластер — несколько независимых кластеров (K8s, базы) под единым управлением. Они могут быть хоть в одной комнате. Задача: изоляция сред, отказоустойчивость, разделение тенантов.
Геораспределённая система — кластеры разнесены на сотни/тысячи км, но решают одну бизнес-задачу как единое целое. На первый план выходят физика сети: задержки, джиттер, партиции.

Реальность — гибрид: географически удалённые площадки, внутри каждой — своя мультикластерная логика.

📌 Три главных архитектурных лекала

1️⃣ Active-Passive
Трафик льётся в один регион, второй в резерве. Просто, но RTO — минуты, часть данных может потеряться. Подходит для начала.

2️⃣ Active-Active
Оба региона работают одновременно. Пользователь из Азии летит в Сингапур, из Европы — во Франкфурт. Требует multi-master БД, разрешения конфликтов (CRDT, Last-Writer-Wins). Почти всегда теряем строгую согласованность ради доступности.

3️⃣ Гео-шардирование
Пользователь «прибит» к своему региону по ID. Домен отказа локален, но кросс-региональные запросы редки и медленны.

⚙️ Практики, оплаченные инцидентами

🔹 Проектируйте под разрывы сети
Сетевая партиция — норма. Каждый межкластерный вызов: таймауты, circuit breaker, деградация. Если соседний сервис не отвечает, продолжаем работать на локальных данных, а не падаем с 500-й ошибкой.

🔹 Состояние — отдельная песня
Старайтесь делать сервисы stateless. Если без распределённых данных никак:
- Асинхронная репликация (PostgreSQL/MySQL) — просто, но смиритесь с возможной потерей последних транзакций.
- Распределённые SQL и NoSQL (CockroachDB, YugabyteDB, Cassandra) — консистентность ценой латентности на запись. Лидеров партиций размещайте рядом с сервисами.
- Объектное хранилище (S3/MinIO) — простейший способ раздать статику глобально.

🔹 Единая наблюдаемость без лавины алертов
Метрики, логи, трейсы — в одну платформу (Grafana Mimir, Loki, Tempo). Алертинг сделайте кластерно-осведомлённым: инцидент в одном регионе не должен взрывать уведомления на дежурном пульте.

🔹 GitOps и канареечные выкатки
Всю конфигурацию — в Git. Развёртываете сначала стейджинг, потом наименее нагруженный продакшен-кластер, проверяете метрики, и только затем катите на остальные. Инструменты: Argo CD, Flux, Kustomize.

🔹 Умный вход пользователя
Сочетайте Anycast, Latency-based DNS и Ingress с GeoIP. При падении региона не ждите протухания DNS — рулите трафиком через HTTP-редирект или мгновенный отвод BGP-маршрута.

🔹 Регулярный «день хаоса»
Ручное переключение по чек-листу раз в год — гарантия фейла в реальной аварии. Отключайте целый регион посреди спринта и смотрите, как система сама восстанавливается. Автоматизируйте failover и тестируйте его в CI/CD.

🔹 Безопасность без иллюзий
Никакого доверия по IP-подсетям. Взаимный TLS между сервисами через Service Mesh (Istio, Consul Connect) — обязательно. Единый IAM должен быть отказоустойчив: OIDC-провайдеры с локальными кешами, чтобы разрыв с центром аутентификации не парализовал все кластеры разом.

💎 Итог
Глобальная инфраструктура — всегда компромисс между доступностью, согласованностью и сложностью. Не гонитесь за хайпом multi-master, если можно начать с асинхронной репликации и stateless-сервисов. Сначала добейтесь идеального восстановления резерва, а потом уже выходите в Active-Active. Тогда ваша геораспределёнка будет активом, а не постоянным источником боли.
🏗 Архитектура несокрушимых: строим отказоустойчивый High-Load

За годы работы я вывел аксиому: в высоконагруженных системах «отказоустойчивость» — не фича, а базовая спецификация. Её нельзя прикрутить поверх монолита. Она закладывается на уровне архитектуры, культуры и автоматизации.
Поговорим о фундаменте — принципах, на которых держатся системы, способные терять дата-центры, но не пользователей.

⚙️ 4 принципа, без которых не взлетит:

1️⃣ Design for Failure
Мы перестаём верить в «надёжное железо». Пишем код и строим инфраструктуру, ожидая, что любой компонент откажет в любой момент. Если приложение не переживает принудительное убийство инстанса (Chaos Engineering) — оно не готово к проду.

2️⃣ Никаких единых точек отказа (SPOF)
Балансировщик, мастер БД, очередь сообщений — всё должно иметь горячее резервирование. Active-active или active-passive с мгновенной промоцией.

3️⃣ Деградация вместо отказа
Если сервис рекомендаций лёг, система не имеет права отвечать 500-кой. Фронт уходит в read-only, но не падает. Реализуется через Circuit Breaker и Bulkhead.

4️⃣ Идемпотентность как стандарт
В асинхронном мире с ретраями одна команда может выполниться дважды. Списание денег или создание заказа обязано быть идемпотентным. Иначе «отказоустойчивость» превращается в «финансовую дыру».

🔜 В следующем посте — архитектурные паттерны выживания: балансировка, кэши, очереди.

#DevOps #HighLoad #архитектура #SRE
🧩 Паттерны выживания под High-Load

Принципы без реализации — просто лозунги. Переходим к железобетонным техническим решениям.

1. Балансировка нагрузки с умом
L7-балансировщик (или Service Mesh вроде Istio) должен не просто «кидать трафик». Его обязанности:
— Health checks на эндпоинтах готовности (ready probe).
— Circuit Breaking: если микросервис стал тормозить, временно отключаем трафик, предотвращая каскадный сбой.
— Canary deployments: плавная раскатка по весам, чтобы багнутая версия не убила весь кластер.

2. Разделение по слоям с изоляцией пулов
Медленный запрос в БД не имеет права занять все потоки веб-сервера. Используем Bulkheads — изолированные thread pools под статику, API, админку. Tomcat/Jetty это умеют, надо только настроить.

3. Многоуровневое кэширование
«Кэшируй всё» близко к истине. Но уровни обязательны:
— Клиентский (браузер/CDN): Cache-Control, ETag.
— Серверный (Redis/Memcached): с прогревом и защитой от cache stampede (блокировки или вероятностная ревалидация).
— Локальный in-memory (Caffeine): спасает от сетевых вызовов, но требует инвалидации через шину.

4. Асинхронность и очереди
Синхронная запись в БД на пике — убийца. Пользовательский запрос падает в быструю и долговечную очередь (Kafka/NATS), а обработчик разгребает в своём темпе. Это даёт буфер, спасающий от краша при flash sale.

🔜 Следующая остановка — управление данными: шардирование, CQRS, multi-region.

#архитектура #микросервисы #кэширование #HighLoad
💾 Управление данными под нагрузкой: шардирование и не только

База данных — главная боль High-Load. Горизонтальное масштабирование — единственный путь.

1. Стратегия шардирования
Забудьте об автоинкременте. Ключи должны быть равномерно размазаны, чтобы не создавать «горячих шардов». Идеальный выбор — UUID или Snowflake ID. Маршрутизация — через ProxySQL, Vitess или умный драйвер на клиенте.

2. CQRS — разделение записи и чтения
Запись и чтение конфликтуют за ресурсы. CQRS предлагает:
— Строгая консистентность на мастере.
— Денормализованные представления для чтения на репликах или Elasticsearch.
Получаем eventual consistency, допустимую в большинстве бизнес-сценариев при правильном UI.

3. Глобальное распределение (Multi-Region)
Система с пользователями по всему миру должна быть активна в нескольких ДЦ.
— GeoDNS направляет в ближайший регион.
— Данные реплицируются через CockroachDB, Yugabyte или CDC.
— Конфликты записи разруливаются на бизнес-уровне: CRDT, векторы версий.
Без такой архитектуры вы упрётесь в потолок очень быстро.

🔜 Дальше — инфраструктурная обвязка: Kubernetes, IaC, наблюдаемость.

#базыданных #шардирование #CQRS #SRE
⚙️ Инфраструктура как код, оркестрация и наблюдаемость

Архитектура на бумаге мертва без правильной операционки.

1. Инфраструктура как Код и Immutable Infrastructure
Никакого ручного SSH. Terraform/Pulumi описывают всё, от VPC до правил автомасштабирования. Образы — Packer, контейнеры — Docker. Изменения — только через замену инстанса. Дрифт конфигурации исключён, rollback мгновенный.

2. Оркестрация и самовосстановление
Kubernetes — стандарт. Его главная задача — следить за желаемым состоянием. Упал Pod? Контроллер запустит новый. Упала нода? Поды переедут. Но Liveness и Readiness пробы — это святое: если Readiness смотрит на соединение с БД, а БД лежит, трафик в этот под не пойдёт.

3. Наблюдаемость — три столпа
Без неё управлять отказоустойчивостью можно только молитвами.
— Метрики (Prometheus): Золотые сигналы — Latency, Traffic, Errors, Saturation. Смотрим на 95-й и 99-й перцентили, а не среднее.
— Трассировка (Jaeger): Сквозной Trace ID через все микросервисы.
— Логи (Loki): Структурированный JSON, агрегация по полям, а не grep.

🔜 Финальный пост — операционная готовность: runbooks, DRP и бюджет на ошибки.

#Kubernetes #IaC #observability #DevOps
🛡 Runbooks, DRP и бюджет на ошибки — без этого нельзя в прод

Архитектура — половина дела. Вторая половина — готовность команды к инцидентам.

1. Runbooks и ChatOps
Плейбуки должны быть живыми скриптами в Git, запускаемыми из Slack/Telegram ботом. Пример: /runbook restart-stuck-kafka-consumers. Никаких Word-документов на сетевом диске.

2. Disaster Recovery Plan и Game Days
План восстановления ничего не стоит, если не тестируется. Минимум раз в квартал проводим учения: обрыв сети между ЦОДами, отключение мастера БД, DDoS. Инженеры должны просыпаться на учениях, а не когда система реально упала.

3. SLO, SLA и бюджет на ошибки
Договоритесь с бизнесом о целевом уровне доступности (SLO), например 99.95% успешных ответов. Разница между фактом и SLO — это бюджет на ошибки. Пока он есть, можно ускорять деплои и проводить хаос-эксперименты. Исчерпан — фиче-релизы замораживаем до стабилизации.

🔜 Заключительный пост — философия надёжности.

#SRE #инциденты #SLI #DevOps
🏁 Главный завет SRE

Отказоустойчивая high-load архитектура — это живой организм. Она начинается с признания, что идеального софта не существует, а сбои носят комплексный характер.

Ключевые выводы всей серии:
— Изолируйте сбои (Bulkhead).
— Убивайте единые точки отказа.
— Закладывайте асинхронность и проектируйте под падение.
— Инвестируйте в наблюдаемость.

Тогда сбои станут скучными и незаметными, а не героическими битвами в три часа ночи.
Помните: «Надёжность — это главная фича». Если продукт не открывается в нужный клиенту момент, никакой красивый UI его не спасёт.

#DevOps #SRE #архитектура #отказоустойчивость
Какая роль у контроллера DaemonSet?

Контроллер DaemonSet в Kubernetes играет важную роль в обеспечении того, чтобы определённый под (Pod) запускался на каждом узле (Node) кластера (или на определённом подмножестве узлов, если заданы ограничения). Основные задачи и функции контроллера DaemonSet:

1. Запуск подов на каждом узле
- DaemonSet гарантирует, что на каждом узле кластера будет запущен экземпляр указанного пода.
- Это полезно для задач, которые должны выполняться на каждом узле, например:
- Сбор логов (например, Fluentd, Logstash).
- Мониторинг (например, Prometheus Node Exporter).
- Сетевые плагины (например, Calico, Weave).
- Хранение данных (например, распределённые хранилища).

2. Автоматическое добавление подов при добавлении новых узлов
- Когда в кластер добавляется новый узел, DaemonSet автоматически создаёт на нём под.
- Это обеспечивает согласованность и автоматизацию развёртывания.

3. Удаление подов при удалении узлов
- Если узел удаляется из кластера, DaemonSet автоматически удаляет под, связанный с этим узлом.

4. Поддержка селекторов и толерантностей
- DaemonSet позволяет использовать селекторы для выбора узлов, на которых будут запускаться поды.
- Также можно использовать толерантности (tolerations), чтобы разрешить запуск подов на узлах с определёнными метками (например, на узлах с taint node-role.kubernetes.io/master).

5. Обновление и управление подами
- DaemonSet поддерживает стратегии обновления (например, RollingUpdate или OnDelete), что позволяет обновлять поды на узлах с минимальным простоем.
- Контроллер следит за состоянием подов и обеспечивает их корректную работу.

Примеры использования DaemonSet:
- Сетевые плагины: Запуск сетевых агентов на каждом узле для обеспечения сетевой связности.
- Мониторинг: Запуск агентов сбора метрик (например, Prometheus Node Exporter) на каждом узле.
- Логирование: Запуск агентов сбора логов (например, Fluentd) на каждом узле.
- Хранение данных: Запуск компонентов распределённых хранилищ (например, Ceph, GlusterFS).

Отличие DaemonSet от других контроллеров:
- Deployment: Запускает определённое количество реплик подов, которые могут быть распределены по любым узлам.
- StatefulSet: Управляет подами с устойчивыми идентификаторами и хранилищем.
- DaemonSet: Запускает по одному поду на каждом узле (или на подмножестве узлов).

Таким образом, роль контроллера DaemonSet заключается в обеспечении запуска и поддержания определённого пода на каждом узле кластера, что делает его идеальным инструментом для задач, которые должны выполняться на всех узлах.

#devops #WeDoOps
🚨 Когда Argo CD не синхронизирует состояние

Развернули приложение через Argo CD — всё зелёное, синхронизация прошла. Через час заходите — статус OutOfSync. Репозиторий вроде не трогали, но кластер считает иначе.

Или другая классика: разработчик пушит изменения, Argo CD их видит, но деплой встаёт. Оказывается, коллега втихаря сделал kubectl apply, и теперь реальное состояние кластера разошлось с Git.

🤔 Главная проблема — потерянный источник истины
В GitOps истина живёт только в Git-репозитории. Любое изменение в обход Git создаёт рассинхрон. Argo CD честно сигнализирует об этом, но сам не знает, что делать, если мы не настроили правила.

🛠 Решение — грамотная syncPolicy
У каждого приложения можно чётко определить, как именно выполнять синхронизацию. Три ключевых параметра:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guestbook
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/argoproj/argocd-example-apps.git
targetRevision: HEAD
path: guestbook
destination:
server: https://kubernetes.default.svc
namespace: guestbook
syncPolicy:
automated:
prune: false # не удаляем ресурсы, которых нет в Git
selfHeal: true # автооткат к состоянию из Git при любом дрифте
syncOptions:
- CreateNamespace=true

🔹 selfHeal: true — главный защитник от «ручных правок». Если кто-то меняет ресурс через kubectl edit, Argo CD сам вернёт всё к тому, что описано в Git. Без этого флага приложение навсегда останется OutOfSync.

🔹 prune: false — безопасный старт. Мы запрещаем удалять из кластера объекты, которых нет в репозитории. Защита от случайной потери данных. На prune: true переходим только когда на 100% уверены в чистоте манифестов.

🔹 CreateNamespace=true — мелочь, а приятно: Argo CD сам создаст нужный namespace, не придётся делать это руками.

😎 Масштабируем подход: App-of-Apps
Для больших проектов используют паттерн «приложение приложений»: одно root-приложение управляет дочерними. Важно: корневой манифест должен разворачиваться строго в неймспейс, где живёт контроллер Argo CD (обычно argocd), иначе дочерние приложения не распознаются.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: app-of-apps
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/org/infra.git
targetRevision: HEAD
path: apps/
destination:
server: https://kubernetes.default.svc
namespace: argocd # обязательно сюда
syncPolicy:
automated:
prune: true
selfHeal: true

Каждое дочернее приложение описывается своим YAML-файлом и может иметь уникальные политики. Например, для баз данных оставляем prune: false, а для легковесного фронтенда включаем prune: true.

🔄 Бонус: очерёдность через Sync Waves
Если нужно сначала поднять базу, а потом бэкенд, используйте аннотацию синхронизации:

metadata:
annotations:
argocd.argoproj.io/sync-wave: "1"

Ресурсы с меньшей волной (хоть -5) применяются и проверяются на готовность раньше остальных.
🚀 Argo CD: практический план внедрения за 6 шагов

При первом знакомстве с GitOps легко утонуть в нюансах. Держите выверенный план, который поможет запустить Argo CD без потери данных и нервов.

1️⃣ Соберите манифесты в Git
Определите все ресурсы, которые должны управляться через Argo CD, и перенесите их в репозиторий. Никаких «потом добавим» — всё, что живёт в кластере, должно иметь источник в Git.

2️⃣ Настройте политики безопасности с умом
Для production сразу ставьте selfHeal: true и prune: false. Это защитит данные от случайного удаления, но при этом Argo CD будет автоматически исправлять ручные правки в кластере. На staging смело включайте prune: true, чтобы поддерживать идеальный порядок.

3️⃣ Подключите уведомления
Интегрируйте Argo CD Notifications со Slack или Telegram. Вы будете мгновенно узнавать о сбоях синхронизации, а не через час, когда кто-то заметит падение сервиса.

4️⃣ Внедрите App-of-Apps
Централизуйте управление всеми сервисами кластера через один корневой репозиторий. Одно приложение управляет другими приложениями — конфигурация становится единой точкой правды, а деплой нового сервиса сводится к добавлению нескольких строк в Git.

5️⃣ Оптимизируйте Webhooks
Настройте webhook от GitHub/GitLab прямо к Argo CD, чтобы синхронизация запускалась мгновенно при пуше, а не раз в три минуты. Время реакции на изменения сократится с минут до секунд.

6️⃣ Договоритесь на берегу
Обучите команду главному правилу GitOps: никогда не менять ресурсы в кластере напрямую. Только через git commit и git push.

⚠️ Если нарушить этот принцип, Argo CD при selfHeal: true молча перезапишет ваши ручные изменения, а при выключенном самовосстановлении кластер навсегда останется в состоянии рассинхрона. Единственный правильный подход — commit в Git, а не kubectl apply в консоли.
Введение в AIOps

🤖 AIOps: как ИИ меняет эксплуатацию и DevOps

Gartner: организации с AIOps сокращают время восстановления (MTTR) на 30–50% за счёт умной корреляции событий и отсеивания ложных алертов. К 2026 году более 40% крупных компаний внедрят AIOps как основной слой управления инцидентами.

⚡️ AIOps — не замена Prometheus/Grafana, а интеллектуальная надстройка над ними.
Она не просто кричит «сломано», а объясняет _почему_ и предлагает готовый сценарий исправления.

Три столпа современного AIOps:
- Качественная наблюдаемость (Observability)
- Машинное обучение и аналитика
- Замкнутая автоматизация с участием человека

📌 Первое правило: сначала OpenTelemetry, потом AI.
86% лидеров рынка (Splunk) подтверждают — без зрелой наблюдаемости AIOps обречён.

#AIOps #WeDevOps #SRE #AI
Инструменты и архитектура

🧩 Рынок AIOps: коробки vs open-source

Gartner выделяет два лагеря:
- Корпоративные платформы: ServiceNow, BigPanda, Datadog Watchdog. Быстрый старт, но дорого и мало гибкости.
- Open-source стек CNCF: Prometheus, Loki, Tempo, Kafka, Flink, MLflow. Полный контроль, но нужна высокая квалификация команды.

В реальности лидеры строят гибрид:
🔹 Телеметрия собирается через OpenTelemetry
🔹 Данные стекаются в Kafka → аналитическую БД (ClickHouse, StarRocks)
🔹 ML-модели тренируются и деплоятся через GitOps (Kubeflow/MLflow)

Такой подход даёт и прозрачность, и возможность тонкой кастомизации под свою архитектуру.

#AIOps #Observability #OpenTelemetry
Анатомия AIOps-платформы

⚙️ Как устроена современная AIOps-машина

1️⃣ Сбор и нормализация
Всё начинается с OpenTelemetry: единый стандарт метрик, логов и трейсов. Шина Kafka гарантирует 99.99% доставки. Обязательна единая система тэгов (namespace, service, environment, version).

2️⃣ Feature engineering и Data Lake
Сырые потоки превращаются в ML-признаки: скользящие перцентили задержек, burst-счётчики ошибок, эмбеддинги логов.
Хранилище: ClickHouse/Druid + озеро данных на S3 (Iceberg, Delta Lake). Тренд 2024 — векторные базы (Qdrant, Milvus) для поиска похожих инцидентов.

3️⃣ Мозг — алгоритмы
- Поиск аномалий: ансамбли Prophet + автоэнкодеры для метрик, кластеризация Drain и BERT для логов.
- Вероятностная первопричина: граф сервисов из трейсов + Bayesian Networks / Graph Attention. Netflix сократил время диагностики на 60%.
- Предиктив: LSTM и Temporal Fusion Transformers предсказывают насыщение ресурсов.
- Автоисправление: детерминированные ранбуки (Argo Workflows) при точности классификации >95%. RL-агенты пока слишком рискованны.

4️⃣ Петля обратной связи
Инженер подтверждает/отвергает гипотезу AI → модель дообучается. Без human-in-the-loop быстрой зрелости не достичь.

#ML #AIOps #DataEngineering
AIOps и DevOps: практическая интеграция

🔗 Как AIOps встраивается в CI/CD и платформенную инженерию

🏗 Концепция Platform Engineering идеально ложится на AIOps: отдельная SRE-команда предоставляет «AIOps as a Service» продуктовым командам.

Observability как код: конфигурация телеметрии в репозитории (Helm-чарты), правки через merge request.

GitOps для ML-пайплайнов:
Код модели, тренировочные скрипты, пороги хранятся в Git. CI/CD (GitLab, Argo Workflows) переобучает модель на свежих данных, проверяет precision/recall и выкатывает canary-релиз ML-движка в прод. Всё версионируется и аудируется.

Сдвиг влево: AI на деплое
Модель обучена на историях плохих выкаток. При релизе она в реальном времени сравнивает поведение сервиса с эталоном и, заметив характерный рост 5xx или задержек, автоматически запускает откат. Это снижает пользовательский удар на 40–70%.

#GitOps #PlatformEngineering #MLOps
Дорожная карта внедрения

🗺 Как пройти путь к AIOps: 4 фазы

Фаза 1 – Data Foundation (1–3 мес.)
→ OpenTelemetry на все сервисы
→ Data Lake на Kafka + ClickHouse
→ Единая разметка сервисов и окружений

Фаза 2 – Augmented Operations (2–4 мес.)
→ Динамические базовые линии на золотых сигналах
→ Базовая корреляция по графу сервисов
→ Снижение потока алертов на 50%

Фаза 3 – AI-Driven Response (4–8 мес.)
→ Автоматический root cause analysis
→ Auto-remediation типовых проблем с подтверждением оператора
→ Интеграция в чат-опс

Фаза 4 – Predictive & Generative (8+ мес.)
→ Прогнозирование сбоев до их наступления
→ RAG-системы: «Что случилось с payment-api?» → AI генерирует полный отчёт с графиком и сценарием исправления.

💡 Важно расти итеративно, начиная с фундамента данных.

#Roadmap #AIOps #SRE