Kubernetes 具有不同配置的多个相同应用程序和数据库部署

Mic*_*ick 8 deployment docker kubernetes statefulset configmap

困境:使用相同的 docker 映像和代码,但配置不同(使用子域的不同客户端)部署多个应用程序和数据库容器对。

有哪些合乎逻辑的方法可以解决这个问题,因为 kubernetes 似乎没有支持这种设置的集成?

可能的方法

  1. 对所有应用程序部署使用单个应用程序服务,对所有数据库部署使用单个数据库服务。运行单个 Nginx 静态文件服务和部署,该服务将从应用程序部署之间共享的静态卷提供静态文件(全部使用同一组静态文件)。每当需要新部署时,让 bash 脚本复制应用程序和数据库 .yaml 部署文件,并将 sed 文本替换为客户端的名称,并指向正确的 configmap(当然是手动编写的)并 kubectl 应用它们。主 nginx 入口将处理传入流量并通过应用程序部署服务指向正确的 pod
  2. 与上面类似,除了使用 StatefulSet 而不是单独的部署,以及使用 init 容器将不同的配置复制到已安装的卷(唯一的缺点是您无法删除有状态集中间的项目,如果您不再需要,就会出现这种情况客户端的特定容器,这似乎是一种非常hacky的方法)。

理想情况下,如果 StatefulSet 可以使用向下 api 根据有状态集的索引动态选择配置映射名称,这将解决问题(您基本上可以使用名称中的索引手动创建配置文件,并且它将被选择)适当地)。就像是:

env:
- name: POD_NAME
  valueFrom:
    fieldRef:
      fieldPath: metadata.name

envFrom:
- configMapRef:
  name: $(POD_NAME)-config
Run Code Online (Sandbox Code Playgroud)

然而,该功能在 kubernetes 中不可用。

mda*_*iel 1

虽然动态结构替换是不可能的(加或减,请参阅下面的整个故事),但我相信你的想法是正确的initContainer:;您可以使用从 API 中serviceAccount获取,然后在主容器启动时获取该环境:configMapinitContainer:

initContainers:
- command:
  - /bin/bash
  - -ec
  - |
       curl -o /whatever/env.sh \
       -H "Authorization: Bearer $(cat /var/run/secret/etc/etc)" \
       https://${KUBERNETES_SERVICE_HOST}/api/v1/namespaces/${POD_NS}/configmaps/${POD_NAME}-config
  volumeMounts:
  - name: cfg  # etc etc
containers:
- command:
  - /bin/bash
  - -ec
  - "source /whatever/env.sh; exec /usr/bin/my-program"
  volumeMounts:
  - name: cfg  # etc etc
volumes:
- name: cfg
  emptyDir: {}
Run Code Online (Sandbox Code Playgroud)

这里我们有ConfigMap与 内联的获取PodSpec,但是如果您有一个专门用于获取ConfigMaps 并将它们序列化为主容器可以使用的格式的 docker 容器,我不认为实际的解决方案会那么冗长


一个单独的、更复杂(但也许更优雅)的方法是Mutating Registration Webhook,看起来他们最近甚至用Pod Presets正式化了你的用例,但从哪个版本的文档中并不清楚功能首先出现,如果有任何 apiserver 标志,也必须调整才能利用它。