

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

# 为在 Amazon EKS 上运行的应用程序配置双向 TLS 身份验证
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks"></a>

*Mahendra Revanasiddappa，Amazon Web Services*

## Summary
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-summary"></a>

基于证书的传输层安全性协议（TLS）是一个可选的 TLS 组件，可在服务器和客户端之间提供双向对等身份验证。使用双向 TLS，客户端必须在会话协商过程中提供 X.509 证书。服务器使用此证书来识别和验证客户端。

双向 TLS 是物联网 (IoT) 应用的常见要求，可用于[开放银行](https://docs.aws.amazon.com/wellarchitected/latest/financial-services-industry-lens/open-banking.html)等 business-to-business应用或标准。

此模式描述如何使用 NGINX 入口控制器为运行在 Amazon Elastic Kubernetes Service（Amazon EKS）集群上的应用程序配置双向 TLS。您可以通过注释入口资源来为 NGINX 入口控制器启用内置的双向 TLS 功能。有关 NGINX 控制器上双向 TLS 注释的更多信息，请参阅 Kubernetes 文档中的[客户端证书身份验证](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#client-certificate-authentication)。

**重要**  
此模式使用自签名证书。我们建议您只在测试集群中使用此功能，而不要在生产环境中使用。如果您想在生产环境中使用此模式，则可以使用 [AWS 私有证书颁发机构（AWS Private CA）](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html)或您现有的公有密钥基础设施（PKI）标准来颁发私有证书。

## 先决条件和限制
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-prereqs"></a>

**先决条件**
+ 一个 Amazon Web Services（AWS）有效账户。
+ 现有 Amazon EKS 集群。
+ AWS 命令行界面（AWS CLI）版本 1.7 或更高版本，已在 macOS、Linux 或 Windows 上安装并配置。
+ 已安装并配置的 kubectl 命令行实用程序，以便访问 Amazon EKS 集群。有关这方面的更多信息，请参阅 Amazon EKS 文档中的[安装 kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html)。
+ 用于测试应用程序的现有域名系统（DNS）名称。

**限制**
+ 此模式使用自签名证书。我们建议您只在测试集群中使用此功能，而不要在生产环境中使用。

## 架构
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-architecture"></a>

![为在 Amazon EKS 上运行的应用程序配置双向 TLS 身份验证](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/ae2761e3-7ed2-4c2a-ba54-a4ddce8a1e7e/images/cefc60f9-2f29-4052-b7ae-df4eb6395e1c.png)


**技术堆栈**
+ Amazon EKS
+ Amazon Route 53
+ Kubectl

## 工具
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-tools"></a>
+ [Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) 可帮助您在 AWS 上运行 Kubernetes，而无需安装或维护您自己的 Kubernetes 控制面板或节点。
+ [Amazon Route 53](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/Welcome.html) 是一种可用性高、可扩展性强的 DNS Web 服务。
+ [Kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html) 是命令行实用程序，用于与 Amazon EKS 集群交互。

## 操作说明
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-epics"></a>

### 生成自签名证书
<a name="generate-the-self-signed-certificates"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
|  生成 CA 密钥和证书。 | 通过运行以下命令生成证书颁发机构（CA）密钥和证书。<pre>openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=Test Cert Authority'</pre> | DevOps 工程师 | 
| 生成服务器密钥和证书，并使用 CA 证书进行签名。 | 通过运行以下命令生成服务器密钥和证书，并使用 CA 证书进行签名。<pre>openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN= <your_domain_name> ' && openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt</pre>请确认将 `<your_domain_name>` 替换为现有域名。 | DevOps 工程师 | 
|  生成客户端密钥和证书，并使用 CA 证书进行签名。 | 通过运行以下命令生成客户端密钥和证书，并使用 CA 证书进行签名。<pre>openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Test' && openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt</pre> | DevOps 工程师 | 

### 部署 NGINX 入口控制器
<a name="deploy-the-nginx-ingress-controller"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 将 NGINX 入口控制器部署到 Amazon EKS 集群中。 | 使用以下命令部署 NGINX 入口控制器。<pre>kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.0/deploy/static/provider/aws/deploy.yaml</pre> | DevOps 工程师 | 
|  验证 NGINX 入口控制器服务正在运行。 | 使用以下命令验证 NGINX 入口控制器服务正在运行。<pre>kubectl get svc -n ingress-nginx</pre>请确认服务地址字段包含网络负载均衡器的域名。 | DevOps 工程师 | 

### 在 Amazon EKS 集群中创建命名空间来测试双向 TLS
<a name="create-a-namespace-in-the-amazon-eks-cluster-to-test-mutual-tls"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在 Amazon EKS 集群中创建命名空间。 | 通过运行以下命令在 Amazon EKS 集群中创建名为 `mtls` 的命名空间。<pre>kubectl create ns mtls</pre><br />这将部署示例应用程序来测试双向 TLS。 | DevOps 工程师 | 

### 为示例应用程序创建部署和服务
<a name="create-the-deployment-and-service-for-the-sample-application"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在 mtls 命名空间中创建 Kubernetes 部署和服务。 | 创建一个名为 `mtls.yaml`的文件。将以下代码粘贴到该文件中。<pre>kind: Deployment<br />apiVersion: apps/v1<br />metadata:<br />  name: mtls-app<br />  labels:<br />    app: mtls<br />spec:<br />  replicas: 1<br />  selector:<br />    matchLabels:<br />      app: mtls<br />  template:<br />    metadata:<br />      labels:<br />        app: mtls<br />    spec:<br />      containers:<br />      - name: mtls-app<br />        image: hashicorp/http-echo<br />        args:<br />          - "-text=mTLS is working"<br /><br /><br />---<br /><br />kind: Service<br />apiVersion: v1<br />metadata:<br />  name: mtls-service<br />spec:<br />  selector:<br />    app: mtls<br />  ports:<br />    - port: 5678 # Default port for image</pre><br /> 通过运行以下命令在 `mtls` 命名空间中创建 Kubernetes 部署和服务。<pre>kubectl create -f mtls.yaml -n mtls</pre> | DevOps 工程师 | 
| 验证已创建 Kubernetes 部署。 | 运行以下命令验证部署是否已创建，且有一个容器组（pod）处于可用状态。<pre>kubectl get deploy -n mtls</pre> | DevOps 工程师 | 
| 验证是否已创建 Kubernetes 服务。 | 通过运行以下命令验证是否已创建 Kubernetes 服务。<pre>kubectl get service -n mtls</pre> | DevOps 工程师 | 

### 在 mtls 命名空间中创建密钥
<a name="create-a-secret-in-the-mtls-namespace"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建入口资源的密钥。 | 运行以下命令，使用您之前创建的证书为 NGINX 入口控制器创建密钥。<pre>kubectl create secret generic mtls-certs --from-file=tls.crt=server.crt --from-file=tls.key=server.key --from-file=ca.crt=ca.crt -n mtls </pre><br />您的密钥有一个服务器证书供客户端识别服务器，还有一个 CA 证书供服务器验证客户端证书。 | DevOps 工程师 | 

### 在 mtls 命名空间中创建入口资源
<a name="create-the-ingress-resource-in-the-mtls-namespace"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在 mtls 命名空间中创建入口资源。 | 创建一个名为 `ingress.yaml`的文件。将以下代码粘贴到文件中（将 `<your_domain_name>` 替换为现有域名）。<pre>apiVersion: networking.k8s.io/v1<br />kind: Ingress<br />metadata:<br />  annotations:<br />    nginx.ingress.kubernetes.io/auth-tls-verify-client: "on"<br />    nginx.ingress.kubernetes.io/auth-tls-secret: mtls/mtls-certs<br />  name: mtls-ingress<br />spec:<br />  ingressClassName: nginx<br />  rules:<br />  - host: "*.<your_domain_name>"<br />    http:<br />      paths:<br />      - path: /<br />        pathType: Prefix<br />        backend:<br />          service:<br />            name: mtls-service<br />            port:<br />              number: 5678<br />  tls:<br />  - hosts:<br />    - "*.<your_domain_name>"<br />    secretName: mtls-certs</pre><br />通过运行以下命令以在 `mtls` 命名空间中创建入口资源。<pre>kubectl create -f ingress.yaml -n mtls</pre><br />这意味着 NGINX 入口控制器可以将流量路由到示例应用程序。 | DevOps 工程师 | 
| 验证入口资源是否已创建。 | 通过运行以下命令验证是否已创建入口资源。<pre>kubectl get ing -n mtls</pre>请确认入口资源的地址显示为 NGINX 入口控制器创建的负载均衡器。 | DevOps 工程师 | 

### 配置 DNS 以将主机名指向负载均衡器
<a name="configure-dns-to-point-the-hostname-to-the-load-balancer"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建指向 NGINX 入口控制器的负载均衡器的 CNAME 记录。 | 登录 AWS 管理控制台，打开 Amazon Route 53 控制台，然后创建将 `mtls.<your_domain_name>` 指向 NGINX 入口控制器的负载均衡器的规范名称（CNAME）记录。<br />有关更多信息，请参阅 Route 53 文档中的[使用 Route 53 控制台创建记录](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html)。 | DevOps 工程师 | 

### 测试应用程序
<a name="test-the-application"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 在没有证书的情况下测试双向 TLS 设置。 | 运行如下命令。<pre>curl -k https://mtls.<your_domain_name> </pre><br />您应该收到“400 未发送必需的 SSL 证书”错误响应。 | DevOps 工程师 | 
| 在有证书的情况下测试双向 TLS 设置。 | 运行如下命令。<pre>curl -k https://mtls.<your_domain_name> --cert client.crt --key client.key</pre><br />您应该收到“mTLS 正在运行”的响应。 | DevOps 工程师 | 

## 相关资源
<a name="configure-mutual-tls-authentication-for-applications-running-on-amazon-eks-resources"></a>
+ [通过使用 Amazon Route 53 控制台创建记录](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-creating.html)
+ [在 Amazon EKS 上使用带有 NGINX 入口控制器的网络负载均衡器](https://aws.amazon.com/blogs/opensource/network-load-balancer-nginx-ingress-controller-eks/)
+ [客户证书认证](https://kubernetes.github.io/ingress-nginx/examples/auth/client-certs/)