How to pull environment variables with Helm charts

我将在 Helm 图表的模板目录中包含我将使用 Helm 运行的容器的几个环境变量,这里有我的 loyment.yaml 文件。

现在我希望能够将环境变量从任何机器的头盔运行本地,这样我就可以隐藏秘密的方式。

当我使用 Helm 来运行应用程序时,如何传递这些信息并让 Helm 在本地获取环境变量?

下面是我的 loyment.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 的值?

这可能吗? 如果可能,那么我该怎么做?

176931 次浏览

您可以 export变量并在运行 helm install时使用它。

在此之前,您必须修改您的图表,以便在安装时该值可以为 set

Skip this part, if you already know, how to setup template fields.


As you don't want to expose the data, so it's better to have it saved as secret in kubernetes.

First of all, add this two lines in your Values file, so that these two values can be set from outside.

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
...
...

If you have modified your template correctly for --set flag, 你可以用环境变量来设置。

$ export USERNAME=root-user

现在在运行头盔安装时使用这个变量,

$ helm install --set username=$USERNAME ./mychart

If you run this helm install in dry-run mode, you can verify the changes,

$ 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

我已经将 这个例子添加到 github repo 中。

库伯内特/头盔回购协议中也有一些关于这方面的讨论。您可以通过 这个问题了解使用环境变量的所有其他方法。

我想问题是如何在图表中查找 env 变量通过查找 env 变量本身而不是通过传递—— set。

例如: 我已经设置了一个键“ my _ db _ password”,并希望通过查看 env 变量中的值来更改这些值。

我不是很肯定的 GO 模板,但我猜这是禁用的,因为他们在舵文档中解释。“出于安全原因,我们删除了两个: 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 }}

在价值观上:

env:
- name: "USERNAME"
value: ""
- name: "PASSWORD"
value: ""

when you install the chart you can pass the username password value

helm install chart_name --name release_name --set env.USERNAME="app-username" --set env.PASSWORD="28sin47dsk9ik"

对于那些希望使用数据结构来替代 env 变量文件列表的人来说,这对我很有用:

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 }}


价值观:

env:
FOO: "BAR"
USERNAME: "CHANGEME"
PASWORD: "CHANGEME"

这样,我就可以通过名称访问舵图其他部分中的特定值,并通过舵命令行传递敏感值。

为了避免手动设置每个秘密,您可以使用:

export MY_SECRET=123
envsubst < values.yaml | helm install my-release . --values -

其中 ${ MY _ Secret T }在 values.yaml 文件中被引用,如下所示:

mychart:
secrets:
secret_1: ${MY_SECRET}

我认为一个简单的方法就是 set the value directly。例如,在 Values.yml 中,您需要传递服务名:

...
myapp:
service:
name: ""
...

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.

If you do debug like:

helm install myapp --set myapp.service.name=$MYAPP_SERVICE --debug --dry-run ./myapp

您可以在您的 yml 的开头看到这些信息,您的“ hello”被设置为。

USER-SUPPLIED VALUES:
myapp:
service:
name: hello

As an alternative to pass local environment variables, I like to store these kind of sensitive values in a folder ignored by your VCS, and use Helm .Files object to read them and provide the values to your templates.

在我看来,这样做的好处是不需要主机操作 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 }}

因此,图表需要的所有内容都可以从定义其他内容的目录中访问。它只需要一个文件,而不是设置系统范围的 env vars。

这个文件可以自动生成,或者从具有虚拟值的提交模板复制。Helm 还会在安装/更新的早期触发一个错误,如果没有定义这个错误,而不是在没有定义 env vars 的情况下用 username=""password=""创建 secret,只有当您的更改应用到集群时才会显而易见。

Helm 3.1支持后期渲染(https://helm.sh/docs/topics/advanced/#post-rendering) ,它在清单实际发送到 Kubernetes API 之前将其传递给脚本。后期渲染允许以多种方式操作清单(例如,在 Helm 上使用 定制)。

替换预定义环境值的 post 渲染器的最简单形式如下:

#!/bin/sh
envsubst <&0

注意,这将取代 $<VARNAME>每个出现,$<VARNAME>可能与模板中的变量发生冲突,比如活性探测中的 shell 脚本。因此,最好明确定义要替换的变量: envsubst '${USERNAME} ${PASSWORD}' <&0

在 shell 中定义 env 变量:

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

通过使用 后渲染器,变量/占位符会自动被 envsubst替换,而不需要额外的脚本。