ServiceAccount token удобно выдавать workload, но это bearer credential: тот, кто получил копию токена, может предъявить её как собственную. Kubernetes 1.37 добавляет стабильный фундамент для другой модели — X.509-сертификатов с доказательством владения приватным ключом. При этом кластер пока не превращается в готовую PKI одним обновлением.
Это русская адаптация и инженерный разбор статьи Taahir Ahmed «Kubernetes v1.37: Pod Certificates and Cluster Trust Bundles», опубликованной Kubernetes 28 августа 2026 года. Материалы сайта распространяются по CC BY 4.0; текст переработан и дополнен рекомендациями для production-внедрения.
Bearer token доказывает предъявление, а не владение
Проецируемые ServiceAccount JWT хорошо встроены в kubelet: появляются до старта контейнера, обновляются автоматически, ограничиваются временем, объектом и audience. Их понимают облачные IAM-системы и множество внешних сервисов.
Слабое место заложено в самой bearer-модели. Для аутентификации клиент передаёт токен другой стороне. Если копия утекла через лог, дамп памяти, прокси или скомпрометированный peer, её можно повторно предъявить. Дополнительные binding сокращают окно и область злоупотребления, но не превращают токен в proof-of-possession credential.
В TLS приватный ключ не отправляется серверу. Клиент доказывает владение подписью, а сертификат связывает публичный ключ с идентичностью и доверенным центром сертификации. Pod Certificates переносят выпуск и доставку такого материала в стандартный жизненный цикл Pod.
Из каких частей собран новый контур
В архитектуре четыре участника.
Приложение объявляет в Pod spec проецируемые источники podCertificate и clusterTrustBundle, затем читает ключ, цепочку сертификатов и trust anchors из файловой системы. Kubelet генерирует приватный ключ и создаёт PodCertificateRequest. Signer controller решает, выдавать ли сертификат, заполняет цепочку и сообщает время начала обновления. ClusterTrustBundle публикует доверенные корневые и промежуточные сертификаты.
После назначения Pod на узел kubelet обнаруживает нужные volume sources. Для каждого сертификата он локально создаёт приватный ключ, отправляет запрос выбранному signer, получает подписанную цепочку и записывает credential bundle в контейнер. Для trust bundle kubelet выбирает объекты по имени signer и label selector, объединяет сертификаты, стабильно упорядочивает их и проецирует в указанный путь.
Ключевой эффект — приватный ключ не обязан покидать узел. Компонент выдачи видит публичную часть и утверждаемую идентичность, но не получает готовый credential целиком. Встроенный NodeRestriction ограничивает kubelet: скомпрометированный узел не должен запрашивать сертификаты для Pod, которые на нём не запущены.
Ротация встроена, reload — нет
Signer указывает status.beginRefreshAt, после чего kubelet повторяет выпуск и обновляет файлы. Для будущих встроенных signer автор статьи ожидает максимальный срок сертификата 24 часа; для других signer верхняя граница — 91 день.
Но обновлённый файл не означает, что процесс начал использовать новый ключ. Приложение должно заметить изменение через inotify или polling, перечитать credential и пересобрать TLS context. Долгоживущие соединения требуют отдельной политики: оставить их до естественного закрытия, дренировать заранее или принудительно переподключить.
Kubelet может записывать приватный ключ и цепочку одним credential bundle. Это упрощает атомарное чтение. При раздельных файлах приложение рискует увидеть новый ключ со старым сертификатом или наоборот. Значит, библиотека загрузки должна уметь обрабатывать согласованный snapshot, ошибки парсинга и повторную попытку без остановки всего процесса.
GA не означает готовый production-signer
На 3 сентября 2026 года Kubernetes не поставляет встроенный Pod Certificate signer. Стабильными стали API, kubelet-интеграция и доставка trust bundle, а политику выдачи реализует внешний контроллер.
В исходной статье для эксперимента используется Tinycert. Он выпускает сертификаты с DNS SAN для Kubernetes Service и SPIFFE-совместимые client certificates, но прямо назван демонстрационным, не production-решением. Переносить его в рабочий кластер без threat model, HA, защиты CA key и аудита нельзя.
Signer становится новой границей доверия. Он должен проверить, какой Pod, namespace, ServiceAccount и node стоят за запросом; ограничить допустимые SAN, EKU и lifetime; защитить ключ CA; вести журнал решений; корректно переживать повторы и частичные сбои. Компрометация signer опаснее утечки одного JWT: злоумышленник может выпускать новые credentials в пределах доступной политики.
Как вводить Pod Certificates без большого взрыва
Начните с одного внутреннего mTLS-сценария, где обе стороны принадлежат вашей платформе. Не пытайтесь сразу заменить все ServiceAccount tokens: JWT остаются полезны для federation с системами, которые уже их поддерживают.
Перед пилотом зафиксируйте контракт:
- Какая идентичность кодируется в subject или URI SAN и кто её проверяет.
- Какие signer names, key types, EKU, SAN и сроки разрешены каждому классу workload.
- Как приложение обнаруживает rotation и что делает с активными соединениями.
- Как распространяется новый trust anchor при ротации CA и сколько длится overlap.
- Какие метрики и события покажут задержку выпуска, отказ signer, просроченный сертификат и ошибку reload.
Проверьте не только happy path. Остановите signer перед обновлением, задержите ответ, отдайте некорректную цепочку, смените trust bundle, перезапустите kubelet и убедитесь, что приложение не продолжает молча работать с истёкшим credential. Отдельно проверьте rollback: старая и новая цепочки должны сосуществовать достаточно долго, чтобы все workload получили trust anchor до переключения.
Для наблюдаемости полезны четыре времени: создание PodCertificateRequest, выдача сертификата, запись файла kubelet и фактический reload приложения. Если измерять только первые три, control plane будет зелёным, пока workload продолжает использовать старый TLS context.
Ограничения
Pod Certificates не заменяют service mesh, authorization и сетевую политику. Сертификат отвечает на вопрос «кто предъявил ключ», но не решает, к каким методам и данным этой идентичности можно обращаться.
Механизм также не устраняет PKI-операции: защита CA, revocation strategy, trust-domain design и cross-cluster federation остаются задачами платформы. Короткий lifetime уменьшает ценность украденного ключа, но повышает зависимость от доступности signer и корректного reload.
Наконец, proof of possession не спасает процесс, который уже скомпрометирован. Вредоносный код внутри контейнера может использовать приватный ключ, не извлекая его наружу. Нужны isolation, минимальные права, контроль образов и runtime detection.
Вывод
Kubernetes 1.37 делает важный слой workload identity стандартным: kubelet создаёт ключ, запрашивает сертификат, доставляет trust bundle и запускает ротацию. Это сокращает объём самописной интеграции и позволяет не передавать peer полный credential, как в bearer-схеме.
Но production-готовность лежит на стыке четырёх контрактов: политики signer, защиты CA, безопасного обновления файлов и reload внутри приложения. Если любой из них отсутствует, сертификат в volume остаётся красивым артефактом, а не работающей mTLS-идентичностью.