如何通过yaml将秘密文件设置为kubernetes秘密?
How to set secret files to kubernetes secrets by yaml?
我想将文件存储在 Kubernetes Secrets 中,但我还没有找到如何使用 yaml
文件来做到这一点。
我已经能够通过 kubectl
:
使用 cli 来实现它
kubectl create secret generic some-secret --from-file=secret1.txt=secrets/secret1.txt
但是当我在 yaml
中尝试类似的东西时:
apiVersion: v1
kind: Secret
metadata:
name: some-secret
type: Opaque
data:
secret1.txt: secrets/secret1.txt
我遇到了这个错误:
[pos 73]: json: error decoding base64 binary 'assets/elasticsearch.yml': illegal base64 data at input byte 20
我正在遵循本指南 http://kubernetes.io/docs/user-guide/secrets/。它解释了如何使用 yaml
创建秘密,但没有解释如何使用 yaml
.
从 文件 创建秘密
可能吗?如果可以,我该怎么做?
当使用 CLI
格式时,基本上您是在将 yaml 发布到服务器端之前使用 yaml 生成器。
由于 Kubernetes 是介于两者之间的 REST API 的客户端-服务器应用程序,并且操作需要是原子的,因此发布的 YAML 需要包含文件的内容,最好的方法是通过将其嵌入为内联的 base64 格式。如果文件可以以其他方式嵌入(缩进可能用于创建文件的边界),那就太好了,但直到现在我还没有看到任何这样的例子。
话虽如此,在 yaml 上放置文件引用是不可能的,因为没有包含内容的 yaml 的飞行前渲染。
正如之前 post 的回答,我们需要向文件提供编码为 base64 的 certificate/key。
这是证书的通用示例(在本例中为 SSL):
secret.yml.tmpl
:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
type: Opaque
data:
server.crt: SERVER_CRT
server.key: SERVER_KEY
预处理文件以包含 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 -
请注意 certificate/key 使用 base64 编码,没有空格 (-w0)。
对于TLS可以简单的是:
kubectl create secret tls test-secret-tls --cert=server.crt --key=server.key
对于房间中的 Windows 用户,将此用于每个 .cer 和 .key(示例显示正在编码的 .key 以插入到 YAML 文件中):
$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
打开新的 .b64
文件并将(单行)输出粘贴到您的 YAML 文件中 - 请注意,如果将 YAML 文件签入包含此信息的源代码存储库,密钥由于 base64 不是加密的,因此实际上会受到损害。
您可以使用 secode 将秘密值替换为 base64
编码字符串,只需执行以下操作:
secode secrets.yaml > secrets_base64.yaml
它对所有 data
字段进行编码,并在每个 yaml
文件中使用多个秘密 (kind:Secret
),当在列表 (kind: List
) 中定义时。
免责声明:我是作者
所以我刚刚学习了一个我错过的非常有用的 k8s 基础知识,然后发现它有一个与之相关的安全漏洞,并提出了解决方案。
TLDR:
您可以将明文多行 strings/textfiles 作为 secret.yaml 在您的秘密仓库中! :)
(请注意,我建议将其存储在 Hashicorp Vault 中,您可以存储具有机密的版本化配置文件,并且可以通过 Vault 网页轻松 view/edit 它们,并且与 git 存储库不同,您可以进行细粒度访问控制,管道可以使用 REST API 来提取更新的秘密,这也使得密码轮换变得非常容易。)
cleartext-appsettings-secret.yaml
appsettings.Dummy.json为默认文件名(秘钥)
(我使用默认文件名这个词,因为你可以在 yaml 挂载中覆盖它)
明文json代码是文件内容(秘密值)
apiVersion: v1
kind: Secret
metadata:
name: appsettings
namespace: api
type: Opaque
stringData:
appsettings.Dummy.json: |-
{
"Dummy": {
"Placeholder": {
"Password": "blank"
}
}
}
当我
kubectl apply -f cleartext-appsettings-secret.yaml
kubectl get secret appsettings -n=api -o yaml
秘密在注释中显示为明文...
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
显然,用于创建注释中显示的秘密的 yaml 是 kubectl apply -f secret.yaml 自 2016 年以来的预期行为/已作为错误报告发布,但问题已关闭没有 resolution/they 忽略它而不是修复它。
如果您是原创的 secret.yaml 是 base64 的,注释至少是 base64 的,但在这种情况下,它是直接的非 base64 的人类可读的明文。
注意 1:命令式秘密创建不会发生这种情况
kubectl create secret generic appsettings --from-file appsettings.Dummy.json --namespace=api
注意 2:支持声明式应用程序设置的另一个原因-secret.yaml 是,当需要编辑 kubectl apply -f 时将配置秘密,但是如果您 运行 创建命令它'我会说错误已经存在,你必须删除它,然后它会让你 运行 再次创建命令。
注意 3:kubectl create secret generic name --from-file file --namespace 的一个原因/反对 secret.yaml 的一个原因是 kubectl show secret 不会显示上次编辑秘密的时间.与 create 命令一样,因为您必须先删除它才能重新创建它,您将根据它存在的时间知道它最后一次编辑的时间,因此这有利于审计试验。 (但还有更好的审计方法)
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
抵消泄漏
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
您可以使用 --dry-运行 标志来准备包含文件数据的 YAML。
kubectl create secret generic jwt-certificates --from-file=jwt-public.cer --from-file=jwt-private.pfx --dry-run=true --output=yaml > jwt-secrets.yaml
编辑
感谢@Leopd 对 API 弃用的评论,新的 kubectl 使用此命令:
kubectl create secret generic jwt-certificates --from-file=jwt-public.cer --from-file=jwt-private.pfx --dry-run=client --output=yaml > jwt-secrets.yaml
我的机器上还有旧的 kubectl 版本
我想将文件存储在 Kubernetes Secrets 中,但我还没有找到如何使用 yaml
文件来做到这一点。
我已经能够通过 kubectl
:
kubectl create secret generic some-secret --from-file=secret1.txt=secrets/secret1.txt
但是当我在 yaml
中尝试类似的东西时:
apiVersion: v1
kind: Secret
metadata:
name: some-secret
type: Opaque
data:
secret1.txt: secrets/secret1.txt
我遇到了这个错误:
[pos 73]: json: error decoding base64 binary 'assets/elasticsearch.yml': illegal base64 data at input byte 20
我正在遵循本指南 http://kubernetes.io/docs/user-guide/secrets/。它解释了如何使用 yaml
创建秘密,但没有解释如何使用 yaml
.
可能吗?如果可以,我该怎么做?
当使用 CLI
格式时,基本上您是在将 yaml 发布到服务器端之前使用 yaml 生成器。
由于 Kubernetes 是介于两者之间的 REST API 的客户端-服务器应用程序,并且操作需要是原子的,因此发布的 YAML 需要包含文件的内容,最好的方法是通过将其嵌入为内联的 base64 格式。如果文件可以以其他方式嵌入(缩进可能用于创建文件的边界),那就太好了,但直到现在我还没有看到任何这样的例子。
话虽如此,在 yaml 上放置文件引用是不可能的,因为没有包含内容的 yaml 的飞行前渲染。
正如之前 post 的回答,我们需要向文件提供编码为 base64 的 certificate/key。
这是证书的通用示例(在本例中为 SSL):
secret.yml.tmpl
:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
namespace: default
type: Opaque
data:
server.crt: SERVER_CRT
server.key: SERVER_KEY
预处理文件以包含 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 -
请注意 certificate/key 使用 base64 编码,没有空格 (-w0)。
对于TLS可以简单的是:
kubectl create secret tls test-secret-tls --cert=server.crt --key=server.key
对于房间中的 Windows 用户,将此用于每个 .cer 和 .key(示例显示正在编码的 .key 以插入到 YAML 文件中):
$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
打开新的 .b64
文件并将(单行)输出粘贴到您的 YAML 文件中 - 请注意,如果将 YAML 文件签入包含此信息的源代码存储库,密钥由于 base64 不是加密的,因此实际上会受到损害。
您可以使用 secode 将秘密值替换为 base64
编码字符串,只需执行以下操作:
secode secrets.yaml > secrets_base64.yaml
它对所有 data
字段进行编码,并在每个 yaml
文件中使用多个秘密 (kind:Secret
),当在列表 (kind: List
) 中定义时。
免责声明:我是作者
所以我刚刚学习了一个我错过的非常有用的 k8s 基础知识,然后发现它有一个与之相关的安全漏洞,并提出了解决方案。
TLDR:
您可以将明文多行 strings/textfiles 作为 secret.yaml 在您的秘密仓库中! :)
(请注意,我建议将其存储在 Hashicorp Vault 中,您可以存储具有机密的版本化配置文件,并且可以通过 Vault 网页轻松 view/edit 它们,并且与 git 存储库不同,您可以进行细粒度访问控制,管道可以使用 REST API 来提取更新的秘密,这也使得密码轮换变得非常容易。)
cleartext-appsettings-secret.yaml
appsettings.Dummy.json为默认文件名(秘钥)
(我使用默认文件名这个词,因为你可以在 yaml 挂载中覆盖它)
明文json代码是文件内容(秘密值)
apiVersion: v1
kind: Secret
metadata:
name: appsettings
namespace: api
type: Opaque
stringData:
appsettings.Dummy.json: |-
{
"Dummy": {
"Placeholder": {
"Password": "blank"
}
}
}
当我
kubectl apply -f cleartext-appsettings-secret.yaml
kubectl get secret appsettings -n=api -o yaml
秘密在注释中显示为明文...
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
显然,用于创建注释中显示的秘密的 yaml 是 kubectl apply -f secret.yaml 自 2016 年以来的预期行为/已作为错误报告发布,但问题已关闭没有 resolution/they 忽略它而不是修复它。
如果您是原创的 secret.yaml 是 base64 的,注释至少是 base64 的,但在这种情况下,它是直接的非 base64 的人类可读的明文。
注意 1:命令式秘密创建不会发生这种情况
kubectl create secret generic appsettings --from-file appsettings.Dummy.json --namespace=api
注意 2:支持声明式应用程序设置的另一个原因-secret.yaml 是,当需要编辑 kubectl apply -f 时将配置秘密,但是如果您 运行 创建命令它'我会说错误已经存在,你必须删除它,然后它会让你 运行 再次创建命令。
注意 3:kubectl create secret generic name --from-file file --namespace 的一个原因/反对 secret.yaml 的一个原因是 kubectl show secret 不会显示上次编辑秘密的时间.与 create 命令一样,因为您必须先删除它才能重新创建它,您将根据它存在的时间知道它最后一次编辑的时间,因此这有利于审计试验。 (但还有更好的审计方法)
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
抵消泄漏
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
您可以使用 --dry-运行 标志来准备包含文件数据的 YAML。
kubectl create secret generic jwt-certificates --from-file=jwt-public.cer --from-file=jwt-private.pfx --dry-run=true --output=yaml > jwt-secrets.yaml
编辑
感谢@Leopd 对 API 弃用的评论,新的 kubectl 使用此命令:
kubectl create secret generic jwt-certificates --from-file=jwt-public.cer --from-file=jwt-private.pfx --dry-run=client --output=yaml > jwt-secrets.yaml
我的机器上还有旧的 kubectl 版本