How to set secret files to kubernetes secrets by yaml?

大兔子大兔子 提交于 2020-06-09 08:37:13

问题


I want to store files in Kubernetes Secrets but I haven't found how to do it using a yaml file.

I've been able to make it using the cli with kubectl:

kubectl create secret generic some-secret --from-file=secret1.txt=secrets/secret1.txt

But when I try something similar in a yaml:

apiVersion: v1
kind: Secret
metadata:
  name: some-secret
type: Opaque
data:
  secret1.txt: secrets/secret1.txt

I´ve got this error:

[pos 73]: json: error decoding base64 binary 'assets/elasticsearch.yml': illegal base64 data at input byte 20

I'm following this guide http://kubernetes.io/docs/user-guide/secrets/. It explains how to create a secret using a yaml but not how to create a secret from a file using yaml.

Is it possible? If so, how can I do it?


回答1:


When using the CLI format basically you're using a generator of the yaml before posting it to the server-side.

Since Kubernetes is client-server app with REST API in between, and the actions need to be atomic, the posted YAML needs to contain the content of the file, and best way to do that is by embedding it as a base64 format in-line. It would be nice if the file could be otherwise embedded (indentation maybe could be used to create the boundaries of the file), but I haven't seen any example of such until now.

That being said, putting a file reference on the yaml is not possible, there is no pre-flight rendering of the yaml to include the content.




回答2:


As answered on previous post, we need to provide the certificate/key encoded as based64 to the file.

Here is generic example for a certiticate (in this case SSL):

The secret.yml.tmpl:

    apiVersion: v1    

    kind: Secret
    metadata:
         name: test-secret
         namespace: default
    type: Opaque
    data:
        server.crt: SERVER_CRT
        server.key: SERVER_KEY

Pre-process the file to include the certificate/key:

sed "s/SERVER_CRT/`cat server.crt|base64 -w0`/g" secret.yml.tmpl | \
sed "s/SERVER_KEY/`cat server.key|base64 -w0`/g" | \
kubectl apply -f -

Note that the certificate/key are encoded using base64 without whitespaces (-w0).

For the TLS can be simply:

kubectl create secret tls test-secret-tls --cert=server.crt --key=server.key



回答3:


You can use --dry-run flag to prepare YAML that contains data from your files.

kubectl create secret generic jwt-certificates --from-file=jwt-public.cer --from-file=jwt-private.pfx --dry-run=true  --output=yaml > jwt-secrets.yaml



回答4:


You can use secode to replace secret values with base64 encoded strings, by simply doing:

secode secrets.yaml > secrets_base64.yaml

It encodes all data fields and works with multiple secrets (kind:Secret) per yaml file, when defined in a list (kind: List).

Disclaimer: I'm the author




回答5:


For the Windows users in the room, use this for each of the .cer and .key (example shows the .key being encoded for insertion in to the YAML file):

$Content = Get-Content -Raw -Path C:\ssl-cert-decrypted.key

[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Content)) | Out-File -FilePath C:\ssl-cert-decrypted.key.b64

Open the new .b64 file and paste the (single line) output in to your YAML file - be aware that if checking in the YAML file to a source code repo with this information in it, the key would effectively be compromised since base64 isn't encryption.




回答6:


So I just learned a super useful k8s fundamental I missed, and then discovered it has a security vulnerability associated with it, and came up with a resolution.

TLDR:
You can have cleartext multiline strings/textfiles as secret.yaml's in your secret repo !!! :)
(Note I recommend storing this in Hashicorp Vault, you can store versioned config files that have secrets, and easily view/edit them through the vault webpage, and unlike a git repo, you can have fine grain access control, pipelines can use the REST API to pull updated secrets which makes password rotation mad easy too.)

cleartext-appsettings-secret.yaml
appsettings.Dummy.json is the default file name (key of the secret)
(I use the word default file name as you could override it in the yaml mount)
and the clear text json code is the file contents (value of the secret)

apiVersion: v1
kind: Secret
metadata:
  name: appsettings
  namespace: api
type: Opaque
stringData:
  appsettings.Dummy.json: |-
    {
      "Dummy": {
        "Placeholder": {
          "Password": "blank"
        }
      }
    }

When I
kubectl apply -f cleartext-appsettings-secret.yaml
kubectl get secret appsettings -n=api -o yaml

The secret shows up cleartext in the annotation...

apiVersion: v1
data:
  appsettings.Dummy.json: ewogICJEdW1teSI6IHsKICAgICJQbGFjZWhvbGRlciI6IHsKICAgICAgIlBhc3N3b3JkIjogImJsYW5rIgogICAgfQogIH0KfQ==
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"appsettings","namespace":"api"},"stringData":{"appsettings.Dummy.json":"{\n  \"Dummy\": {\n    \"Placeholder\": {\n      \"Password\": \"blank\"\n    }\n  }\n}"},"type":"Opaque"}
  creationTimestamp: 2019-01-31T02:50:16Z
  name: appsettings
  namespace: api
  resourceVersion: "4909"
  selfLink: /api/v1/namespaces/api/secrets/appsettings
  uid: f0629027-2502-11e9-9375-6eb4e0983acc


Apparently the yaml used to create the secret showing up in the annotation is expected behavior for kubectl apply -f secret.yaml since 2016/has been posted as a bug report, but issue closed without resolution/they're ignoring it vs fixing it.

If you're original secret.yaml is base64'd the annotation will at least be base64'd but in this scenario it's straight up non-base64'd human readable clear text.

Note1: it doesn't happen with imperative secret creation
kubectl create secret generic appsettings --from-file appsettings.Dummy.json --namespace=api

Note2: Another reason for favoring the declarative appsettings-secret.yaml, is that when it's time to edit kubectl apply -f will configure the secret, but if you run that create command it'll say error already exists and you'll have to delete it, before it'll let you run the create command again.

Note3: A reason for kubectl create secret generic name --from-file file --namespace / a reason against secret.yaml is that kubectl show secret won't show you the last time the secret got edited. Where as with the create command, because you have to delete it before you can recreate it, you'll know when it was last edited based on how long it's existed for, so that's good for audit trial. (But there's better ways of auditing)

kubectl apply -f cleartext-appsettings-secret.yaml
kubectl annotate secret appsettings -n=api kubectl.kubernetes.io/last-applied-configuration-
kubectl get secret appsettings -n=api -o yaml
Counteracts the leak

apiVersion: v1
data:
  appsettings.Dummy.json: ewogICJEdW1teSI6IHsKICAgICJQbGFjZWhvbGRlciI6IHsKICAgICAgIlBhc3N3b3JkIjogImJsYW5rIgogICAgfQogIH0KfQ==
kind: Secret
metadata:
  creationTimestamp: 2019-01-31T03:06:55Z
  name: appsettings
  namespace: api
  resourceVersion: "6040"
  selfLink: /api/v1/namespaces/api/secrets/appsettings
  uid: 43f1b81c-2505-11e9-9375-6eb4e0983acc
type: Opaque


来源:https://stackoverflow.com/questions/36887946/how-to-set-secret-files-to-kubernetes-secrets-by-yaml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!