Kubernetes: кластеры и Helm charts
Kubernetes: кластеры и Helm charts
1) Архитектура кластера — взгляд сверху
Control Plane: `kube-apiserver`, `etcd`, `kube-scheduler`, `kube-controller-manager`, (в управляемых облаках часть спрятана).
Worker: `kubelet`, CRI-рантайм (containerd/CRI-O), CNI-плагин, kube-proxy/ebpf-proxy.
Внутрикластерная сеть: Pod-to-Pod, Service-VIP/ClusterIP, DNS CoreDNS.
Хранилища: CSI-драйверы, динамическое провижининг PVC → PV (StorageClass).
Границы отказа: узел/AZ/регион. Размещайте реплики по зонам (TopologySpreadConstraints/anti-affinity).
Типовые роли
Платформенная команда: создает/апгрейдит кластеры, CNI/CSI/Ingress, политику и GitOps.
Продуктовые команды: деплоят чарты/релизы, следуют политикам безопасности и ресурсам.
2) Жизненный цикл кластера
Создание: kOps, kubeadm, Rancher, EKS/AKS/GKE. Сразу включайте OIDC-аутентификацию и аудит.
Апгрейды: minor-версии по очереди (control plane → узлы), контролируемый maxUnavailable, тесты на стейджинге.
Add-ons (все — через Helm/GitOps): CNI (Calico/Cilium), CSI драйвер, Ingress-контроллер (NGINX/Gateway API/Contour/Traefik), Metrics-Server, Cluster-Autoscaler, Node-Local DNS, логирование/метрики/трейс.
Бэкапы: etcd snapshot (если self-managed), Velero для namespace/PVC.
3) Сети, сервисы и ingress
CNI: Calico (NetworkPolicy), Cilium (eBPF/servicemesh-фичи).
Service: `ClusterIP`, `NodePort`, `LoadBalancer` (L4 балансировка облака), `ExternalName`.
Ingress / Gateway API: L7-маршрутизация, TLS, анамнез rate-limit/WAF на периметре.
NetworkPolicy: по умолчанию deny-all + явные allow по namespace/label.
Headless-service (`clusterIP: None`) для StatefulSet и сервис-дискавери.
4) Хранилища (CSI) и состояния
StorageClass: `reclaimPolicy`, `volumeBindingMode` (`WaitForFirstConsumer` для лучшего размещения).
StatefulSet: стабильные имена/тома (`volumeClaimTemplates`), `podManagementPolicy: Parallel` для быстрых разверток.
ReadWriteMany: используйте распределенные файловые (EFS/Filestore) осторожно — оценивайте латентность.
Снимки: `VolumeSnapshotClass` + cron-бэкапы.
5) Многоарендность и политика
Namespaces по продуктам/средам.
RBAC: минимальные роли, отдельные сервис-аккаунты, `Role`/`RoleBinding` вместо `ClusterRole`, где возможно.
PSA (Pod Security Admission): режимы `baseline`/`restricted` (замена PSP).
ResourceQuota / LimitRange: потолки CPU/Memory/PVC/LoadBalancer.
OPA Gatekeeper/Kyverno: политика допуска (например, запрет `:latest`, требование `resources`, `readOnlyRootFilesystem`).
ImagePolicy/вебхуки: проверка подписи образов (cosign/policy-controller).
6) Наблюдаемость и эксплуатация
Метрики: Prometheus-стек, kube-state-metrics, node-экспортеры.
Логи: Fluent Bit/Vector → объектное/ES/OpenSearch, ротация на узлах.
Трейсы: OpenTelemetry Collector.
SLO-дашборды: RED-модель на ingress и ключевых сервисах.
Автоскейл: HPA (по метрикам приложения), VPA для бэкграунда, Cluster-Autoscaler для узлов.
7) Паттерны манифестов (шпаргалка)
Deployment (выдержка):yaml apiVersion: apps/v1 kind: Deployment metadata: { name: api, labels: { app: api } }
spec:
replicas: 3 strategy: { type: RollingUpdate, rollingUpdate: { maxUnavailable: 0, maxSurge: 1 } }
selector: { matchLabels: { app: api } }
template:
metadata:
labels: { app: api }
spec:
serviceAccountName: api-sa securityContext: { runAsNonRoot: true, fsGroup: 2000 }
containers:
- name: api image: registry. example. com/api:1. 2. 3 ports: [{ containerPort: 8080 }]
resources: { requests: { cpu: "200m", memory: "256Mi" }, limits: { cpu: "1", memory: "512Mi" } }
readinessProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 5 }
livenessProbe: { httpGet: { path: /livez, port: 8080 }, initialDelaySeconds: 20 }
StatefulSet (фрагмент):
yaml apiVersion: apps/v1 kind: StatefulSet metadata: { name: db }
spec:
serviceName: db replicas: 3 podManagementPolicy: Parallel selector: { matchLabels: { app: db } }
template:
metadata: { labels: { app: db } }
spec:
containers:
- name: db image: postgres:16-alpine volumeMounts: [{ name: data, mountPath: /var/lib/postgresql/data }]
volumeClaimTemplates:
- metadata: { name: data }
spec:
accessModes: ["ReadWriteOnce"]
resources: { requests: { storage: 100Gi } }
storageClassName: fast-ssd
PDB (PodDisruptionBudget):
yaml apiVersion: policy/v1 kind: PodDisruptionBudget metadata: { name: api-pdb }
spec:
minAvailable: 2 selector: { matchLabels: { app: api } }
Ingress (Nginx, кратко):
yaml apiVersion: networking. k8s. io/v1 kind: Ingress metadata:
name: api annotations:
nginx. ingress. kubernetes. io/proxy-read-timeout: "30"
spec:
tls: [{ hosts: ["api. example. com"], secretName: api-tls }]
rules:
- host: api. example. com http:
paths:
- path: /
pathType: Prefix backend: { service: { name: api, port: { number: 80 } } }
8) Helm v3 — основы и структура
Чарт = шаблоны + значения + метаданные.
mychart/
Chart. yaml # name, version (semver), type (application/library), dependencies values. yaml # default values. schema. json # (recommended) validation values templates/# .yaml. gotmpl (Deployment, Service, Ingress, …)
templates/tests/ # helm tests (smoke)
charts/# local dependencies (or OCI dependencies)
Chart.yaml (пример):
yaml apiVersion: v2 name: api description: API service type: application version: 1. 4. 0 # chart version (semver)
appVersion: "1. 2. 3" # dependencies application version:
- name: redis version: 17. x.x repository: "oci://registry. example. com/charts"
9) Шаблоны Helm — практики
Используйте helpers в `_helpers.tpl` для имен/меток/аннотаций.
Везде указывайте `resources`, `securityContext`, `readiness/liveness`.
Генерируйте labels по стандартизованной схеме (`app.kubernetes.io/`).
Делайте фичи опциональными через `values` (ingress/hpa/pdb/servicemonitor).
Включайте `values.schema.json` — стоп от неверных конфигов.
Для чувствительных данных — Secrets от внешних операторов (External Secrets, SOPS), а не хранить в values.
gotmpl
{{- define "api. fullname" -}}
{{- printf "%s-%s".Chart. Name. Release. Name trunc 63 trimSuffix "-" -}}
{{- end -}}
Deployment.tpl (фрагмент):
gotmpl apiVersion: apps/v1 kind: Deployment metadata:
name: {{ include "api. fullname". }}
labels: {{- include "api. labels". nindent 4 }}
spec:
replicas: {{.Values. replicaCount }}
strategy:
rollingUpdate:
maxSurge: 1 maxUnavailable: 0 selector:
matchLabels: {{- include "api. selectorLabels". nindent 6 }}
template:
metadata:
labels: {{- include "api. selectorLabels". nindent 8 }}
spec:
serviceAccountName: {{ include "api. serviceAccountName". }}
securityContext: {{- toYaml. Values. podSecurityContext nindent 8 }}
containers:
- name: {{.Chart. Name }}
image: "{{.Values. image. repository }}:{{.Values. image. tag }}"
imagePullPolicy: IfNotPresent ports: [{ containerPort: {{.Values. service. port }} }]
resources: {{- toYaml. Values. resources nindent 10 }}
envFrom:
- secretRef: { name: {{.Values. secretsRef }} }
10) Зависимости, репозитории и OCI
Helm v3 поддерживает OCI-регистры: `oci://registry/org/charts`.
Лочите версии зависимостей (`^1.2.0`, `~1.2`) и прогоняйте `helm dependency build`.
Подписывайте чарт (prov), храните артефакты в артефакт-репозитории CI.
Library charts: общие шаблоны (ingress/servicemonitor) для переиспользования.
11) Hooks, CRD и порядок операций
Hooks: `pre-install`, `post-install`, `pre-upgrade`, `post-upgrade`, `test`. Добавляйте policies (`before-hook-creation`, `hook-succeeded`).
CRD: кладите в `crds/` (установятся до темплейтов), избегайте апдейтов CRD «на лету» — делайте миграции отдельно.
Миграции БД/инициализация — job-hook с idempotency и таймаутами.
12) Тестирование чарта и CI
`helm lint` + валидация схемы.
Helm unittest (unit), chart-testing (ct) — сборка/инсталляция в kind/minikube в CI.
Snapshot-тесты шаблонов (`helm template` → сравнить с эталоном).
Smoke-тесты `helm test` (поднимают `Pod` с проверками).
13) GitOps (Argo CD/Flux)
Источник правды — репозиторий. Чарт хранится как HelmRelease/HelmChart (Flux) или Application (Argo).
Политики синка: auto-sync с prune/self-heal, статусы и health-checks.
Промоушен версий: tag-боты/semver-range, PR-флоу.
Разделяйте repo на apps (чарты) и env (overrides/values).
Secret-менеджмент: SOPS (age/KMS), External Secrets.
14) Безопасность: минимум необходимого
PSA restricted: без привилегий, без hostPath, с ограниченными capabilities, read-only rootfs.
ImagePolicy: только подписанные/доверенные образы.
NetworkPolicy: «по умолчанию заперто».
RBAC: сервис-аккаунт per-app, `Role`/`RoleBinding` в namespace.
Admission-контроль: Gatekeeper/Kyverno правила (resources/limits, labels, no latest).
Секреты: SOPS/External Secrets; не класть секреты в values/plain Git.
15) Анти-паттерны
`:latest` в чартах и образах; отсутствие `values.schema.json`.
Один огромный чарт «на все» вместо модульных.
CRD обновляются шаблонами в `templates/` → хаос на апгрейдах.
Жестко захардкоженные имена/порт/namespace в шаблонах.
Отсутствие ресурсов/лимитов и проб → дрейф латентности и нестабильность.
Нет PDB → нулевой даунтайм невозможен при drain/апгрейдах.
Секреты в Git без шифрования; манифесты без политика-checks.
16) Чек-лист внедрения (0–45 дней)
0–10 дней
Завести базовый чарт-скелет с `_helpers.tpl`, labels, probes, resources, PDB/Ingress опционально.
Включить PSA restricted, NetworkPolicy deny-all, ResourceQuota/LimitRange.
Настроить GitOps (Argo/Flux), приватный регистр, подпись образов/чартов.
11–25 дней
Разделить чарт на модули/зависимости, добавить `values.schema.json`, тесты (`helm lint`, unit, ct).
Подключить observability (ServiceMonitor/PodMonitor), лог-агенты, OTel.
Ввести процесс апгрейдов: staging → canary → prod, hook-миграции с rollback.
26–45 дней
Автоматизировать обновления зависимостей (боты/semver-ranges + PR).
Добавить Gatekeeper/Kyverno политики и policy-репорты в CI.
Документировать runbook апгрейда кластера, DR-процедуры (Velero/etcd snapshot).
17) Метрики зрелости
100% приложений деплоятся через Helm/GitOps, без `kubectl apply` вручную.
Все чарты имеют `values.schema.json`, тесты, подпись и зафиксированные версии зависимостей.
PSA restricted/NetworkPolicy включены во всех namespace.
PDB и HPA присутствуют у всех критичных сервисов.
Безопасные секреты (SOPS/External Secrets), политика «no latest», подпись образов.
Апгрейды кластера и чарта проходят без даунтайма (canary/blue-green), restore-тесты регулярны.
18) Заключение
Сильный Kubernetes-фундамент = надежная архитектура кластера + строгая политика + Helm-чарты промышленного качества под управлением GitOps. Стандартизируйте шаблоны, защитите окружение PSA/NetworkPolicy/RBAC, валидируйте values и автоматизируйте тесты, подпись и промоушен. Тогда апгрейды и релизы станут предсказуемыми, а платформа — устойчивой и удобной для продуктовых команд.