# ConfigMap и Secret

> Объекты Kubernetes для передачи конфигурации в поды — ConfigMap хранит обычные настройки, Secret предназначен для паролей, токенов и ключей.

Источник: https://llmdocs.ru/wiki/configmap-secret/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Тип**: объекты API Kubernetes (core/v1)
- **Хранилище**: etcd
- **Максимальный размер**: 1 МиБ на объект
- **Способы передачи**: переменные окружения, файлы в томе, аргументы команды
- **Неизменяемые объекты**: поле immutable (стабильно с 1.21)
- **Шифрование в etcd**: по умолчанию выключено, включается EncryptionConfiguration
- **Внешние решения**: Sealed Secrets, External Secrets Operator, HashiCorp Vault, SOPS
**ConfigMap** и **Secret** — объекты [Kubernetes](https://llmdocs.ru/wiki/kubernetes.md), которые отделяют конфигурацию приложения от его образа. Один и тот же [образ](https://llmdocs.ru/wiki/oci-image.md) запускается в тестовом и боевом окружении, а различия — адрес базы, уровень логирования, ключи внешних API — подставляются при старте [пода](https://llmdocs.ru/wiki/pod.md). ConfigMap предназначен для обычных настроек,[1] Secret — для чувствительных данных: паролей, токенов, TLS-сертификатов, ключей доступа к реестру образов.[2]

## Зачем

Принцип «конфигурация хранится в окружении, а не в коде» сформулирован в методологии Twelve-Factor App.[6] Kubernetes реализует его так: конфигурация — отдельный объект в API кластера, который можно менять, версионировать и подключать к любому числу подов. Код не пересобирается ради смены одного параметра, а секреты не попадают в слои образа и в историю [Git](https://llmdocs.ru/wiki/git.md).

## ConfigMap

ConfigMap — это словарь «ключ → строка». Значением может быть и короткий параметр, и целый файл конфигурации.

```yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: web-config
data:
  LOG_LEVEL: info
  FEATURE_X: "true"
  nginx.conf: |
    server {
      listen 8080;
      location / { proxy_pass http://127.0.0.1:8000; }
    }
```

Числа и логические значения в `data` нужно брать в кавычки — там допускаются только строки. Для двоичных данных есть поле `binaryData`.

## Secret

Устроен так же, но значения в поле `data` записываются в кодировке Base64, а в `stringData` можно писать открытым текстом — API сам их закодирует. У Secret есть типы, задающие ожидаемые ключи:

| Тип | Назначение |
|---|---|
| `Opaque` | произвольные данные (по умолчанию) |
| `kubernetes.io/tls` | сертификат и ключ: `tls.crt`, `tls.key` (используется [Ingress](https://llmdocs.ru/wiki/service-ingress.md)) |
| `kubernetes.io/dockerconfigjson` | учётные данные для закрытого реестра образов |
| `kubernetes.io/basic-auth`, `ssh-auth` | логин и пароль, SSH-ключ |
| `kubernetes.io/service-account-token` | токен сервисного аккаунта (устаревший способ) |

```bash
kubectl create secret generic db --from-literal=PASSWORD='s3cr3t'
kubectl create secret tls example-com --cert=fullchain.pem --key=privkey.pem
kubectl get secret db -o jsonpath='{.data.PASSWORD}' | base64 -d
```

**Base64 — не шифрование.** Любой, кто может прочитать объект через API, получит секрет в открытом виде. По умолчанию Secret хранится в etcd незашифрованным; шифрование «на диске» включают отдельной настройкой API-сервера (EncryptionConfiguration), в том числе с ключом во внешнем KMS.[4] Главная защита — права доступа RBAC: чтение секретов разрешают только тем сервисным аккаунтам и людям, которым это действительно нужно.[3]

## Как передать в под

```yaml
spec:
  containers:
    - name: app
      image: ghcr.io/example/web:1.4.0
      envFrom:
        - configMapRef: {name: web-config}       # все ключи как переменные
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef: {name: db, key: PASSWORD}
      volumeMounts:
        - name: nginx-conf
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: nginx-conf
      configMap:
        name: web-config
        items: [{key: nginx.conf, path: default.conf}]
```

Два способа ведут себя по-разному при изменении объекта:

- **[Переменные окружения](https://llmdocs.ru/wiki/environment-variables.md)** читаются только при старте контейнера. Чтобы применить новое значение, поды нужно перезапустить, например `kubectl rollout restart deployment/web`.
- **Файлы в томе** kubelet обновляет автоматически (с задержкой до минуты), но приложение должно само перечитать файл. Исключение — тома, смонтированные через `subPath`: они не обновляются.

Популярный приём — добавить в аннотацию шаблона пода хеш конфигурации: при её изменении меняется шаблон, и [Deployment](https://llmdocs.ru/wiki/deployment-replicaset.md) сам выполняет плавное обновление. Так делают многие чарты [Helm](https://llmdocs.ru/wiki/helm.md).

С версии 1.21 объект можно пометить `immutable: true`: его нельзя изменить, только пересоздать, а kubelet перестаёт следить за ним — это снижает нагрузку на API-сервер в больших кластерах и защищает от случайных правок.[1]

## Секреты и Git

Хранить манифесты Secret в репозитории в открытом виде нельзя: Base64 раскодирует кто угодно. Распространённые решения:

- **Sealed Secrets** — секрет шифруется открытым ключом контроллера в кластере; в Git лежит зашифрованный `SealedSecret`, расшифровать его может только кластер.
- **SOPS** — шифрует значения в YAML-файлах ключами age, PGP или облачного KMS; удобно в связке с GitOps (Argo CD, Flux).
- **External Secrets Operator** — синхронизирует секреты из внешнего хранилища (HashiCorp Vault, AWS Secrets Manager, Yandex Lockbox и др.) в объекты Secret.[5]
- **CSI-драйвер Secrets Store** — монтирует секреты из хранилища прямо в под, минуя etcd.

Подробнее о подходах — в статье [Управление секретами](https://llmdocs.ru/wiki/secrets-management.md).

## Ограничения

- Размер одного объекта — не больше 1 МиБ: для больших файлов нужен [PersistentVolume](https://llmdocs.ru/wiki/persistentvolume.md) или образ.
- ConfigMap и Secret принадлежат пространству имён и доступны только подам из него же.
- Под не запустится, если указанный ConfigMap или Secret отсутствует (если ссылка не помечена `optional: true`).
- Секрет, переданный через переменную окружения, может утечь в логи, дампы и вывод отладочных инструментов; файлы в томе безопаснее.

## См. также

- [Pod](https://llmdocs.ru/wiki/pod.md)
- [kubectl](https://llmdocs.ru/wiki/kubectl.md)
- [Аутентификация и авторизация](https://llmdocs.ru/wiki/authn-authz.md)
- [Helm](https://llmdocs.ru/wiki/helm.md)

## Источники

1. [Kubernetes Docs — ConfigMaps](https://kubernetes.io/docs/concepts/configuration/configmap/)
2. [Kubernetes Docs — Secrets](https://kubernetes.io/docs/concepts/configuration/secret/)
3. [Kubernetes Docs — Good practices for Kubernetes Secrets](https://kubernetes.io/docs/concepts/security/secrets-good-practices/)
4. [Kubernetes Docs — Encrypting Confidential Data at Rest](https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/)
5. [External Secrets Operator](https://external-secrets.io/)
6. [The Twelve-Factor App — III. Config](https://12factor.net/config)
