

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

# 在 Amazon EKS 叢集上部署以 gRPC 為基礎的應用程式，並使用 Application Load Balancer 存取它
<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*

## 摘要
<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 為基礎的應用程式，並透過 Application Load Balancer 安全地存取它。

[gRPC](https://grpc.io/) 是一種可在任何環境中執行的開放原始碼遠端程序呼叫 (RPC) 架構。您可以使用它進行微服務整合和用戶端-伺服器通訊。如需 gRPC 的詳細資訊，請參閱 AWS 部落格文章 [Application 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 用戶端會透過具有 SSL/TLS 加密連線的 HTTP/2 通訊協定連線至 Application Load Balancer。Application Load Balancer 會將流量轉送至在 Amazon EKS Pod 上執行的 gRPC 應用程式。您可以使用 [Kubernetes Horizontal Pod Autoscaler，根據流量自動擴展 gRPC Pod ](https://docs.aws.amazon.com/eks/latest/userguide/horizontal-pod-autoscaler.html)的數量。Application Load Balancer 的目標群組會對 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 帳戶
+ 在 Linux、macOS 或 Windows 上安裝和設定 [Docker](https://www.docker.com/)。
+ [在 Linux、macOS 或 Windows 上安裝和設定 AWS Command Line Interface (AWS CLI) 第 2 版](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)。  macOS
+ [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)。 
+ [gRPCurl](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 控制器](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)。

## Architecture
<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_tw/prescriptive-guidance/latest/patterns/images/pattern-img/abf727c1-ff8b-43a7-923f-bce825d1b459/images/281936fa-bc43-4b4e-a343-ba1eab97df38.png)


 

下圖顯示從卸載至 Application Load Balancer 的 gRPC 用戶端接收 SSL/TLS 流量的工作流程。流量會以純文字轉送至 gRPC 伺服器，因為它來自虛擬私有雲端 (VPC)。

![\[將 SSL/TLS 流量傳送至 gRPC 伺服器的工作流程\]](http://docs.aws.amazon.com/zh_tw/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 Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) 是一種開放原始碼工具，可協助您透過命令列 Shell 中的命令與 AWS 服務互動。
+ [Elastic Load Balancing](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 Load Balancer 控制器](https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html) 可協助您 管理 Kubernetes 叢集的 AWS Elastic Load Balancer。
+ [gRPCurl ](https://github.com/fullstorydev/grpcurl)是一種命令列工具，可協助您與 gRPC 服務互動。

**程式碼儲存庫**

此模式的程式碼可在 GitHub [grpc-traffic-on-alb-to-eks](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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 建立 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。您也可以執行下列命令，使用 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_tw/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_tw/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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 修改 Kubernetes 資訊清單檔案中的值。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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 工程師 | 

### 建立 Application Load Balancer FQDN 的 DNS 記錄
<a name="create-the-dns-record-for-the-application-load-balancerapos-s-fqdn"></a>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 記錄 Application Load Balancer 的 FQDN。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/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>


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 測試 gRPC 伺服器。 | 執行下列命令，使用 gRPCurl 來測試端點：<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 伺服器的主機名稱。 下列程式碼範例顯示用戶端請求的 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>這表示用戶端可以與伺服器通訊，而且連線成功。 | DevOps 工程師 | 

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


| 任務 | Description | 所需的技能 | 
| --- | --- | --- | 
| 移除 DNS 記錄。 | 移除指向您先前建立之 Application Load Balancer FQDN 的 DNS 記錄。 | 雲端管理員 | 
| 移除負載平衡器。 | 在 [Amazon EC2 主控台](https://console.aws.amazon.com/ec2/)上，選擇**負載平衡器**，然後移除 Kubernetes 控制器為輸入資源建立的負載平衡器。 | 雲端管理員 | 
| 刪除 Amazon EKS 叢集。 | 使用 刪除 Amazon EKS 叢集`eksctl`：<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)
+ [Application Load Balancer 的目標群組](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
```