我在Helm图表的templates目录中有我的deployment.yaml文件,其中包含我将使用Helm运行的容器的几个环境变量。
现在我希望能够从运行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的值?
这可能吗?如果是,那我该怎么做?
答案 0 :(得分:41)
您可以export
变量并在运行helm install
时使用它。
在此之前,您必须修改图表,以便在安装时值为set
。
如果您已经知道,请跳过此部分,了解如何设置模板字段。
由于您不想公开数据,因此最好将其保存为kubernetes中的秘密。
首先,在Values
文件中添加这两行,以便可以从外部设置这两个值。
username: root
password: password
现在,在secret.yaml
文件夹中添加template
文件。并将此代码段复制到该文件中。
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
data:
password: {{ .Values.password }}
username: {{ .Values.username }}
现在调整部署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
现在在运行helm install时使用此变量,
$ 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
您可以看到秘密用户名的数据已更改为root-user
。
我已将this example添加到github repo。
kubernetes/helm回购中也有一些关于此问题的讨论。您可以看到this issue以了解使用环境变量的所有其他方法。
答案 1 :(得分:8)
您可以通过如下设置部署yaml来传递yaml值中的env键值:
spec:
restartPolicy: Always
containers:
- name: sample-app
image: "sample-app:latest"
imagePullPolicy: Always
env:
{{- range .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"
答案 2 :(得分:4)
对于那些希望使用数据结构代替其环境变量文件列表的人来说,这对我有用:
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"
这样,我可以在舵图的其他部分中按名称访问特定值,并通过舵命令行传递敏感值。
答案 3 :(得分:4)
作为传递本地环境变量的替代方法,我喜欢将这些类型的敏感值存储在您的 VCS 忽略的文件夹中,并使用 Helm .Files
对象读取它们并将值提供给您的模板。< /p>
在我看来,优点是它不需要运行 Helm 图表的主机来设置任何操作系统特定的环境变量,并使图表自包含而不暴露这些值。
# 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 还会在安装/更新的早期触发错误,而不是在未定义环境变量的情况下使用 username=""
和 password=""
创建您的秘密,这只会变得很明显一旦您的更改应用于集群。
答案 4 :(得分:2)
我认为一种简单的方法就是直接设置值。例如,在您的 Values.yml 中,您希望传递服务名称:
...
myapp:
service:
name: ""
...
你的 service.yml 照常使用这个值:
{{ .Values.myapp.service.name }}
然后设置值,只需--set
,例如:--set myapp.service.name=hello
那么,比如,如果你想使用环境变量,只需在此之前进行导出:
#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
您可以在 yml 的开头看到此信息,该信息设置了您的“hello”。
USER-SUPPLIED VALUES:
myapp:
service:
name: hello
答案 5 :(得分:1)
我想的问题是,如何通过自身查看环境变量而不是通过--set传递它来在图表内查找环境变量。
例如:我已经设置了一个键“ my_db_password”,并希望通过查看evn变量中的值来更改值。
我对GO模板不是很确定,但是我猜想这是禁用的,因为他们在头盔文档中对此进行了解释。 “出于安全考虑,我们删除了两个:env和expandenv(这将使图表作者可以访问Tiller的环境)。” https://helm.sh/docs/developing_charts/#know-your-template-functions
答案 6 :(得分:0)
要摆脱手动设置每个秘密的麻烦,可以使用:
export MY_SECRET=123
envsubst < values.yaml | helm install my-release . --values -
在您的values.yaml文件中引用了$ {MY_SECRET},例如:
mychart:
secrets:
secret_1: ${MY_SECRET}