如何使用 Helm 图表拉取环境变量
How to pull environment variables with Helm charts
我在 Helm 图表的模板目录中有我的 deployment.yaml 文件,其中有几个容器的环境变量我将 运行 使用 Helm。
现在我希望能够从掌舵的任何机器本地提取环境变量 运行 这样我就可以用这种方式隐藏秘密。
当我使用 Helm 到 运行 应用程序时,如何传入它并让 helm 在本地获取环境变量?
这是我的 deployment.yaml 文件的一部分
...
...
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
- name: "USERNAME"
value: "app-username"
- name: "PASSWORD"
value: "28sin47dsk9ik"
...
...
当我 运行 helm 时,如何从本地环境变量中提取 USERNAME 和 PASSWORD 的值?
这可能吗?如果是,那我该怎么做?
您可以 export
变量并在 运行 宁 helm install
时使用它。
在此之前,您必须修改您的图表,以便在安装时该值可以是 set
。
如果您已经知道如何设置模板字段,请跳过此部分。
因为不想暴露数据,所以最好在kubernetes中保存为secret。
首先,将这两行添加到您的 Values
文件中,以便可以从外部设置这两个值。
username: root
password: password
现在,在 template
文件夹中添加一个 secret.yaml
文件。并将此代码片段复制到该文件中。
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
data:
password: {{ .Values.password | b64enc }}
username: {{ .Values.username | b64enc }}
现在调整您的部署 yaml 模板并在 env
部分进行更改,像这样
...
...
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
- name: "USERNAME"
valueFrom:
secretKeyRef:
key: username
name: {{ .Release.Name }}-auth
- name: "PASSWORD"
valueFrom:
secretKeyRef:
key: password
name: {{ .Release.Name }}-auth
...
...
如果您已针对 --set
标志正确修改模板,
您可以使用环境变量进行设置。
$ export USERNAME=root-user
现在在 运行ning helm 安装时使用这个变量,
$ helm install --set username=$USERNAME ./mychart
如果你运行这个helm install
处于dry-run
模式,你可以验证更改,
$ helm install --dry-run --set username=$USERNAME --debug ./mychart
[debug] Created tunnel using local port: '44937'
[debug] SERVER: "127.0.0.1:44937"
[debug] Original chart version: ""
[debug] CHART PATH: /home/maruf/go/src/github.com/the-redback/kubernetes-yaml-drafts/helm-charts/mychart
NAME: irreverant-meerkat
REVISION: 1
RELEASED: Fri Apr 20 03:29:11 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
username: root-user
COMPUTED VALUES:
password: password
username: root-user
HOOKS:
MANIFEST:
---
# Source: mychart/templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: irreverant-meerkat-auth
data:
password: password
username: root-user
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: irreverant-meerkat
labels:
app: irreverant-meerkat
spec:
replicas: 1
template:
metadata:
name: irreverant-meerkat
labels:
app: irreverant-meerkat
spec:
containers:
- name: irreverant-meerkat
image: alpine
env:
- name: "USERNAME"
valueFrom:
secretKeyRef:
key: username
name: irreverant-meerkat-auth
- name: "PASSWORD"
valueFrom:
secretKeyRef:
key: password
name: irreverant-meerkat-auth
imagePullPolicy: IfNotPresent
restartPolicy: Always
selector:
matchLabels:
app: irreverant-meerkat
可以看到secret中username的数据已经变成root-user
.
我已将 this example 添加到 github 存储库中。
kubernetes/helm repo regarding this. You can see this issue 中也有一些讨论,以了解使用环境变量的所有其他方式。
我想问题是如何通过查看 env 变量本身而不是通过 --set 传递它来查找 chart 中的 env 变量。
例如:我设置了一个键“my_db_password”,不支持通过查看环境变量中的值来更改值。
我不太确定 GO 模板,但我猜这是禁用的,正如他们在 helm 文档中所解释的那样。 “出于安全原因,我们删除了两个:env 和 expandenv(这将使图表作者能够访问 Tiller 的环境)。” https://helm.sh/docs/developing_charts/#know-your-template-functions
您可以通过如下设置部署 yaml 来从值 yaml 传递 env 键值:
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
{{- range $name, $value := .Values.env }}
- name: {{ $name }}
value: {{ $value }}
{{- end }}
在values.yaml中:
env:
- name: "USERNAME"
value: ""
- name: "PASSWORD"
value: ""
安装图表时可以传递用户名密码值
helm install chart_name --name release_name --set env.USERNAME="app-username" --set env.PASSWORD="28sin47dsk9ik"
对于那些希望使用数据结构而不是列表作为环境变量文件的人来说,这对我有用:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- range $key, $val := .Values.env }}
- name: {{ $key }}
value: {{ $val | quote }}
{{- end }}
values.yaml:
env:
FOO: "BAR"
USERNAME: "CHANGEME"
PASWORD: "CHANGEME"
这样我就可以在 helm chart 的其他部分按名称访问特定值,并通过 helm 命令行传递敏感值。
为了避免手动设置每个秘密,您可以使用:
export MY_SECRET=123
envsubst < values.yaml | helm install my-release . --values -
在您的 values.yaml 文件中引用了 ${MY_SECRET},例如:
mychart:
secrets:
secret_1: ${MY_SECRET}
我认为一种简单的方法就是直接设置值。例如,在您的 Values.yml 中,您希望传递服务名称:
...
myapp:
service:
name: ""
...
您的 service.yml 照常使用此值即可:
{{ .Values.myapp.service.name }}
然后设置值,使用--set
,如:--set myapp.service.name=hello
然后比如你要使用环境变量,在这之前做export:
#set your env variable
export MYAPP_SERVICE=hello
#pass it to helm
helm install myapp --set myapp.service.name=$MYAPP_SERVICE.
如果你像这样调试:
helm install myapp --set myapp.service.name=$MYAPP_SERVICE --debug --dry-run ./myapp
您可以在设置“hello”的 yml 开头看到此信息。
USER-SUPPLIED VALUES:
myapp:
service:
name: hello
作为传递本地环境变量的替代方法,我喜欢将这些敏感值存储在 VCS 忽略的文件夹中,并使用 Helm .Files
对象读取它们并将值提供给模板.
在我看来,优点是它不需要运行 Helm chart 的主机来设置任何 OS 特定的环境变量,并使 chart 自包含而不暴露这些值.
# In a folder not committed, e.g. <chart_base_directory>/secrets
username: app-username
password: 28sin47dsk9ik
然后在您的图表模板中:
# In deployment.yaml file
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
stringData::
{{ .Files.Get "<chart_base_directory>/secrets" | indent 2 }}
因此,图表所需的一切都可以从您定义其他所有内容的目录中访问。而不是设置系统范围的环境变量,它只需要一个文件。
此文件可以自动生成,也可以使用虚拟值从已提交的模板中复制。如果未定义,Helm 也会在 install/update 早期触发错误,而不是如果您的环境变量尚未定义,则使用 username=""
和 password=""
创建您的秘密,这仅一旦您的更改应用到集群,就会变得很明显。
Helm 3.1 支持 post 渲染 (https://helm.sh/docs/topics/advanced/#post-rendering),它在将清单实际发送到 Kubernetes API 之前将清单传递给脚本。 Post 呈现允许以多种方式操作清单(例如,在 Helm 上使用 kustomize)。
替换预定义环境值的 post 渲染器的最简单形式如下所示:
#!/bin/sh
envsubst <&0
请注意,这将替换 $<VARNAME>
的 每 次出现,这可能会与模板中的变量发生冲突,例如活性探测中的 shell 脚本.因此,最好明确定义要替换的变量: envsubst '${USERNAME} ${PASSWORD}' <&0
在 shell:
中定义环境变量
export USERNAME=john PASSWORD=my-secret
在模板中(例如 secret.yaml
)使用 values.yaml
中定义的值:
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
data:
username: {{ .Values.username }}
password: {{ .Values.password }}
请注意,在 Helm 已经处理完所有 YAML 文件后,您不能在清单中注入 b64enc 等字符串转换。相反,如果需要,您可以在 post 渲染器中对它们进行编码。
在values.yaml
中使用变量占位符:
...
username: ${USERNAME}
password: ${PASSWORD}
几个 Helm 命令支持参数 --post-renderer
,例如
helm install --dry-run --post-renderer ./my-post-renderer.sh my-chart
通过使用 post 渲染器,variables/placeholders 会自动被 envsubst
替换,无需额外的脚本。
我在 Helm 图表的模板目录中有我的 deployment.yaml 文件,其中有几个容器的环境变量我将 运行 使用 Helm。
现在我希望能够从掌舵的任何机器本地提取环境变量 运行 这样我就可以用这种方式隐藏秘密。
当我使用 Helm 到 运行 应用程序时,如何传入它并让 helm 在本地获取环境变量?
这是我的 deployment.yaml 文件的一部分
...
...
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
- name: "USERNAME"
value: "app-username"
- name: "PASSWORD"
value: "28sin47dsk9ik"
...
...
当我 运行 helm 时,如何从本地环境变量中提取 USERNAME 和 PASSWORD 的值?
这可能吗?如果是,那我该怎么做?
您可以 export
变量并在 运行 宁 helm install
时使用它。
在此之前,您必须修改您的图表,以便在安装时该值可以是 set
。
如果您已经知道如何设置模板字段,请跳过此部分。
因为不想暴露数据,所以最好在kubernetes中保存为secret。
首先,将这两行添加到您的 Values
文件中,以便可以从外部设置这两个值。
username: root
password: password
现在,在 template
文件夹中添加一个 secret.yaml
文件。并将此代码片段复制到该文件中。
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
data:
password: {{ .Values.password | b64enc }}
username: {{ .Values.username | b64enc }}
现在调整您的部署 yaml 模板并在 env
部分进行更改,像这样
...
...
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
- name: "USERNAME"
valueFrom:
secretKeyRef:
key: username
name: {{ .Release.Name }}-auth
- name: "PASSWORD"
valueFrom:
secretKeyRef:
key: password
name: {{ .Release.Name }}-auth
...
...
如果您已针对 --set
标志正确修改模板,
您可以使用环境变量进行设置。
$ export USERNAME=root-user
现在在 运行ning helm 安装时使用这个变量,
$ helm install --set username=$USERNAME ./mychart
如果你运行这个helm install
处于dry-run
模式,你可以验证更改,
$ helm install --dry-run --set username=$USERNAME --debug ./mychart
[debug] Created tunnel using local port: '44937'
[debug] SERVER: "127.0.0.1:44937"
[debug] Original chart version: ""
[debug] CHART PATH: /home/maruf/go/src/github.com/the-redback/kubernetes-yaml-drafts/helm-charts/mychart
NAME: irreverant-meerkat
REVISION: 1
RELEASED: Fri Apr 20 03:29:11 2018
CHART: mychart-0.1.0
USER-SUPPLIED VALUES:
username: root-user
COMPUTED VALUES:
password: password
username: root-user
HOOKS:
MANIFEST:
---
# Source: mychart/templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: irreverant-meerkat-auth
data:
password: password
username: root-user
---
# Source: mychart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: irreverant-meerkat
labels:
app: irreverant-meerkat
spec:
replicas: 1
template:
metadata:
name: irreverant-meerkat
labels:
app: irreverant-meerkat
spec:
containers:
- name: irreverant-meerkat
image: alpine
env:
- name: "USERNAME"
valueFrom:
secretKeyRef:
key: username
name: irreverant-meerkat-auth
- name: "PASSWORD"
valueFrom:
secretKeyRef:
key: password
name: irreverant-meerkat-auth
imagePullPolicy: IfNotPresent
restartPolicy: Always
selector:
matchLabels:
app: irreverant-meerkat
可以看到secret中username的数据已经变成root-user
.
我已将 this example 添加到 github 存储库中。
kubernetes/helm repo regarding this. You can see this issue 中也有一些讨论,以了解使用环境变量的所有其他方式。
我想问题是如何通过查看 env 变量本身而不是通过 --set 传递它来查找 chart 中的 env 变量。
例如:我设置了一个键“my_db_password”,不支持通过查看环境变量中的值来更改值。
我不太确定 GO 模板,但我猜这是禁用的,正如他们在 helm 文档中所解释的那样。 “出于安全原因,我们删除了两个:env 和 expandenv(这将使图表作者能够访问 Tiller 的环境)。” https://helm.sh/docs/developing_charts/#know-your-template-functions
您可以通过如下设置部署 yaml 来从值 yaml 传递 env 键值:
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
{{- range $name, $value := .Values.env }}
- name: {{ $name }}
value: {{ $value }}
{{- end }}
在values.yaml中:
env:
- name: "USERNAME"
value: ""
- name: "PASSWORD"
value: ""
安装图表时可以传递用户名密码值
helm install chart_name --name release_name --set env.USERNAME="app-username" --set env.PASSWORD="28sin47dsk9ik"
对于那些希望使用数据结构而不是列表作为环境变量文件的人来说,这对我有用:
spec:
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- range $key, $val := .Values.env }}
- name: {{ $key }}
value: {{ $val | quote }}
{{- end }}
values.yaml:
env:
FOO: "BAR"
USERNAME: "CHANGEME"
PASWORD: "CHANGEME"
这样我就可以在 helm chart 的其他部分按名称访问特定值,并通过 helm 命令行传递敏感值。
为了避免手动设置每个秘密,您可以使用:
export MY_SECRET=123
envsubst < values.yaml | helm install my-release . --values -
在您的 values.yaml 文件中引用了 ${MY_SECRET},例如:
mychart:
secrets:
secret_1: ${MY_SECRET}
我认为一种简单的方法就是直接设置值。例如,在您的 Values.yml 中,您希望传递服务名称:
...
myapp:
service:
name: ""
...
您的 service.yml 照常使用此值即可:
{{ .Values.myapp.service.name }}
然后设置值,使用--set
,如:--set myapp.service.name=hello
然后比如你要使用环境变量,在这之前做export:
#set your env variable
export MYAPP_SERVICE=hello
#pass it to helm
helm install myapp --set myapp.service.name=$MYAPP_SERVICE.
如果你像这样调试:
helm install myapp --set myapp.service.name=$MYAPP_SERVICE --debug --dry-run ./myapp
您可以在设置“hello”的 yml 开头看到此信息。
USER-SUPPLIED VALUES:
myapp:
service:
name: hello
作为传递本地环境变量的替代方法,我喜欢将这些敏感值存储在 VCS 忽略的文件夹中,并使用 Helm .Files
对象读取它们并将值提供给模板.
在我看来,优点是它不需要运行 Helm chart 的主机来设置任何 OS 特定的环境变量,并使 chart 自包含而不暴露这些值.
# In a folder not committed, e.g. <chart_base_directory>/secrets
username: app-username
password: 28sin47dsk9ik
然后在您的图表模板中:
# In deployment.yaml file
---
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
stringData::
{{ .Files.Get "<chart_base_directory>/secrets" | indent 2 }}
因此,图表所需的一切都可以从您定义其他所有内容的目录中访问。而不是设置系统范围的环境变量,它只需要一个文件。
此文件可以自动生成,也可以使用虚拟值从已提交的模板中复制。如果未定义,Helm 也会在 install/update 早期触发错误,而不是如果您的环境变量尚未定义,则使用 username=""
和 password=""
创建您的秘密,这仅一旦您的更改应用到集群,就会变得很明显。
Helm 3.1 支持 post 渲染 (https://helm.sh/docs/topics/advanced/#post-rendering),它在将清单实际发送到 Kubernetes API 之前将清单传递给脚本。 Post 呈现允许以多种方式操作清单(例如,在 Helm 上使用 kustomize)。
替换预定义环境值的 post 渲染器的最简单形式如下所示:
#!/bin/sh
envsubst <&0
请注意,这将替换 $<VARNAME>
的 每 次出现,这可能会与模板中的变量发生冲突,例如活性探测中的 shell 脚本.因此,最好明确定义要替换的变量: envsubst '${USERNAME} ${PASSWORD}' <&0
在 shell:
中定义环境变量export USERNAME=john PASSWORD=my-secret
在模板中(例如 secret.yaml
)使用 values.yaml
中定义的值:
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
data:
username: {{ .Values.username }}
password: {{ .Values.password }}
请注意,在 Helm 已经处理完所有 YAML 文件后,您不能在清单中注入 b64enc 等字符串转换。相反,如果需要,您可以在 post 渲染器中对它们进行编码。
在values.yaml
中使用变量占位符:
...
username: ${USERNAME}
password: ${PASSWORD}
几个 Helm 命令支持参数 --post-renderer
,例如
helm install --dry-run --post-renderer ./my-post-renderer.sh my-chart
通过使用 post 渲染器,variables/placeholders 会自动被 envsubst
替换,无需额外的脚本。