在 Amazon EKS 叢集上部署以 gRPC 為基礎的應用程式,並使 Application Load Balancer 存取 - AWS 方案指引

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

在 Amazon EKS 叢集上部署以 gRPC 為基礎的應用程式,並使 Application Load Balancer 存取

由基蘭庫馬爾·錢德拉什卡(AWS)和 Huy 阮(AWS)創建

代碼存儲庫:grpc-traffic-on-alb到 eks

環境:PoC 或試點

技術:容器和微服務;內容傳遞;虛擬主機;網站和 Web 應用程式

工作負載:所有其他工作

AWS 服務:Amazon EKS;Elastic Load Balancing (ELB)

Summary

此模式說明如何在 Amazon 彈性 Kubernetes 服務 (Amazon EKS) 叢集上託管以 gRPC 為基礎的應用程式,並透過應用程式負載平衡器安全地存取該應用程式。

GrPC 是可在任何環境中執行的開放原始碼遠端程序呼叫 (RPC) 架構。您可以將其用於微服務整合和用戶端伺服器通訊。如需 GrPC 的詳細資訊,請參閱 AWS 部落格文章 end-to-end HTTP/2 和 gRPC 的 Application Load Balancer 支援

此模式說明如何託管在 Amazon EKS 上 Kubernetes 網繭上執行的基於 gRPC 的應用程式。gRPC 用戶端透過具有 SSL/TLS 加密連線的 HTTP/2 通訊協定連線到 Application Load Balancer。應用程式負載平衡器會將流量轉送至在 Amazon EKS 網繭上執行的 gRPC 應用程式。您可以使用 Kubernetes 水平網繭自動配置器,根據流量自動調整 gRPC 網繭的數目。應用程式負載平衡器的目標群組會在 Amazon EKS 節點上執行運作狀態檢查、評估目標是否運作良好,以及僅將流量轉送至運作良好的節點。

先決條件和限制

先決條件

架構

下圖顯示了這種模式實現的體系結構。

Amazon EKS 上基於 gRPC 的應用程序的架構

下圖顯示了從將負載卸載到應用程式負載平衡器的 GrPC 用戶端接收 SSL/TLS 流量的工作流程。流量是以明文形式轉送到 GrPC 伺服器,因為它來自虛擬私有雲 (VPC)。

工具

AWS 服務

工具

  • eksctl 是一個簡單的 CLI 工具,用於在 Amazon EKS 上創建集群。

  • kubectl 是一個命令列公用程式,可針對 Kubernetes 叢集執行命令。

  • AWS Load Balancer 控制器可協助您管理 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到 eks 存儲庫。

    git clone https://github.com/aws-samples/grpc-traffic-on-alb-to-eks.git
  2. 從存儲庫的根目錄中,確保 Docker 文件存在,然後運行以下命令來構建 Docker 映像: 

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

    重要事項:請務必<amazon_ecr_repository_url>以先前建立之 Amazon ECR 儲存庫的 URL 取代。

DevOps 工程師

將碼頭圖像推送到 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 工程師
任務描述所需技能

修改 Kubernetes 資訊清單檔案中的值。

  1. 根據您的需求,修改存放grpc-sample.yaml庫 Kubernetes 資料夾中的 Kubernetes 資訊清單檔案。您必須修改輸入資源中的註釋和主機名稱。如需範例輸入資源,請參閱其他資訊一節。如需有關輸入註釋的詳細資訊,請參閱 Kubernetes 文件中的輸入註釋

  2. 在 Kubernetes 部署資源中,將部署資源變更為您將 Docker 映像推送image到的 Amazon ECR 儲存庫的統一資源識別碼 (URI)。如需範例部署資源,請參閱其他資訊一節。

DevOps 工程師

部署 Kubernetes 資訊清單檔案。

執行下列kubectl命令,將grpc-sample.yaml檔案部署到 Amazon EKS 叢集: 

kubectl apply -f ./kubernetes/grpc-sample.yaml
DevOps 工程師
任務描述所需技能

記錄應 Application Load Balancer 的 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> alb.ingress.kubernetes.io/healthcheck-protocol: HTTP 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