Изменение конфигурации в работающем Kubernetes Pod
Я написал nifi.properties
в Kubernetes ConfigMap
, Когда я разверну NiFi (как StatefulSet
) Я хочу иметь это nifi.properties
файл, который будет использоваться только что развернутым NiFi. Для этого я добавил том для ConfigMap
и смонтировал его в контейнере. Связанный statefulset.yaml
выглядит так:
...
containers:
- name: 'myName'
image: 'apache/nifi:latest'
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: http-2
containerPort: 1337
protocol: TCP
volumeMounts:
- name: 'nifi-config'
mountPath: /opt/nifi/nifi-1.6.0/conf/nifi.properties
volumes:
- name: 'nifi-config'
configMap:
name: 'nifi-config'
...
Это не работает, я думаю, что это так, потому что NiFi уже работает и nifi.properties
файл заблокирован сервисом. Модуль не может быть создан, я получаю сообщение об ошибке: ...Device or resource is busy
, Я также попробовал это с bootstrap.conf
файл, который работает, но я не думаю, что изменения там распознаются сервисом NiFi, потому что он должен быть перезапущен.
У меня уже была та же проблема с NiFi, развернутым на чистом Docker, где я работал, останавливая контейнер, копируя файлы и запуская контейнер; не очень красиво, но работает.
Использование переменных среды для изменения значений в NiFi, как указано здесь, также не вариант, потому что возможность изменения параметров там очень ограничена.
Эта проблема не возникает только для NiFi. Я думаю, что есть много ситуаций, когда кто-то хочет изменить конфигурацию системы, работающей в Kubernetes
, поэтому я надеюсь, что есть какое-то решение для решения этой проблемы.
2 ответа
Я решил это с помощью этого файла helm, но немного изменил. На самом деле это почти так же, как ответ, который дал Пепов, но, как указано в моем комментарии, я получил CrashLoopBackOff
, Это также не имело ничего общего с версией изображения, потому что я использовал свое собственное изображение, основанное на NiFi 1.6.0, также содержащее несколько пользовательских процессоров.
Поэтому мое решение состоит в том, чтобы использовать postStart
Обработчик Кубернетеса. Проблема в том, что не гарантируется, что этот обработчик вызывается перед ENTRYPOINT ( см.). Но в этом случае стручок сломался бы и перезапустился, в конечном счете получая это правильно; сейчас у меня не было этой проблемы, так что, похоже, сейчас все хорошо.
Я копирую содержимое configMap
в отдельную папку и скопируйте их в соответствующую папку NiFi в postStart
обработчик.
Так вот statefulset.yaml
:
...
containers:
- name: 'myName'
image: 'apache/nifi:latest'
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: http-2
containerPort: 1337
protocol: TCP
volumeMounts:
- name: 'nifi-config'
mountPath: /opt/nifi/nifi-1.6.0/kubeconfig
lifecycle:
postStart:
exec:
command:
- bash
- -c
- |
cp -a /opt/nifi/nifi-1.6.0/kubeconfig/. /opt/nifi/nifi-1.6.0/conf
volumes:
- name: 'nifi-config'
configMap:
name: 'nifi-config'
...
Есть две проблемы с вышеупомянутой установкой:
- Вы должны указать подпуть, чтобы указать, какой элемент вы монтируете из файла конфигурации в виде одного файла, см. https://github.com/kubernetes/kubernetes/issues/44815.
- Вы не можете смонтировать элемент configmap как том для чтения и записи по умолчанию на 1.9.6 и выше, поэтому стартовый скрипт не сможет заменить свойства в нем, см.: https://github.com/kubernetes/kubernetes/issues/62099
Чтобы обойти второй вопрос, вы можете просто смонтировать элемент configmap в виде отдельного файла (nifi.properties.tmp) и скопировать его в место назначения, обернув точку входа контейнера специальной командой.
...
containers:
- name: 'myName'
image: 'apache/nifi:latest'
ports:
- name: http
containerPort: 8080
protocol: TCP
- name: http-2
containerPort: 1337
protocol: TCP
volumeMounts:
- name: 'nifi-config'
mountPath: /opt/nifi/nifi-1.6.0/conf/nifi.properties.tmp
subPath: nifi.properties
command:
- bash
- -c
- |
cat "${NIFI_HOME}/conf/nifi.properties.tmp" > "${NIFI_HOME}/conf/nifi.properties"
exec "${NIFI_BASE_DIR}/scripts/start.sh
# or you can do the property edits yourself and skip the helper script:
# exec bin/nifi.sh run
volumes:
- name: 'nifi-config'
configMap:
name: 'nifi-config'
...