

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

# 在 Amazon EKS 集群上部署基于 gRPC 的应用程序并使用应用程序负载均衡器访问它
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer"></a>

*Kirankumar Chandrashekar 和 Huy Nguyen，Amazon Web Services*

## Summary
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-summary"></a>

此模式描述如何在 Amazon Elastic Kubernetes Service (Amazon EKS) 集群上托管基于 gRPC 的应用程序，并通过应用程序负载均衡器安全地访问该应用程序。

[gRPC](https://grpc.io/) 是一个开源远程过程调用 (RPC) 框架，可以在任何环境中运行。您可将其用于微服务集成和客户端-服务器通信。有关 gRPC 的更多信息，请参阅 AWS 博客文章 App [lication Load Balancer 对 end-to-end HTTP/2 和 gRPC 的支持](https://aws.amazon.com/blogs/aws/new-application-load-balancer-support-for-end-to-end-http-2-and-grpc/)。

此模式向您介绍如何在 Amazon EKS 上托管作为 Kubernetes 容器组（pod）运行的基于 gRPC 的应用程序。gRPC 客户端通过加密连接通过 HTTP/2 协议连接到 Application Load Balancer。 SSL/TLS 应用程序负载均衡器将流量转发至 Amazon EKS 容器组（pod）上运行的 gRPC 应用程序。使用 [Kubernetes Horizontal Pod Autoscaler](https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html)，可以根据流量自动扩缩 gRPC 容器组（pod）的数量。应用程序负载均衡器的目标组对 Amazon EKS 节点执行运行状况检查，评估目标是否运行状况良好，并且仅将流量转发到运行状况良好的节点。

## 先决条件和限制
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-prereqs"></a>

**先决条件**
+ 一个活跃的 AWS 账户。
+ [Docker](https://www.docker.com/)，已在 Linux、macOS 或 Windows 上安装并配置。
+ [AWS 命令行界面（AWS CLI）版本 2](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)，已在 Linux、macOS 或 Windows 上安装并配置。
+ [eksctl](https://github.com/eksctl-io/eksctl#installation)，已在 Linux、macOS 或 Windows 上安装并配置。
+ `kubectl`，已安装并配置为访问 Amazon EKS 集群上的资源。有关更多信息，请参阅 Amazon EKS 文档中的[安装或更新 kubectl](https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html)。 
+ [g RPCurl](https://github.com/fullstorydev/grpcurl)，已安装并配置。
+ 新的或现有的 Amazon EKS 集群。有关更多信息，请参阅 [Amazon EKS 入门](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)。
+ 您的计算机终端被配置为访问 Amazon EKS 集群。有关详情，请参阅 Amazon EKS 文档中的[将计算机配置为与您的集群通信](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html#eks-configure-kubectl)。
+ [AWS Load Balancer Controller](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html)，在 Amazon EKS 集群中配备。
+ 具有有效 SSL 或 SSL/TLS 证书的现有 DNS 主机名。您可通过使用 AWS Certificate Manager (ACM) 或将现有证书上载到 ACM 获取域证书。有关这两个选项的更多信息，请参阅 ACM 文档中的[请求公共证书](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html)和[将证书导入 AWS Certificate Manager](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate.html)。

## 架构
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-architecture"></a>

下图显示了此模式实施的架构。

![在 Amazon EKS 上的基于 gRPC 的应用程序的架构](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/abf727c1-ff8b-43a7-923f-bce825d1b459/images/281936fa-bc43-4b4e-a343-ba1eab97df38.png)


 

下图显示了一个工作流程，其中从 gRPC 客户端接收 SSL/TLS 流量，然后将其卸载到 Application Load Balancer。由于流量来自虚拟私有云（VPC），因此以明文形式转发到 gRPC 服务器。

![向 gRP SSL/TLS C 服务器发送流量的工作流程](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/images/pattern-img/abf727c1-ff8b-43a7-923f-bce825d1b459/images/09e0c3f6-0c39-40b7-908f-8c4c693a5f02.png)


## 工具
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-tools"></a>

**AWS 服务**
+ [AWS 命令行界面（AWS CLI）](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)是一种开源工具，它可帮助您通过命令行 Shell 中的命令与 Amazon Web Services 交互。
+ [弹性负载均衡](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html)在多个目标上分配传入的应用程序或网络流量。例如您可以将流量分配到一个或多个可用区中的 Amazon Elastic Compute Cloud (Amazon EC2) 实例、容器以及 IP 地址。
+ [Amazon Elastic Container Registry (Amazon ECR)](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) 是一项安全、可扩展且可靠的托管容器映像注册表服务。 
+ [Amazon Elastic Kubernetes Service (Amazon EKS)](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html) 可帮助您在 AWS 上运行 Kubernetes，而无需安装或维护您自己的 Kubernetes 控制面板或节点。 

**工具**
+ [eksctl](https://eksctl.io/) 是一个用于在 Amazon EKS 上创建集群的简单 CLI 工具。
+ [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) 是针对 Kubernetes 集群运行命令的命令行实用程序。
+ [AWS 负载均衡器控制器](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html)帮助管理 Kubernetes 集群的 AWS 弹性负载均衡器。
+ [g RPCurl](https://github.com/fullstorydev/grpcurl) 是一个命令行工具，可帮助您与 gRPC 服务进行交互。

**代码存储库**

此模式的代码可在 to-e GitHub [grpc-traffic-on-albks 存储库中找到](https://github.com/aws-samples/grpc-traffic-on-alb-to-eks.git)。

## 操作说明
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-epics"></a>

### 构建 gRPC 服务器的 Docker 映像并将其推送到 Amazon ECR
<a name="build-and-push-the-grpc-serverrsquor-s-docker-image-to-amazon-ecr"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 创建 Amazon ECR 存储库。 | 登录 AWS 管理控制台并打开[ Amazon ECR 控制台](https://console.aws.amazon.com/ecr/)，然后创建 Amazon ECR 存储库。有关更多信息，请参阅 Amazon ECR 文档中的[创建存储库](https://docs.aws.amazon.com/AmazonECR/latest/userguide/repository-create.html)。请务必记录 Amazon ECR 存储库的 URL。<br />您也可以通过运行以下命令，使用 AWS CLI 创建 Amazon ECR 存储库：<pre>aws ecr create-repository --repository-name helloworld-grpc</pre> | 云管理员 | 
| 构建 Docker 映像。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer.html) | DevOps 工程师 | 
| 将 Docker 映像推送到 Amazon ECR。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer.html) | DevOps 工程师 | 

### 将 Kubernetes 清单部署到 Amazon EKS 集群
<a name="deploy-the-kubernetes-manifests-to-the-amazon-eks-cluster"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 修改 Kubernetes 清单文件值。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer.html) | DevOps 工程师 | 
| 部署 Kubernetes 清单文件。 | 通过运行以下 `kubectl` 命令，将 `grpc-sample.yaml` 文件部署到 Amazon EKS 集群： <pre>kubectl apply -f ./kubernetes/grpc-sample.yaml</pre> | DevOps 工程师 | 

### 为应用程序负载均衡器的 FQDN 创建 DNS 记录
<a name="create-the-dns-record-for-the-application-load-balancerapos-s-fqdn"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 应用程序负载均衡器的 FQDN 记录。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/zh_cn/prescriptive-guidance/latest/patterns/deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer.html) | DevOps 工程师 | 

### 测试解决方案
<a name="test-the-solution"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 测试 gRPC 服务器。 | 使用 g 通过运行以下命令RPCurl 来测试端点：<pre>grpcurl grpc.example.com:443 list <br />grpc.reflection.v1alpha.ServerReflection<br />helloworld.helloworld</pre>将 `grpc.example.com` 替换为您的 DNS 名称。 | DevOps 工程师 | 
| 使用 gRPC 客户端测试 gRPC 服务器。 | 在 `helloworld_client_ssl.py` 示例 gRPC 客户端中，将 `grpc.example.com` 中的主机名替换为用于 gRPC 服务器的主机名。 <br />下列代码示例显示了 gRPC 服务器对客户端请求的响应：<pre>python ./app/helloworld_client_ssl.py<br />message: "Hello to gRPC server from Client"<br /><br />message: "Thanks for talking to gRPC server!! Welcome to hello world. Received message is \"Hello to gRPC server from Client\""<br />received: true</pre><br />这表明客户端可与服务器通信，并且连接成功。 | DevOps 工程师 | 

### 清理
<a name="clean-up"></a>


| Task | 说明 | 所需技能 | 
| --- | --- | --- | 
| 移除 DNS 记录。 | 移除指向您之前创建的应用程序负载均衡器的 FQDN 的 DNS 记录。 | 云管理员 | 
| 移除负载均衡器。 | 在 [Amazon EC2 控制台](https://console.aws.amazon.com/ec2/)上，选择**负载均衡器**，然后移除 Kubernetes 控制器为您的入口资源创建的负载均衡器。 | 云管理员 | 
| 删除 Amazon EKS 集群。 | 使用 `eksctl` 删除 Amazon EKS 集群：<pre>eksctl delete cluster -f ./eks.yaml</pre> | AWS DevOps | 

## 相关资源
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-resources"></a>
+ [Amazon EKS 上的网络负载均衡器](https://docs.aws.amazon.com/eks/latest/userguide/load-balancing.html)
+ [应用程序负载均衡器的目标组](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#target-group-protocol-version)

## 附加信息
<a name="deploy-a-grpc-based-application-on-an-amazon-eks-cluster-and-access-it-with-an-application-load-balancer-additional"></a>

**入口资源示例：**

```
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
    alb.ingress.kubernetes.io/ssl-redirect: "443"
    alb.ingress.kubernetes.io/backend-protocol-version: "GRPC"
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:<AWS-Region>:<AccountId>:certificate/<certificate_ID>
  labels:
    app: grpcserver
    environment: dev
  name: grpcserver
  namespace: grpcserver
spec:
  ingressClassName: alb
  rules:
  - host: grpc.example.com # <----- replace this as per your host name for which the SSL certtficate is available in ACM
    http:
      paths:
      - backend:
          service:
            name: grpcserver
            port:
              number: 9000
        path: /
        pathType: Prefix
```

**部署资源示例：**

```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grpcserver
  namespace: grpcserver
spec:
  selector:
    matchLabels:
      app: grpcserver
  replicas: 1
  template:
    metadata:
      labels:
        app: grpcserver
    spec:
      containers:
      - name: grpc-demo
        image: <your_aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/helloworld-grpc:1.0   #<------- Change to the URI that the Docker image is pushed to
        imagePullPolicy: Always
        ports:
        - name: grpc-api
          containerPort: 9000
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
      restartPolicy: Always
```

**示例输出**：

```
NAME             CLASS           HOSTS                          Address                PORTS          AGE
 grpcserver      <none>      <DNS-HostName>                  <ELB-address>              80            27d
```