Объект Secret — это фундаментальный компонент Kubernetes для безопасного хранения и управления конфиденциальными данными в контейнеризированных средах. В 2026 году, с ужесточением требований к безопасности и распространением облачных нативных архитектур, правильное использование секретов стало критически важным навыком для каждого DevOps-инженера и системного администратора. Это руководство предоставляет проверенные на практике, пошаговые инструкции по созданию, подключению и защите секретов — от базовых команд kubectl до интеграции с Ingress-контроллерами и реализации политик контроля доступа.
Вы освоите все методы работы с паролями, API-токенами, SSH-ключами и TLS-сертификатами, научитесь избегать распространенных уязвимостей и сможете сразу применять полученные знания в своих рабочих кластерах, экономя время на поиск и проверку информации.
Что такое Kubernetes Secrets и зачем они нужны в 2026 году
Kubernetes Secret — это специальный объект API, предназначенный для хранения и управления конфиденциальной информацией, такой как пароли, OAuth-токены, SSH-ключи и TLS-сертификаты. В отличие от ConfigMap, который хранит неконфиденциальные данные в открытом виде, Secret обеспечивает дополнительный уровень безопасности за счет кодирования данных в base64 и интеграции с механизмами контроля доступа RBAC.
В 2026 году актуальность работы с секретами только возросла по нескольким причинам:
- Ужесточение требований безопасности — современные стандарты (GDPR, PCI DSS, HIPAA) требуют строгого контроля доступа к конфиденциальным данным
- Распространение GitOps-практик — необходимость безопасного хранения секретов вне систем контроля версий
- Масштабирование микросервисных архитектур — увеличение количества сервисов требует централизованного управления учетными данными
- Интеграция с внешними системами — облачные провайдеры, базы данных, API-сервисы требуют безопасного хранения токенов доступа
Основные типы данных, которые хранятся в Secrets:
- Учетные данные — пароли, логины, ключи доступа к базам данных
- API-токены — ключи для доступа к облачным сервисам (AWS, Google Cloud, Azure)
- TLS/SSL сертификаты — для шифрования трафика в Ingress-контроллерах
- SSH-ключи — для доступа к приватным Git-репозиториям
- Регистрационные данные Docker — для pull-запросов к приватным реестрам образов
Важно понимать, что базовое кодирование base64 не является шифрованием — это лишь способ представления бинарных данных в текстовом формате. Реальная безопасность достигается через RBAC, ограничение доступа к etcd и использование внешних систем управления секретами для production-сред с высокими требованиями.
Практическое создание секретов: от базовых команд до продвинутых методов
Существует несколько способов создания секретов в Kubernetes, каждый из которых подходит для разных сценариев. Выбор метода зависит от требований безопасности, уровня автоматизации и специфики рабочего процесса.
Создание секрета через kubectl create secret: быстрый старт
Для быстрого создания секрета в тестовой среде или при решении срочной задачи используйте команду kubectl create secret generic. Это самый простой метод, который не требует подготовки YAML-манифестов.
Создание секрета из литералов (значений, передаваемых напрямую):
kubectl create secret generic app-db-secret \
--from-literal=username=prod_admin \
--from-literal=password='S3cur3P@ssw0rd!2026' \
--namespace=production
Создание секрета из файлов (удобно для сертификатов и ключей):
kubectl create secret generic tls-secret \
--from-file=tls.crt=./ssl/certificate.crt \
--from-file=tls.key=./ssl/private.key
Важное предупреждение: При использовании --from-literal секретные значения могут сохраняться в истории командной оболочки (shell history). Чтобы избежать этого, используйте файлы или переменные окружения:
export DB_PASSWORD='S3cur3P@ssw0rd!2026'
kubectl create secret generic db-secret \
--from-literal=password="${DB_PASSWORD}"
После создания проверьте секрет:
kubectl get secret app-db-secret -o yaml
kubectl describe secret app-db-secret
Декларативный подход: YAML-манифесты для полного контроля
Для production-сред рекомендуется использовать декларативный подход с YAML-манифестами. Это обеспечивает воспроизводимость, возможность версионирования и интеграцию с GitOps-практиками.
Перед созданием манифеста закодируйте значения в base64:
echo -n 'prod_admin' | base64
# Результат: cHJvZF9hZG1pbg==
echo -n 'S3cur3P@ssw0rd!2026' | base64
# Результат: UzNjdXIzUEBzc3cwcmQhMjAyNg==
Пример полного YAML-манифеста для секрета:
apiVersion: v1
kind: Secret
metadata:
name: app-db-secret
namespace: production
type: Opaque
data:
username: cHJvZF9hZG1pbg== # prod_admin
password: UzNjdXIzUEBzc3cwcmQhMjAyNg== # S3cur3P@ssw0rd!2026
Примените манифест:
kubectl apply -f secret.yaml
Рекомендация по безопасности: Храните в Git только шаблоны манифестов без реальных значений или используйте инструменты типа Sealed Secrets, SOPS или внешние хранилища секретов. Реальные секретные значения должны заполняться в CI/CD-пайплайне или через операторы.
Генераторы (Kustomize) и работа с файлами конфигурации
Kustomize предоставляет мощный механизм secretGenerator для динамического создания и обновления секретов. Это особенно полезно при управлении множеством окружений (dev, staging, production).
Создайте файл kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
secretGenerator:
- name: app-secrets
files:
- .env.secret
type: Opaque
Файл .env.secret (никогда не добавляйте в Git!):
DB_HOST=postgres.production.svc.cluster.local
DB_PORT=5432
DB_USER=app_user
DB_PASSWORD=S3cur3P@ssw0rd!2026
API_KEY=ak_7x9b2c4d6e8f0a1b3c5d7e9f
Или используйте литералы напрямую в kustomization.yaml:
secretGenerator:
- name: api-secret
literals:
- API_KEY=ak_7x9b2c4d6e8f0a1b3c5d7e9f
- JWT_SECRET=jwt_s3cr3t_k3y_2026
Примените конфигурацию:
kubectl apply -k .
Преимущество Kustomize: При изменении исходных файлов или литералов Kustomize автоматически генерирует новый секрет с обновленными данными и уникальным суффиксом в имени, что позволяет безопасно обновлять секреты без конфликтов.
Безопасное использование секретов в Pod: как избежать уязвимостей
После создания секрета критически важно правильно подключить его к подам. Kubernetes предоставляет два основных метода, каждый со своими особенностями безопасности.
Переменные окружения: простота vs риски
Подключение секретов как переменных окружения — самый простой, но не всегда самый безопасный метод.
Пример манифеста пода с секретом в переменных окружения:
apiVersion: v1
kind: Pod
metadata:
name: app-with-secret-env
spec:
containers:
- name: app-container
image: myapp:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: app-db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-db-secret
key: password
Риски использования переменных окружения:
- Логирование — многие приложения автоматически логируют переменные окружения при запуске или при ошибках
- Доступ процессов — все дочерние процессы получают доступ к переменным окружения родительского процесса
- Инспекция контейнера — команды типа
kubectl execмогут показывать переменные окружения - Дампы памяти — при аварийном завершении секреты могут оставаться в дампах памяти
Рекомендация: Используйте переменные окружения только для не самых критичных данных или в development-средах. Для production с высокими требованиями безопасности предпочтительнее метод с volumes.
Подключение через Volumes: рекомендуемый подход для production
Монтирование секретов как файлов в файловую систему пода — более безопасная альтернатива, рекомендованная для production-сред.
Пример конфигурации:
apiVersion: v1
kind: Pod
metadata:
name: app-with-secret-volume
spec:
containers:
- name: app-container
image: myapp:latest
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: app-db-secret
items:
- key: username
path: db-username
- key: password
path: db-password
Преимущества подхода с volumes:
- Контроль прав доступа — можно установить
readOnly: trueдля предотвращения модификации - Изоляция — секреты доступны только как файлы, не передаются дочерним процессам
- Меньше шансов залогировать — приложения реже логируют содержимое файлов, чем переменные окружения
- Динамическое обновление — при изменении секрета kubelet может автоматически обновлять файлы (настраивается)
Для дополнительной безопасности настройте права доступа к файлам:
volumes:
- name: secret-volume
secret:
secretName: app-db-secret
defaultMode: 0400 # Только чтение для владельца
Этот подход особенно важен при работе с stateful-приложениями, где правильная настройка томов критична для отказоустойчивости. Для комплексного управления развертываниями рекомендуем ознакомиться с полным руководством по Kubernetes Deployment, где подробно разбираются стратегии обновления и управления репликами.
Работа с сертификатами, SSH-ключами и API-токенами
Kubernetes поддерживает специальные типы секретов для работы с конкретными форматами данных. Использование правильных типов упрощает интеграцию с другими компонентами системы.
TLS/SSL сертификаты для безопасного Ingress
Для работы с TLS-шифрованием в Ingress-контроллерах используйте секреты типа tls. Они автоматически распознаются Ingress-ресурсами и используются для termination TLS.
Создание TLS-секрета через kubectl:
kubectl create secret tls my-tls-secret \
--cert=path/to/fullchain.pem \
--key=path/to/privkey.pem \
--namespace=production
Или через YAML-манифест (предварительно закодируйте сертификат и ключ в base64):
apiVersion: v1
kind: Secret
metadata:
name: my-tls-secret
namespace: production
type: kubernetes.io/tls
data:
tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t... # Ваш сертификат в base64
tls.key: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0t... # Ваш приватный ключ в base64
Использование в Ingress-ресурсе:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: secure-ingress
namespace: production
spec:
tls:
- hosts:
- app.example.com
secretName: my-tls-secret # Ссылка на TLS-секрет
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
Важно: Файлы сертификата и ключа должны быть в правильном формате (PEM). Проверьте их перед созданием секрета:
# Для сертификата
openssl x509 -in certificate.crt -text -noout
# Для ключа
openssl rsa -in private.key -check
SSH-ключи и Docker-registry секреты
Для работы с приватными Git-репозиториями, доступными по SSH, создайте секрет типа ssh-auth:
kubectl create secret generic ssh-key-secret \
--type=kubernetes.io/ssh-auth \
--from-file=ssh-privatekey=~/.ssh/id_rsa \
--from-file=ssh-publickey=~/.ssh/id_rsa.pub
Использование в поде:
spec:
containers:
- name: git-cloner
image: alpine/git
volumeMounts:
- name: ssh-volume
mountPath: /root/.ssh
volumes:
- name: ssh-volume
secret:
secretName: ssh-key-secret
defaultMode: 0600
Для pull-запросов образов из приватных Docker-регистри создайте секрет типа docker-registry:
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=deploy-user \
--docker-password='d3pl0yT0k3n2026' \
--docker-email=devops@company.com
Использование в спецификации пода:
spec:
imagePullSecrets:
- name: regcred
containers:
- name: private-app
image: registry.example.com/company/app:latest
Эти специализированные секреты интегрируются с внутренними механизмами Kubernetes и обеспечивают более безопасное управление доступом по сравнению с универсальными Opaque-секретами.
Интеграция с Ingress и усиление защиты доступа
Безопасность секретов не ограничивается их хранением — важно также защитить endpoint'ы, которые используют эти секреты для аутентификации. Комбинация TLS-шифрования и IP-базированных политик доступа создает многоуровневую защиту.
Настройка TLS-termination в Ingress с вашим секретом
После создания TLS-секрета его можно использовать в Ingress-контроллере для обеспечения шифрованного соединения. Схема работы:
- Клиент устанавливает HTTPS-соединение с Ingress-контроллером
- Ingress использует приватный ключ из секрета для расшифровки трафика
- Трафик перенаправляется на соответствующий сервис внутри кластера
- Сертификат из секрета отправляется клиенту для проверки подлинности
Пример полной конфигурации с TLS и path-based routing:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-service-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- api.company.com
secretName: api-tls-secret-2026
rules:
- host: api.company.com
http:
paths:
- path: /v1/users
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
- path: /v1/orders
pathType: Prefix
backend:
service:
name: order-service
port:
number: 8081
Для управления сложными конфигурациями Ingress и автоматизации развертываний рассмотрите использование Helm. В нашем руководстве по созданию production-ready Helm-чартов вы найдете готовые шаблоны и best practices для 2026 года.
Дополнительная защита: IP-базированные политики доступа (allowlist/denylist)
Для критичных endpoint'ов, таких как административные панели или API с повышенными требованиями безопасности, TLS-шифрования недостаточно. NGINX Ingress Controller позволяет определять IP-базированные правила доступа в виде отдельных ресурсов Policy, которые можно прикреплять к Ingress-ресурсам.
Факт: NGINX Ingress Controller позволяет определять IP-базированные правила доступа один раз в ресурсе Policy и применять их согласованно ко всем связанным Ingress.
Создание политики allowlist (разрешающей только определенные IP-адреса):
apiVersion: k8s.nginx.org/v1
kind: Policy
metadata:
name: corp-access-policy
spec:
accessControl:
allow:
- 203.0.113.0/24 # Корпоративная сеть
- 198.51.100.0/24 # VPN-сеть компании
- 192.0.2.16/28 # Офис разработки
Прикрепление политики к Ingress (на уровне всего ресурса):
Факт: Политика доступа, прикрепленная на уровне Ingress, применяется ко всем путям (paths) в этом Ingress.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: admin-panel-ingress
annotations:
nginx.org/policies: corp-access-policy
spec:
tls:
- hosts:
- admin.company.com
secretName: admin-tls-secret
rules:
- host: admin.company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: admin-panel-service
port:
number: 8080
Реальный кейс: Ограничение доступа к внутренней панели управления только с корпоративных IP-адресов и VPN. Это особенно важно для endpoint'ов, которые используют секреты для аутентификации администраторов.
Для сложных сценариев, когда разные пути требуют разных правил доступа:
Факт: Для применения разных правил доступа к разным путям одного приложения необходимо создавать отдельные ресурсы Ingress.
# Ingress для публичного API (без ограничений)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: public-api-ingress
spec:
rules:
- host: api.company.com
http:
paths:
- path: /public
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
# Отдельный Ingress для административных endpoint'ов (с ограничениями)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: admin-api-ingress
annotations:
nginx.org/policies: corp-access-policy
spec:
rules:
- host: api.company.com
http:
paths:
- path: /admin
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Такой подход обеспечивает глубокую защиту, комбинируя безопасность на уровне секретов (TLS-сертификаты) с безопасностью на сетевом уровне (IP-фильтрация).
Управление жизненным циклом и лучшие практики безопасности
Создание секретов — только начало. Для поддержания безопасности в production-средах необходимо правильно управлять их жизненным циклом, обновлением и аудитом.
Обновление и ротация секретов без downtime
Регулярная ротация секретов — обязательная практика для compliance и безопасности. В Kubernetes есть несколько подходов к обновлению секретов:
Метод 1: Прямое обновление существующего секрета
# 1. Закодируйте новое значение
echo -n 'N3wS3cur3P@ss2026' | base64
# Результат: TjN3UzNjdXJQQUA3czIwMjY=
# 2. Обновите манифест или примените patch
kubectl patch secret app-db-secret \
-p '{"data":{"password":"TjN3UzNjdXJQQUA3czIwMjY="}}'
# Или отредактируйте напрямую
kubectl edit secret app-db-secret
Важно: Существующие поды не получат автоматически обновленные значения. Им требуется перезапуск или recreation.
Метод 2: Создание нового секрета с обновлением Deployment
# 1. Создайте новый секрет с суффиксом версии
kubectl create secret generic app-db-secret-v2 \
--from-literal=password='N3wS3cur3P@ss2026'
# 2. Обновите Deployment для использования нового секрета
kubectl patch deployment app-deployment \
-p '{"spec":{"template":{"spec":{"volumes":[{"name":"secret-volume","secret":{"secretName":"app-db-secret-v2"}}]}}}}'
# 3. Запустите rolling update
kubectl rollout restart deployment/app-deployment
Для stateful-приложений или сервисов с длительными соединениями используйте стратегию blue-green deployment или feature flags для плавной миграции.
Чего избегать: распространенные ошибки и уязвимости
На основе практического опыта работы с production-кластерами выделим ключевые ошибки, которых следует избегать:
- Хранение секретов в незашифрованном виде в Git
Никогда не коммитьте реальные секретные значения в системы контроля версий. Используйте шаблоны, placeholders или специализированные инструменты (Sealed Secrets, SOPS, Vault). - Использование base64 как "шифрования"
Base64 — это кодирование, а не шифрование. Любой, кто имеет доступ к etcd или права на чтение секретов, может легко декодировать значения. Реальная защита обеспечивается через:- Шифрование данных в etcd (Kubernetes 1.13+)
- Строгий RBAC с принципом минимальных привилегий
- Использование внешних систем управления секретами
- Логирование секретов через переменные окружения
Как упоминалось ранее, переменные окружения часто попадают в логи. Используйте volumes и настройте приложения так, чтобы они не логировали конфиденциальные данные. - Недостаточный RBAC для ресурсов Secret
Ограничьте доступ к секретам по принципу наименьших привилегий. Пример опасной роли:
Вместо этого создавайте специализированные роли для конкретных use cases. Подробнее о гранулярном управлении доступом читайте в нашем руководстве по полной диагностике Custom Resources в Kubernetes.# НЕ ДЕЛАЙТЕ ТАК - слишком широкие права apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: secret-admin rules: - apiGroups: [""] resources: ["secrets"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - Игнорирование внешних систем управления секретами для production
Для кластеров с высокими требованиями безопасности рассмотрите использование специализированных решений:- HashiCorp Vault — наиболее полное решение с автоматической ротацией, аудитом и динамическими секретами
- AWS Secrets Manager / Azure Key Vault / Google Secret Manager — нативные решения облачных провайдеров
- External Secrets Operator — оператор для синхронизации секретов из внешних хранилищ в Kubernetes
Для комплексной безопасности контейнерной инфраструктуры также важно уделять внимание безопасности самих образов. В нашем руководстве по созданию безопасных Docker-образов для Python, Node.js и Go вы найдете готовые шаблоны многоэтапной сборки, оптимизации и сканирования на CVE-уязвимости.
Регулярно проводите аудит секретов в кластере:
# Поиск секретов с истекшими или скоро истекающими TLS-сертификатами
kubectl get secrets --all-namespaces -o json | \
jq -r '.items[] | select(.type=="kubernetes.io/tls") | \
.metadata.namespace + "/" + .metadata.name' | \
while read secret; do \
kubectl get secret -n $(echo $secret | cut -d/ -f1) \
$(echo $secret | cut -d/ -f2) -o jsonpath='{.data.tls\.crt}' | \
base64 -d | openssl x509 -noout -dates; \
done
Внедрение этих практик и регулярный аудит помогут поддерживать высокий уровень безопасности в ваших Kubernetes-кластерах и соответствовать современным требованиям compliance.