在 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 Blog 文章应用程序负载均衡器支持端到端 HTTP/2 和 gRPC

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

先决条件和限制

先决条件

架构

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

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

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

将 SSL/TLS 流量发送到 gRPC 服务器的工作流

工具

Amazon Web Services

工具

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

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

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

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

代码存储库

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

操作说明

任务描述所需技能

创建 Amazon ECR 存储库。

登录 AWS 管理控制台并打开 Amazon 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-alb-to-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
    重要

    请确认已将 <your_aws_account_id> 更换为 AWS 账户 ID。

DevOps 工程师
任务描述所需技能

修改 Kubernetes 清单文件值。

  1. 根据要求修改该存储库的 Kubernetes 文件夹中的 grpc-sample.yaml 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 工程师
任务描述所需技能

应用程序负载均衡器的 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 工程师
任务描述所需技能

测试 gRPC 服务器。

通过运行以下命令,使用 gRPCurl 测试端点:

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.example.com 中的主机名替换为用于 gRPC 服务器的主机名。 

下列代码示例显示了 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 工程师
任务描述所需技能

移除 DNS 记录。

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

云管理员

移除负载均衡器。

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

云管理员

删除 Amazon EKS 集群。

使用 eksctl 删除 Amazon EKS 集群:

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