Подключение в виде volume
Достаточно часто стоит задача – подключить к подам не пустые файлы с конфигурацией или простыми данными. В принципе можно воспользоваться volume типа emptyDir и при помощи инит контейнера создать все необходимые файлы и директории. Но этот способ очень громоздкий и неудобный.
Наилучшим вариантом решения такой задачи является использование volumes типа configMap.
configMap применяется для:
- Создание конфигурационных файлов или любых других не пустых файлов.
- Определения большого количества переменных среды окружения контейнера.
Содержимое configMap хранится в базе etcd. Поэтому не имеет смысл использовать его для больших бинарных файлов.
Текстовые данные должны быть в кодировке UTF-8. Если файл должен быть в другой кодировке, используйте binаryData.
Необходимо сначала создать объект configMap, прежде чем вы начнёте его использовать. Иначе при инициализации пода будет выводиться сообщение об ошибке, а сам под не будет запущен.
Например, в поде с web сервером openresty необходимо заменить файл index.html, выдаваемый по умолчанию при обращении в корень.
Файл index.html (meta charset закомментировано специально, мы будем использовать эту строку в дальнейшем).
<html> <head> <title>Тестовая страница</title> <!--<meta charset="UTF-8">--> </head> <body> <h1>Тестовая страница</h1> <p>Простая тестовая страница, для видео на <a href="https://www.youtube.com/channel/UCU55LZT7oRxhX4GTvb5H4HA"> моём канале</a>. </p> </body> </html>
Для того, чтобы получить configMap из этого файла, необходимо выполнить следующую команду:
kubectl create configmap index-html --from-file=index.html \ --dry-run=client -o yaml | sed '/creationTimestamp/d' > 00-index-html.yaml
Параметр —dry-run заставляет программу kubectl получившийся yaml файл выводить на стандартный вывод, а не применять его в кластер Kubernetes. Также при помощи sed мы удалим параметр creationTimestamp, что бы в дальнейшем кластер мог нормально работать с этим configMap. По умолчанию параметру присваивается значение 0 и кубернетес перестает отслеживать изменения данного объекта API.
В результате будет создан файл (00-index-html.yaml), следующего содержания:
apiVersion: v1 data: index.html: |- <html> <head> <title>Тестовая страница</title> <!--<meta charset="UTF-8">--> </head> <body> <h1>Тестовая страница</h1> <p>Простая тестовая страница, для видео на <a href="https://www.youtube.com/channel/UCU55LZT7oRxhX4GTvb5H4HA"> моём канале</a>. </p> </body> </html> kind: ConfigMap metadata: name: index-html
В один configMap можно поместить сразу несколько файлов. Например, если необходимо включить все файлы в текущей директории, команда будет выглядеть следующим образом:
kubectl create configmap index-html --from-file=./ --dry-run=client \ -o yaml | sed '/creationTimestamp/d' > 00-index-html.yaml
Пример подключения configMap в качестве volume:
apiVersion: apps/v1 kind: Deployment metadata: name: openresty namespace: volumes-sample labels: app: openresty spec: replicas: 1 selector: matchLabels: app: openresty template: metadata: labels: app: openresty spec: containers: - name: openresty image: openresty/openresty:centos-rpm env: - name: NGINX_HOST valueFrom: fieldRef: fieldPath: metadata.name volumeMounts: - name: index-html mountPath: /usr/local/openresty/nginx/html/index.html subPath: index.html volumes: - name: index-html configMap: name: index-html
В разделе volumes указываются все подключаемые тома. В случае configMap достаточно указать name.
Подключение к поду описывается стандартно в разделе volumeMounts.
- Name – указываем имя volume из раздела volumes.
- mountPath – точка монтирования. В конкретном примере в configMap описан один файл и монтирование происходит как файл, а не как директории.
- subPath — путь внутри тома, из которого должен быть смонтирован том контейнера. По умолчанию «» (корень тома).
Явно описав параметр subPath мы указали, что index.html в mountPath не директория куда подключать том. Т.е. мы в директории заменили/добавили конкретный файл.
Но при использовании subPath возникает проблема: при изменении configMap не будет изменяться содержимое подмонтированного ресурса. Поэтому, если вы предполагаете вносить изменения в файлы в configMap используйте другой способ подключения volume.
volumeMounts: - name: index-html mountPath: /usr/local/openresty/nginx/html/
В данном случае volume будет подмонтирован как обычный том. Т.е. если в это директории раньше были какие либо файлы, они не будут видны.
Если вы настроили доступ к Deployment через внешний сервис или ingress, посмотрите содержимое страницы, русские буквы будут отображаться не корректно.
Если вы этого не делали, подключитесь к поду и посмотрите содержимое файла. Для начала посмотрите название подов:
kubectl -n volumes-sample get pods
Затем запустите bash внутри пода, указав его правильное имя:
kubectl -n volumes-sample exec openresty-7cd79cfd94-5zjgl -i -t -- bash
Внутри пода в bash выполните команду:
cat /usr/local/openresty/nginx/html/index.html
Попробуйте отредактировать configMap прямо в кубернетес (при условии, что вы применили файлы деплоя configMap и Deploy), при помощи следующей команды:
kubectl -n volumes-sample edit cm index-html
В html файле уберите комментарии (<!— и —>) и сохраните изменения.
Через некоторое время посмотрите содержимое страницы, русские буквы будут отображаться корректно. Следовательно, изменения в configMap приводят к изменению содержимого файлов в поде, куда они подключены.
Подключение в виде переменных среды окружения
Достаточно часто, при запуске приложения приходится определять большое количество переменных среды окружения. Это можно делать явно, при описании под. Но можно вынести в отдельный configMap.
Пример определения configMap.
apiVersion: v1 kind: ConfigMap metadata: name: env-config data: ENV_HOSTS: "1" ENV_SOME_VALUE: new ENV_URL_KRYUKOV_BIZ: http://www.kryukov.biz
Как видно из примера, переменные среды окружения определяются в разделе data.
Пример подключения configMap:
apiVersion: apps/v1 kind: Deployment metadata: name: openresty namespace: volumes-sample labels: app: openresty spec: replicas: 1 selector: matchLabels: app: openresty template: metadata: labels: app: openresty spec: containers: - name: openresty image: openresty/openresty:centos-rpm env: - name: NGINX_HOST valueFrom: fieldRef: fieldPath: metadata.name envFrom: - configMapRef: name: env-config ports: - containerPort: 80 name: http protocol: TCP volumeMounts: - name: index-html mountPath: /usr/local/openresty/nginx/html/ volumes: - name: index-html configMap: name: index-html
Подключение configMap происходит в определении контейнера при помощи envFrom.
Что бы увидеть эти переменные, можно подключиться к поду как в предыдущем примере. И в командной строке набрать:
env | grep ENV
При изменении configMap во время работы пода, не произойдет изменение переменных среды окружения. Т.е. сначала изменяем configMap, затем перезапускаем под.
<- Оглавление