[英]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 Dubois和shaunc的回答给我带来了很多麻烦。 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
中的定义
{{/*
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 }}
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.