我想在 Helm 模板中生成密码,使用
randAlphaNum
函数很容易做到这一点。但是,当版本升级时,密码将会更改。有没有办法检查密码是否先前生成,然后使用现有值?像这样的东西:
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 }}
您可以基于 shaunc 的想法,使用 lookup 函数来修复原始海报的代码,如下所示:
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 }}
仅在
Secret
尚不存在时创建它是行不通的,因为 Helm 将删除在升级过程中不再定义的对象。
使用注释来保留对象的缺点是,当您使用
helm delete ...
删除版本时,该对象不会被删除。
我对 Jan Dubois 和 shaunc 的答案遇到了很多麻烦。所以我构建了一个组合解决方案。
Jan 答案的缺点:与
--dry-run
一起使用时会导致错误。helm upgrade
被删除。
这是我的代码:
# 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 }}
这仍然是 Helm 最大的问题之一。据我了解,目前还没有好的解决方案(请参阅https://github.com/helm/charts/issues/5167)。
一个肮脏的解决方法是创建秘密作为预安装挂钩。这种方法的明显缺点是秘密不会在 helm 删除时被删除。
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 }}
基于 shaunc 使用 lookup 函数的想法,我创建了以下模板:
{{/*
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 }}
然后您可以简单地配置秘密,例如:
---
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") }}"
实际的工具都在这里。我的解决方法只是建议工具的另一种组合
{{- 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 }}
因此,如果没有这样的秘密,就会创建它。如果秘密存在,它将从图表中删除,但不会从集群中删除,
"helm.sh/resource-policy": "keep"
将阻止它。
您可能会问(正如上面有人已经做过的那样)为什么是
lookup
,而不是.Release.IsUpdate
。想象一下这种情况:您的秘密是数据库的密码。您将数据保存在持久卷中,该卷的声明也用 "helm.sh/resource-policy": "keep"
注释,因此,即使您卸载并重新安装图表,数据也会保留。如果您以 .Release.IsUpdate
作为条件执行此操作,那么您的密码将被重新创建,旧密码将丢失,并且您将失去对数据的访问权限。如果你询问秘密存在,它就不会发生。
我重写了kubernetes复制器并添加了一些注释来处理此类问题:https://github.com/olli-ai/k8s-replicator#use-random-password- generated-by-an-helm-图表
现在可以使用 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 }}
希望它能帮助人们。
您可以利用
_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" . }}
您可以使用不可变的秘密https://kubernetes.io/docs/concepts/configuration/secret/#secret-immutable
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-database-password
namespace: {{ .Release.Namespace }}
labels:
app: {{ .Release.Name }}-database
annotations:
"helm.sh/hook": pre-install
"helm.sh/hook-delete-policy": before-hook-creation
type: Opaque
immutable: true
data:
db-password: {{ randAlphaNum 20 | b64enc | quote }}
这里有点晚了,大多数人可能只是在文档中发现了它:
helm 通过注释为您完成此操作
"helm.sh/resource-policy": keep
参见:
https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource