最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

kubernetes - How to move shared configuration and sensitive data to a global config and secrets in Helm? - Stack Overflow

programmeradmin1浏览0评论

I have the following project structure:

some-module1
  templates
    deployment.yaml
  values.yaml

some-module2
  templates
    deployment.yaml
  values.yaml

some-module3
  templates
    deployment.yaml
  values.yaml

global-config
  templates
    secrets.yaml
  values.yaml

The values.yaml files for some-module1, some-module2, and some-module3 contain the same section:

shards:
  - name: "db1"
    url: "url1"
    login: "login1"
    password: "password1"
  - name: "db2"
    url: "url2"
    login: "login2"
    password: "password2"

The deployment.yaml files for some-module1, some-module2, and some-module3 contain the following identical part:

{{- range $name, $val := .Values.shards }}
env:
  - name: DB_URL
    value: {{ $val.url }}
  - name: DB_LOGIN
    value: {{ $val.login }}
  - name: DB_PASSWORD
    value: {{ $val.password }}
{{- end }}

I have two tasks:

Move the shards configuration to global-config/values.yaml. Move all sensitive data from global-config/values.yaml (under shards) to secrets in global-config/secrets.yaml. As a result, some-module1, some-module2, and some-module3 should read the shards data from the global config (i.e., the loop should look like {{- range $name, $val := .Values.global.shards }}), and all sensitive data should be sourced from the secrets.

Is this possible? If yes, how can I achieve this?

I have the following project structure:

some-module1
  templates
    deployment.yaml
  values.yaml

some-module2
  templates
    deployment.yaml
  values.yaml

some-module3
  templates
    deployment.yaml
  values.yaml

global-config
  templates
    secrets.yaml
  values.yaml

The values.yaml files for some-module1, some-module2, and some-module3 contain the same section:

shards:
  - name: "db1"
    url: "url1"
    login: "login1"
    password: "password1"
  - name: "db2"
    url: "url2"
    login: "login2"
    password: "password2"

The deployment.yaml files for some-module1, some-module2, and some-module3 contain the following identical part:

{{- range $name, $val := .Values.shards }}
env:
  - name: DB_URL
    value: {{ $val.url }}
  - name: DB_LOGIN
    value: {{ $val.login }}
  - name: DB_PASSWORD
    value: {{ $val.password }}
{{- end }}

I have two tasks:

Move the shards configuration to global-config/values.yaml. Move all sensitive data from global-config/values.yaml (under shards) to secrets in global-config/secrets.yaml. As a result, some-module1, some-module2, and some-module3 should read the shards data from the global config (i.e., the loop should look like {{- range $name, $val := .Values.global.shards }}), and all sensitive data should be sourced from the secrets.

Is this possible? If yes, how can I achieve this?

Share Improve this question asked Feb 2 at 11:16 AidarKhaibulovAidarKhaibulov 112 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

There's a couple of parts here, and some are easier than others.

The duplicated output block. If you have the same block of output YAML that you're repeating in several places, you can split that into a named template. For example,

{{/* env.db generates part of an env: block that sets database-specific
     parameters.  Takes a shard object as a parameter.  Unindented, ends
     with a newline. */}}
{{- define "env.db" -}}
- name: DB_URL
  value: {{ .url }}
- name: DB_LOGIN
  value: {{ .login }}
- name: DB_PASSWORD
  value: {{ .password }}
{{ end -}}

{{- range $name, $val := .Values.shards }}
env:
{{ include "env.db" $val | indent 2 }}
{{- end -}}

Having done that, you can move the template definition into a library chart. This could be something like moving the {{ define }}...{{ end }} block into your existing global-secrets/templates/_helpers.tpl file. The main charts would need to include a dependency on the library chart in their Chart.yaml files, but then they could call the template in exactly the same way.

Note that, if you define a function in a library chart, settings like .Values come from the place it's called, not the place it's defined. So it won't work to put the credential in the library chart too, it needs to be defined in the per-service chart.

The duplicated input settings. You can pass arbitrarily many helm install -f options to add values files when you deploy a chart, and these are used in addition to the chart's values.yaml file. One possible setup here is that your CD system can extract the credentials from a secret store and write them out as a YAML (or JSON) file, and then run

helm upgrade --install mod1 ./some-module1 --namespace mod1 \
  -f values-credentials.yaml

I would avoid putting these values under the special global: top-level key; that's only useful when you have multiple levels of nested charts or settings that are the same across multiple components being installed in the same Helm invocation. Also note (see same documentation link) that a dependency's global: settings do not propagate upward to the main chart: if the credentials are in global-config/values.yaml and the main chart depends on them, the main chart (including the include call above) will not be able to see those values.

Using a Secret instead of Helm values. Well, you can, I guess, there's a supported path in Helm to do this. I'd avoid having external dependencies like this if you can. In the previous section I suggested using some sort of credential store and having automation generate parts of the values, and it could kubectl get secret and base64-decode the values if you don't have anything better available.

Helm does have a lookup function that can find arbitrary resources in the cluster. You can, in principle, get a Secret value like

{{- $secret := lookup "v1" "Secret" .Release.Namespace "secret-name" -}}
{{- $password := $secret.data.password | b64dec -}}

You could reuse the $secret but you'd have to do something like the second line for each value you want to get out of the Secret. Helm doesn't have a couple of standard functional-programming tools like "map" that would make a more generic solution possible. You'd also have to tolerate cases where the Secret doesn't exist, and figure out how to develop and test the chart without access to the production Secret. If the Secret changes in the cluster, the Helm chart won't redeploy itself, and you'll need to remember to do this by hand.

(If you want the deployment to be driven by Kubernetes resources, consider writing a custom operator, maybe in Go using Kubebuilder. It is not harder than writing a really robust Helm chart once you start getting into complexities around library charts, and Go is a much more mainstream language that includes a unit-testing framework.)

Use a Secret as a source for Helm values. Helm doesn't have a way to do this. If the credential was only in a Secret, and you didn't have automation to pull it out, then nothing in Helm itself would let you refer to it as part of .Values. You'd need to invoke lookup as above.


To reiterate:

  1. I would break the repeated environment block out into a library chart that you control.
  2. I would not try to do anything to avoid repeating blocks of values.yaml settings.
  3. I would have your deployment system get the right credentials from somewhere and inject them with a helm install -f option.
  4. I would not try to put settings into a Kubernetes Secret.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论