Практика и гайды

Что такое секреты Kubernetes

Что такое секреты Kubernetes

Секреты Kubernetes — это объекты кластера для хранения чувствительных данных: паролей, токенов, API-ключей, TLS-сертификатов и SSH-ключей. Они позволяют держать такие значения отдельно от образов контейнеров, манифестов и кода приложения.

В Kubernetes секрет хранится как набор пар ключ-значение и может использоваться pod, Deployment и другими ресурсами. Это базовый механизм управления конфиденциальными данными внутри кластера.

Содержание статьи

Что такое Kubernetes и зачем ему секреты

Kubernetes — это платформа оркестрации контейнеров, которая управляет запуском, масштабированием и жизненным циклом приложений. Секреты нужны ей для безопасной передачи чувствительных данных рабочим нагрузкам без встраивания этих данных в конфигурацию контейнера.

Когда приложение подключается к базе данных, внешнему API или приватному реестру образов, ему почти всегда нужны учётные данные. Если хранить их прямо в YAML-файле pod или в переменных внутри образа, риск утечки растёт. Секреты снижают этот риск, потому что выносят конфиденциальные значения в отдельный ресурс.

Их часто сравнивают с ConfigMap. Разница простая: ConfigMap предназначен для обычной конфигурации, а Secret — для данных, которые не стоит держать в открытом виде.

Как работают секреты Kubernetes в кластере

Секреты хранятся в кластере как отдельные объекты Kubernetes, а доступ к ним идёт через Kubernetes API. Pod не обязан содержать пароль или токен внутри своей спецификации: он может просто сослаться на нужный Secret.

Данные секретов сохраняются в etcd, хранилище ключ-значение, на котором работает управляющая плоскость Kubernetes. По умолчанию значения обычно представлены в виде Base64. Это формат кодирования, а не защита от чтения.

Дальше в работу вступают компоненты кластера. API-сервер отдаёт объект только аутентифицированным и авторизованным клиентам. Kubelet на узле получает секреты, на которые ссылаются pod, запущенные на этом узле, и передаёт их контейнеру как переменные окружения или как файлы в смонтированном томе.

Из-за этого у секретов есть важная особенность: безопасность зависит не только от самого объекта Secret, но и от настроек доступа, шифрования и прав на создание pod.

Как выглядит объект Secret в YAML

Secret в Kubernetes описывается обычным YAML-манифестом с полями apiVersion, kind, metadata, type и блоком данных. Внутри данных используются пары ключ-значение.

Чаще всего применяют поля data или stringData. В поле data значения указывают в Base64, а в stringData можно записывать строки в открытом виде, после чего Kubernetes сам преобразует их при создании объекта.

Пример структуры:

apiVersion: v1

kind: Secret

metadata:

name: mysecret

namespace: default

type: Opaque

data:

username: dXNlcg==

password: cGFzc3dvcmQ=

В этом примере username и password — ключи, а их значения представлены в Base64. Смысл при этом остаётся прежним: секрет хранит конкретные данные, которые затем может использовать приложение.

Какие типы секретов есть в Kubernetes

Kubernetes поддерживает несколько встроенных типов Secret, и выбор типа зависит от того, какие данные вы храните. Поле type помогает системе и инструментам понимать ожидаемую структуру секрета.

  • Opaque — тип по умолчанию для произвольных пар ключ-значение, например паролей и API-ключей.
  • Секреты токенов service account — содержат токены для аутентификации pod в Kubernetes API.
  • Docker registry secrets с типом dockerconfigjson — хранят данные для доступа к приватным реестрам контейнеров.
  • TLS secrets — содержат сертификат и закрытый ключ для TLS.
  • Basic authentication secrets — хранят имя пользователя и пароль для базовой аутентификации.
  • SSH authentication secrets — содержат SSH-ключи.
  • Bootstrap token secrets — применяются при добавлении узлов в кластер.

На практике чаще всего используют Opaque, TLS и секреты для доступа к реестру. Остальные типы встречаются реже, но они тоже встроены в модель Kubernetes.

Как создать секрет в Kubernetes через kubectl

Создать Secret можно из командной строки через kubectl, передав литералы или файлы. Для универсального секрета обычно используют команду kubectl create secret generic.

Пример создания из пар ключ-значение:

kubectl create secret generic mysecret

—from-literal=username=user

—from-literal=password=password

Эта команда создаёт объект mysecret, где значения будут записаны как данные секрета. После этого можно проверить, что ресурс появился в кластере.

Если секрет уже хранится в файлах, подходит другой вариант:

kubectl create secret generic db-user-pass

—from-file=username.txt

—from-file=password.txt

В таком случае имя файла обычно становится ключом, а его содержимое — значением. Этот способ удобен для сертификатов, ключей и готовых файлов с учётными данными.

Как проверить, что секрет создан

Проверка выполняется стандартными командами kubectl. Они показывают список секретов, метаданные и состав данных без обязательного вывода самих значений.

  • kubectl get secrets
  • kubectl get secret mysecret
  • kubectl describe secret mysecret

Как посмотреть секреты в Kubernetes

Посмотреть секреты можно через kubectl, но по умолчанию значения не выводятся в расшифрованном виде. Обычно сначала смотрят список объектов и ключи внутри конкретного секрета.

Для списка секретов в пространстве имён используют:

kubectl get secrets

Для просмотра описания конкретного объекта:

kubectl describe secret mysecret

Для проверки набора ключей внутри секрета:

kubectl get secret mysecret -o jsonpath='{.data}’

Такой просмотр полезен для диагностики: можно быстро понять, существует ли объект, в каком namespace он лежит и какие ключи содержит.

Как прочитать значения секрета

Чтобы прочитать содержимое Secret, данные нужно декодировать из Base64. Сам Kubernetes не считает Base64 защитой, поэтому вывод в открытом виде требует отдельного шага.

Если нужно получить одно значение, используют jsonpath и декодирование:

kubectl get secret mysecret -o jsonpath='{.data.username}’ | base64 —decode

Если требуется вывести все ключи сразу, применяют вывод в JSON и обработку через jq:

kubectl get secret mysecret -o json | jq -r ‘.data | map_values(@base64d)’

Можно и просто экспортировать объект в YAML:

kubectl get secret mysecret -o yaml

Но в этом случае значения всё равно останутся в Base64. То есть экспорт показывает структуру ресурса, а не готовые к чтению строки.

Как использовать секреты в pod и других рабочих нагрузках

Секреты в Kubernetes обычно подключают двумя способами: через переменные окружения или через том, смонтированный в файловую систему контейнера. Оба способа позволяют приложению получать нужные данные без жёсткого встраивания в образ.

Первый вариант подходит, когда приложение читает настройки из переменных окружения. В спецификации pod указывают env, а значение берут через secretKeyRef.

Принцип такой:

в переменную DB_USERNAME подставляется ключ username из секрета mysecret

в переменную DB_PASSWORD подставляется ключ password из того же секрета

Этот подход удобен, если приложение уже умеет читать логины, пароли и токены из окружения.

Второй вариант — монтирование секрета как тома. Тогда каждый ключ внутри Secret становится отдельным файлом в заданном каталоге контейнера. Такой способ часто используют для TLS-сертификатов, SSH-ключей и других файловых данных.

Если приложению нужен именно файл, а не строка в переменной, том обычно подходит лучше. Если нужны отдельные значения в процессе запуска, удобнее переменные окружения.

Как права доступа влияют на безопасность секретов

Безопасность Secret сильно зависит от RBAC, namespace и принципа минимальных привилегий. Даже правильно созданный секрет может стать уязвимым, если у пользователей или сервисных учётных записей слишком широкие права.

RBAC управляет тем, кто может читать, изменять и перечислять секреты. Права задаются через роли и привязки ролей. Если субъекту разрешены действия get, list или update для ресурсов secret, он может получить доступ к конфиденциальным данным в пределах допустимого namespace.

Есть и другой важный момент. Секреты привязаны к конкретному namespace. Но пользователь, который может создавать pod в этом namespace, потенциально способен подключить к pod любой доступный там Secret. Поэтому контроль прав на создание и изменение рабочих нагрузок не менее важен, чем контроль прав на сами секреты.

Service account тоже участвуют в этой схеме. Pod запускается от имени service account и наследует её права. Если у этой учётной записи есть доступ к секретам, приложение внутри pod сможет их использовать.

Чем Secret отличается от безопасного хранилища по умолчанию

Secret в Kubernetes не шифруется автоматически только потому, что называется секретом. По умолчанию данные часто хранятся в формате Base64, а это способ представления данных, а не механизм защиты.

Для защиты данных в etcd включают шифрование на стороне API-сервера. В этом режиме секрет шифруется перед записью в хранилище. Это снижает риск раскрытия значений при доступе к backend-хранилищу.

Отдельно защищается передача данных между компонентами кластера. Для этого используется TLS. Он нужен, чтобы секреты не передавались по сети в открытом виде между API-сервером, kubelet и другими компонентами.

Получается простая картина: Base64 нужен для формата данных, TLS — для передачи, шифрование в etcd — для хранения.

Где применяются секреты Kubernetes

Секреты Kubernetes используют везде, где приложению нужны чувствительные данные во время работы. Чаще всего это доступ к базам данных, внешним сервисам, приватным реестрам и зашифрованным соединениям.

  • пароли и имена пользователей для баз данных;
  • токены и API-ключи внешних сервисов;
  • данные для входа в приватный реестр контейнеров;
  • TLS-сертификаты и закрытые ключи;
  • SSH-ключи для автоматизированного доступа;
  • токены service account для работы с Kubernetes API.

Во всех этих случаях смысл один: приложение получает доступ к нужному ресурсу, а сами чувствительные значения не попадают в образ контейнера и не размазываются по конфигурации.

Как управлять секретами Kubernetes на практике

Управление секретами включает весь жизненный цикл данных: создание, хранение, выдачу доступа, обновление и удаление. Здесь важна не одна настройка, а связка нескольких мер.

  1. Включить шифрование данных в etcd, чтобы секреты не лежали в хранилище в виде, удобном для чтения.
  2. Ограничить доступ через RBAC, оставив права только тем пользователям и service account, которым они действительно нужны.
  3. Сократить круг тех, кто может создавать pod в namespace, потому что через pod можно подключать секреты.
  4. Регулярно обновлять пароли, токены, ключи и сертификаты, чтобы старые значения не жили слишком долго.
  5. Не хранить секреты в системе контроля версий в открытом виде, даже если данные уже представлены в Base64.
  6. Проверять журналы аудита, если в кластере настроен аудит обращений к API.
  7. Использовать внешние менеджеры секретов, когда нужен централизованный контроль жизненного цикла и единая политика доступа.

Когда секретов немного, встроенных механизмов Kubernetes часто хватает. Когда их много, появляется задача ротации, журналирования и синхронизации, и тогда управление усложняется уже на уровне процессов.

Когда нужны внешние менеджеры секретов

Внешние менеджеры секретов нужны тогда, когда встроенного объекта Secret уже недостаточно для централизованного контроля. Обычно это связано с требованиями к ротации, аудиту, единому месту хранения и разграничению доступа между разными системами.

В таких сценариях используют сервисы вроде HashiCorp Vault, AWS Secrets Manager или Google Secret Manager вместе с механизмами интеграции Kubernetes, например Secrets Store CSI Driver. Kubernetes в этом случае остаётся потребителем секрета, а не основным местом его жизненного цикла.

Подход полезен, если одна и та же учётная запись нужна не только внутри кластера, но и в других средах. Тогда секретом проще управлять из одной точки, а не копировать его по нескольким системам.

Краткое сравнение Secret и ConfigMap

Secret и ConfigMap похожи по форме, но различаются по назначению. Первый используют для чувствительных данных, второй — для обычной конфигурации.

Параметр Secret ConfigMap
Назначение Конфиденциальные данные Обычная конфигурация
Типичные данные Пароли, токены, ключи, сертификаты Настройки приложения, флаги, параметры
Способ хранения Объект Kubernetes с данными в key-value Объект Kubernetes с данными в key-value
Отношение к защите Требует отдельной настройки шифрования и доступа Не предназначен для чувствительных данных

Какие практики считаются базовыми

Базовые правила работы с секретами Kubernetes сводятся к ограничению доступа, защите хранилища и аккуратному использованию в манифестах. Эти меры не убирают все риски, но закрывают самые частые ошибки.

  • Включайте шифрование секретов в etcd.
  • Выдавайте доступ по RBAC только по необходимости.
  • Не храните чувствительные данные в открытом виде в Git и других репозиториях.
  • Регулярно меняйте API-ключи, пароли и сертификаты.
  • Проверяйте, кто может создавать pod и изменять рабочие нагрузки.

Если смотреть на секреты без лишней теории, вывод простой. Secret удобен как штатный контейнер для конфиденциальных данных внутри Kubernetes, но его безопасность держится на настройках кластера, а не на одном только названии ресурса.