From 8cb62864d9bfd7ed284e6f9eb50b372f8c22f369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=99=B4?= Date: Tue, 21 May 2019 16:30:43 +0800 Subject: [PATCH] zh-trans: add /content/zh/docs/tasks/administer-cluster/kms-provider.md (#14049) * zh-trans: add /content/zh/docs/tasks/administer-cluster/kms-provider.md * Update content/zh/docs/tasks/administer-cluster/kms-provider.md Co-Authored-By: yyqqing * accept suggestions from reviewer `tengqm`. thx --- .../tasks/administer-cluster/kms-provider.md | 270 ++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 content/zh/docs/tasks/administer-cluster/kms-provider.md diff --git a/content/zh/docs/tasks/administer-cluster/kms-provider.md b/content/zh/docs/tasks/administer-cluster/kms-provider.md new file mode 100644 index 0000000000..1acedec63d --- /dev/null +++ b/content/zh/docs/tasks/administer-cluster/kms-provider.md @@ -0,0 +1,270 @@ +--- +reviewers: +- smarterclayton +title: 使用 KMS 提供商进行数据加密 +content_template: templates/task +--- + +{{% capture overview %}} + + +本页展示了如何配置秘钥管理服务—— Key Management Service (KMS) 提供商和插件以启用数据加密。 + +{{% /capture %}} + +{{% capture prerequisites %}} + +* {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} + + + +* 需要 Kubernetes 版本为 1.10.0 或更新 + + + +* 需要 etcd v3 或更新版本 + +{{< feature-state for_k8s_version="v1.12" state="beta" >}} + +{{% /capture %}} + +{{% capture steps %}} + + + +KMS 加密提供商使用封套加密模型来加密 etcd 中的数据。数据使用数据加密秘钥(DEK)加密;每次加密都生成一个新的 DEK。这些 DEK 经一个秘钥加密秘钥(KEK)加密后在一个远端的 KMS 中存储和管理。KMS 提供商使用 gRPC 与一个特定的 KMS 插件通信。这个 KMS 插件作为一个 gRPC 服务器被部署在 Kubernetes 主服务器的同一个主机上,负责与远端 KMS 的通信。 + + + +## 配置 KMS 提供商 + + + +为了在 API 服务器上配置 KMS 提供商,在加密配置文件中的提供商数组中加入一个类型为 ```kms``` 的提供商,并设置下列属性: + + + + * `name`: KMS 插件的显示名称。 + * `endpoint`: gRPC 服务器(KMS 插件)的监听地址。该端点是一个 UNIX 的套接字。 + * `cachesize`: 以明文缓存的数据加密秘钥(DEKs)的数量。一旦被缓存,就可以直接使用 DEKs 而无需另外调用 KMS;而未被缓存的 DEKs 需要调用一次 KMS 才能解包。 + + + +参见 [理解静态数据加密配置](/docs/tasks/administer-cluster/encrypt-data) + + + +## 实现 KMS 插件 + + + +为实现一个 KMS 插件,您可以开发一个新的插件 gRPC 服务器或启用一个由您的云服务提供商提供的 KMS 插件。您可以将这个插件与远程 KMS 集成,并把它部署到 Kubernetes 的主服务器上。 + + + +### 启用由云服务提供商支持的 KMS +有关启用云服务提供商特定的 KMS 插件的说明,请咨询您的云服务提供商。 + + +### 开发 KMS 插件 gRPC 服务器 +您可以使用 Go 语言的存根文件开发 KMS 插件 gRPC 服务器。对于其他语言,您可以用 proto 文件创建可以用于开发 gRPC 服务器代码的存根文件。 + + +* 使用 Go :使用存根文件 [service.pb.go](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/service.pb.go) 中的函数和数据结构开发 gRPC 服务器代码。 + + +* 使用 Go 以外的其他语言:用 protoc 编译器编译 proto 文件: [service.proto](https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1/service.proto) 为指定语言生成存根文件。 + + +然后使用存根文件中的函数和数据结构开发服务器代码。 + + + +**注意:** + + + +* kms 插件版本:`v1beta1` + +作为对过程调用 Version 的响应,兼容的 KMS 插件应把 v1beta1 作为 VersionResponse.version 返回 + + + +* 消息版本:`v1beta1` + +所有来自 KMS 提供商的消息都把 version 字段设置为当前版本 v1beta1 + + + +* 协议:UNIX 域套接字 (`unix`) + +gRPC 服务器应监听 UNIX 域套接字 + + + +### 将 KMS 插件与远程 KMS 整合 +KMS 插件可以用任何受 KMS 支持的协议与远程 KMS 通信。 +所有的配置数据,包括 KMS 插件用于与远程 KMS 通信的认证凭据,都由 KMS 插件独立地存储和管理。KMS 插件可以用额外的元数据对密文进行编码,这些元数据是在把它发往 KMS 进行解密之前可能要用到的。 + + + +### 部署 KMS 插件 +确保 KMS 插件与 Kubernetes 主服务器运行在同一主机上。 + + + +## 使用 KMS 提供商加密数据 + + +为了加密数据: + + +1. 使用 `kms` 提供商的相应的属性创建一个新的加密配置文件: + +```yaml +kind: EncryptionConfig +apiVersion: v1 +resources: + - resources: + - secrets + providers: + - kms: + name: myKmsPlugin + endpoint: unix:///tmp/socketfile.sock + cachesize: 100 + - identity: {} +``` + + +2. 设置 kube-apiserver 的 `--experimental-encryption-provider-config` 参数指向配置文件的位置。 + +3. 重启 API 服务器。 + + +## 验证数据是否已加密 + +写入 etcd 时数据被加密。重启 kube-apiserver 后,任何新建或更新的秘密信息在存储时应该已被加密。要验证这点,您可以用 etcdctl 命令行程序获取秘密信息内容。 + + +1. 在默认的命名空间里创建一个名为 secret1 的秘密信息: +``` +kubectl create secret generic secret1 -n default --from-literal=mykey=mydata +``` + +2. 用 etcdctl 命令行,从 etcd 读取出秘密信息: +``` +ETCDCTL_API=3 etcdctl get /kubernetes.io/secrets/default/secret1 [...] | hexdump -C +``` + + 其中 `[...]` 是用于连接 etcd 服务器的额外参数。 + + +3. 验证保存的秘密信息是否是以 `k8s:enc:kms:v1:` 开头的,这表明 `kms` 提供商已经对结果数据加密。 + + +4. 验证秘密信息在被 API 获取时已被正确解密: +``` +kubectl describe secret secret1 -n default +``` + +应该符合 `mykey: mydata` 格式 + + +## 确保所有秘密信息都已被加密 +因为秘密信息是在写入时被加密的,所以在更新秘密信息时会加密该内容。 + + + +下列命令读取所有秘密信息并更新他们以应用服务器端加密。如果因为写入冲突导致错误发生,请重试此命令。对较大的集群,您可能希望根据命名空间或脚本更新去细分秘密内容。 + +``` +kubectl get secrets --all-namespaces -o json | kubectl replace -f - +``` + + +## 从本地加密提供商切换到 KMS 提供商 +为了从本地加密提供商切换到 `kms` 提供商并重新加密所有秘密内容: + + +1. 在配置文件中加入 `kms` 提供商作为第一个条目,如下列样例所示 + +```yaml +kind: EncryptionConfig +apiVersion: v1 +resources: + - resources: + - secrets + providers: + - kms: + name : myKmsPlugin + endpoint: unix:///tmp/socketfile.sock + cachesize: 100 + - aescbc: + keys: + - name: key1 + secret: +``` + + +2. 重启所有 kube-apiserver 进程。 + + +3. 运行下列命令使用 `kms` 提供商强制重新加密所有秘密信息。 + +``` +kubectl get secrets --all-namespaces -o json| kubectl replace -f - +``` + + +## 禁用静态数据加密 +要禁用静态数据加密: + + +1. 将 `identity` 提供商作为配置文件中的第一个条目: + +```yaml +kind: EncryptionConfig +apiVersion: v1 +resources: + - resources: + - secrets + providers: + - identity: {} + - kms: + name : myKmsPlugin + endpoint: unix:///tmp/socketfile.sock + cachesize: 100 +``` + +2. 重启所有 kube-apiserver 进程。 + +3. 运行下列命令强制重新加密所有秘密信息。 +``` +kubectl get secrets --all-namespaces -o json | kubectl replace -f - +``` +{{% /capture %}} + +