Обеспечьте, чтобы состояние кластера непрерывно соответствовало желаемому состоянию.
Положитесь на `kube-controller-manager`. Он запускает циклы управления, которые отслеживают ресурсы (например, ReplicaSet, Deployment) и устраняют различия.
Почему: Это основной декларативный, самовосстанавливающийся механизм. Если Pod, управляемый ReplicaSet, выходит из строя, контроллер автоматически заменяет его.
Автоматически назначать вновь созданные Pods наиболее подходящему рабочему узлу.
Положитесь на `kube-scheduler`. Он фильтрует узлы на основе требований Pod (например, запросов ресурсов) и оценивает их для выбора наиболее подходящего.
Почему: Планировщик принимает решения о размещении на основе политики, близости и доступности, абстрагируя выбор узла от пользователя.
Обеспечьте, чтобы контейнеры, указанные в Pods, работали и были здоровы на данном рабочем узле.
Агент `kubelet` работает на каждом узле, взаимодействует с API-сервером и управляет жизненным циклом контейнера (запуск, остановка, проверки работоспособности) через среду выполнения контейнера.
Почему: Kubelet является связующим звеном между плоскостью управления и рабочим узлом; он выполняет спецификации Pod.
Надежно сохранять все состояние и конфигурацию кластера Kubernetes.
Используйте `etcd`, согласованное и высокодоступное хранилище "ключ-значение". Оно служит единственным источником достоверной информации для кластера.
Почему: Все объекты кластера (Pods, Services и т. д.) хранятся в etcd. Только API-сервер напрямую взаимодействует с ним.
Реализовать сетевые правила на каждом узле для обеспечения связи через Kubernetes Services.
Компонент `kube-proxy` на каждом узле поддерживает сетевые правила (например, iptables, IPVS), которые перенаправляют трафик с IP Service на соответствующие backend Pods.
Почему: Kube-proxy - это деталь реализации абстракции Service, отвечающая за балансировку нагрузки и маршрутизацию.
Логически разделить один кластер Kubernetes для нескольких команд, проектов или сред.
Создавайте ресурсы `Namespace`. Namespaces предоставляют область действия для имен и способ прикрепления авторизации и политик (например, ResourceQuota).
Почему: Namespaces обеспечивают многопользовательскую работу и организацию ресурсов без накладных расходов на несколько кластеров.
Предоставить стабильную сетевую конечную точку (IP и DNS) для набора эфемерных Pods.
Определите ресурс `Service`, который нацелен на набор Pods с использованием селектора меток.
Почему: Pods эфемерны, и их IP-адреса меняются. Service предоставляет надежную абстракцию, которая балансирует нагрузку трафика на правильные Pods.
Выставить приложение, работающее в Pods, в различные сетевые области.
Выберите `type` Service: `ClusterIP` (только внутренний, по умолчанию), `NodePort` (выставляет на каждом узле IP:порт) или `LoadBalancer` (предоставляет облачный балансировщик нагрузки).
Почему: Тип Service определяет доступность приложения, от чисто внутреннего до полностью внешнего.
Включить прямое сетевое обнаружение отдельных Pods, минуя прокси Service.
Создайте `Service` с `clusterIP: None`. Это создает записи DNS A для каждого Pod, позволяя клиентам напрямую подключаться к Pods.
Почему: Необходимо для stateful-приложений, таких как базы данных (часто с StatefulSets), где требуется одноранговая связь или стабильная идентификация Pod.
Организовать и выбрать подмножество объектов Kubernetes.
Прикрепите пары "ключ-значение" `labels` к объектам (например, `app: my-api`). Используйте `label selectors` в других объектах (например, Services, Deployments) для их выбора.
Почему: Метки являются основным механизмом группировки в Kubernetes, обеспечивая слабую связанность между ресурсами.
Отделить конфигурацию приложения от образа контейнера.
Храните нечувствительные данные конфигурации в `ConfigMap`. Подключайте его как том или внедряйте ключи как переменные среды в Pods.
Почему: Это позволяет управлять конфигурацией независимо от кода приложения, следуя принципам The Twelve-Factor App.
Хранить конфиденциальные данные, такие как пароли, токены или ключи API, для использования приложением.
Используйте объект `Secret`. Подключайте как том или внедряйте как переменную среды.
Почему: Secrets предназначены специально для конфиденциальных данных и обрабатываются более безопасно, чем ConfigMaps (например, по умолчанию не отображаются в `kubectl describe`, могут быть зашифрованы в состоянии покоя).
Предоставить stateful-приложениям хранилище, которое сохраняется после перезапусков Pod.
Pod создает `PersistentVolumeClaim` (PVC) для запроса хранилища. Администратор предоставляет `PersistentVolume` (PV), который удовлетворяет запрос.
Почему: Это разделяет потребление хранилища (PVC) от предоставления хранилища (PV), что позволяет создавать переносимые определения рабочих нагрузок.
Управлять выделением CPU и памяти для контейнеров.
Установите `resources.requests` для гарантированных ресурсов (используются для планирования) и `resources.limits` для максимально допустимого использования (применяется во время выполнения).
Почему: Requests гарантируют, что Pods имеют достаточно ресурсов для работы; Limits предотвращают потребление Pods слишком большого количества ресурсов и влияние на другие рабочие нагрузки.
Установить совокупные ограничения ресурсов для пространства имен.
Создайте объект `ResourceQuota` для ограничения общего количества CPU, памяти или числа объектов (Pods, Services), которые могут быть созданы в пространстве имен.
Почему: ResourceQuota необходимы для многопользовательских сред для обеспечения справедливого распределения ресурсов и предотвращения чрезмерного потребления.
Управлять ресурсами Kubernetes с помощью версионированных файлов конфигурации.
Используйте `kubectl apply -f <filename.yaml>`. Эта команда создает или обновляет ресурсы на основе содержимого файла.
Почему: `apply` является декларативным, что делает его идеальным для GitOps и CI/CD. Он отслеживает изменения и выполняет трехстороннее слияние, что безопаснее, чем императивные `create` или `replace`.
Диагностировать, почему Pod работает некорректно (например, застрял в Pending, ContainerCreating или CrashLoopBackOff).
Используйте `kubectl describe pod <pod-name>`. Проверьте раздел `Events` внизу на наличие подробных сообщений от планировщика, kubelet или контроллеров.
Почему: `describe` предоставляет хронологический журнал событий, который является основным инструментом для отладки проблем жизненного цикла ресурсов.
Предоставить сетевую функциональность для контейнеров, обеспечивая связь между Pods по всему кластеру.
Используйте плагин Container Network Interface (CNI) (например, Calico, Flannel, Cilium). Kubelet на каждом узле использует плагин CNI для настройки сети для каждого Pod.
Почему: CNI предоставляет стандартный интерфейс, позволяя интегрировать Kubernetes с различными сетевыми решениями без изменения основных компонентов.
Контролировать доступ к ресурсам Kubernetes API для пользователей и приложений.
Используйте управление доступом на основе ролей (RBAC). Определите `Role` (для пространства имен) или `ClusterRole` (для всего кластера) с разрешениями и привяжите его к субъекту (User, Group, ServiceAccount) с помощью `RoleBinding` или `ClusterRoleBinding`.
Почему: RBAC является стандартом для защиты Kubernetes, обеспечивая принцип наименьших привилегий для всех взаимодействий с API.
Управлять stateless-приложением, обеспечивая легкие обновления и откаты.
Используйте рабочую нагрузку `Deployment`. Она управляет ReplicaSet для обеспечения желаемого количества запущенных реплик Pod и предоставляет декларативные стратегии обновления.
Почему: Deployments являются стандартом для stateless-приложений, абстрагируя детали масштабирования и скользящих обновлений.
Развернуть stateful-приложение (например, базу данных), которое требует стабильной сетевой идентификации и хранения.
Используйте рабочую нагрузку `StatefulSet`. Она предоставляет каждому Pod стабильное, уникальное имя хоста и постоянное хранилище, которое следует за ним при перезапусках.
Почему: В отличие от Deployments, StatefulSet управляют Pods с идентификацией, обеспечивая упорядоченное развертывание и масштабирование, что критически важно для stateful-систем.
Развернуть агент (например, сборщик логов, агент мониторинга) на каждом узле в кластере.
Используйте рабочую нагрузку `DaemonSet`. Она гарантирует, что копия Pod работает на каждом узле (или подмножестве узлов).
Почему: DaemonSet автоматизируют распространение сервисов уровня узла, автоматически масштабируясь на новые узлы по мере их присоединения к кластеру.
Запустить конечную, однократную задачу, которая должна быть выполнена до конца.
Используйте ресурс `Job`. Он создает один или несколько Pods и гарантирует их успешное завершение.
Почему: Jobs предназначены для пакетной обработки, в отличие от Deployments, которые предназначены для непрерывных сервисов. Pods не заменяются после успешного завершения.
Запускать задачу по повторяющемуся расписанию (например, ночные резервные копии, отчеты).
Используйте ресурс `CronJob`. Он создает Jobs на основе строки расписания cron.
Почему: CronJobs предоставляют нативный способ Kubernetes для управления временными, повторяющимися задачами.
Автоматически перезапускать контейнер, который перестал отвечать (например, из-за взаимоблокировки).
Настройте `livenessProbe` в спецификации контейнера. Если проверка не удалась, kubelet перезапускает контейнер.
Почему: Liveness-пробы предоставляют мощный механизм самовосстановления для приложений, которые могут застрять в нерабочем состоянии без сбоя.
Предотвратить отправку трафика контейнеру, который еще не готов к обслуживанию запросов.
Настройте `readinessProbe` в спецификации контейнера. Pod добавляется в конечные точки Service только после успешной проверки.
Почему: Readiness-пробы критически важны для скользящих обновлений без простоев, гарантируя, что новые Pods полностью инициализированы до получения производственного трафика.
Запускать задачи настройки или ждать готовности зависимостей перед запуском основного контейнера приложения.
Определите один или несколько `initContainers` в спецификации Pod. Они выполняются последовательно до завершения перед запуском любых контейнеров приложения.
Почему: Init-контейнеры обеспечивают чистое разделение логики настройки, гарантируя выполнение предварительных условий без загромождения основного контейнера приложения.
Обеспечить планирование Pods на узлы с определенными характеристиками (например, узлы с GPU, SSD).
Используйте `nodeAffinity` в спецификации Pod для установки правил на основе меток узлов. Может быть "обязательным" (hard) или "предпочтительным" (soft) ограничением.
Почему: Node affinity более выразителен, чем `nodeSelector`, и является современным способом управления размещением Pod на основе свойств узлов.
Контролировать совместное размещение Pods относительно друг друга для повышения производительности или высокой доступности.
Используйте `podAffinity` для планирования Pods вместе (например, на одном узле) или `podAntiAffinity` для их разнесения (например, по разным узлам или зонам).
Почему: Anti-affinity крайне важен для обеспечения того, чтобы реплики сервиса не находились в одном домене отказа, тем самым повышая доступность.
Предотвратить планирование Pods общего назначения на выделенные или специализированные узлы.
Примените `Taint` к узлу. Pods должны иметь соответствующее `Toleration` в своей спецификации, чтобы быть запланированными на этом узле.
Почему: Taints и tolerations гарантируют, что узлы зарезервированы для рабочих нагрузок, которым явно разрешено там работать.
Обеспечить высокую доступность путем равномерного распределения Pods по доменам отказа, таким как зоны или узлы.
Определите `topologySpreadConstraints` в спецификации Pod для контроля распределения Pods на основе меток и ключей топологии (например, `topology.kubernetes.io/zone`).
Почему: Это обеспечивает более детальный контроль над высокой доступностью, чем anti-affinity Pod, предотвращая концентрацию всех реплик в одном месте.
Автоматически масштабировать количество реплик приложения на основе наблюдаемой нагрузки.
Создайте ресурс `HorizontalPodAutoscaler` (HPA), который нацелен на Deployment и указывает метрику (например, утилизацию CPU) и целевое значение.
Почему: HPA обеспечивает эластичное масштабирование, гарантируя производительность под нагрузкой и экономя затраты в периоды затишья, без ручного вмешательства.
Автоматически добавлять или удалять рабочие узлы из кластера для соответствия спросу на ресурсы.
Разверните `Cluster Autoscaler`. Он отслеживает Pods, которые не могут быть запланированы (из-за нехватки ресурсов), и добавляет узлы, или удаляет недоиспользуемые узлы.
Почему: Cluster Autoscaler управляет эластичностью на уровне инфраструктуры, работая с облачными провайдерами для корректировки размера кластера в зависимости от потребностей рабочей нагрузки.
Обеспечить доступность минимального количества реплик приложения во время добровольных прерываний (например, обновлений узлов).
Создайте `PodDisruptionBudget` (PDB), указывая `minAvailable` или `maxUnavailable` для набора Pods.
Почему: PDBs предотвращают такие действия, как `kubectl drain`, от отключения слишком большого количества реплик одновременно, обеспечивая доступность приложения.
Выполнить обновление stateless-приложения без простоя.
Используйте `Deployment` со стратегией `RollingUpdate` по умолчанию. Настройте `maxSurge` и `maxUnavailable` для управления процессом обновления.
Почему: Скользящие обновления постепенно заменяют старые Pods новыми, обеспечивая доступность сервиса на протяжении всего обновления.
Доставка облачных приложений
Управлять развертыванием инфраструктуры и приложений декларативно с контролем версий и журналом аудита.
Реализуйте GitOps. Используйте репозиторий Git как единственный источник достоверной информации. Используйте инструмент, такой как Argo CD или Flux, для автоматической синхронизации состояния кластера с Git.
Почему: GitOps предоставляет четкую, проверяемую историю всех изменений и обеспечивает легкий откат путем отмены Git-коммитов. Он операционализирует "Инфраструктуру как код".
Упаковывать, настраивать и развертывать сложные приложения Kubernetes многократно используемым и версионированным способом.
Используйте `Helm`, менеджер пакетов для Kubernetes. Упаковывайте приложения как `Charts` с шаблонизированными манифестами и настраиваемыми файлами `values.yaml`.
Почему: Helm упрощает управление сложными приложениями со множеством компонентов, обрабатывая зависимости, версионирование и управление жизненным циклом.
Настраивать манифесты Kubernetes для разных сред без использования шаблонов.
Используйте `Kustomize`. Определите файл `kustomization.yaml`, который указывает базовую конфигурацию и применяет патчи или наложения для каждой среды.
Почему: Kustomize предлагает декларативный, беcшаблонный способ управления вариантами конфигурации, который может быть проще и менее подвержен ошибкам, чем текстовое шаблонизирование.
Протестировать новую версию приложения с небольшой частью производственного трафика перед полным развертыванием.
Разверните новую версию рядом со старой. Используйте service mesh или Ingress-контроллер для маршрутизации небольшого процента трафика (например, 5%) к новой "канареечной" версии.
Почему: Канареечные релизы снижают риск внедрения неудачного релиза, ограничивая область поражения и позволяя проводить тестирование в производственной среде.
Развернуть новую версию приложения без простоя и с возможностью мгновенного отката.
Разверните новую "зеленую" версию рядом с существующей "синей" версией. Как только зеленая версия будет проверена, переключите 100% трафика с синей на зеленую на уровне Service/маршрутизатора.
Почему: Сине-зеленые развертывания исключают простои. Откат так же прост, как переключение трафика обратно в синюю среду.
Облачная архитектура
Разработать сложное приложение как набор небольших, независимых и слабо связанных сервисов.
Структурируйте приложение как микросервисы, каждый из которых организован вокруг бизнес-возможности. Каждый сервис должен владеть своими данными и общаться через четко определенные API.
Почему: Эта архитектура обеспечивает независимую разработку, развертывание и масштабирование сервисов, повышая гибкость и отказоустойчивость.
Создать переносимое, масштабируемое и облачное приложение, следуя установленным лучшим практикам.
Придерживайтесь методологии The Twelve-Factor App. Ключевой принцип - хранение всей конфигурации, которая меняется между средами, в переменных окружения.
Почему: Это строго разделяет конфигурацию и код, позволяя одному и тому же образу контейнера продвигаться по средам без изменений.
Управлять сложным взаимодействием между сервисами, обеспечивая управление трафиком, безопасность и наблюдаемость.
Внедрите service mesh (например, Istio, Linkerd). Он внедряет sidecar-прокси в каждый Pod для перехвата и управления всем сетевым трафиком.
Почему: Service mesh абстрагирует сетевые проблемы (mTLS, повторные попытки, размыкание цепи) от кода приложения, обеспечивая их соблюдение на уровне платформы.
Расширить или улучшить функциональность контейнера приложения без изменения его кода.
Разверните "sidecar" контейнер в том же Pod, что и основное приложение. Он разделяет ту же сеть и хранилище.
Почему: Sidecar используются для сквозных задач, таких как логирование, мониторинг или проксирование (как в service mesh), способствуя разделению ответственности.
Получить глубокое понимание поведения распределенной системы для облегчения устранения неполадок.
Внедрите три столпа наблюдаемости: `Metrics` (агрегированные числовые данные), `Logs` (дискретные события) и `Traces` (сквозные потоки запросов).
Почему: Вместе эти типы данных обеспечивают всестороннее представление о работоспособности и производительности системы, что крайне важно для сложных микросервисных архитектур.