Kubernetes 如何使用Kubeseal来密封头盔模板的秘密?

Kubernetes 如何使用Kubeseal来密封头盔模板的秘密?,kubernetes,kubernetes-helm,kubernetes-secrets,Kubernetes,Kubernetes Helm,Kubernetes Secrets,想象一下这样一个秘密: apiVersion: v1 kind: Secret metadata: name: {{ include "test-cicd.fullname" . }} labels: app.kubernetes.io/name: {{ include "test-cicd.name" . }} helm.sh/chart: {{ include "test-cicd.chart" . }} app.kubernetes.io/instance:

想象一下这样一个秘密:

apiVersion: v1
kind: Secret
metadata:
  name: {{ include "test-cicd.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "test-cicd.name" . }}
    helm.sh/chart: {{ include "test-cicd.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
type: Opaque
data:
  secret.yaml: |
    {{ if eq .Values.env "prod" }}
    foo: bar-prod
    foo2: bar2_prod
    {{ else if eq .Values.evn "dev" }}
    foo: bar-dev
    {{ end }}
是否可以使用密封件密封此部件? 现在这样做时,我得到
无效的映射键:map[interface{}]interface{}{“include\”test cicd.fullname\“:interface{}(nil)}
,这可能是因为它不是一个“有效”的yaml文件

我试过的一件事是: 1.拆卸舵模板线 2.生成sealedsecret 3.使用头盔制作密封秘密的模板


但是,通过这样做,集群端操作员无法在部署时解密sealedsecret

mkmik回答了我关于的问题,所以我在这里引用它也是为了记录在案


因此,您正在使用客户端模板构建一个秘密值。 secret.yaml文件的某些部分是机密的,但这些部分必须是模板指令(if),因此无法加密

您有两个选择:

  • 您可以使用一些客户端vault软件(可能与helm集成(例如)一起)以某种方式加密您的机密。这就要求应用掌舵图的每个用户(和CI环境)都能够解密这些秘密

  • 您可以重新考虑您的机密,使机密具有“原子性”,并使用密封机密从其“单向加密”方法中获益,该方法允许您的devops用户(和CI automation)应用helm图表,而不必亲自查看机密值

  • 此答案的其余部分假设您选择了选项(2)


    现在,既然您决定使用Helm,那么您必须处理这样一个事实,即Helm模板不是json/yaml文件,而是Go模板,因此它们不能被设计用于处理结构化数据格式的工具处理

    幸运的是,kubeseal有一个--raw命令,它允许您对各个秘密值进行加密,并手动将它们放入您用来描述k8s资源的任何文件格式中

    因此,假设您希望为SealedSecrets资源创建一个Helm模板,该模板将名称和标签值作为参数,并根据布尔prod/dev参数选择要放置的机密,此示例可能适用于您:

    apiVersion: bitnami.com/v1alpha1
    kind: SealedSecret
    metadata:
      name: {{ include "test-cicd.fullname" . }}
      annotations:
        # this is because the name is a deployment time parameter
        # consider also using "cluster-wide" if the namespace is also a parameter
        # please make sure you understand the implications, see README
        sealedsecrets.bitnami.com/namespace-wide: "true"
      labels:
        app.kubernetes.io/name: {{ include "test-cicd.name" . }}
        helm.sh/chart: {{ include "test-cicd.chart" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
        app.kubernetes.io/managed-by: {{ .Release.Service }}
    type: Opaque
    spec:
      template:
        metadata:
          labels:
            app.kubernetes.io/name: {{ include "test-cicd.name" . }}
            app.kubernetes.io/instance: {{ .Release.Name }}
            app.kubernetes.io/managed-by: {{ .Release.Service }}
      encryptedData:
        {{ if eq .Values.env "prod" }}
        foo: AgASNmKx2+QYbbhSxBE0KTa91sDBeNSaicvgBPW8Y/q/f806c7lKfF0mnxzEirjBsvF67C/Yp0fwSokIpKyy3gXtatg8rhf8uiQAA3VjJGkl5VYLcad0t6hKQyIfHsD7wrocm36uz9hpH30DRPWtL5qy4Z+zbzHj8AvEV+xTpBHCSyJPF2hyvHXTr6iQ6KJrAKy04MDwjyQzllN5OQJT2w4zhVgTxXSg/c7m50U/znbcJ1x5vWLXLSeiDRrsJEJeNoPQM8OHmosf5afSOTDWQ4IhG3srSBfDExSFGBIC41OT2CUUmCCtrc9o61LJruqshZ3PkiS7PqejytgwLpw/GEnj2oa/uNSStiP9oa9mCY6IUMujwjF9rKLIT456DlrnsS0bYXO2NmYwSfFX+KDbEhCIVFMbMupMSZp9Ol2DTim5SLIgIza/fj0CXaO3jGiltSQ0aM8gLSMK9n3c1V+X5hKmzMI3/Xd01QmhMmwqKp+oy21iidLJjtz67EiWyfIg1l7hiD5IIVlM9Gvg3k67zij5mOcXPkFnMmUQhQWxVKgAf4z8qEgprt03C+q+Wwwt25UDhQicpwoGtVQzU5ChJi09ja5LeW4RrvDf2B5KRp9HXoj1eu93MMl1Kcnx+X7uVT5OqQz28c4wOLT4FDItFzh8zREGZbiG/B3o1vI8MmwvxXj++pQ7SfBxoz9Xe8gmQ7BuXno=
        foo2: AgAkaTBYcESwogPiauZ15YbNldmk4a9esyYuR2GDt7hNcv+ycPLHmnsJcYs0hBtqucmrO3HbgCy/hQ6dMRCY12RA7w7XsFqNjZy3kavnhqwM6YkHntK2INwercRNQpO6B9bH6MxQTXcxfJbPqaPt30iTnTAhtpN47lueoyIoka4WWzwG/3PAikXhIlkTaq0hrclRJHRqg4z8Kmcaf5A/BRL2xX8syHbjA7MK9/OoK+zytv+LGrbLLHUtuhNNNQ2PG9u05rP6+59wRduQojEDtB9FTCa+daS+04/F4H1vi6XUNnjkK+Xna1T2Eavyuq2GieKj/7ig96et/4HoTAz44zwVhh8/pk0IFC8srcH3p+rFtZZmjvbURrFahEjFZbav3BDMBNhrU8SI3MDN0Abiyvz4vJJfSxIYcyLD1EQ507q7ZXrqYN/v1EiYgYUACi0JGxSWHB9TlCkZOAdCl+hroXEhBN2u5utLJ12njBQJ8ACNQDOYf+CmtV0y7foCZ6Aaap0pV7a8twyqK8c17kImzfi102Zel8ALfLAzdAXBV9c1+1pH76turnTCE33aSMQlaVF3VTmFQWqB8uIO/FQhZDPo8u/ki3L8J31nepup4/WE7i59IT0/9qGh2LKql4oAv6v4D7qtKziN6DvG7bsJlj14Dln0roiTfTWEEnBqdDER+GKZJlKayOWsPQdN0Wp+2KVfwLM=
        {{ else if eq .Values.evn "dev" }}
        foo: AgAkaTBYcESwogPi..........
        {{ end }}
    
    另一种方法是使用两个模板,一个用于prod,另一个用于dev,并根据部署到的环境使用Helm模板逻辑来选择正确的文件

    无论如何,这些base64 Blob中的每一个都可以通过以下方式生成:

    $ kubeseal --raw --scope namespace-wide --from-file=yoursecret.txt
    
    专业提示,如果秘密不在文件中,您可以通过管道传输:

    $ echo -n yoursecret | kubeseal --raw --scope namespace-wide --from-file=/dev/stdin
    

    然后,您必须将该命令的输出粘贴到您的Helm Go模板中。

    我不会将来自不同环境的凭据放入单个机密中,因为它可以部署到具有不同控制器的不同集群中

    为什么不为每个环境单独设置秘密文件呢

    要密封一个秘密,我使用以下命令:

    kubeseal --name=name-of-the-config --controller-namespace=fluxcd \
           --controller-name=sealed-secrets  --format yaml \
          < secret.yaml > sealedsecret.yaml
    
    我的方法

  • 针对不同的环境使用不同的.values.yml文件
  • 创建.secrets.yml文件以存储机密值(包括在.gitignore中)
  • 制作一个git预提交钩子,它使用
    kubeseal--raw
    加密各个秘密,然后将它们写入值文件
  • 将值文件存储在git中

  • 我写了一个要点:

    我不熟悉Kubeseal,但如果你想了解其他解决方案,可以查看我的。谢谢@Omerevehvroni。我是从上的
    mkmik
    得到答案的。@Milad你能把GitHub的答案也发到这里吗?如果kubeseal能够加密Helm values.yaml文件,那就太好了。e、 你在互联网上其他任何地方都找不到这个。这是一种将密封秘密与头盔模板结合使用的方法,这是一个很好的解决方案。谢谢分享。
    kubectl get HelmRelease -A -o jsonpath="{.items[?(@.spec.chart@.name=='sealed-secrets')]}"