更改 运行 Kubernetes Pod 中的配置

Changing configuration in running 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 文件被服务锁定。无法创建 Pod,出现错误:...Device or resource is busy。我还尝试使用 bootstrap.conf 文件,该文件有效,但我认为 NiFi 服务无法识别其中的更改,因为它必须重新启动。

我已经在纯 Docker 上部署 NiFi 时遇到了同样的问题,我通过停止容器、复制文件和启动容器来解决这个问题;不是很漂亮,但工作。

使用环境变量更改 NiFi 中的值,如所述 here 也不是一种选择,因为更改参数的可能性非常有限。

这个问题不会只发生在NiFi上。我认为在很多情况下有人想要在 Kubernetes 内更改系统 运行 的配置,所以我希望有任何解决方案来处理这个问题。

以上设置有两个问题:

要解决第二个问题,您只需将 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'
...

我在这个 helm file 的帮助下解决了这个问题,但做了一些改动。实际上它与 pepov 给出的答案几乎相同,但正如我评论中所述,我得到了 CrashLoopBackOff。这也与图像版本无关,因为我使用了我自己的图像,该图像基于 NiFi 1.6.0,也包含一些自定义处理器。

所以我的解决方案是使用 Kubernetes 的 postStart 处理程序。问题是不能保证在 ENTRYPOINT (see) 之前调用此处理程序。但在这种情况下,pod 会崩溃并重新启动,最终会恢复正常;现在我还没有遇到这个问题,所以现在看来​​还不错。
我将 configMap 的内容复制到一个专用文件夹中,并将它们复制到 postStart 处理程序中的关联 NiFi 文件夹中。

所以这里是 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'
...