Почему: `--from-literal` предназначен для прямого ввода пар ключ-значение. Используйте флаг несколько раз для нескольких ключей. Это быстрее, чем создание YAML-файла для простых случаев.
Внедрить все пары ключ-значение из ConfigMap или Secret в контейнер как переменные среды.
В спецификации контейнера используйте `envFrom` с `configMapRef` или `secretRef`. Пример: `envFrom: [{configMapRef: {name: my-config}}]`.
Почему: `envFrom` - это массовая операция, которая сопоставляет все ключи из источника с переменными среды. Это позволяет избежать ручного перечисления каждого ключа.
Почему: `valueFrom` обеспечивает выборочное внедрение и позволяет сопоставлять ключ источника с другим именем переменной среды.
Монтировать ConfigMap или Secret как файлы в Pod, что позволяет обновлять их в реальном времени.
Определите `volume` типа `configMap` или `secret`. Смонтируйте его в контейнер с помощью `volumeMounts`. Файлы будут названы в соответствии с ключами.
Почему: Смонтированные файлы из ConfigMap/Secret автоматически обновляются при изменении источника. Переменные среды - нет, что требует перезапуска Pod.
Применить лучшие практики безопасности: запретить запуск от имени root, сделать корневую файловую систему только для чтения или указать ID пользователя.
Используйте `securityContext` на уровне Pod или контейнера. Установите `runAsNonRoot: true`, `readOnlyRootFilesystem: true` и/или `runAsUser: <UID>`.
Почему: SecurityContext обеспечивает детальный, декларативный контроль над привилегиями контейнера, что важно для усиления безопасности приложений и соблюдения политик безопасности.
Предоставить Pod минимальные разрешения для доступа к Kubernetes API.
1. Создайте пользовательский `ServiceAccount`. 2. Создайте `Role` только с необходимыми разрешениями API (например, list pods). 3. Создайте `RoleBinding` для связывания ServiceAccount и Role. 4. Назначьте ServiceAccount Pod через `spec.serviceAccountName`.
Почему: Следует принципу наименьших привилегий, минимизируя поверхность атаки в случае компрометации Pod.
Предотвратить автоматическое монтирование токена ServiceAccount в Pod, которому не требуется доступ к API.
Установите `automountServiceAccountToken: false` в спецификации Pod или в самом ServiceAccount.
Почему: Уменьшает поверхность атаки, не предоставляя учетные данные API контейнерам, которым они не требуются.
Создать Secret для использования при завершении TLS для Ingress или другого защищенного сервиса.
Почему: Это создает Secret правильного типа `kubernetes.io/tls` со стандартными ключами данных `tls.crt` и `tls.key`, ожидаемыми контроллерами Ingress.
Предоставить метаданные Pod (например, имя, пространство имен, метки или IP-адрес узла) контейнеру.
Используйте Downward API для проецирования метаданных как переменных среды или файлов в том `downwardAPI`. Пример: `valueFrom: {fieldRef: {fieldPath: metadata.name}}`.
Почему: Позволяет контейнерам быть самодостаточными, не требуя запросов к Kubernetes API, что упрощает конфигурацию и снижает требования RBAC.
Установить значения по умолчанию для запросов и лимитов CPU/памяти для всех Pod в пространстве имен.
Создайте объект `LimitRange` в пространстве имен. Определите значения `default` и `defaultRequest` для ресурсов.
Почему: Обеспечивает наличие ограничений ресурсов для всех Pod, улучшая планирование и стабильность, даже если разработчики забыли их указать. Работает совместно с ResourceQuota.
Ограничить общий объем ресурсов (CPU, память, количество объектов), которые могут быть потреблены в пространстве имен.
Создайте объект `ResourceQuota`. Определите жесткие лимиты в `spec.hard`, например, `requests.cpu: "4"`, `pods: "10"`.
Почему: Предотвращает потребление всех ресурсов кластера одним пространством имен или командой, обеспечивая справедливое распределение ресурсов.
Проектирование и создание приложения
Выполнить предварительные задачи (например, дождаться базы данных, выполнить миграции, получить данные) до запуска основного приложения.
Определите один или несколько `initContainers` в спецификации Pod. Они выполняются последовательно до завершения, прежде чем запустятся основные контейнеры приложения.
Почему: Разделяет логику настройки от контейнера приложения и гарантирует выполнение зависимостей до запуска приложения.
Расширить основной контейнер приложения вспомогательной функциональностью, такой как логирование, мониторинг или проксирование.
Добавьте второй контейнер (the sidecar) в спецификацию Pod. Оба контейнера совместно используют ресурсы, такие как сеть и тома.
Почему: Расширяет функциональность без изменения основного кода приложения, способствуя разделению ответственности.
Совместно использовать директорию для чтения/записи между контейнерами в одном Pod.
Определите том `emptyDir` в спецификации Pod и смонтируйте его во все необходимые контейнеры.
Почему: `emptyDir` предоставляет простой, временный том хранения, который существует в течение всего жизненного цикла Pod, идеально подходящий для обмена данными внутри Pod.
Переопределить ENTRYPOINT и/или CMD образа контейнера по умолчанию.
В спецификации контейнера используйте `command` для переопределения ENTRYPOINT и `args` для переопределения CMD. `command: ["/bin/sh"], args: ["-c", "echo hello"]`.
Почему: Обеспечивает полный контроль над командой запуска контейнера из определения Pod, полезно для адаптации общих образов.
Выполнить конечную задачу до завершения, контролируя параллелизм и количество успешных завершений.
Используйте ресурс `Job`. Установите `spec.completions` для целевого количества успешных завершений и `spec.parallelism` для количества одновременно работающих Pod. Используйте `spec.backoffLimit` для управления повторными попытками.
Почему: Jobs предназначены для задач, выполняющихся до завершения, в отличие от долгосрочных Deployments. Эти настройки являются ключом к управлению пакетными рабочими нагрузками.
Запланировать повторяющуюся задачу с использованием синтаксиса cron и контролировать обработку перекрывающихся заданий.
Используйте ресурс `CronJob`. Определите `spec.schedule` в формате cron (например, `*/5 * * * *`). Установите `spec.concurrencyPolicy` в `Allow`, `Forbid` или `Replace`.
Почему: Автоматизирует запланированные задачи. `concurrencyPolicy` имеет решающее значение для предотвращения перекрывающихся запусков (`Forbid`) или замены устаревших (`Replace`).
Быстро сгенерировать YAML-манифест для ресурса без его создания в кластере.
Используйте флаги `--dry-run=client -o yaml` с императивными командами. Пример: `kubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml`.
Почему: Экономит время, создавая действительный манифест, который можно настроить, а затем применить декларативно.
Развертывание приложения
Императивно обновлять, масштабировать, проверять статус, просматривать историю и откатывать Deployment.
Используйте `kubectl set image`, `kubectl scale`, `kubectl rollout status`, `kubectl rollout history` и `kubectl rollout undo`.
Почему: Это основные императивные команды для управления жизненным циклом развернутого приложения во время разработки и устранения неполадок.
Контролировать скорость и безопасность обновления Deployment для обеспечения доступности.
В `spec.strategy.rollingUpdate` настройте `maxSurge` (сколько дополнительных Pod может быть создано) и `maxUnavailable` (сколько может быть недоступно).
Почему: Балансировка `maxSurge` и `maxUnavailable` является ключом к управлению емкостью по сравнению с использованием ресурсов во время обновлений. Для нулевого простоя `maxUnavailable` должно быть меньше `replicas`.
Обеспечить, чтобы две версии приложения не работали одновременно, завершая все старые Pod до создания новых.
Установите `spec.strategy.type: Recreate` в Deployment.
Почему: Гарантирует, что старые и новые версии не сосуществуют, что необходимо для приложений, которые не могут обрабатывать две разные версии, обращающиеся к одним и тем же данным. Эта стратегия приводит к простою.
Внести несколько изменений в активный Deployment без запуска промежуточного развертывания для каждого изменения.
Почему: Объединяет несколько обновлений в одно событие развертывания, предотвращая излишнюю активность и состояния гонки.
Ограничить количество старых ReplicaSet, сохраняемых для Deployment, чтобы сэкономить место в etcd.
Установите `spec.revisionHistoryLimit` на желаемое количество сохраняемых ревизий (например, 3). По умолчанию - 10.
Почему: Установка меньшего лимита уменьшает беспорядок в etcd. Установка в `0` полностью отключает возможность отката.
Документировать причину обновления Deployment, чтобы она отображалась в истории ревизий.
Добавьте аннотацию `kubernetes.io/change-cause` к манифесту Deployment. Пример: `kubectl annotate deployment/nginx kubernetes.io/change-cause="update to 1.20"`.
Почему: Предоставляет ценный контекст при просмотре истории развертываний (`kubectl rollout history`), упрощая идентификацию ревизии, к которой следует откатиться.
Развернуть новую версию приложения рядом со старой и мгновенно переключить трафик с нулевым временем простоя.
Используйте два Deployment (например, `app-blue`, `app-green`) с разными метками версий. Один Service выбирает активную версию через свой `selector`. Для переключения используйте `kubectl patch service`, чтобы обновить `selector` до метки новой версии.
Почему: Обеспечивает мгновенные, низкорисковые релизы и немедленную возможность отката, просто изменяя `selector` Service.
Направить небольшой процент трафика на новую версию приложения для тестирования в производственной среде.
Используйте два Deployment (стабильный, канареечный), совместно использующие одну и ту же метку `selector`. Service нацеливается на оба. Контролируйте процент трафика соотношением реплик (например, 9 стабильных реплик, 1 канареечная для 10% трафика).
Почему: Простой способ выполнения канареечных релизов без service mesh, позволяющий контролируемо и с низким риском тестировать новые функции. Распределение трафика является приблизительным.
Сервисы и сети
Предоставить набор Pod для связи только внутри кластера.
Используйте Service с `type: ClusterIP`. Это тип по умолчанию.
Почему: `ClusterIP` предоставляет стабильный внутренний IP-адрес и DNS-имя для Service, абстрагируясь от отдельных IP-адресов Pod.
Предоставить Service на статическом порту по IP-адресу каждого узла.
Используйте Service с `type: NodePort`. K8s выделяет порт из диапазона (по умолчанию: 30000-32767).
Почему: Полезно для разработки или когда внешний балансировщик нагрузки недоступен. Трафик на `<NodeIP>:<NodePort>` перенаправляется в Service.
Маршрутизировать внешний HTTP/S трафик к внутренним Service на основе имени хоста или пути URL.
Создайте ресурс `Ingress`. Определите `rules` для хостов и `http.paths` для сопоставления с бэкэнд-сервисами. Настройте TLS с `spec.tls`, указывающим на TLS Secret.
Почему: Ingress обеспечивает маршрутизацию уровня L7, объединяя несколько сервисов под одним внешним IP и разгружая завершение TLS.
Ограничить сетевой трафик к Pod и от них на основе меток, пространств имен или блоков IP.
Создайте `NetworkPolicy`, нацеленный на Pod с `podSelector`. Определите правила `ingress` и/или `egress` для разрешения определенного трафика. По умолчанию, применение политики к Pod запрещает весь трафик, который не разрешен явно.
Почему: NetworkPolicies являются основополагающими для сегментации сети и реализации модели безопасности с нулевым доверием в Kubernetes.
Запретить весь входящий и исходящий трафик для всех Pod в пространстве имен по умолчанию.
Создайте NetworkPolicy с пустым `podSelector: {}` и пустыми правилами ingress/egress. Пример: `podSelector: {}, policyTypes: [Ingress, Egress]`.
Почему: Устанавливает безопасную основу, при которой весь трафик запрещен, если он явно не разрешен другими, более специфичными NetworkPolicies.
Предоставить стабильную запись DNS, которая разрешается непосредственно во все IP-адреса Pod, без виртуального IP для балансировки нагрузки.
Создайте Service с `spec.clusterIP: None`.
Почему: Необходим для stateful-приложений (таких как StatefulSets) или P2P-систем, которым требуется обнаруживать и обмениваться данными с конкретными Pod напрямую.
Обеспечить, чтобы бэкэнд-Pod видели исходный IP-адрес клиента для трафика от Service типа NodePort или LoadBalancer.
Установите `spec.externalTrafficPolicy: Local` в Service.
Почему: Политика по умолчанию (`Cluster`) скрывает исходный IP-адрес через трансляцию сетевых адресов. `Local` сохраняет его, но может привести к неравномерному распределению трафика, если Pod расположены не на всех узлах.
Обеспечить, чтобы все запросы от конкретного клиента отправлялись в один и тот же Pod.
В Service установите `spec.sessionAffinity: ClientIP`.
Почему: Обеспечивает 'липкие сессии', что необходимо для устаревших приложений, которые хранят состояние сессии в памяти на конкретном Pod.
Pod в одном пространстве имен должен взаимодействовать с Service в другом пространстве имен.
Используйте полное DNS-имя: `<service-name>.<namespace-name>.svc.cluster.local` или краткую форму `<service-name>.<namespace-name>`.
Почему: Простые имена Service разрешаются только в том же пространстве имен. Межпространственное взаимодействие требует указания целевого пространства имен в DNS-запросе.
Наблюдаемость и обслуживание приложения
Определить проверки работоспособности для управления жизненным циклом Pod: перезапуск при сбое против удаления из Service.
`livenessProbe`: Перезапускает контейнер, если проверка не удалась. `readinessProbe`: Удаляет Pod из конечных точек Service, если проверка не удалась. `startupProbe`: Отключает другие проверки, пока контейнер не завершит свой запуск.
Почему: Правильно настроенные проверки необходимы для самовосстановления приложения и достижения развертываний с нулевым временем простоя.
Диагностировать, почему Pod застрял в нерабочем состоянии (например, Pending, ContainerCreating, CrashLoopBackOff).
Используйте `kubectl describe pod <pod-name>`. Раздел `Events` предоставляет важные подсказки от планировщика (проблемы с ресурсами), kubelet (ошибки при извлечении образа) или среды выполнения контейнера.
Почему: `describe` - самая важная команда для понимания проблем жизненного цикла Pod, которые возникают до запуска приложения или вывода каких-либо логов.
Просмотреть логи из контейнера, который завершил работу с ошибкой и находится в цикле перезапуска (CrashLoopBackOff).
Используйте `kubectl logs <pod-name> --previous`.
Почему: Флаг `--previous` показывает логи из последнего завершенного экземпляра контейнера, который содержит ошибку, вызвавшую сбой.
Просматривать и отслеживать логи всех Pod, соответствующих селектору меток, в реальном времени.
Используйте `kubectl logs -l <label-selector> -f`. Добавьте `--prefix`, чтобы увидеть, из какого Pod поступила каждая строка.
Почему: Агрегирует логи из распределенного приложения, предоставляя единое представление о его поведении.
Выполнить команду или получить интерактивную оболочку внутри запущенного контейнера для отладки.
Используйте `kubectl exec -it <pod-name> -- /bin/sh` (или `/bin/bash`). `--` разделяет флаги kubectl от команды.
Почему: Обеспечивает прямой доступ к среде контейнера для отладки в реальном времени, проверки файлов или проверки сетевого подключения.
Просмотреть текущее потребление CPU и памяти запущенного Pod.
Используйте `kubectl top pod <pod-name>`. Используйте `--containers`, чтобы увидеть потребление для каждого контейнера в Pod.
Почему: Требуется установка Metrics Server. Это необходимо для выявления ресурсоемких приложений, утечек памяти или узких мест CPU.
Устранить неполадки запущенного контейнера, который не имеет оболочки или инструментов отладки.
Используйте `kubectl debug <pod-name> -it --image=busybox --share-processes --copy-to=debug-pod`. Это создает новый Pod с отладочным контейнером, совместно использующим то же пространство имен процессов.
Почему: `kubectl debug` - это современный способ прикрепления временного "ephemeral container" с инструментами отладки к запущенному Pod без изменения исходной спецификации Pod.