← Kubernetes: конфигурация
7 мин · просто · Урок 2 из 8

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

ConfigMap metadata.name: app-config data: APP_MODE, APP_LOG_LEVEL Pod · envFrom configMapRef.name: app-config все ключи станут env совпадение строк
Связь идёт по имени объекта, а не по ссылке. Имя разошлось, и контейнер не стартует.
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

Что часто ломается

Домашка

Теорию закрепляет задание на своём кластере: 3 шага с проверкой. Кластер поднимается по треку Kubernetes локально, задания лежат в репозитории k8s-practice.

./run.sh start k8s-configmap     # развернуть стартовое состояние
./run.sh verify k8s-configmap    # проверить текущий шаг

Коротко

Прошли материал до конца? Отметьте урок пройденным.