SPIFFE и SPIRE в Kubernetes: короткий ответ и область применения
SPIFFE (Secure Production Identity Framework for Everyone) задаёт формат идентификатора сервиса, SPIRE реализует этот стандарт в Kubernetes и вне кластера. Связка SPIFFE/SPIRE заменяет статические секреты динамическим документом SVID (SPIFFE Verifiable Identity Document). SPIRE Server выпускает SVID и управляет центром доверия, SPIRE Agent на каждом узле доставляет SVID приложению через UNIX-сокет Workload API. mTLS настраивается без хранения ключей в Kubernetes Secret.
Руководство даёт рабочий сценарий: устанавливаете SPIRE Server и Agent через Helm, настраиваете доверенный домен, регистрируете поды по ServiceAccount, получаете SVID в поде и настраиваете mTLS между двумя сервисами. Диагностика и требования для production разобраны в конце.
Что именно вы получите после развёртывания
- SPIRE Server запущен в отдельном namespace
spireи управляет корневым центром доверия. - SPIRE Agent запущен как DaemonSet на каждом узле и отдаёт SVID через Workload API.
- Pod с ServiceAccount
service-aполучает SPIFFE ID видаspiffe://example.org/ns/default/sa/service-aбез чтения статического секрета. - Два сервиса общаются по mTLS: каждый предъявляет SVID и проверяет SPIFFE ID оппонента.
- Идентификаторы обновляются автоматически до истечения TTL без рестарта приложения.
Почему статические секреты проигрывают динамической идентификации
Статический секрет, например bearer-токен или сертификат в Secret, известен обеим сторонам и хранится дольше, чем безопасная сессия. Ротация одного секрета требует одновременного обновления всех потребителей. Рассинхрон вызывает отказы, утечка открывает доступ на неопределённый срок. По умолчанию каждый под Kubernetes получает ServiceAccount с токеном, который может обращаться к Kubernetes API. Этот токен нужно явно ограничить через automountServiceAccountToken и минимальные RBAC, иначе компрометация пода даёт доступ к кластеру.
SPIRE снимает эту проблему: SVID выпускается под зарегистрированную рабочую нагрузку, живёт коротко и привязан к SPIFFE ID. Приложение получает ключ в память и не читает Secret.
Чем SVID отличается от Kubernetes Secret
SVID выпускается с коротким TTL, обычно 1 час, содержит SPIFFE ID, подпись SPIRE Server и публичный ключ. Kubernetes Secret хранит произвольные данные в etcd, по умолчанию не ротируется и не привязан к живой идентичности процесса. SVID не кладётся в Secret и обновляется агентом до истечения срока.
Когда SPIRE действительно оправдан
- Нужен межсервисный mTLS с проверкой SPIFFE ID.
- Вы строите zero trust сеть, где доверие не зависит от IP или подсети.
- Требуется единая идентичность сервисов в нескольких кластерах.
- Нужно отказаться от долгоживущих статических токенов.
Если нужен только TLS внутри одного namespace, достаточно cert-manager. SPIRE добавляет ценность при проверке идентичности сервиса, а не просто при шифровании трафика.
Архитектура SPIRE: SPIRE Server, Agent и Workload API
SPIRE состоит из сервера, агентов на узлах и механизма регистрации рабочих нагрузок. Путь идентификатора выглядит так: registration entry описывает под, агент аттестует узел и под, сервер проверяет селекторы и выдаёт SVID агенту, агент доставляет SVID приложению через Workload API.
SPIRE Server: центр доверия и выдачи SVID
SPIRE Server управляет корневым CA, хранит registration entries и подписывает SVID. В production нужно выделять отдельный trust domain, защищать ключи сервера и настраивать резервное копирование CA.
SPIRE Agent и Workload API: точка интеграции на узле
SPIRE Agent размещается на каждом узле как DaemonSet. Агент кэширует SVID и предоставляет UNIX-сокет Workload API, обычно /run/spire/agent/public/api.sock. Приложение запрашивает SVID локально и не обращается к Kubernetes API напрямую.
Workload Registration: как SPIRE узнаёт о ваших подах
Регистрация выполняется через селекторы: k8s:ns, k8s:sa, k8s:pod-label. SPIRE сопоставляет поды с SPIFFE ID на основе этих селекторов. Workload Registrars автоматизируют создание registration entries при появлении новых ServiceAccount или подов.
Подготовка кластера и установка SPIRE через Helm
Перед установкой нужно освежить устройство кластера и объектов API. Если нужно повторить базовые сущности Kubernetes, смотрите Kubernetes: архитектура кластера и ключевые объекты API.
Требования к кластеру и выбор namespace
Минимальные требования: Kubernetes 1.26 и Helm 3.12. Для изоляции компонентов создайте namespace spire. DaemonSet агента займёт по одному поду на узел, серверу достаточно одного реплика в тестовой среде и трёх в production. Если управляемого кластера ещё нет, Kubernetes можно развернуть в Timeweb Cloud.
Минимальный values.yaml для SPIRE Server и Agent
Создайте values.yaml. Trust domain задаётся одинаковым для сервера и агента. Пример конфигурации:
spire-server:
enabled: true
replicaCount: 1
trustDomain: example.org
spire-agent:
enabled: true
trustDomain: example.org
server:
address: spire-server.spire.svc.cluster.local
port: 8081
socketPath: /run/spire/agent/public/api.sock
logLevel: INFO
Добавьте официальный Helm-репозиторий SPIRE и обновите кеш. Затем выполните установку:
kubectl create namespace spire
helm install spire spiffe/spire --namespace spire --values values.yaml
Проверка установки: логи, поды и статусы
kubectl get pods -n spire -o wide
kubectl logs -n spire -l app=spire-server
kubectl logs -n spire -l app=spire-agent
Все поды сервера и агентов должны находиться в состоянии Running и проходить readiness-пробу. Если агент не запускается, смотрите логи через kubectl describe pod.
Настройка доверенного домена и подключение агентов
Что такое trust domain и как выбрать корректное имя
Формат SPIFFE ID: spiffe://trust-domain/path. Имя должно быть стабильным и уникальным, обычно используют домен организации: example.org. Переименование trust domain после развёртывания болезненно, потому что все записи и проверки mTLS завязаны на этот корень.
Методы аутентификации агентов: join token и Kubernetes PSAT
Join token подходит для начального подключения агентов. Генерируется на сервере:
kubectl exec -n spire spire-server-0 -- spire-server agent generate-join-token -spiffeID spiffe://example.org/agent/cluster1 -ttl 3600
Kubernetes PSAT использует projected service account token и лучше подходит для автоматического добавления узлов. Для PSAT задайте метод соединения в values.yaml агента и минимум прав для TokenReview.
Проверка регистрации агентов на сервере
kubectl exec -n spire spire-server-0 -- spire-server agent list
В выводе агент должен иметь статус attested. Пока агент не аттестован, выдача SVID для подов на этом узле невозможна.
Регистрация рабочих нагрузок: от ServiceAccount к SPIFFE ID
Selectors: как SPIRE сопоставляет поды с идентификаторами
Селекторы определяют, какие поды получают SPIFFE ID. Запись с селекторами k8s:ns:default и k8s:sa:service-a выдаёт один и тот же SPIFFE ID всем подам в namespace default, использующим ServiceAccount service-a.
Пример регистрации сервиса через namespace и ServiceAccount
kubectl exec -n spire spire-server-0 -- spire-server entry create -spiffeID spiffe://example.org/ns/default/sa/service-a -parentID spiffe://example.org/agent/cluster1 -selector k8s:ns:default -selector k8s:sa:service-a -ttl 3600
Параметр -ttl ограничивает срок жизни SVID. Для сервиса service-b создайте аналогичную запись с собственным SPIFFE ID.
Проверка выдачи SVID в тестовом поде
Запустите под с ServiceAccount service-a. Проверьте наличие сокета Workload API:
kubectl exec -n default test-pod -- ls -l /run/spire/agent/public/api.sock
Через Workload API под получит SPIFFE ID, приватный ключ в памяти и trust bundle. Приложение не хранит эти данные в файловой системе или Secret.
Интеграция приложений через Workload API и настройка mTLS без статических секретов
Приложение обращается к локальному сокету Workload API. Агент возвращает SVID, приватный ключ в памяти и корневые сертификаты. Если нужно настроить сетевой доступ между сервисами, смотрите Service и Ingress в Kubernetes.
Как приложение получает SVID и корневые сертификаты
SVID содержит цепочку сертификатов и приватный ключ. Trust bundle содержит корневые сертификаты, нужные для проверки оппонента. Всё передаётся через gRPC-вызовы к сокету, поэтому секрет не попадает в переменные окружения и файловую систему.
Настройка Envoy SDS для mTLS: практический пример
Envoy получает сертификаты через SDS от SPIRE Agent. Пример фрагмента конфигурации для upstream:
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
'@type': type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
tls_certificate_sds_secret_configs:
- name: spiffe://example.org/ns/default/sa/service-a
sds_config:
api_config_source:
api_type: GRPC
grpc_services:
envoy_grpc:
cluster_name: spire-agent
validation_context_sds_secret_configs:
- name: spiffe://example.org
sds_config:
api_config_source:
api_type: GRPC
grpc_services:
envoy_grpc:
cluster_name: spire-agent
Кластер spire-agent направляет SDS-запросы на UNIX-сокет Workload API. Envoy обновляет сертификаты без перезапуска.
Проверка mTLS между двумя сервисами
Отправьте запрос от service-a к service-b по HTTPS или gRPC. Проверьте, что оба сервиса предъявили SVID и доверяют корням. При ошибке рукопожатия в логах Envoy появится TLS error: certificate verify failed, что указывает на несовпадение trust domain или trust bundle.
Автоматическая ротация SVID и сертификатов
Жизненный цикл SVID: TTL, обновление и отзыв
TTL задаётся при создании registration entry. Агент запрашивает новый SVID до истечения срока, не дожидаясь протухания сертификата. Отзыв выполняется удалением registration entry, после чего новые SVID не выдаются, а уже выпущенные перестанут обновляться.
Ротация trust bundle и корневых сертификатов
Trust bundle обновляется через Workload API. Приложения должны принимать несколько корневых сертификатов в переходный период, чтобы обновление корня не разрывало mTLS-соединения.
Как проверить, что ротация работает без рестарта
Посмотрите срок действия выданного SVID, дождитесь обновления и повторите mTLS-запрос. Сессия между сервисами не должна прерываться. В логах агента видно, когда SVID был перевыпущен.
Безопасная эксплуатация SPIRE: минимальные RBAC-права и аудит
Какие права нужны SPIRE Server и Agent: минимальный набор
Агенту нужны права на чтение подов и узлов, а также создание TokenReview для аттестации. Пример Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: spire-agent
namespace: spire
rules:
- apiGroups: ['']
resources: ['pods', 'nodes']
verbs: ['get', 'list', 'watch']
- apiGroups: ['authentication.k8s.io']
resources: ['tokenreviews']
verbs: ['create']
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: spire-agent
namespace: spire
subjects:
- kind: ServiceAccount
name: spire-agent
namespace: spire
roleRef:
kind: Role
name: spire-agent
apiGroup: rbac.authorization.k8s.io
Серверу нужны права на управление registration entries и узлами. Используйте Role + RoleBinding внутри namespace, ClusterRole только для кластерных ресурсов.
Типовые антипаттерны: wildcard, cluster-admin и лишние токены
Wildcard в verbs и resources даёт права на все текущие и будущие ресурсы. Привязка к встроенной роли cluster-admin снимает все ограничения. Отключайте автоматическое монтирование токена ServiceAccount, если приложение не обращается к Kubernetes API.
Аудит RBAC: kubectl auth can-i, rakkess, rbac-tool
Перед написанием манифеста проверьте текущие разрешения:
kubectl auth can-i --list --as=system:serviceaccount:spire:spire-agent
Для быстрого аудита используйте rakkess и rbac-tool. Запускайте проверку регулярно, чтобы права не накапливались при обновлениях.
Диагностика типовых неисправностей SPIRE в Kubernetes
Для быстрой диагностики подов и узлов через метрики CPU, памяти и сети используйте Kubernetes troubleshooting: диагностика pods и узлов через метрики мониторинга.
Агент не подключается к серверу
Проверьте join token, сетевое соединение до spire-server.spire.svc.cluster.local:8081, RBAC агента и отпечаток сервера. Выполните spire-server agent list и kubectl logs -n spire -l app=spire-agent. Частая причина: истёкший join token или неверный trust domain.
Под не получает SVID: селекторы и регистрационные записи
Проверьте селекторы k8s:ns и k8s:sa, наличие registration entry и правильность ServiceAccount пода. Выполните spire-server entry show и сравните с фактическим namespace и ServiceAccount. Если запись есть, проверьте сокет Workload API внутри пода.
mTLS-ошибки: trust domain и bundle mismatch
Проверьте SPIFFE ID обеих сторон, совпадение trust domain и наличие trust bundle. Ошибка certificate verify failed обычно означает, что оппонент предъявляет SVID из другого trust domain или в trust bundle нет нужного корня.
Чеклист production-развёртывания SPIFFE/SPIRE
Перед выкаткой в production сверьтесь с контрольным списком. Если проектируете кластер с нуля, за основу можно взять Kubernetes 2026: проектирование и управление промышленными кластерами.
Контрольные точки перед выкаткой
- RBAC для сервера и агента ограничен минимальными правами.
- Trust domain выбран и зафиксирован.
- ServiceAccount с лишними токенами отключены или ограничены.
- TTL SVID установлен, но не слишком короткий для стабильной работы.
- Логи сервера и агентов собираются в систему мониторинга.
- Резервная копия CA доступна и защищена.
Поддержание и обновление SPIRE в production
Регулярно проверяйте RBAC-права, обновляйте Helm-чарт в staging до production, тестируйте отказоустойчивость сервера и следите за ротацией SVID. План обновления должен включать откат и проверку trust bundle.