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

时间:2019-05-16 13:44:38

标签: kubernetes passwords kubernetes-helm

我想在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 }}

7 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

您可以使用lookup function并在秘密已经存在的情况下跳过生成:

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

它仍然是Helm最大的问题之一。据我了解,尚无好的解决方案(请参见https://github.com/helm/charts/issues/5167)。

一个肮脏的解决方法是创建密钥作为预安装挂钩。这种方法的明显缺点是秘密删除后不会删除机密。

In [4]: num_cols = len(list(df))

In [5]: num_cols
Out[5]: 13

In [6]: new_cols = []
In [7]: for i in range(num_cols):
    ...:     if i == 0:
    ...:         new_cols.append("Event")
    ...:     elif i % 2 == 0:
    ...:         new_cols.append(f'Job{int(i/2)}')
    ...:     else:
    ...:         new_cols.append(f'Name{int((i+1)/2)}')

In [8]: new_cols
Out[8]:
['Event',
 'Name1',
 'Job1',
 'Name2',
 'Job2',
 'Name3',
 'Job3',
 'Name4',
 'Job4',
 'Name5',
 'Job5',
 'Name6',
 'Job6']

答案 4 :(得分:0)

我已经重写了kubernetes复制器,并添加了一些注释来解决此类问题:https://github.com/olli-ai/k8s-replicator#use-random-password-generated-by-an-helm-chart

现在可以生成带有头盔的随机密码,并且只能将其复制到另一个秘密一次,因此将来不会被头盔更改。

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

希望它将对人们有所帮助。

答案 5 :(得分:0)

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

答案 6 :(得分:-1)

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

helm使用注释"helm.sh/resource-policy": keep

为您完成此操作

请参阅:

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