ConfigMap как env и как volume
Три способа отдать настройки в Pod из ConfigMap и разница между ними при обновлении данных.
Что такое ConfigMap
ConfigMap - объект с парами «ключ/значение» в etcd. Сам по себе ничего не делает. Внутрь кладут настройки приложения (URL базы, режим запуска, уровень логов), а Pod выбирает, как их потреблять: как env-переменные или как файлы.
Образ остаётся одним и тем же, ConfigMap-ы у каждого окружения свои. Один образ едет в dev, staging и prod, конфиги разные.
В отличие от Secret, ConfigMap хранит значения в открытом виде, без base64 и без шифрования. Туда кладут публичные настройки, не пароли.
Минимальный YAML
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_MODE: prod
APP_LOG_LEVEL: info
data это map строк. Если значение многострочное (например, целый
nginx.conf), его пишут в YAML через |. Есть ещё binaryData для
бинарных файлов в base64, но это редкость.
Как подключить к Pod
Env-переменная из конкретного ключа
env:
- name: APP_MODE
valueFrom:
configMapKeyRef:
name: app-config
key: APP_MODE
kubelet читает ключ один раз на старте контейнера и кладёт в env. Если ConfigMap поменять, env внутри работающего Pod не обновится. Нужен rollout.
Все ключи разом через envFrom
envFrom:
- configMapRef:
name: app-config
Все ключи ConfigMap становятся env-переменными с тем же именем. Удобно, когда ключей много и они уже названы как нужно.
ConfigMap удалили или ошиблись в имени. Работающий Pod доживёт на старых
env, но после перезапуска встанет в CreateContainerConfigError.
Volume типа configMap
volumes:
- name: config
configMap:
name: app-config
items:
- key: APP_LOG_LEVEL
path: log.level
volumeMounts:
- name: config
mountPath: /etc/config
Volume ведёт себя умнее env. kubelet периодически синхронит файлы с
актуальной версией ConfigMap. Поменялся data, через минуту-две файл
внутри Pod обновится. Приложение может перечитать конфиг по SIGHUP
без рестарта. Так делают nginx, envoy, fluent-bit.
Блок items нужен, когда имя ключа в ConfigMap не совпадает с тем
именем файла, которое хочет приложение. Без items все ключи
становятся файлами по своим именам.
Три способа подключения отличаются по тому, обновляются ли данные в работающем Pod:
| способ | что даёт | обновляется на лету |
|---|---|---|
env.valueFrom | один ключ в env | нет, нужен rollout |
envFrom | все ключи в env | нет, нужен rollout |
| volume | ключи как файлы | да, kubelet синкает |
Связанные команды
kubectl create configmap app-config --from-literal=APP_MODE=prod
kubectl create configmap app-config --from-file=./config.json
kubectl get configmap app-config -o yaml
kubectl describe configmap app-config
kubectl explain pod.spec.containers.envFrom
kubectl explain pod.spec.volumes.configMap --recursive
Что часто ломается
- ConfigMap обновили, env в Pod не поменялся. Env не реактивны, только volume. Либо rollout, либо переход на mount.
- Размер ConfigMap ограничен 1 MiB (лимит etcd). Большие файлы туда не кладут.
- ConfigMap живёт в namespace. Pod из другого namespace не достанет.
Домашка
Теорию закрепляет задание на своём кластере: 3 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.
./run.sh start k8s-configmap # развернуть стартовое состояние
./run.sh verify k8s-configmap # проверить текущий шаг
Коротко
- ConfigMap хранит пары «ключ/значение» в открытом виде, без шифрования.
- Ключ отдают в Pod тремя способами:
env.valueFrom,envFrom, volume типаconfigMap. - Обе env-формы читаются один раз на старте, обновление требует rollout.
- Volume-форма обновляется сама: kubelet синхронит файлы через минуту-две.
- Лимит объекта 1 MiB, namespace-scoped.
Прошли материал до конца? Отметьте урок пройденным.
Прогресс сохранён в этом браузере
Почистишь историю или откроешь с телефона, и отметки пропадут. Оставь почту, они переедут в аккаунт. Пароль придумывать не нужно.
Готово. теперь в аккаунте: прогресс виден с любого устройства. Мой прогресс