如何通过Helm在K8s其他容器中复用容器环境变量?
我有一个Deployment,其Pod通过大量环境变量完成配置。现在需要添加一个Sidecar容器,要求与已定义容器使用完全相同的环境变量,希望遵循DRY原则,避免复制粘贴所有变量。
当前Deployment定义示例:
apiVersion: apps/v1 kind: Deployment spec: template: spec: containers: - name: container1 env: - name: MYSQL_HOST value: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }} - name: MYSQL_DATABASE value: {{ .Values.mariadb.auth.database | quote }} - name: MYSQL_USER valueFrom: secretKeyRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} key: {{ .Values.usernameKey | default "db-username" }} - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} key: {{ .Values.passwordKey | default "db-password" }}
我尝试用ConfigMap复用非敏感环境变量,配置如下:
apiVersion: v1 kind: ConfigMap metadata: name: config data: MYSQL_HOST: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }} MYSQL_DATABASE: {{ .Values.mariadb.auth.database | quote }} --- apiVersion: apps/v1 kind: Deployment spec: template: spec: containers: - name: container1 envFrom: - configMapRef: name: config - name: container2 envFrom: - configMapRef: name: config
但这种方式下,MYSQL_USER、MYSQL_PASSWORD(以及另外20个类似的环境变量)仍需重复配置。请问能否复用现有Secret中的MYSQL_USER和MYSQL_PASSWORD作为环境变量,而无需在container1和container2中重复定义?
解决方案:结合envFrom同时引用ConfigMap和Secret
完全可以通过envFrom字段同时引用ConfigMap和Secret,实现两类环境变量的复用,无需在每个容器中重复定义单个变量:
保留ConfigMap存储非敏感配置
继续用ConfigMap管理如MYSQL_HOST、MYSQL_DATABASE这类非敏感变量,定义不变:apiVersion: v1 kind: ConfigMap metadata: name: config data: MYSQL_HOST: {{ template "mariadb.primary.fullname" .Subcharts.mariadb }} MYSQL_DATABASE: {{ .Values.mariadb.auth.database | quote }}在容器中同时引用ConfigMap和Secret
在每个容器的envFrom列表中添加ConfigMap引用,再针对Secret中需要映射的变量,用env字段批量复用引用逻辑。针对你的场景,完整的Deployment配置如下:apiVersion: apps/v1 kind: Deployment spec: template: spec: containers: - name: container1 envFrom: - configMapRef: name: config env: - name: MYSQL_USER valueFrom: secretKeyRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} key: {{ .Values.usernameKey | default "db-username" }} - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} key: {{ .Values.passwordKey | default "db-password" }} - name: container2 envFrom: - configMapRef: name: config env: - name: MYSQL_USER valueFrom: secretKeyRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} key: {{ .Values.usernameKey | default "db-username" }} - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} key: {{ .Values.passwordKey | default "db-password" }}进阶优化:用Secret批量导入(键名与环境变量名一致时)
如果你的Secret中直接使用MYSQL_USER、MYSQL_PASSWORD作为键名,可以进一步简化,直接通过secretRef批量导入所有Secret中的键值对作为环境变量:apiVersion: apps/v1 kind: Deployment spec: template: spec: containers: - name: container1 envFrom: - configMapRef: name: config - secretRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }} - name: container2 envFrom: - configMapRef: name: config - secretRef: name: {{ .Values.secretName | default (printf "%s-%s" .Release.Name "db") }}这样所有Secret中的键值对都会自动映射为同名环境变量,无需逐个定义。
内容的提问来源于stack exchange,提问作者Kenny Retzlaff

