静态加密 Secret 数据
你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。 如果你还没有集群,你可以通过 构建一 个你自己的集群,或者你可以使用下面任意一个 Kubernetes 工具构建:
要获知版本信息,请输入 .
需要 etcd v3 或者更高版本
配置并确定是否已启用静态数据加密
kube-apiserver
的参数 --experimental-encryption-provider-config
控制 API 数据在 etcd 中的加密方式。 下面提供一个配置示例。
每个 resources
数组项目是一个单独的完整的配置。 resources.resources
字段是要加密的 Kubernetes 资源名称(resource
或 resource.group
)的数组。 providers
数组是可能的加密 provider 的有序列表。 每个条目只能指定一个 provider 类型(可以是 identity
或 aescbc
,但不能在同一个项目中同时指定)。
列表中的第一个 provider 用于加密进入存储的资源。 当从存储器读取资源时,与存储的数据匹配的所有 provider 将按顺序尝试解密数据。 如果由于格式或密钥不匹配而导致没有 provider 能够读取存储的数据,则会返回一个错误,以防止客户端访问该资源。
每个 provider 都支持多个密钥 - 在解密时会按顺序使用密钥,如果是第一个 provider,则第一个密钥用于加密。
在 EncryptionConfig 中保存原始的加密密钥与不加密相比只会略微地提升安全级别。 请使用 kms
驱动以获得更强的安全性。 默认情况下,identity
驱动被用来对 etcd 中的 Secret 提供保护, 而这个驱动不提供加密能力。 EncryptionConfiguration
的引入是为了能够使用本地管理的密钥来在本地加密 Secret 数据。
封套加密(Envelope Encryption)引入了对独立密钥的依赖,而这个密钥并不保存在 Kubernetes 中。 在这种情况下下,入侵者需要攻破 etcd、kube-apiserver 和第三方的 KMS 驱动才能获得明文数据,因而这种方案提供了比本地保存加密密钥更高的安全级别。
加密你的数据
创建一个新的加密配置文件:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
- resources:
providers:
- aescbc:
keys:
- name: key1
secret: <BASE 64 ENCODED SECRET>
- identity: {}
遵循如下步骤来创建一个新的 secret:
生成一个 32 字节的随机密钥并进行 base64 编码。如果你在 Linux 或 Mac OS X 上,请运行以下命令:
head -c 32 /dev/urandom | base64
将这个值放入到 secret 字段中。
- 设置
kube-apiserver
的--experimental-encryption-provider-config
参数,将其指向 配置文件所在位置。 - 重启你的 API server。
数据在写入 etcd 时会被加密。重新启动你的 kube-apiserver
后,任何新创建或更新的密码在存储时都应该被加密。 如果想要检查,你可以使用 etcdctl
命令行程序来检索你的加密内容。
创建一个新的 secret,名称为
secret1
,命名空间为default
:使用 etcdctl 命令行,从 etcd 中读取 secret:
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
验证存储的密钥前缀是否为
k8s:enc:aescbc:v1:
,这表明aescbc
provider 已加密结果数据。通过 API 检索,验证 secret 是否被正确解密:
kubectl describe secret secret1 -n default
其输出应该是 ,
mydata
数据是被加密过的,请参阅 解密 Secret 了解如何完全解码 Secret 内容。
确保所有 Secret 都被加密
由于 Secret 是在写入时被加密,因此对 Secret 执行更新也会加密该内容。
上面的命令读取所有 Secret,然后使用服务端加密来更新其内容。
在不发生停机的情况下更改 Secret 需要多步操作,特别是在有多个 kube-apiserver
进程正在运行的 高可用环境中。
- 重新启动所有
kube-apiserver
进程以确保每台服务器都可以使用新密钥进行解密 - 将新密钥设置为
keys
数组中的第一个条目,以便在配置中使用其进行加密 - 重新启动所有
kube-apiserver
进程以确保每个服务器现在都使用新密钥进行加密 - 运行
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
以用新密钥加密所有现有的秘密 - 在使用新密钥备份 etcd 后,从配置中删除旧的解密密钥并更新所有密钥
如果只有一个 kube-apiserver
,第 2 步可能可以忽略。
解密所有数据
要禁用 rest 加密,请将 identity
provider 作为配置中的第一个条目:
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- identity: {}
- aescbc:
keys:
- name: key1
secret: <BASE 64 ENCODED SECRET>
以强制解密所有 secret。