Знакомство с Kubernetes. Часть 13: Конфигмапы (ConfigMap)

Aug 13, 2018 07:03 · 814 words · 4 minute read kubernetes

Использование конфигмапов (ConfigMaps) позволяет разделять конфигурационные файлы и контейнеры с приложениями, избавляя от необходимости упаковывать конфиги в docker-образ. В данной статье рассмотрим несколько примеров использования конфигмапов - давайте разберемся!

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

kubectl create configmap <map-name> <data-source>

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

Создание конфигмапа (ConfigMap) из каталога подразумевает создание объекта из одного или нескольких файлов, расположенных в одной директории. Например, создаем каталог и скачиваем в него два файла с параметрами:

mkdir -p configmap-from-dir/
wget https://k8s.io/docs/tasks/configure-pod-container/configmap/kubectl/game.properties -O configmap-from-dir/game.properties
wget https://k8s.io/docs/tasks/configure-pod-container/configmap/kubectl/ui.properties -O configmap-from-dir/ui.properties
ls configmap-from-dir/
game.properties
ui.properties

Создаем конфигмап из каталога:

kubectl create configmap game-config --from-file=configmap-from-dir/

Проверим, что созданный конфигмап действительно состоит из двух файлов:

kubectl describe configmaps game-config
Name:           game-config
Namespace:      default
Labels:         <none>
Annotations:    <none>

Data
====
game.properties:        158 bytes
ui.properties:          83 bytes

Проверим содержимое конфигмапа (секция data:), вывод сокращен:

kubectl get configmaps game-config -o yaml

apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
...

Создание конфигмапа из файла тоже не должно вызывать сложностей:

kubectl create configmap game-config-2 --from-file=configmap-from-dir/game.properties

Проверка:

kubectl describe configmaps game-config-2
Name:           game-config-2
Namespace:      default
Labels:         <none>
Annotations:    <none>

Data
====
game.properties:        158 bytes

К слову, есть возможность несколько раз указывать параметр --from-file для данной команды - при этом будет создан конфигмап из нескольких файлов, например:

kubectl create configmap game-config-2 --from-file=configmap-from-dir/game.properties --from-file=configmap-from-dir/ui.properties

Есть возможность создавать конфигмапы из файлов с переменными (env-file). Эти файлы должны содержать информацию в формате ключ=значение (по одному на строку), пустые строки и строки, начинающиеся с символа # игнорируются. Например, создадим в нашем каталоге файл с именем game-env-file.properties и следующим содержимым:

enemies=aliens
lives=3
allowed="true"

Теперь создадим из этого файла конфигмап командой:

kubectl create configmap game-config-env-file --from-env-file=configmap-from-dir/game-env-file.properties

Cодержимое конфигмапа:

kubectl get configmap game-config-env-file -o yaml

apiVersion: v1
data:
  allowed: '"true"'
  enemies: aliens
  lives: "3"
kind: ConfigMap
metadata:
...

Стоит отметить, что при передаче нескольких параметров --from-env-file для создания конфигмапа, будет использован только последний из указанных файлов.

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

kubectl create configmap game-config-3 --from-file=game-special-key=configmap-from-dir/game.properties

Обратите внимание на название ключа:

kubectl get configmaps game-config-3 -o yaml

apiVersion: v1
data:
  game-special-key: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
kind: ConfigMap
metadata:
...

Еще одна возможность - создавать конфигмапы указывая параметры прямо в командной строке с помощью --from-literal:

kubectl create configmap special-config --from-literal=special.how=very --from-literal=special.type=charm

Проверим:

kubectl get configmaps special-config -o yaml

apiVersion: v1
data:
  special.how: very
  special.type: charm
kind: ConfigMap
metadata:
...

Напоследок - самый удобный (на мой взгляд) вариант создания конфигмапов - описание их в отдельном yaml-файле (по аналогии с другими объектами Kubernetes). Создадим два таких файла:

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO

Теперь мы можем использовать созданные выше конфигмапы при описании пода (Pod):

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: env-config
              key: log_level
  restartPolicy: Never

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

Можно создать конфигмап с несколькими парами ключ=значение, например:

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  SPECIAL_LEVEL: very
  SPECIAL_TYPE: charm

Такой конфигмап в описании пода будет выглядеть несколько проще:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: special-config
  restartPolicy: Never

Еще одна важная (и самая востребованная) особенность - возможность монтировать конфигмапы в контейнеры в качестве томов. Пример с использованием созданного ранее конфигмапа special-config:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: special-config
  restartPolicy: Never

При старте данного пода команда ls /etc/config/ выведет на экран следующее:

special.level
special.type

Можно указывать конкретный путь для монтирования данных из конфигмапа. Например, сущность special.level из конфигмапа с именем special-config может быть смонтирована в /etc/config/keys внутри контейнера:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh","-c","cat /etc/config/keys" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: special.level
          path: keys
  restartPolicy: Never

При запуске пода команда cat /etc/config/keys выведет на экран:

very

Напоследок стоит отметить, что смонтированные внутрь контейнера конфигмапы будут обновляться автоматически (за исключением монтирования как subPath). Период обновления, как указано в документации, составляет kubelet sync period + ttl of ConfigMaps cache in kubelet. В следующей статье цикла рассмотрим создание и работу с секретами в кластере Kubernetes.

tweet Share