Kubernetes: 引用先前定义的ConfigMap键值对

5

TL;DR

我能在ConfigMap中引用先前定义的键值对吗?

完整版本

我正在为一个应用程序编写部署规范,该应用程序在启动时从环境变量接收其配置。其中一些环境变量是由其他变量派生而来的。如果我将它们设置为文件以在应用程序启动时被源化,我只需执行:

[me@myserver ~]$ cat ./myenv.sh
export FOO=foo
export BAR=bar
export FOOBAR=$FOO$BAR
[me@myserver ~]$ . ./myenv.sh
[me@myserver ~]$ printenv FOOBAR
foobar

然而,在ConfigMap中通过引用先前定义的键值对来执行类似操作的方法无法实现(请参见下面的示例ConfigMap和Pod)。以下是结果:

[me@myserver ~]$ kubectl create -f my-app-config.yaml -f my-app-pod.yaml
configmap "my-app" created
pod "my-app" created
[me@myserver ~]$ kubectl exec -it my-app -- printenv | grep MY_CONFIGMAP
MY_CONFIGMAP_FOO=foo
MY_CONFIGMAP_FOOBAR=$(MY_CONFIGMAP_FOO)$(MY_CONFIGMAP_BAR)
MY_CONFIGMAP_BAR=bar

ConfigMap

MY_CONFIGMAP_FOOBAR的期望值为foobar

我尝试交叉应用以下指令,来自文档中的在Pod命令中使用ConfigMap定义的环境变量

您可以使用Kubernetes替换语法$(VAR_NAME), 在Pod规范的command部分中使用ConfigMap定义的环境变量。

然而,这显然没有起作用,我也未能在研究中找到答案。

我怀疑我已经知道答案,但有没有任何方法可以实现这个目标呢?

MCVE

apiVersion: v1
kind: ConfigMap
metadata:
  name: my-app

data:
  MY_CONFIGMAP_FOO: foo
  MY_CONFIGMAP_BAR: bar
  
  # Desired concatenation would be `foobar`
  MY_CONFIGMAP_FOOBAR: $(MY_CONFIGMAP_FOO)$(MY_CONFIGMAP_BAR)

Pod

apiVersion: v1
kind: Pod
metadata:
  name: my-app

spec:
  containers:
  - name: my-app
    image: alpine
    imagePullPolicy: IfNotPresent
    envFrom:
      - configMapRef:
          name: my-app
          
    command:
      - /bin/sh
      
    args:
      - -c
      - "while true; do sleep 3600; done"

结语:二十九个月后

在额外的两年半时间里,与 Kubernetes 的工作经验之后,我最终的解决方案(和建议)是使用Helm chart,最好是通过 Ansible 管理的部署。

2个回答

2
您可以使用此工具envsubst来实现您期望的结果。
按照以下方式创建ConfigMap
envsubst < my-app-config.yaml | kubectl apply -f -

现在,你的ConfigMap上所有环境变量都将被替换为已解析的值。

不是我所期望的答案,但比预期的好。但除非有人给出仅依赖于Kubernetes的答案,否则我肯定会接受它。 - Deacon
这也是可行的。您可以使用ConfigMap定义的环境变量,在Pod规范的命令部分中使用$(VAR_NAME) Kubernetes替换语法。您在这里遇到了什么问题? - Emruz Hossain
确实。我甚至在我的初始问题中引用了它。;-) 我试图解决的问题是,应用程序使用各种环境变量,既可以单独使用,也可以组合在一起使用,但当它们组合在一起时,它期望它们被组合成第三个环境变量。即,它分别使用变量FOOBAR,并将它们组合在一起作为变量FOOBAR。从FOOBAR派生FOOBAR将更方便且不容易出错。 - Deacon

1
建议使用kind: Deployment。在该配置文件中,组合变量运行良好。我还没有直接尝试过Pods。
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app

spec:
  selector:
    matchLabels:
      app: my-app
  replicas: 1
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: alpine
        imagePullPolicy: IfNotPresent
        env:
        - name: MY_CONFIGMAP_FOOBAR
          value: $(MY_CONFIGMAP_FOO)$(MY_CONFIGMAP_BAR)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接