首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Kubernetes具有不同配置的多个相同的应用程序和数据库部署

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

Stack Overflow用户
提问于 2020-01-23 06:01:37
回答 3查看 1.4K关注 0票数 6

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

有什么合乎逻辑的方法来解决这个问题,因为库伯内特斯似乎没有支持这种设置的集成?

可能接近

  1. 对所有应用程序部署使用单个应用程序服务,对所有数据库部署使用单个数据库服务。让一个Nginx静态文件服务和部署运行,这将从应用程序部署之间共享的静态卷(所有都使用相同的静态文件集)提供静态文件。每当需要新部署时,让bash脚本将应用程序和数据库.yaml部署文件和sed文本复制为客户端的名称,并指向正确的configmap (当然是手动编写的)并将其应用于kubectl。主nginx入口将处理传入的通信量,并通过app部署服务指向正确的吊舱。
  2. 与上述类似,除了使用statefulset而不是单独的部署,以及init容器将不同的信任复制到已挂载的卷(唯一的缺点是不能删除状态集中间的项,如果您不再需要客户端的特定容器,这似乎是一种非常麻烦的方法)。

理想情况下,如果一个StatefulSet可以使用向下的api动态地根据有状态集的索引来选择一个configmap名称,这将解决这个问题(在这里,您基本上可以使用名称中的索引手动生成配置文件,并且它将被适当地选择)。类似于:

代码语言:javascript
运行
复制
env:
- name: POD_NAME
  valueFrom:
    fieldRef:
      fieldPath: metadata.name

envFrom:
- configMapRef:
  name: $(POD_NAME)-config

然而,这种功能在kubernetes中是不可用的。

EN

回答 3

Stack Overflow用户

发布于 2020-01-23 10:43:46

掌舵这样的模板引擎可以在这方面有所帮助。(我相信库斯托姆也能做到这一点,但我更熟悉Helm。)基本思想是,您有一个包含Kubernetes YAML文件的图表,但是可以使用模板语言( Go text/template库)动态填充内容。

在这个设置中,通常需要Helm同时创建ConfigMap和匹配的部署;在设置中,您将分别为每个租户安装它(一个Helm发行版)。假设Nginx配置非常不同,您希望将它们存储在外部文件中;图表的核心部分包括

values.yaml (可覆盖配置,helm install --set nginxConfig=bar.conf):

代码语言:javascript
运行
复制
# nginxConfig specifies the name of the Nginx configuration
# file to embed.
nginxConfig: foo.conf

templates/configmap.yaml

代码语言:javascript
运行
复制
apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}-config
data:
  nginx.conf: |-
{{ .Files.Get .Values.nginxConfig | indent 4 }}

deployment.yaml

代码语言:javascript
运行
复制
apiVersion: v1
kind: Deployment
metadata:
  name: {{ .Release.Name }}-{{ .Chart.Name }}-nginx
spec:
  ...
    volumes:
      - name: nginx-config
        configMap:
          name: {{ .Release.Name }}-{{ .Chart.Name }}-config

{{ .Release.Name }}-{{ .Chart.Name }}是一个典型的约定,它允许在同一个名称空间中安装图表的多个副本;第一部分是您给出的helm install命令的名称,第二部分是图表本身的名称。您还可以直接指定ConfigMap内容,引用来自values.yaml文件的其他.Values...设置,使用ConfigMap作为环境变量而不是文件,等等。

票数 2
EN

Stack Overflow用户

发布于 2020-01-23 08:27:50

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

代码语言:javascript
运行
复制
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: {}

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

另一种更复杂(但可能很优雅)的方法是变异接纳Webhook,看起来他们最近甚至用吊舱预置将您的用例正规化,但从文档中还不清楚该功能最初出现在哪个版本中,也不清楚是否有任何apiserver标志必须绕过才能利用它。

票数 1
EN

Stack Overflow用户

发布于 2021-04-16 21:10:33

从v1.20开始,PodPresets就被删除了,更优雅的解决方案是基于变异接纳Web钩子的,解决这个问题的方法是现在的https://github.com/spoditor/spoditor

本质上,它在PodSpec模板上使用了一个自定义注释,如:

代码语言:javascript
运行
复制
      annotations:
        spoditor.io/mount-volume: |
          {
            "volumes": [
              {
                "name": "my-volume",
                "secret": {
                  "secretName": "my-secret"
                }
              }
            ],
            "containers": [
              {
                "name": "nginx",
                "volumeMounts": [
                  {
                    "name": "my-volume",
                    "mountPath": "/etc/secrets/my-volume"
                  }
                ]
              }
            ]
          }

现在,nginx容器在StatefulSet的每个Pod中将尝试在my-secret-{pod ordinal}模式中挂载自己的专用秘密。

您只需要确保my-secret-0my-secret-1等存在于StatefulSet的同一个名称空间中。

在项目的文档中有更高级的注释用法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59872398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档