kubernetes - 在 kubernetes 中,如何访问 configmap 里面的环境变量?
问题描述
我有将 pod 名称附加到“ jdbc_db_url ”属性的用例。位于“ common-configmap.config ”文件中。为了实现,我遵循了以下步骤,但不幸的是无法做到。
第一步: common-configmap.config
# Database Properties
jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=${POD_NAME}
第 2 步: 使用以下命令将 configmap 部署到集群中
kubectl create configmap common-configmap --from-env-file /app/conf/common-configmap.config -n default
第 3 步: 使用以下清单文件创建“myapp”容器和服务
部署清单文件:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
meta.helm.sh/release-name: master
meta.helm.sh/release-namespace: default
generation: 1
labels:
app.kubernetes.io/instance: master
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: myapp
app.kubernetes.io/version: 4.0.0
helm.sh/chart: myapp-4.0.0
name: myapp
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 5
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/instance: master
app.kubernetes.io/name: myapp
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
labels:
app.kubernetes.io/instance: master
app.kubernetes.io/name: myapp
spec:
containers:
- env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
envFrom:
- configMapRef:
name: myapp-configmap
- configMapRef:
name: common-configmap
image: docker.com/myapp:4.0.0
imagePullPolicy: Always
name: myapp
ports:
- containerPort: 8080
name: http
protocol: TCP
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
服务清单文件:
apiVersion: v1
kind: Service
metadata:
annotations:
meta.helm.sh/release-name: master
meta.helm.sh/release-namespace: default
labels:
app.kubernetes.io/instance: master
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: myapp
app.kubernetes.io/version: 4.0.0
helm.sh/chart: myapp-4.0.0
name: myapp
namespace: default
spec:
ports:
- name: http
port: 8080
protocol: TCP
targetPort: http
selector:
app.kubernetes.io/instance: master
app.kubernetes.io/name: myapp
sessionAffinity: None
type: ClusterIP
验证结果我已进入运行 shell 的容器并打印环境变量:
kubectl exec --stdin --tty myapp-d5db776b9-h25q5 -c myapp -- /bin/sh
实际结果:
# printenv
jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=${POD_NAME}
预期结果:
jdbc_auto_commit=false
jdbc_postgresql_driverClassName=org.postgresql.Driver
jdbc_db_url=jdbc:postgresql://dev.postgres.database.azure.com/dbname?ApplicationName=myapp-d5db776b9-h25q5
如何在部署/容器运行时替换 config-map 中的环境变量?或者有没有其他方法可以传递/替换JDBC_URL中的pod_name
我可以知道,在这种情况下我做错了什么?
预先感谢您的帮助。
解决方案
你可以使用一个 init-container 来做到这一点,emptyDir
它在它和你的主容器之间有一个类型的共享卷。
首先,编辑您的部署以添加一个emptyDir
卷和一个 init 容器,并将卷挂载到这两个容器:
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
meta.helm.sh/release-name: master
meta.helm.sh/release-namespace: default
generation: 1
labels:
app.kubernetes.io/instance: master
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: myapp
app.kubernetes.io/version: 4.0.0
helm.sh/chart: myapp-4.0.0
name: myapp
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 5
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/instance: master
app.kubernetes.io/name: myapp
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
labels:
app.kubernetes.io/instance: master
app.kubernetes.io/name: myapp
spec:
volumes: # emptyDir volume for the entire pod
- name: config-volume
emptyDir: {}
initContainers: # an init container that will compile the env var with the pod name
- name: config-compiler
image: bash
volumeMounts:
- name: config-compiler
mountPath: /configs
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
envFrom:
- configMapRef:
name: common-configmap
command:
- bash
- -c
- 'echo $jdbc_db_url | sed "s/POD_NAME/${POD_NAME}/" > /configs/compiled.env'
containers:
- volumeMounts:
- name: config-compiler
mountPath: /configs
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
envFrom:
- configMapRef:
name: myapp-configmap
- configMapRef:
name: common-configmap
image: docker.com/myapp:4.0.0
imagePullPolicy: Always
name: myapp
ports:
- containerPort: 8080
name: http
protocol: TCP
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
然后,您需要确保您的实际 pod 正在读取 env vars 文件 - 您可以通过编辑入口点脚本添加如下行来做到这一点:
source /configs/compiled.env
或将您的 pod 的命令编辑为如下内容:
command: [ 'source', '/configs/compiled.env;', 'previous-command' ]
上面两个都有点hack-ish - 所以我建议做的是查看你的应用程序默认读取的配置文件,并将你的编译脚本与这些文件相匹配。
例如,如果您的应用程序读取/etc/myapp/confs.d/files.env
- 将您的空目录安装到/etc/myapp/confs.d
并让 init 容器写入到files.env
,并以您的应用程序期望的格式执行此操作(例如,如果它是一个 ini 文件而不是 env 文件,则编译它以使其匹配那种格式)
显然有更好的方法来编译配置文件然后使用sed
- 但如果你想(并且有能力)保持简短,这是一个选择
推荐阅读
- unit-testing - 异步单元测试方法
- arrays - 使用对象作为索引时,mongodb如何对文档进行排序?
- javascript - 无限轮播滑块
- canopen - CANopen 禁止定时器的正确操作是什么?
- c++ - 带有抽象类的 C++ 虚拟继承,用于一些数学函数的基本实现
- grpc-java - 谷歌云扳手java客户端使用代理
- javascript - 在滚动或任何其他事件上加载功能
- asp.net-mvc - MVC 在 Razor 页面视图中动态创建 N 个下拉框
- python - 为什么这个 python 代码不翻译单词?
- python-3.x - 只允许将类似列表的对象传递给 isin(),您传递了 [NoneType]