diff --git a/content/zh/docs/tasks/administer-cluster/encrypt-data.md b/content/zh/docs/tasks/administer-cluster/encrypt-data.md index c63032ca4d..1f2eefd0a0 100644 --- a/content/zh/docs/tasks/administer-cluster/encrypt-data.md +++ b/content/zh/docs/tasks/administer-cluster/encrypt-data.md @@ -4,9 +4,9 @@ content_type: task --- @@ -21,26 +21,40 @@ This page shows how to enable and configure encryption of secret data at rest. * {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} -* 需要 etcd v3 或者更高版本 +* 需要 etcd v3.0 或者更高版本 ## 配置并确定是否已启用静态数据加密 -`kube-apiserver` 的参数 `--experimental-encryption-provider-config` 控制 API 数据在 etcd 中的加密方式。 -下面提供一个配置示例。 +`kube-apiserver` 的参数 `--encryption-provider-config` 控制 API 数据在 etcd 中的加密方式。 +该配置作为一个名为 [`EncryptionConfiguration`](/zh/docs/reference/config-api/apiserver-encryption.v1/) 的 API 提供。 +下面提供了一个示例配置。 + +{{< caution >}} +**重要:** 对于高可用配置(有两个或多个控制平面节点),加密配置文件必须相同! +否则,`kube-apiserver` 组件无法解密存储在 etcd 中的数据。 +{{< /caution >}} + + ## 理解静态数据加密 ```yaml @@ -48,56 +62,61 @@ apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - - secrets + - secrets providers: - - identity: {} - - aesgcm: - keys: - - name: key1 - secret: c2VjcmV0IGlzIHNlY3VyZQ== - - name: key2 - secret: dGhpcyBpcyBwYXNzd29yZA== - - aescbc: - keys: - - name: key1 - secret: c2VjcmV0IGlzIHNlY3VyZQ== - - name: key2 - secret: dGhpcyBpcyBwYXNzd29yZA== - - secretbox: - keys: - - name: key1 - secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY= + - identity: {} + - aesgcm: + keys: + - name: key1 + secret: c2VjcmV0IGlzIHNlY3VyZQ== + - name: key2 + secret: dGhpcyBpcyBwYXNzd29yZA== + - aescbc: + keys: + - name: key1 + secret: c2VjcmV0IGlzIHNlY3VyZQ== + - name: key2 + secret: dGhpcyBpcyBwYXNzd29yZA== + - secretbox: + keys: + - name: key1 + secret: YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoxMjM0NTY= ``` 每个 `resources` 数组项目是一个单独的完整的配置。 `resources.resources` 字段是要加密的 Kubernetes 资源名称(`resource` 或 `resource.group`)的数组。 `providers` 数组是可能的加密 provider 的有序列表。 -每个条目只能指定一个 provider 类型(可以是 `identity` 或 `aescbc`,但不能在同一个项目中同时指定)。 - -列表中的第一个 provider 用于加密进入存储的资源。 +每个条目只能指定一个 provider 类型(可以是 `identity` 或 `aescbc`,但不能在同一个项目中同时指定二者)。 +列表中的第一个 provider 用于加密写入存储的资源。 当从存储器读取资源时,与存储的数据匹配的所有 provider 将按顺序尝试解密数据。 如果由于格式或密钥不匹配而导致没有 provider 能够读取存储的数据,则会返回一个错误,以防止客户端访问该资源。 +有关 `EncryptionConfiguration` 结构体的更多详细信息,请参阅[加密配置 API](/zh/docs/reference/config-api/apiserver-encryption.v1/)。 + {{< caution >}} -**重要:** 如果通过加密配置无法读取资源(因为密钥已更改),唯一的方法是直接从底层 etcd 中删除该密钥。 +如果通过加密配置无法读取资源(因为密钥已更改),唯一的方法是直接从底层 etcd 中删除该密钥。 任何尝试读取资源的调用将会失败,直到它被删除或提供有效的解密密钥。 {{< /caution >}} @@ -127,31 +146,38 @@ is the first provider, the first key is used for encryption. 每个 provider 都支持多个密钥 - 在解密时会按顺序使用密钥,如果是第一个 provider,则第一个密钥用于加密。 -__在 EncryptionConfig 中保存原始的加密密钥与不加密相比只会略微地提升安全级别。 -请使用 `kms` 驱动以获得更强的安全性。__ -默认情况下,`identity` 驱动被用来对 etcd 中的 Secret 提供保护, -而这个驱动不提供加密能力。 -`EncryptionConfiguration` 的引入是为了能够使用本地管理的密钥来在本地加密 Secret 数据。 +{{< caution >}} +在 EncryptionConfig 中保存原始的加密密钥与不加密相比只会略微地提升安全级别。 +请使用 `kms` 驱动以获得更强的安全性。 +{{< /caution >}} +默认情况下,`identity` 驱动被用来对 etcd 中的 Secret 提供保护,而这个驱动不提供加密能力。 +`EncryptionConfiguration` 的引入是为了能够使用本地管理的密钥来在本地加密 Secret 数据。 + 使用本地管理的密钥来加密 Secret 能够保护数据免受 etcd 破坏的影响,不过无法针对 主机被侵入提供防护。 这是因为加密的密钥保存在主机上的 EncryptionConfig YAML 文件中,有经验的入侵者 仍能访问该文件并从中提取出加密密钥。 - 封套加密(Envelope Encryption)引入了对独立密钥的依赖,而这个密钥并不保存在 Kubernetes 中。 -在这种情况下下,入侵者需要攻破 etcd、kube-apiserver 和第三方的 KMS +在这种情况下,入侵者需要攻破 etcd、kube-apiserver 和第三方的 KMS 驱动才能获得明文数据,因而这种方案提供了比本地保存加密密钥更高的安全级别。 -遵循如下步骤来创建一个新的 secret: +遵循如下步骤来创建一个新的 Secret: -1. 生成一个 32 字节的随机密钥并进行 base64 编码。如果你在 Linux 或 Mac OS X 上,请运行以下命令: +1. 生成一个 32 字节的随机密钥并进行 base64 编码。如果你在 Linux 或 macOS 上,请运行以下命令: - ``` + ```shell head -c 32 /dev/urandom | base64 ``` -2. 将这个值放入到 secret 字段中。 -3. 设置 `kube-apiserver` 的 `--experimental-encryption-provider-config` 参数,将其指向 +2. 将这个值放入到 `EncryptionConfiguration` 结构体的 `secret` 字段中。 +3. 设置 `kube-apiserver` 的 `--encryption-provider-config` 参数,将其指向 配置文件所在位置。 4. 重启你的 API server。 - + {{< caution >}} 你的配置文件包含可以解密 etcd 内容的密钥,因此你必须正确限制主控节点的访问权限, 以便只有能运行 kube-apiserver 的用户才能读取它。 @@ -212,10 +240,10 @@ To create a new secret perform the following steps: ## Verifying that data is encrypted Data is encrypted when written to etcd. After restarting your `kube-apiserver`, any newly created or -updated secret should be encrypted when stored. To check, you can use the `etcdctl` command line -program to retrieve the contents of your secret. +updated Secret should be encrypted when stored. To check this, you can use the `etcdctl` command line +program to retrieve the contents of your Secret. -1. Create a new secret called `secret1` in the `default` namespace: +1. Create a new Secret called `secret1` in the `default` namespace: --> ## 验证数据已被加密 @@ -229,9 +257,9 @@ program to retrieve the contents of your secret. ``` -2. 使用 etcdctl 命令行,从 etcd 中读取 secret: +2. 使用 etcdctl 命令行,从 etcd 中读取 Secret: ```shell ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C ``` @@ -242,39 +270,43 @@ program to retrieve the contents of your secret. 这里的 `[...]` 是用来连接 etcd 服务的额外参数。 3. 验证存储的密钥前缀是否为 `k8s:enc:aescbc:v1:`,这表明 `aescbc` provider 已加密结果数据。 -4. 通过 API 检索,验证 secret 是否被正确解密: + +4. 通过 API 检索,验证 Secret 是否被正确解密: ```shell kubectl describe secret secret1 -n default ``` - 其输出应该是 `mykey: bXlkYXRh`,`mydata` 数据是被加密过的,请参阅 - [解密 Secret](/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/#decoding-secret) + 其输出应该包含 `mykey: bXlkYXRh`,`mydata` 的内容是被加密过的, + 请参阅[解密 Secret](/zh/docs/tasks/configmap-secret/managing-secret-using-kubectl/#decoding-secret) 了解如何完全解码 Secret 内容。 ## 确保所有 Secret 都被加密 由于 Secret 是在写入时被加密,因此对 Secret 执行更新也会加密该内容。 -``` +```shell kubectl get secrets --all-namespaces -o json | kubectl replace -f - ``` 上面的命令读取所有 Secret,然后使用服务端加密来更新其内容。 @@ -290,17 +322,19 @@ For larger clusters, you may wish to subdivide the secrets by namespace or scrip ## 轮换解密密钥 @@ -308,48 +342,53 @@ With a single `kube-apiserver`, step 2 may be skipped. 高可用环境中。 1. 生成一个新密钥并将其添加为所有服务器上当前提供程序的第二个密钥条目 -2. 重新启动所有 `kube-apiserver` 进程以确保每台服务器都可以使用新密钥进行解密 -3. 将新密钥设置为 `keys` 数组中的第一个条目,以便在配置中使用其进行加密 -4. 重新启动所有 `kube-apiserver` 进程以确保每个服务器现在都使用新密钥进行加密 -5. 运行 `kubectl get secrets --all-namespaces -o json | kubectl replace -f -` 以用新密钥加密所有现有的秘密 -6. 在使用新密钥备份 etcd 后,从配置中删除旧的解密密钥并更新所有密钥 +1. 重新启动所有 `kube-apiserver` 进程以确保每台服务器都可以使用新密钥进行解密 +1. 将新密钥设置为 `keys` 数组中的第一个条目,以便在配置中使用其进行加密 +1. 重新启动所有 `kube-apiserver` 进程以确保每个服务器现在都使用新密钥进行加密 +1. 运行 `kubectl get secrets --all-namespaces -o json | kubectl replace -f -` + 以用新密钥加密所有现有的 Secret +1. 在使用新密钥备份 etcd 后,从配置中删除旧的解密密钥并更新所有密钥 -如果只有一个 `kube-apiserver`,第 2 步可能可以忽略。 +当只运行一个 `kube-apiserver` 实例时,第 2 步可能可以忽略。 ## 解密所有数据 -要禁用 rest 加密,请将 `identity` provider 作为配置中的第一个条目: +要禁用静态加密,请将 `identity` provider +作为配置中的第一个条目并重新启动所有 `kube-apiserver` 进程。 ```yaml apiVersion: apiserver.config.k8s.io/v1 kind: EncryptionConfiguration resources: - resources: - - secrets + - secrets providers: - - identity: {} - - aescbc: - keys: - - name: key1 - secret: + - identity: {} + - aescbc: + keys: + - name: key1 + secret: ``` -并重新启动所有 `kube-apiserver` 进程。然后运行: +然后运行以下命令以强制解密所有 Secret: +```shell +kubectl get secrets --all-namespaces -o json | kubectl replace -f - ``` -kubectl get secrets -all-namespaces -o json | kubectl replace -f -` -``` + +## {{% heading "whatsnext" %}} -以强制解密所有 secret。 - +进一步学习 [EncryptionConfiguration 配置 API (v1)](/zh/docs/reference/config-api/apiserver-encryption.v1/)。