简体   繁体   English

如何不覆盖 Helm 模板中随机生成的秘密

[英]How not to overwrite randomly generated secrets in Helm templates

I want to generate a password in a Helm template, this is easy to do using the randAlphaNum function. However the password will be changed when the release is upgraded.我想在 Helm 模板中生成密码,使用randAlphaNum function 很容易做到这一点。但是,当版本升级时,密码将被更改。 Is there a way to check if a password was previously generated and then use the existing value?有没有办法检查以前是否生成密码然后使用现有值? Something like this:像这样:

apiVersion: v1
kind: Secret
metadata:
  name: db-details
data:
  {{ if .Secrets.db-details.db-password }}
  db-password:  {{ .Secrets.db-details.db-password | b64enc }}
  {{ else }}
  db-password: {{ randAlphaNum 20 | b64enc }}
  {{ end }}

You can build on shaunc 's idea to use the lookup function to fix the original poster's code like this:您可以基于shaunc的想法使用查找功能来修复原始海报的代码,如下所示:

apiVersion: v1
kind: Secret
metadata:
  name: db-details
data:
  {{- if .Release.IsInstall }}
  db-password: {{ randAlphaNum 20 | b64enc }}
  {{ else }}
  # `index` function is necessary because the property name contains a dash.
  # Otherwise (...).data.db_password would have worked too.
  db-password:  {{ index (lookup "v1" "Secret" .Release.Namespace "db-details").data "db-password" }}
  {{ end }}

Only creating the Secret when it doesn't yet exist won't work because Helm will delete objects that are no longer defined during the upgrade.只有在Secret尚不存在时才创建它是行不通的,因为 Helm 将删除升级期间不再定义的对象。

Using an annotation to keep the object around has the disadvantage that it will not be deleted when you delete the release with helm delete ... .使用注释来保留对象的缺点是,当您使用helm delete ...删除发布时,它不会被删除。

It's still one of the biggest issues of Helm.这仍然是 Helm 最大的问题之一。 As far as I understand no good solution is available yet (see https://github.com/helm/charts/issues/5167 ).据我所知,目前还没有好的解决方案(参见https://github.com/helm/charts/issues/5167 )。

One dirty workaround is to create secret as pre-install hook .一种肮脏的解决方法是创建 secret 作为 pre-install hook Obvious downside of this approach is that secret will not be deleted on helm delete.这种方法的明显缺点是在 helm delete 时不会删除 secret。

apiVersion: v1
kind: Secret
metadata:
  name: {{ template "helm-random-secret.fullname" . }}
  annotations:
    "helm.sh/hook": "pre-install"
    "helm.sh/hook-delete-policy": "before-hook-creation"
  labels:
    app: {{ template "helm-random-secret.name" . }}
    chart: {{ template "helm-random-secret.chart" . }}
    release: {{ .Release.Name }}
    heritage: {{ .Release.Service }}
data:
  some-password: {{ default (randAlphaNum 10) .Values.somePassword | b64enc | quote }}

You can use the lookup function and skip generation if secret already exists:如果秘密已经存在,您可以使用lookup功能并跳过生成:

{{- if not (lookup "v1" "secret" .Release.Namespace "db-details") -}}
<create secret here>
{{- end -}}

I've got a lot of trouble with the answers from Jan Dubois and shaunc . Jan Duboisshaunc的回答给我带来了很多麻烦。 So I built a combined solution.所以我构建了一个组合解决方案。

The downside of Jan's answer: It leads to errors, when it is used with --dry-run . Jan 答案的缺点:当它与--dry-run一起使用时会导致错误。
The downside of shaunc's answer: It won't work, because the resources will be deleted on helm upgrade . shaunc 的答案的缺点:它不会工作,因为资源将在helm upgrade被删除。

Here is my code:这是我的代码:

# store the secret-name as var
# in my case, the name was very long and containing a lot of fields
# so it helps me a lot
{{- $secret_name := "your-secret-name" -}}

apiVersion: v1
kind: Secret
metadata:
  name: {{ $secret_name }}

data:
  # try to get the old secret
  # keep in mind, that a dry-run only returns an empty map 
  {{- $old_sec := lookup "v1" "Secret" .Release.Namespace $secret_name }}

  # check, if a secret is already set
  {{- if or (not $old_sec) (not $old_sec.data) }}
  # if not set, then generate a new password
  db-password: {{ randAlphaNum 20 | b64enc }}
  {{ else }}
  # if set, then use the old value
  db-password: {{ index $old_sec.data "db-password" }}
  {{ end }}

Building on shaunc 's idea to use the lookup function, I've created the following template:基于shaunc使用查找功能的想法,我创建了以下模板:

{{/*
Returns a secret if it already in Kubernetes, otherwise it creates
it randomly.
*/}}
{{- define "getOrGeneratePass" }}
{{- $len := (default 16 .Length) | int -}}
{{- $obj := (lookup "v1" .Kind .Namespace .Name).data -}}
{{- if $obj }}
{{- index $obj .Key -}}
{{- else if (eq (lower .Kind) "secret") -}}
{{- randAlphaNum $len | b64enc -}}
{{- else -}}
{{- randAlphaNum $len -}}
{{- end -}}
{{- end }}

Then you can simply configure secrets like:然后你可以简单地配置秘密,如:

---
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  PASSWORD: "{{ include "getOrGeneratePass" (dict "Namespace" .Release.Namespace "Kind" "Secret" "Name" "my-secret" "Key" "PASSWORD") }}"

I've rewritten kubernetes replicator and added some annotations to deal with this kind of problems: https://github.com/olli-ai/k8s-replicator#use-random-password-generated-by-an-helm-chart我已经重写了 kubernetes 复制器并添加了一些注释来处理此类问题: https : //github.com/olli-ai/k8s-replicator#use-random-password-generated-by-an-helm-chart

Now can generate a random password with helm, and replicate it only once to another secret thus it won't be change by helm in the future.现在可以用 helm 生成一个随机密码,并且只将它复制一次到另一个秘密,这样以后就不会被 helm 改变了。

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: admin-password-source
  annotations:
    k8s-replicator/replicate-to: "admin-password"
    k8s-replicator/replicate-once: "true"
stringData:
  password: {{ randAlphaNum 64 | quote }}

Hope it will help people.希望它能帮助人们。

The actual tools are all here.实际的工具都在这里。 My workaround is just another combination of suggested tools我的解决方法只是建议工具的另一种组合

{{- if not (lookup "v1" "Secret" .Release.Namespace "mysecret") }}
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  annotations:
    "helm.sh/resource-policy": "keep"
type: Opaque
stringData:
  password: {{ randAlphaNum 24 }}
{{- end }}

You can leverage definitions in the _helpers.tpl您可以利用_helpers.tpl中的定义

_helpers.tpl _helpers.tpl

{{/*
Create the secret name
*/}}
{{- define "mssql-server.secretName" -}}
{{- include "mssql-server.name" . }}-mssql-secret
{{- end }}

{{/*
Get sa password value
*/}}
{{- define "mssql-server.sapassword" -}}
{{- if .Release.IsInstall -}}
{{ .Values.sa_password | default (randAlphaNum 20) | b64enc | quote }}
{{- else -}}
{{ index (lookup "v1" "Secret" .Release.Namespace (include "mssql-server.secretName" .)).data "sa_password" }}
{{- end }}
{{- end }}

secret.yaml秘密.yaml

apiVersion: v1
kind: Secret
metadata:
  name: {{ include "mssql-server.secretName" . }}
  labels:
    {{- include "mssql-server.labels" . | nindent 4 }}
type: Opaque
data:
  sa_password: {{ include "mssql-server.sapassword" . }}

A bit late here, and most people may just catch it in the documentation:这里有点晚了,大多数人可能只是在文档中看到它:

helm does this for you with the annotation "helm.sh/resource-policy": keep helm 使用注释"helm.sh/resource-policy": keep为您执行此操作"helm.sh/resource-policy": keep

see:看:

https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM