Урок по треку Docker и Kubernetes 8 мин

RBAC и Helm за 8 минут

ServiceAccount, Role, ClusterRole, привязки, Helm-чарты, values, релизы и откаты.

Две темы для middle и senior: кто и что может делать в кластере (RBAC) и как упаковывать и выкатывать приложения (Helm).

Аутентификация и авторизация

Каждый запрос к API server проходит три этапа:

  1. Аутентификация: кто ты. Пользователей как объектов в Kubernetes нет: люди приходят через сертификаты, OIDC (SSO компании) или облачную IAM. Программы внутри кластера используют ServiceAccount.
  2. Авторизация: можно ли тебе это действие. Обычно RBAC.
  3. Admission: дополнительные проверки и мутации объекта (политики, квоты, значения по умолчанию).

RBAC: четыре объекта

  • Role: набор разрешений внутри одного namespace.
  • ClusterRole: разрешения на уровне кластера (узлы, PV, namespaces) или шаблон, который можно выдать в любом namespace.
  • RoleBinding: выдаёт Role или ClusterRole субъекту в namespace.
  • ClusterRoleBinding: выдаёт ClusterRole во всём кластере.

Субъекты: User, Group, ServiceAccount.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: prod
rules:
  - apiGroups: [""]              # "" это core: pods, services, secrets...
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: dev-pod-reader
  namespace: prod
subjects:
  - kind: Group
    name: developers
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Правила только разрешающие, запрещающих нет: если ни одно правило не разрешило, действие запрещено. Глаголы: get, list, watch, create, update, patch, delete, deletecollection, а также особые (impersonate, escalate, bind). Подресурсы указываются отдельно: pods/log, pods/exec, deployments/scale.

Удобный приём: ClusterRole как шаблон (например встроенные view, edit, admin) и RoleBinding в нужном namespace.

Проверка прав:

kubectl auth can-i delete pods -n prod
kubectl auth can-i list secrets -n prod --as=system:serviceaccount:prod:api
kubectl auth can-i --list -n prod

Опасные права

  • list или watch на secrets возвращает содержимое всех секретов, не только имена.
  • create на pods (или Deployment, Job) в namespace даёт доступ к его секретам и ServiceAccount: под может их смонтировать.
  • pods/exec позволяет войти в любой контейнер.
  • escalate, bind, impersonate позволяют выдать себе больше прав.
  • Wildcard * в ресурсах или глаголах, cluster-admin для CI.
  • Права на узлы и nodes/proxy.

ServiceAccount

У каждого пода есть ServiceAccount (по умолчанию default своего namespace). Kubernetes монтирует в под короткоживущий токен (projected token с ограниченным сроком и аудиторией), по которому под обращается к API.

Практика:

  • отдельный ServiceAccount на приложение, права только те, что нужны;
  • если приложению API не нужен, automountServiceAccountToken: false;
  • облачный доступ (S3, очереди) через привязку ServiceAccount к облачной роли (workload identity), а не через статичные ключи в Secret.

Pod Security Admission

Встроенный механизм ограничений для подов вместо удалённой PodSecurityPolicy. Включается метками namespace с тремя уровнями: privileged (без ограничений), baseline (запрет явно опасного: privileged, hostNetwork, hostPath...), restricted (не root, без повышения прав, сброс capabilities, seccomp). Режимы: enforce, audit, warn.

metadata:
  labels:
    pod-security.kubernetes.io/enforce: restricted

Для своих правил (только образы из нашего реестра, обязательные метки, лимиты) используют Kyverno, OPA Gatekeeper или встроенные ValidatingAdmissionPolicy.

Helm

Helm это пакетный менеджер Kubernetes. Чарт это шаблоны манифестов плюс значения по умолчанию:

mychart/
  Chart.yaml          # имя, версия чарта, appVersion, зависимости
  values.yaml         # значения по умолчанию
  templates/          # шаблоны Go template
    deployment.yaml
    _helpers.tpl
# templates/deployment.yaml (фрагмент)
spec:
  replicas: {{ .Values.replicaCount }}
  template:
    metadata:
      annotations:
        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
    spec:
      containers:
        - name: app
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"

Релиз это установленный экземпляр чарта. Helm хранит историю релизов в Secret в namespace релиза, что позволяет откатываться.

helm upgrade --install api ./chart -n prod -f values-prod.yaml --set image.tag=1.4.3
helm list -n prod
helm history api -n prod
helm rollback api 3 -n prod
helm template ./chart -f values-prod.yaml     # отрисовать манифесты без установки
helm diff upgrade ...                         # плагин: что изменится
helm uninstall api -n prod

Порядок значений: values.yaml чарта, затем файлы -f по порядку, затем --set (последнее побеждает). Флаги --wait и --atomic заставляют ждать готовности ресурсов и автоматически откатываться при неудаче.

Секреты в values в открытом виде не хранят: helm-secrets с SOPS или External Secrets.

Альтернативы и соседи: kustomize (наложения без шаблонов, встроен в kubectl), Argo CD и Flux (GitOps: кластер сам синхронизируется с git, умеют и Helm, и kustomize).

Частые ошибки

  • cluster-admin для CI или приложения.
  • Права на list secrets «чтобы видеть, что они есть».
  • Приложению без нужды монтируется токен ServiceAccount.
  • В values чарта лежат пароли.
  • helm upgrade без --atomic и без проверки helm diff.
  • Ручные kubectl edit поверх ресурсов, которыми управляет Helm или GitOps.

Что спросят на собесе

  • Чем Role отличается от ClusterRole, RoleBinding от ClusterRoleBinding.
  • Как дать разработчику только чтение логов в одном namespace.
  • Что такое ServiceAccount и как под обращается к API.
  • Зачем Helm, что такое чарт, релиз, values; как откатить релиз.
  • Helm против kustomize, что такое GitOps.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.