在 Amazon EKS 集群上部署基于 gRPC 的应用程序并使用应用程序负载均衡器访问它 - AWS Prescriptive Guidance

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

在 Amazon EKS 集群上部署基于 gRPC 的应用程序并使用应用程序负载均衡器访问它

Kirankumar Chandrashekar 和 Huy Nguyen,Amazon Web Services

摘要

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

gRPC 是一个开源远程过程调用 (RPC) 框架,可以在任何环境中运行。您可将其用于微服务集成和客户端-服务器通信。有关 gRPC 的更多信息,请参阅 AWS 博客文章 App lication Load Balancer 对 end-to-end HTTP/2 和 gRPC 的支持

此模式向您展示如何托管在 Amazon EKS 上的 Kubernetes 容器上运行的基于 GRPC 的应用程序。gRPC 客户端通过加密连接通过 HTTP/2 协议连接到 Application Load Balancer。 SSL/TLS 应用程序负载均衡器将流量转发至 Amazon EKS 容器组(pod)上运行的 gRPC 应用程序。使用 Kubernetes Horizontal Pod Autoscaler,可以根据流量自动扩缩 gRPC 容器组(pod)的数量。应用程序负载均衡器的目标组对 Amazon EKS 节点执行运行状况检查,评估目标是否正常,并仅将流量转发到运行状况良好的节点。

先决条件和限制

先决条件

架构

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

Amazon EKS 上基于 GRPC 的应用程序架构

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

向 gRP SSL/TLS C 服务器发送流量的工作流程

工具

Amazon Web Services

工具

  • eksctl 是一款用于在 Amazon EKS 上创建集群的简单 CLI 工具。

  • kubectl 是针对 Kubernetes 集群运行命令的命令行实用程序。

  • AWS 负载均衡器控制器帮助管理 Kubernetes 集群的 AWS 弹性负载均衡器。

  • g RPCurl 是一个命令行工具,可帮助您与 gRPC 服务进行交互。

代码存储库

此模式的代码可在 to-e GitHub grpc-traffic-on-albks 存储库中找到

操作说明

Task描述所需技能

创建 Amazon ECR 存储库。

登录 AWS 管理控制台,打开 A mazon ECR 控制台,然后创建 Amazon ECR 存储库。有关更多信息,请参阅 Amazon ECR 文档中的创建存储库。请务必记录 Amazon ECR 存储库的 URL。

您也可以通过运行以下命令,使用 AWS CLI 创建 Amazon ECR 存储库:

aws ecr create-repository --repository-name helloworld-grpc
云管理员

构建 Docker 映像。

  1. 克隆 GitHub grpc-traffic-on-albto-eks 存储库。

    git clone https://github.com/aws-samples/grpc-traffic-on-alb-to-eks.git
  2. 在存储库的根目录中,确保 Dockerfile 存在,然后运行以下命令来构建 Docker 镜像: 

    docker build -t <amazon_ecr_repository_url>:<Tag> .
    重要

    请务必<amazon_ecr_repository_url>使用之前创建的 Amazon ECR 存储库的 URL 进行替换。

DevOps 工程师

将 Docker 映像推送到 Amazon ECR。

  1. 运行以下命令以登录 Amazon ECR 存储库:

    aws ecr get-login-password --region us-east-1 --no-cli-auto-prompt | docker login --username AWS --password-stdin <your_aws_account_id>.dkr.ecr.us-east-1.amazonaws.com
  2. 通过运行以下命令将 Docker 映像推送到 Amazon ECR 存储库。

    docker push <your_aws_account_id>.dkr.ecr.us-east-1.amazonaws.com/helloworld-grpc:1.0
    重要

    请务必使用您的 AWS 账户 ID <your_aws_account_id> 进行替换。

DevOps 工程师
Task描述所需技能

修改 Kubernetes 清单文件值。

  1. 根据您的要求修改存储grpc-sample.yaml库 Kubernetes 文件夹中的 Kubernetes 清单文件。您必须修改入口资源的注释和主机名。有关示例入口资源,请参阅其他信息部分。有关入口注释的更多信息,请参阅 Kubernetes 文档中的入口注释

  2. 在 Kubernetes 部署资源中,将部署资源的 image 更改为:您将 Docker 映像推至的 Amazon ECR 存储库的统一资源标识符 (URI)。有关此部署资源的样本,请参阅其他信息部分。

DevOps 工程师

部署 Kubernetes 清单文件。

通过运行以下kubectl命令将grpc-sample.yaml文件部署到 Amazon EKS 集群: 

kubectl apply -f ./kubernetes/grpc-sample.yaml
DevOps 工程师
Task描述所需技能

应用程序负载均衡器的 FQDN 记录。

  1. 运行以下 kubectl 命令来描述管理应用程序负载均衡器的 Kubernetes 入口资源:

    kubectl get ingress -n grpcserver

    输出示例在 “其他信息” 部分提供。在输出中,HOSTS 字段显示为其创建 SSL 证书的 DNS 主机名。

  2. 在输出Address字段中记录应用程序负载均衡器的完全限定域名 (FQDN)。 

  3. 创建指向应用程序负载均衡器的 FQDN 的 DNS 记录。如果您的 DNS 提供程序是 Amazon Route 53,请创建一条指向应用程序负载均衡器的 FQDN 的别名记录。有关此选项的更多信息,请参阅 Route 53 文档中的在别名和非别名记录之间进行选择

DevOps 工程师
Task描述所需技能

测试 gRPC 服务器。

使用 g 通过运行以下命令RPCurl 来测试端点:

grpcurl grpc.example.com:443 list grpc.reflection.v1alpha.ServerReflection helloworld.helloworld
注意

grpc.example.com替换为您的 DNS 名称。

DevOps 工程师

使用 gRPC 客户端测试 gRPC 服务器。

helloworld_client_ssl.py示例 gRPC 客户端中,将中的主机名替换为用于 gRPC 服务器的主机名。grpc.example.com 

下列代码示例显示了 gRPC 服务器对客户端请求的响应:

python ./app/helloworld_client_ssl.py message: "Hello to gRPC server from Client" message: "Thanks for talking to gRPC server!! Welcome to hello world. Received message is \"Hello to gRPC server from Client\"" received: true

这表明客户端可与服务器通信,并且连接成功。

DevOps 工程师
Task描述所需技能

删除 DNS 记录。

删除您之前创建的指向应用程序负载均衡器的 FQDN 的 DNS 记录。

云管理员

移除负载均衡器。

Amazon EC2 控制台上,选择负载均衡器,然后移除 Kubernetes 控制器为您的入口资源创建的负载均衡器。

云管理员

删除 Amazon EKS 集群。

使用以下方法删除 Amazon EKS 集群eksctl

eksctl delete cluster -f ./eks.yaml
AWS DevOps

相关资源

其他信息

入口资源示例:

--- 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