如何使用Helm图表拉取环境变量

时间:2018-04-19 19:27:54

标签: kubernetes kubectl kubernetes-helm

我在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的值?

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

7 个答案:

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