[zh] Tidy up and fix links in tasks section (6/10)
This commit is contained in:
@@ -1,17 +1,13 @@
|
||||
---
|
||||
reviewers:
|
||||
- smarterclayton
|
||||
title: 静态加密 Secret 数据
|
||||
content_type: task
|
||||
---
|
||||
|
||||
<!--
|
||||
---
|
||||
reviewers:
|
||||
- smarterclayton
|
||||
title: Encrypting Secret Data at Rest
|
||||
content_type: task
|
||||
---
|
||||
-->
|
||||
|
||||
<!-- overview -->
|
||||
@@ -20,42 +16,21 @@ This page shows how to enable and configure encryption of secret data at rest.
|
||||
-->
|
||||
本文展示如何启用和配置静态 Secret 数据的加密
|
||||
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
|
||||
* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
<!--
|
||||
* Kubernetes version 1.7.0 or later is required
|
||||
|
||||
* etcd v3 or later is required
|
||||
|
||||
* Encryption at rest is alpha in 1.7.0 which means it may change without notice. Users may be required to decrypt their data prior to upgrading to 1.8.0.
|
||||
-->
|
||||
* 需要 Kubernetes 1.7.0 或者更高版本
|
||||
|
||||
* 需要 etcd v3 或者更高版本
|
||||
|
||||
* 静态数据加密在 1.7.0 中仍然是 alpha 版本,这意味着它可能会在没有通知的情况下进行更改。在升级到 1.8.0 之前,用户可能需要解密他们的数据。
|
||||
|
||||
|
||||
|
||||
{{< toc >}}
|
||||
|
||||
## {{% heading "prerequisites" %}}
|
||||
|
||||
|
||||
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
|
||||
|
||||
|
||||
|
||||
<!-- steps -->
|
||||
|
||||
<!--
|
||||
## Configuration and determining whether encryption at rest is already enabled
|
||||
|
||||
The `kube-apiserver` process accepts an argument `--experimental-encryption-provider-config`
|
||||
The `kube-apiserver` process accepts an argument `-experimental-encryption-provider-config`
|
||||
that controls how API data is encrypted in etcd. An example configuration
|
||||
is provided below.
|
||||
|
||||
@@ -69,8 +44,8 @@ is provided below.
|
||||
## 理解静态数据加密
|
||||
|
||||
```yaml
|
||||
kind: EncryptionConfiguration
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
@@ -100,23 +75,31 @@ Each `resources` array item is a separate config and contains a complete configu
|
||||
that should be encrypted. The `providers` array is an ordered list of the possible encryption
|
||||
providers. Only one provider type may be specified per entry (`identity` or `aescbc` may be provided,
|
||||
but not both in the same item).
|
||||
-->
|
||||
每个 `resources` 数组项目是一个单独的完整的配置。
|
||||
`resources.resources` 字段是要加密的 Kubernetes 资源名称(`resource` 或 `resource.group`)的数组。
|
||||
`providers` 数组是可能的加密 provider 的有序列表。
|
||||
每个条目只能指定一个 provider 类型(可以是 `identity` 或 `aescbc`,但不能在同一个项目中同时指定)。
|
||||
|
||||
<!--
|
||||
The first provider in the list is used to encrypt resources going into storage. When reading
|
||||
resources from storage each provider that matches the stored data attempts to decrypt the data in
|
||||
order. If no provider can read the stored data due to a mismatch in format or secret key, an error
|
||||
is returned which prevents clients from accessing that resource.
|
||||
-->
|
||||
列表中的第一个 provider 用于加密进入存储的资源。
|
||||
当从存储器读取资源时,与存储的数据匹配的所有 provider 将按顺序尝试解密数据。
|
||||
如果由于格式或密钥不匹配而导致没有 provider 能够读取存储的数据,则会返回一个错误,以防止客户端访问该资源。
|
||||
|
||||
<!--
|
||||
**IMPORTANT:** If any resource is not readable via the encryption config (because keys were changed),
|
||||
the only recourse is to delete that key from the underlying etcd directly. Calls that attempt to
|
||||
read that resource will fail until it is deleted or a valid decryption key is provided.
|
||||
-->
|
||||
每个 `resources` 数组项目是一个单独的完整的配置。 `resources.resources` 字段是要加密的 Kubernetes 资源名称(`resource` 或 `resource.group`)的数组。
|
||||
`providers` 数组是可能的加密 provider 的有序列表。每个条目只能指定一个 provider 类型(可以是 `identity` 或 `aescbc`,但不能在同一个项目中同时指定)。
|
||||
|
||||
列表中的第一个提供者用于加密进入存储的资源。当从存储器读取资源时,与存储的数据匹配的所有提供者将尝试按顺序解密数据。
|
||||
如果由于格式或密钥不匹配而导致提供者无法读取存储的数据,则会返回一个错误,以防止客户端访问该资源。
|
||||
|
||||
**重要:** 如果通过加密配置无法读取资源(因为密钥已更改),唯一的方法是直接从基础 etcd 中删除该密钥。任何尝试读取资源的调用将会失败,直到它被删除或提供有效的解密密钥。
|
||||
{{< caution >}}
|
||||
**重要:** 如果通过加密配置无法读取资源(因为密钥已更改),唯一的方法是直接从底层 etcd 中删除该密钥。
|
||||
任何尝试读取资源的调用将会失败,直到它被删除或提供有效的解密密钥。
|
||||
{{< /caution >}}
|
||||
|
||||
### Providers:
|
||||
|
||||
@@ -132,28 +115,57 @@ Name | Encryption | Strength | Speed | Key Length | Other Considerations
|
||||
Each provider supports multiple keys - the keys are tried in order for decryption, and if the provider
|
||||
is the first provider, the first key is used for encryption.
|
||||
-->
|
||||
名称 | 加密类型 | 强度 | 速度 | 密钥长度 | 其它事项
|
||||
{{< table caption="Kubernetes 静态数据加密的 Providers" >}}
|
||||
名称 | 加密类型 | 强度 | 速度 | 密钥长度 | 其它事项
|
||||
-----|------------|----------|-------|------------|---------------------
|
||||
`identity` | 无 | N/A | N/A | N/A | 不加密写入的资源。当设置为第一个 provider 时,资源将在新值写入时被解密。
|
||||
`aescbc` | 填充 PKCS#7 的 AES-CBC | 最强 | 快 | 32字节 | 建议使用的加密项,但可能比 `secretbox` 稍微慢一些。
|
||||
`secretbox` | XSalsa20 和 Poly1305 | 强 | 更快 | 32字节 | 较新的标准,在需要高度评审的环境中可能不被接受。
|
||||
`aesgcm` | 带有随机数的 AES-GCM | 必须每 200k 写入一次 | 最快 | 16, 24, 或者 32字节 | 建议不要使用,除非实施了自动密钥循环方案。
|
||||
`kms` | 使用信封加密方案:数据使用带有 PKCS#7 填充的 AES-CBC 通过 data encryption keys(DEK)加密,DEK 根据 Key Management Service(KMS)中的配置通过 key encryption keys(KEK)加密 | 最强 | 快 | 32字节 | 建议使用第三方工具进行密钥管理。为每个加密生成新的 DEK,并由用户控制 KEK 轮换来简化密钥轮换。[配置 KMS 提供程序](/docs/tasks/administer-cluster/kms-provider/)
|
||||
`aesgcm` | 带有随机数的 AES-GCM | 必须每 200k 写入一次 | 最快 | 16, 24 或者 32字节 | 建议不要使用,除非实施了自动密钥循环方案。
|
||||
`kms` | 使用信封加密方案:数据使用带有 PKCS#7 填充的 AES-CBC 通过数据加密密钥(DEK)加密,DEK 根据 Key Management Service(KMS)中的配置通过密钥加密密钥(Key Encryption Keys,KEK)加密 | 最强 | 快 | 32字节 | 建议使用第三方工具进行密钥管理。为每个加密生成新的 DEK,并由用户控制 KEK 轮换来简化密钥轮换。[配置 KMS 提供程序](/zh/docs/tasks/administer-cluster/kms-provider/)
|
||||
|
||||
每个 provider 都支持多个密钥 - 在解密时会按顺序使用密钥,如果是第一个 provider,则第一个密钥用于加密。
|
||||
|
||||
<!--
|
||||
__Storing the raw encryption key in the EncryptionConfig only moderately improves your security posture, compared to no encryption.
|
||||
Please use `kms` provider for additional security.__ By default, the `identity` provider is used to protect secrets in etcd, which
|
||||
provides no encryption. `EncryptionConfiguration` was introduced to encrypt secrets locally, with a locally managed key.
|
||||
-->
|
||||
__在 EncryptionConfig 中保存原始的加密密钥与不加密相比只会略微地提升安全级别。
|
||||
请使用 `kms` 驱动以获得更强的安全性。__
|
||||
默认情况下,`identity` 驱动被用来对 etcd 中的 Secret 提供保护,
|
||||
而这个驱动不提供加密能力。
|
||||
`EncryptionConfiguration` 的引入是为了能够使用本地管理的密钥来在本地加密 Secret 数据。
|
||||
|
||||
<!--
|
||||
Encrypting secrets with a locally managed key protects against an etcd compromise, but it fails to protect against a host compromise.
|
||||
Since the encryption keys are stored on the host in the EncryptionConfig YAML file, a skilled attacker can access that file and
|
||||
extract the encryption keys.
|
||||
-->
|
||||
使用本地管理的密钥来加密 Secret 能够保护数据免受 etcd 破坏的影响,不过无法针对
|
||||
主机被侵入提供防护。
|
||||
这是因为加密的密钥保存在主机上的 EncryptionConfig YAML 文件中,有经验的入侵者
|
||||
仍能访问该文件并从中提取出加密密钥。
|
||||
|
||||
<!--
|
||||
Envelope encryption creates dependence on a separate key, not stored in Kubernetes. In this case, an attacker would need to compromise etcd, the kubeapi-server, and the third-party KMS provider to retrieve the plaintext values, providing a higher level of security than locally-stored encryption keys.
|
||||
-->
|
||||
封套加密(Envelope Encryption)引入了对独立密钥的依赖,而这个密钥并不保存在 Kubernetes 中。
|
||||
在这种情况下下,入侵者需要攻破 etcd、kube-apiserver 和第三方的 KMS
|
||||
驱动才能获得明文数据,因而这种方案提供了比本地保存加密密钥更高的安全级别。
|
||||
|
||||
<!--
|
||||
## Encrypting your data
|
||||
|
||||
Create a new encryption config file:
|
||||
-->
|
||||
## 加密您的数据
|
||||
## 加密你的数据
|
||||
|
||||
创建一个新的加密配置文件:
|
||||
|
||||
```yaml
|
||||
kind: EncryptionConfiguration
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
@@ -172,11 +184,11 @@ To create a new secret perform the following steps:
|
||||
-->
|
||||
遵循如下步骤来创建一个新的 secret:
|
||||
|
||||
1. 生成一个 32 字节的随机密钥并进行 base64 编码。如果您在 Linux 或 Mac OS X 上,请运行以下命令:
|
||||
1. 生成一个 32 字节的随机密钥并进行 base64 编码。如果你在 Linux 或 Mac OS X 上,请运行以下命令:
|
||||
|
||||
```
|
||||
head -c 32 /dev/urandom | base64
|
||||
```
|
||||
```
|
||||
head -c 32 /dev/urandom | base64
|
||||
```
|
||||
|
||||
<!--
|
||||
2. Place that value in the secret field.
|
||||
@@ -186,11 +198,15 @@ To create a new secret perform the following steps:
|
||||
**IMPORTANT:** Your config file contains keys that can decrypt content in etcd, so you must properly restrict permissions on your masters so only the user who runs the kube-apiserver can read it.
|
||||
-->
|
||||
2. 将这个值放入到 secret 字段中。
|
||||
3. 设置 `kube-apiserver` 的 `--experimental-encryption-provider-config` 参数,将其指定到配置文件所在位置。
|
||||
4. 重启您的 API server。
|
||||
3. 设置 `kube-apiserver` 的 `--experimental-encryption-provider-config` 参数,将其指向
|
||||
配置文件所在位置。
|
||||
4. 重启你的 API server。
|
||||
|
||||
**重要:** 您的配置文件包含可以解密 etcd 内容的密钥,因此您必须正确限制主设备的权限,以便只有能运行 kube-apiserver 的用户才能读取它。
|
||||
|
||||
{{< caution >}}
|
||||
你的配置文件包含可以解密 etcd 内容的密钥,因此你必须正确限制主控节点的访问权限,
|
||||
以便只有能运行 kube-apiserver 的用户才能读取它。
|
||||
{{< caution >}}
|
||||
|
||||
<!--
|
||||
## Verifying that data is encrypted
|
||||
@@ -201,53 +217,58 @@ program to retrieve the contents of your secret.
|
||||
|
||||
1. Create a new secret called `secret1` in the `default` namespace:
|
||||
-->
|
||||
## 验证数据是否被加密
|
||||
## 验证数据已被加密
|
||||
|
||||
数据在写入 etcd 时会被加密。重新启动你的 `kube-apiserver` 后,任何新创建或更新的密码在存储时都应该被加密。
|
||||
如果想要检查,你可以使用 `etcdctl` 命令行程序来检索你的加密内容。
|
||||
|
||||
1. 创建一个新的 secret,名称为 `secret1`,命名空间为 `default`:
|
||||
|
||||
```
|
||||
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
|
||||
```
|
||||
```shell
|
||||
kubectl create secret generic secret1 -n default --from-literal=mykey=mydata
|
||||
```
|
||||
|
||||
<!--
|
||||
2. Using the etcdctl commandline, read that secret out of etcd:
|
||||
-->
|
||||
2. 使用 etcdctl 命令行,从 etcd 中读取 secret:
|
||||
|
||||
```
|
||||
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
|
||||
```
|
||||
```shell
|
||||
ETCDCTL_API=3 etcdctl get /registry/secrets/default/secret1 [...] | hexdump -C
|
||||
```
|
||||
|
||||
<!--
|
||||
where `[...]` must be the additional arguments for connecting to the etcd server.
|
||||
-->
|
||||
这里的 `[...]` 是用来连接 etcd 服务的额外参数。
|
||||
|
||||
<!--
|
||||
where `[...]` must be the additional arguments for connecting to the etcd server.
|
||||
3. Verify the stored secret is prefixed with `k8s:enc:aescbc:v1:` which indicates the `aescbc` provider has encrypted the resulting data.
|
||||
4. Verify the secret is correctly decrypted when retrieved via the API:
|
||||
-->
|
||||
这里的 `[...]` 是用来连接 etcd 服务的额外参数。
|
||||
3. 验证存储的密钥前缀是否为 `k8s:enc:aescbc:v1:`,这表明 `aescbc` provider 已加密结果数据。
|
||||
4. 通过 API 检索,验证 secret 是否被正确解密:
|
||||
|
||||
```
|
||||
kubectl describe secret secret1 -n default
|
||||
```
|
||||
|
||||
<!--
|
||||
should match `mykey: mydata`
|
||||
-->
|
||||
必须匹配 `mykey: mydata`
|
||||
```shell
|
||||
kubectl describe secret secret1 -n default
|
||||
```
|
||||
|
||||
<!--
|
||||
should match `mykey: mydata`, mydata is encoded, check [decoding a secret](/docs/concepts/configuration/secret#decoding-a-secret) to
|
||||
completely decode the secret.
|
||||
-->
|
||||
其输出应该是 `mykey: bXlkYXRh`,`mydata` 数据是被加密过的,请参阅
|
||||
[解密 Secret](/zh/docs/concepts/configuration/secret#decoding-a-secret)
|
||||
了解如何完全解码 Secret 内容。
|
||||
|
||||
<!--
|
||||
## Ensure all secrets are encrypted
|
||||
|
||||
Since secrets are encrypted on write, performing an update on a secret will encrypt that content.
|
||||
-->
|
||||
## 确保所有 secret 都被加密
|
||||
## 确保所有 Secret 都被加密
|
||||
|
||||
由于 secret 是在写入时被加密,因此对 secret 执行更新也会加密该内容。
|
||||
由于 Secret 是在写入时被加密,因此对 Secret 执行更新也会加密该内容。
|
||||
|
||||
```
|
||||
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
|
||||
@@ -255,13 +276,17 @@ kubectl get secrets --all-namespaces -o json | kubectl replace -f -
|
||||
|
||||
<!--
|
||||
The command above reads all secrets and then updates them to apply server side encryption.
|
||||
-->
|
||||
上面的命令读取所有 Secret,然后使用服务端加密来更新其内容。
|
||||
|
||||
<!--
|
||||
If an error occurs due to a conflicting write, retry the command.
|
||||
For larger clusters, you may wish to subdivide the secrets by namespace or script an update.
|
||||
-->
|
||||
上面的命令读取所有 secret,然后使用服务端加密来进行更新。
|
||||
{{< note >}}
|
||||
如果由于冲突写入而发生错误,请重试该命令。
|
||||
对于较大的集群,您可能希望通过命名空间或更新脚本来分割 secret。
|
||||
|
||||
对于较大的集群,你可能希望通过命名空间或更新脚本来对 Secret 进行划分。
|
||||
{{< /note >}}
|
||||
|
||||
<!--
|
||||
## Rotating a decryption key
|
||||
@@ -273,14 +298,15 @@ the presence of a highly available deployment where multiple `kube-apiserver` pr
|
||||
2. Restart all `kube-apiserver` processes to ensure each server can decrypt using the new key
|
||||
3. Make the new key the first entry in the `keys` array so that it is used for encryption in the config
|
||||
4. Restart all `kube-apiserver` processes to ensure each server now encrypts using the new key
|
||||
5. Run `kubectl get secrets --all-namespaces -o json | kubectl replace -f -` to encrypt all existing secrets with the new key
|
||||
5. Run `kubectl get secrets -all-namespaces -o json | kubectl replace -f -` to encrypt all existing secrets with the new key
|
||||
6. Remove the old decryption key from the config after you back up etcd with the new key in use and update all secrets
|
||||
|
||||
With a single `kube-apiserver`, step 2 may be skipped.
|
||||
-->
|
||||
## 回滚解密密钥
|
||||
## 轮换解密密钥
|
||||
|
||||
在不发生停机的情况下更改 secret 需要多步操作,特别是在有多个 `kube-apiserver` 进程正在运行的高可用部署的情况下。
|
||||
在不发生停机的情况下更改 Secret 需要多步操作,特别是在有多个 `kube-apiserver` 进程正在运行的
|
||||
高可用环境中。
|
||||
|
||||
1. 生成一个新密钥并将其添加为所有服务器上当前提供程序的第二个密钥条目
|
||||
2. 重新启动所有 `kube-apiserver` 进程以确保每台服务器都可以使用新密钥进行解密
|
||||
@@ -291,7 +317,6 @@ With a single `kube-apiserver`, step 2 may be skipped.
|
||||
|
||||
如果只有一个 `kube-apiserver`,第 2 步可能可以忽略。
|
||||
|
||||
|
||||
<!--
|
||||
## Decrypting all data
|
||||
|
||||
@@ -302,8 +327,8 @@ To disable encryption at rest place the `identity` provider as the first entry i
|
||||
要禁用 rest 加密,请将 `identity` provider 作为配置中的第一个条目:
|
||||
|
||||
```yaml
|
||||
kind: EncryptionConfiguration
|
||||
apiVersion: apiserver.config.k8s.io/v1
|
||||
kind: EncryptionConfiguration
|
||||
resources:
|
||||
- resources:
|
||||
- secrets
|
||||
@@ -316,11 +341,16 @@ resources:
|
||||
```
|
||||
|
||||
<!--
|
||||
and restart all `kube-apiserver` processes. Then run the command `kubectl get secrets --all-namespaces -o json | kubectl replace -f -`
|
||||
and restart all `kube-apiserver` processes. Then run
|
||||
-->
|
||||
并重新启动所有 `kube-apiserver` 进程。然后运行:
|
||||
|
||||
```
|
||||
kubectl get secrets -all-namespaces -o json | kubectl replace -f -`
|
||||
```
|
||||
|
||||
<!--
|
||||
to force all secrets to be decrypted.
|
||||
-->
|
||||
并重新启动所有 `kube-apiserver` 进程。然后运行命令 `kubectl get secrets --all-namespaces -o json | kubectl replace -f -` 强制解密所有 secret。
|
||||
|
||||
|
||||
|
||||
以强制解密所有 secret。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user