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

问题描述 投票:0回答:10

我想在 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 }}
kubernetes passwords kubernetes-helm
10个回答
24
投票

您可以基于 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 ...
删除版本时,该对象不会被删除。


14
投票

我对 Jan Duboisshaunc 的答案遇到了很多麻烦。所以我构建了一个组合解决方案。

Jan 答案的缺点:与

--dry-run
一起使用时会导致错误。
shaunc 答案的缺点:它不起作用,因为资源将在
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 }}

9
投票

这仍然是 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 }}

4
投票

基于 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") }}"

4
投票

实际的工具都在这里。我的解决方法只是建议工具的另一种组合

{{- 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
作为条件执行此操作,那么您的密码将被重新创建,旧密码将丢失,并且您将失去对数据的访问权限。如果你询问秘密存在,它就不会发生。


3
投票

您可以使用

lookup
功能并跳过生成(如果秘密已存在):

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

0
投票

我重写了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 }}

希望它能帮助人们。


0
投票

您可以利用

_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 }}

秘密.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" . }}

0
投票

您可以使用不可变的秘密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 }}

-5
投票

这里有点晚了,大多数人可能只是在文档中发现了它:

helm 通过注释为您完成此操作

"helm.sh/resource-policy": keep

参见:

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

© www.soinside.com 2019 - 2024. All rights reserved.