

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用证书管理器和 “让我们加 end-to-end密” 为 Amazon EKS 上的应用程序设置加密
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt"></a>

*Mahendra Revanasiddappa 和 Vasanth Jeyaraj，Amazon Web Services*

## Summary
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt-summary"></a>

实施 end-to-end加密可能很复杂，您需要管理微服务架构中每项资产的证书。尽管您可以使用网络负载均衡器或 Amazon API Gateway 终止亚马逊网络服务 (AWS) 网络边缘的传输层安全 (TLS) 连接，但有些组织需要 end-to-end加密。

此模式使用 Nginx Ingress Controller 作为入口。这是因为当您创建 Kubernetes 入口时，入口资源使用网络负载均衡器。网络负载均衡器不允许上传客户端证书。因此，您无法通过 Kubernetes 入口实现双向 TLS。

这种模式旨在针对需要在其应用程序中所有微服务之间相互认证的组织。双向 TLS 减轻了用户名或密码的维护负担，还可以使用交钥匙安全框架。如果您的组织具有大量连接的设备或必须遵守严格的安全指南，则此模式的方法是兼容的。

这种模式通过对在 Amazon Elastic Kubernetes Service (Amazon EKS) 上运行的应用程序实施 end-to-end加密，有助于提高组织的安全状况。此模式在 [Amazon EKS 存储库中的 GitHub End-to-end 加密](https://github.com/aws-samples/end-to-end-encryption-on-amazon-eks#readme)中提供了示例应用程序和代码，以显示微服务如何在 Amazon EKS 上通过 end-to-end加密运行。该模式的方法使用 [cert-manager](https://cert-manager.io/docs/)（Kubernetes 的附加组件），将 [Let 's Encrypt](https://letsencrypt.org/) 作为证书颁发机构 (CA)。Let's Encrypt 是一款经济实惠的证书管理解决方案，它提供有效期为 90 天的免费证书。当在 Amazon EKS 上部署新的微服务时，CERT-MANAGER自动化证书的按需供应和旋转。 

**目标受众**

建议使用 Kubernetes、TLS、Amazon Route 53 和域名系统（DNS）的用户使用此模式。

## 先决条件和限制
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt-prereqs"></a>

**先决条件**
+ 一个有效的 Amazon Web Services account。
+ 现有 Amazon EKS 集群。
+ 已在 macOS、Linux 或 Windows 上安装和配置的 AWS 命令行界面（AWS CLI）1.7 或更高版本
+ `kubectl` 命令行实用程序，已安装并配置以便访问 Amazon EKS 集群。有关这方面的更多信息，请参阅 Amazon EKS 文档中的[安装 kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html)。
+ 用于测试应用程序的现有 DNS 名称。有关更多信息，请参阅 Amazon Route 53 文档中的[使用 Amazon Route 53 注册域名](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/registrar.html)。 
+ 最新 [Helm](https://docs.aws.amazon.com/eks/latest/userguide/helm.html) 版本，安装在您的本地计算机上。有关这方面的更多信息，请参阅 [Amazon EKS 文档和 Helm 存储库中的将 Hel GitHub [m](https://github.com/helm/helm) 与 Amazon EKS 配合使用](https://docs.aws.amazon.com/eks/latest/userguide/helm.html)。 
+ [Amazon EKS 存储库上的 GitHub End-to-end 加密](https://github.com/aws-samples/end-to-end-encryption-on-amazon-eks#readme)已克隆到您的本地计算机。 
+ 替换 [Amazon EKS 存储库中克隆 GitHub End-to-end 加密](https://github.com/aws-samples/end-to-end-encryption-on-amazon-eks#readme)的`policy.json`和`trustpolicy.json`文件中的以下值：
  + `<account number>` — 替换为您要在其中部署解决方案的账户的 Amazon Web Services account ID。 
  + `<zone id>` — 替换为域名的 Route 53 区域 ID。 
  + `<node_group_role>` – 替换为与 Amazon EKS 节点关联的 AWS Identity and Access Management（IAM） 角色的名称。
  + `<namespace>` — 替换为在其中部署 NGINX Ingress Controller和示例应用程序的 Kubernetes 命名空间。
  + `<application-domain-name>` — 替换为 Route 53 中的 DNS 域名。

**限制**
+ 该模式无法描述如何旋转证书，而仅演示如何在 Amazon EKS 上使用微服务的证书。 

## 架构
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt-architecture"></a>

下图显示了此模式的工作流和架构组件。

![使用证书管理器和 Let's Encrypt 为 Amazon EKS 上的应用程序设置加密的工作流。](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/9aa3ee9e-73db-41f5-a467-b5c47fef496e/images/40692ede-6fb3-474e-8c9e-85c51529e8ad.png)


下图显示了如下工作流：

1. 客户端发送请求将应用程序访问到DNS名称。

1. Route 53 记录为网络负载均衡器的别名记录。

1. 网络负载均衡器将请求转发至配置了 TLS 侦听器的 NGINX Ingress Controller。NGINX Ingress Controller与网络负载均衡器之间的通信遵循 HTTPS 协议。

1. NGINX Ingress Controller 根据客户端对应用程序服务的请求进行基于路径的路由。

1. 应用程序服务将请求转发至应用程序容器组（pod）。该应用程序旨在通过调用秘密使用相同的证书。

1. 容器组（pod）使用证书管理器证书运行示例应用程序。NGINX Ingress Controller 和容器组（pod）之间的通信使用 HTTPS。


| 
| 
| 注意：证书管理器在自己的命名空间运行。它使用 Kubernetes 集群角色来提供特定名称空间中的秘密证书。您可以将这些名称空间附加到应用程序容器组（pod）和 Nginx Ingress Controller。 | 
| --- |

## 工具
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt-tools"></a>

**Amazon Web Services**
+ [Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/what-is-eks.html) 是一项托管服务，可让您在 AWS 上轻松运行 Kubernetes，而无需安装、操作或维护您自己的 Kubernetes 控制面板或节点。
+ [弹性负载均衡](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html)会自动将您的传入流量分配到多个目标、容器和 IP 地址。
+ [AWS Identity and Access Management (AWS IAM) ](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)通过控制验证和授权使用您 AWS 资源的用户，帮助您安全地管理对您 AWS 资源的访问。
+ [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html) 是一种可用性高、可扩展性强的 DNS Web 服务。

**其他工具**
+ [cert-manager](https://cert-manager.io/docs/installation/supported-releases/) 是 Kubernetes 的附加组件，用于请求证书、将证书分发到 Kubernetes 容器和自动续订证书。
+ [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/) 是一款适用于 Kubernetes 和容器化环境中的云原生应用程序的流量管理解决方案。

## 操作说明
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt-epics"></a>

### 使用 Route 53 创建与配置公共托管区域
<a name="create-and-configure-a-public-hosted-zone-with-route-53"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在 Route 53 中创建一个公有托管区。 | 登录 AWS 管理控制台，打开 Amazon Route 53 控制台，选择**托管区域**，然后选择**创建托管区域**。创建公共托管区域，并记录区域 ID。有关更多信息，请参阅 Amazon Route 53 文档中的[创建公有托管区](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/CreatingHostedZone.html)。ACME DNS01 使用 DNS 提供程序发布质疑，要求证书管理器颁发证书。这项挑战要求您通过将特定值放在该域名下的TXT记录中来证明您控制域名的 DNS。在 Let's Encrypt 向您的 ACME 客户端提供令牌后，您的客户端会创建一条从该令牌和您的账户密钥派生的 TXT 记录，并将该记录置于 `_acme-challenge.<YOURDOMAIN>`。然后 Let's Encrypt 在 DNS 中查询此记录。如找到匹配项，则可以继续颁发证书。 | AWS DevOps | 

### 配置 IAM 角色，以允许证书管理员访问公共托管区域
<a name="configure-an-iam-role-to-allow-cert-manager-to-access-the-public-hosted-zone"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 为证书管理器创建 IAM policy。 | 要求 IAM policy 为证书管理器提供许可，以验证您拥有53号公路域。A [mazon EKS 存储库中的克隆 GitHub End-to-end 加密`1-IAMRole`](https://github.com/aws-samples/end-to-end-encryption-on-amazon-eks#readme)目录中提供了`policy.json`示例 IAM 策略。<br />在 AWS CLI 中输入以下命令以创建 IAM policy。<pre>aws iam create-policy \<br />  --policy-name PolicyForCertManager \<br />  --policy-document file://policy.json</pre> | AWS DevOps | 
| 为证书管理器创建 IAM 角色。 | 创建 IAM policy后，必须创建 IAM 角色。`1-IAMRole` 目录中提供了 `trustpolicy.json` 示例 IAM 角色。<br />在 AWS CLI 中输入以下命令以创建 IAM 角色。<pre>aws iam create-role \<br />  --role-name RoleForCertManager \<br />  --assume-role-policy-document file://trustpolicy.json</pre> | AWS DevOps | 
| 将 策略附加到该角色。 | 在 AWS CLI 中输入以下命令以将 IAM policy 附加到 IAM 角色。将 `AWS_ACCOUNT_ID` 替换为您的 Amazon Web Services account 的 ID。<pre>aws iam attach-role-policy \<br />  --policy-arn arn:aws:iam::AWS_ACCOUNT_ID:policy/PolicyForCertManager \<br />  --role-name RoleForCertManager</pre> | AWS DevOps | 

### 在Amazon EKS 中设置 NGINX Ingress Controller
<a name="set-up-the-nginx-ingress-controller-in-amazon-eks"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 部署 NGINX Ingress Controller。 | 使用 Helm 安装最新版`nginx-ingress`。在部署 `nginx-ingress` 配置之前，您可以根据自己的要求对其进行修改。此模式使用带注释的、面向内部的网络负载均衡器，该网络负载均衡器可在 `5-Nginx-Ingress-Controller` 目录中找到。 <br />通过从 `5-Nginx-Ingress-Controller` 目录中运行以下 Helm 命令来安装 NGINX Ingress Controller。<br />`helm install test-nginx nginx-stable/nginx-ingress  -f  5-Nginx-Ingress-Controller/values_internal_nlb.yaml` | AWS DevOps | 
| 验证 NGINX Ingress Controller 是否已安装。 | 输入 `helm list`命令。输出应显示 NGINX Ingress Controller 已安装。 | AWS DevOps | 
| 创建 Route 53 A 记录。 | 创建指向 NGINX Ingress Controller 的网络负载均衡器的别名记录。[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt.html) | AWS DevOps | 

### 在 VirtualServer 亚马逊 EKS 上设置 NGINX
<a name="set-up-nginx-virtualserver-on-amazon-eks"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 部署 NGINX VirtualServer。 | NGINX VirtualServer 资源是一种负载平衡配置，可以替代入口资源。创建 NGINX VirtualServer 资源的配置可在目录中的`nginx_virtualserver.yaml`文件中找到。`6-Nginx-Virtual-Server`在中输入以下命令`kubectl`以创建 NGINX 资源 VirtualServer 。<br />`kubectl apply -f  nginx_virtualserver.yaml`请务必更新 `nginx_virtualserver.yaml` 文件中的应用程序域名、证书密钥和应用程序服务名称。 | AWS DevOps | 
| 验证是否已创建 NGINX VirtualServer 。 | 在中输入以下命令`kubectl`以验证 NGINX VirtualServer 资源是否已成功创建。<br />`kubectl get virtualserver`请确认 `Host` 列与您的应用程序的域名相匹配。 | AWS DevOps | 
| 在启用 TLS 的情况下部署 NGINX Web 服务器。 | 此模式使用启用了 TLS 的 NGINX Web 服务器作为测试 end-to-end加密的应用程序。部署测试应用程序所需配置文件可在 `demo-webserver` 目录中找到。 <br />在 `kubectl` 中输入以下命令以部署测试应用程序。<br />`kubectl apply -f nginx-tls-ap.yaml` | AWS DevOps | 
| 验证测试应用程序资源是否已创建。 | 在 `kubectl` 中输入以下命令，以验证是否为测试应用程序创建了所需资源：[See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt.html) | AWS DevOps | 
| 验证应用程序。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt.html) | AWS DevOps | 

## 相关资源
<a name="set-up-end-to-end-encryption-for-applications-on-amazon-eks-using-cert-manager-and-let-s-encrypt-resources"></a>

**AWS 资源**
+ [使用 Amazon Route 53 控制台创建记录](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html)（Amazon Route 53 文档）
+ [在 Amazon EKS 上使用带有 NGINX 入口控制器的网络负载均衡器](https://aws.amazon.com/blogs/opensource/network-load-balancer-nginx-ingress-controller-eks/)（AWS Blog 文章）

**其他资源**
+ [Route 53](https://cert-manager.io/docs/configuration/acme/dns01/route53/)（证书管理器文档）
+ [配置 DNS01 Challenge 提供程序](https://cert-manager.io/docs/configuration/acme/dns01/)（证书管理器文档）
+ [Let’s encrypt DNS 问题](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) (Let’s Encrypt 文档)