部署和偵錯 Amazon EKS叢集 - AWS 方案指引

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

部署和偵錯 Amazon EKS叢集

由 Svenja Raether (AWS) 和 Mathew George (AWS) 建立

環境:PoC 或試行

技術:容器與微服務;基礎設施;現代化;無伺服器; CloudNative

工作負載:所有其他工作負載

AWS 服務:Amazon EKS;AWSFargate

Summary

容器正在成為雲端原生應用程式開發的重要部分。Kubernetes 提供有效的方式來管理和協調容器。Amazon Elastic Kubernetes Service (Amazon EKS) 是一項完全受管且經過認證的 Kubernetes 一致性服務,可在 Amazon Web Services () 上建置、保護、操作和維護 Kubernetes 叢集AWS。它支援在 AWS Fargate 上執行 Pod,以提供隨需、大小正確的運算容量。

開發人員和管理員在執行容器化工作負載時,必須了解偵錯選項。此模式會逐步引導您在EKS使用 AWS Fargate 的 Amazon 上部署和偵錯容器。它包括建立、部署、存取、偵錯和清理 Amazon EKS工作負載。

先決條件和限制

先決條件

限制

  • 此模式為開發人員提供開發環境的實用偵錯實務。它不會說明生產環境的最佳實務。

  • 如果您執行 Windows,請使用作業系統特定的命令來設定環境變數。

使用的產品版本

架構

技術堆疊

  • Application Load Balancer

  • Amazon EKS

  • AWS Fargate

目標架構

圖表中顯示的所有資源都是使用 eksctl和從本機機器發出的kubectl命令來佈建。私有叢集必須從私有 內的執行個體執行VPC。

目標架構由使用 Fargate 啟動類型的EKS叢集組成。這提供隨需、大小正確的運算容量,而不需要指定伺服器類型。EKS 叢集具有控制平面,用於管理叢集節點和工作負載。Pod 會佈建至跨越多個可用區域的私有VPC子網路。Amazon ECR Public Gallery 用於擷取 NGINX Web 伺服器映像並將其部署至叢集的 Pod。

下圖顯示如何使用 kubectl 命令存取 Amazon EKS控制平面,以及如何透過使用 Application Load Balancer 存取應用程式。

.

使用 Amazon EKS控制平面和 Fargate 設定檔的四步驟程序,節點位於個別 。 VPCs
  1. Cloud 外部的本機機器會將命令AWS傳送至 Amazon EKS受管 內的 Kubernetes 控制平面VPC。

  2. Amazon 會根據 Fargate 設定檔中的選取器來EKS排程 Pod。

  3. 本機機器會在瀏覽器URL中開啟 Application Load Balancer。

  4. Application Load Balancer 會分割 Fargate 叢集節點中 Kubernetes Pod 之間的流量,這些節點部署在跨越多個可用區域的私有子網路中。

工具

AWS 服務

  • Amazon Elastic Container Registry (Amazon ECR) 是安全、可擴展且可靠的受管容器映像登錄服務。

  • Amazon Elastic Kubernetes Service (Amazon EKS) 可協助您在 上執行 Kubernetes,AWS而無需安裝或維護您自己的 Kubernetes 控制平面或節點。此模式也會使用 eksctl 命令列工具,在 Amazon 上使用 Kubernetes 叢集EKS。

  • AWS Fargate 可協助您執行容器,而無需管理伺服器或 Amazon Elastic Compute Cloud (AmazonEC2) 執行個體。它與 Amazon Elastic Container Service (Amazon ) 搭配使用ECS。

  • Elastic Load Balancing (ELB) 會將傳入的應用程式或網路流量分散到多個目標。例如,您可以在一或多個可用區域中跨 Amazon Elastic Compute Cloud (AmazonEC2) 執行個體、容器和 IP 地址分配流量。此模式使用 AWS Load Balancer 控制器控制元件,在佈建 Kubernetes 輸入時建立 Application Load Balancer。Application Load Balancer 會在多個目標之間分配傳入流量。

其他工具

  • Helm 是 Kubernetes 的開放原始碼套件管理員。在此模式中,Helm 用於安裝 AWS Load Balancer 控制器。

  • Kubernetes 是一種開放原始碼系統,用於自動化容器化應用程式的部署、擴展和管理。

  • NGINX 是高效能 Web 和反向代理伺服器。

史詩

任務描述所需的技能

建立檔案。

使用其他資訊區段中的程式碼,建立下列檔案:

  • clusterconfig-fargate.yaml

  • nginx-deployment.yaml

  • nginx-service.yaml

  • nginx-ingress.yaml

  • index.html

應用程式開發人員、AWS管理員、 AWS DevOps

設定環境變數。

注意:如果命令因為先前的未完成任務而失敗,請等待幾秒鐘,然後再次執行命令。

此模式使用 檔案 中定義的AWS區域和叢集名稱clusterconfig-fargate.yaml。設定與環境變數相同的值,以便在進一步的命令中參考它們。

export AWS_REGION="us-east-1" export CLUSTER_NAME="my-fargate"
應用程式開發人員、AWS DevOps、AWS系統管理員

建立 EKS 叢集

若要建立使用 clusterconfig-fargate.yaml 檔案規格的EKS叢集,請執行下列命令。

eksctl create cluster -f clusterconfig-fargate.yaml

檔案包含 ClusterConfig,該 會在 us-east-1區域中佈建名為 的新EKS叢集,以及一個預設 Fargate 設定檔 my-fargate-clusterfp-default)。

預設 Fargate 設定檔設定有兩個選取器 (defaultkube-system)。

應用程式開發人員、AWS DevOps、AWS管理員

檢查已建立的叢集。

若要檢查建立的叢集,請執行下列命令。

eksctl get cluster --output yaml

輸出應該如下。

- Name: my-fargate Owned: "True" Region: us-east-1

使用 檢查建立的 Fargate 設定檔CLUSTER_NAME

eksctl get fargateprofile --cluster $CLUSTER_NAME --output yaml

此命令會顯示 資源的相關資訊。您可以使用資訊來驗證建立的叢集。輸出應該如下。

- name: fp-default podExecutionRoleARN: arn:aws:iam::<YOUR-ACCOUNT-ID>:role/eksctl-my-fargate-cluster-FargatePodExecutionRole-xxx selectors: - namespace: default - namespace: kube-system status: ACTIVE subnets: - subnet-aaa - subnet-bbb - subnet-ccc
應用程式開發人員、AWS DevOps、AWS系統管理員
任務描述所需的技能

部署 NGINX Web 伺服器。

若要在叢集上套用 NGINX Web 伺服器部署,請執行下列命令。

kubectl apply -f ./nginx-deployment.yaml

輸出應該如下。

deployment.apps/nginx-deployment created

部署包含三個從 Amazon ECR Public Gallery 擷取NGINX的映像複本。映像會部署到預設命名空間,並在執行中的 Pod 上的連接埠 80 上公開。

應用程式開發人員、AWS DevOps、AWS系統管理員

檢查部署和 Pod。

(選用) 檢查部署。您可以使用下列命令來驗證部署的狀態。

kubectl get deployment

輸出應該如下。

NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 7m14s

Pod 是 Kubernetes 中的可部署物件,包含一或多個容器。若要列出所有 Pod,請執行下列命令。 

kubectl get pods

輸出應該如下。

NAME READY STATUS RESTARTS AGE nginx-deployment-xxxx-aaa 1/1 Running 0 94s nginx-deployment-xxxx-bbb 1/1 Running 0 94s nginx-deployment-xxxx-ccc 1/1 Running 0 94s
應用程式開發人員、AWS DevOps、AWS管理員

擴展部署。

若要將部署從 中指定的三個複本擴展deployment.yaml為四個複本,請使用下列命令。 

kubectl scale deployment nginx-deployment --replicas 4

輸出應該如下。

deployment.apps/nginx-deployment scaled
應用程式開發人員、AWS DevOps、AWS系統管理員
任務描述所需的技能

設定環境變數。

描述叢集的 CloudFormation 堆疊,以擷取其 的相關資訊VPC。

aws cloudformation describe-stacks --stack-name eksctl-$CLUSTER_NAME-cluster --query "Stacks[0].Outputs[?OutputKey==\`VPC\`].OutputValue"

輸出應該如下。

[ "vpc-<YOUR-VPC-ID>" ]

複製 VPC ID 並將其匯出為環境變數。

export VPC_ID="vpc-<YOUR-VPC-ID>"
應用程式開發人員、AWS DevOps、AWS系統管理員

IAM 為叢集服務帳戶設定 。

使用先前史詩CLUSTER_NAME中的 AWS_REGION和 為叢集建立 IAM Open ID Connect 供應商。

eksctl utils associate-iam-oidc-provider \ --region $AWS_REGION \ --cluster $CLUSTER_NAME \ --approve
應用程式開發人員、AWS DevOps、AWS系統管理員

下載並建立IAM政策。

下載 AWS Load Balancer 控制器IAM的政策,允許其AWSAPIs代表您呼叫 。

curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json

使用 AWS 在AWS帳戶中建立政策CLI。

aws iam create-policy \ --policy-name AWSLoadBalancerControllerIAMPolicy \ --policy-document file://iam-policy.json

您應該會看到下列輸出。

{ "Policy": { "PolicyName": "AWSLoadBalancerControllerIAMPolicy", "PolicyId": "<YOUR_POLICY_ID>", "Arn": "arn:aws:iam::<YOUR-ACCOUNT-ID>:policy/AWSLoadBalancerControllerIAMPolicy", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 0, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "CreateDate": "<YOUR-DATE>", "UpdateDate": "<YOUR-DATE>" } }

將政策的 Amazon Resource Name (ARN) 儲存為 $POLICY_ARN

export POLICY_ARN=”arn:aws:iam::<YOUR-ACCOUNT-ID>:policy/AWSLoadBalancerControllerIAMPolicy”
應用程式開發人員、AWS DevOps、AWS系統管理員

建立IAM服務帳戶。

kube-system命名空間aws-load-balancer-controller中建立名為 IAM的服務帳戶。使用POLICY_ARN您先前設定的 AWS_REGIONCLUSTER_NAME和 。

eksctl create iamserviceaccount \ --cluster=$CLUSTER_NAME \ --region=$AWS_REGION \ --attach-policy-arn=$POLICY_ARN \ --namespace=kube-system \ --name=aws-load-balancer-controller \ --override-existing-serviceaccounts \ --approve

驗證建立。

eksctl get iamserviceaccount \ --cluster $CLUSTER_NAME \ --name aws-load-balancer-controller \ --namespace kube-system \ --output yaml

輸出應該如下。

- metadata: name: aws-load-balancer-controller namespace: kube-system status: roleARN: arn:aws:iam::<YOUR-ACCOUNT-ID>:role/eksctl-my-fargate-addon-iamserviceaccount-ku-Role1-<YOUR-ROLE-ID> wellKnownPolicies: autoScaler: false awsLoadBalancerController: false certManager: false ebsCSIController: false efsCSIController: false externalDNS: false imageBuilder: false
應用程式開發人員、AWS DevOps、AWS系統管理員

安裝 AWS Load Balancer 控制器。

更新 Helm 儲存庫。

helm repo update

將 Amazon EKS圖表儲存庫新增至 Helm 儲存庫。 

helm repo add eks https://aws.github.io/eks-charts

套用 Kubernetes 自訂資源定義 (CRDs),供背景中的 AWS Load Balancer Controller eks-chart 使用。

kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"

輸出應該如下。

customresourcedefinition.apiextensions.k8s.io/ingressclassparams.elbv2.k8s.aws created customresourcedefinition.apiextensions.k8s.io/targetgroupbindings.elbv2.k8s.aws created

使用您先前設定的環境變數,安裝 Helm Chart。

helm install aws-load-balancer-controller eks/aws-load-balancer-controller \ --set clusterName=$CLUSTER_NAME \ --set serviceAccount.create=false \ --set region=$AWS_REGION \ --set vpcId=$VPC_ID \ --set serviceAccount.name=aws-load-balancer-controller \ -n kube-system

輸出應該如下。

NAME: aws-load-balancer-controller LAST DEPLOYED: <YOUR-DATE> NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: AWS Load Balancer controller installed!
應用程式開發人員、AWS DevOps、AWS系統管理員

建立 NGINX 服務。

使用 nginx-service.yaml 檔案建立 服務以公開 NGINX Pod。

kubectl apply -f nginx-service.yaml

輸出應該如下。

service/nginx-service created
應用程式開發人員、AWS DevOps、AWS系統管理員

建立 Kubernetes 輸入資源。

使用 nginx-ingress.yaml 檔案建立 服務以公開 Kubernetes NGINX 輸入。

kubectl apply -f nginx-ingress.yaml

輸出應該如下。

ingress.networking.k8s.io/nginx-ingress created
應用程式開發人員、AWS DevOps、AWS系統管理員

取得負載平衡器 URL。

若要擷取輸入資訊,請使用下列命令。

kubectl get ingress nginx-ingress

輸出應該如下。

NAME CLASS HOSTS ADDRESS PORTS AGE nginx-ingress <none> * k8s-default-nginxing-xxx.us-east-1.elb.amazonaws.com 80 80s

從輸出複製 ADDRESS(例如 k8s-default-nginxing-xxx.us-east-1.elb.amazonaws.com),並將其貼到瀏覽器以存取 index.html 檔案。

應用程式開發人員、AWS DevOps、AWS系統管理員
任務描述所需的技能

選取 Pod。

列出所有 Pod,並複製所需的 Pod 名稱。 

kubectl get pods

輸出應該如下。

NAME READY STATUS RESTARTS AGE nginx-deployment-xxxx-aaa 1/1 Running 0 55m nginx-deployment-xxxx-bbb 1/1 Running 0 55m nginx-deployment-xxxx-ccc 1/1 Running 0 55m nginx-deployment-xxxx-ddd 1/1 Running 0 42m

此命令會列出現有的 Pod 和其他資訊。

如果您對特定 Pod 感興趣,請填寫您感興趣的 POD_NAME Pod 名稱,或將其設定為環境變數。否則,請省略此參數來查詢所有資源。

export POD_NAME="nginx-deployment-<YOUR-POD-NAME>"
應用程式開發人員、AWS DevOps、AWS系統管理員

存取日誌。

從您要偵錯的 Pod 取得日誌。

kubectl logs $POD_NAME
應用程式開發人員、AWS系統管理員 AWS DevOps

轉送NGINX連接埠。

使用連接埠轉送將 Pod 的連接埠映射至本機機器上的連接埠,以存取 NGINX Web 伺服器。

kubectl port-forward deployment/nginx-deployment 8080:80

在瀏覽器中開啟下列 URL。

http://localhost:8080

port-forward 命令提供對 index.html 檔案的存取,而不會讓檔案透過負載平衡器公開提供。這對於在除錯時存取執行中的應用程式很有用。您可以按下鍵盤命令 Ctrl+C 來停止連接埠轉送。

應用程式開發人員、AWS DevOps、AWS系統管理員

在 Pod 中執行命令。

若要查看目前的index.html檔案,請使用下列命令。 

kubectl exec $POD_NAME -- cat /usr/share/nginx/html/index.html

您可以使用 exec命令直接在 Pod 中發出任何命令。這對於偵錯執行中的應用程式很有用。

應用程式開發人員、AWS DevOps、AWS系統管理員

將檔案複製到 Pod。

移除此 Pod 上的預設index.html檔案。

kubectl exec $POD_NAME -- rm /usr/share/nginx/html/index.html

將自訂本機檔案上傳至 index.html Pod。

kubectl cp index.html $POD_NAME:/usr/share/nginx/html/

您可以使用 cp命令直接變更或新增檔案至任何 Pod。

應用程式開發人員、AWS DevOps、AWS系統管理員

使用連接埠轉送來顯示變更。

使用連接埠轉送來驗證您對此 Pod 所做的變更。

kubectl port-forward pod/$POD_NAME 8080:80

在瀏覽器URL中開啟下列項目。

http://localhost:8080

套用index.html的檔案變更應該會顯示在瀏覽器中。

應用程式開發人員、AWS DevOps、AWS系統管理員
任務描述所需的技能

刪除負載平衡器。

刪除輸入。

kubectl delete ingress/nginx-ingress

輸出應該如下。

ingress.networking.k8s.io "nginx-ingress" deleted

刪除服務。

kubectl delete service/nginx-service

輸出應該如下。

service "nginx-service" deleted

刪除負載平衡器控制器。

helm delete aws-load-balancer-controller -n kube-system

輸出應該如下。

release "aws-load-balancer-controller" uninstalled

刪除服務帳戶。

eksctl delete iamserviceaccount --cluster $CLUSTER_NAME --namespace kube-system --name aws-load-balancer-controller
應用程式開發人員、AWS DevOps、AWS系統管理員

刪除部署。

若要刪除部署資源,請使用下列命令。

kubectl delete deploy/nginx-deployment

輸出應該如下。

deployment.apps "nginx-deployment" deleted
應用程式開發人員、AWS DevOps、AWS系統管理員

刪除叢集。

使用下列命令刪除EKS叢集,其中 my-fargate是叢集名稱。

eksctl delete cluster --name $CLUSTER_NAME

此命令會刪除整個叢集,包括所有相關資源。

應用程式開發人員、AWS DevOps、AWS系統管理員

刪除IAM政策。

使用 AWS 刪除先前建立的政策CLI。

aws iam delete-policy --policy-arn $POLICY_ARN
應用程式開發人員、AWS管理員、 AWS DevOps

故障診斷

問題解決方案

建立叢集時,您會收到錯誤訊息,指出目標可用區域沒有足夠的容量來支援叢集。您應該會看到類似下列的訊息。

Cannot create cluster 'my-fargate' because us-east-1e, the targeted availability zone, does not currently have sufficient capacity to support the cluster. Retry and choose from these availability zones: us-east-1a, us-east-1b, us-east-1c, us-east-1d, us-east-1f

使用錯誤訊息中建議的可用區域再次建立叢集。指定clusterconfig-fargate.yaml檔案最後一行中的可用區域清單 (例如 availabilityZones: ["us-east-1a", "us-east-1b", "us-east-1c"])。

相關資源

其他資訊

clusterconfig-fargate.yaml

apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: my-fargate region: us-east-1 fargateProfiles: - name: fp-default selectors: - namespace: default - namespace: kube-system

nginx-deployment.yaml

apiVersion: apps/v1 kind: Deployment metadata: name: "nginx-deployment" namespace: "default" spec: replicas: 3 selector: matchLabels: app: "nginx" template: metadata: labels: app: "nginx" spec: containers: - name: nginx image: public.ecr.aws/nginx/nginx:latest ports: - containerPort: 80

nginx-service.yaml

apiVersion: v1 kind: Service metadata: annotations: alb.ingress.kubernetes.io/target-type: ip name: "nginx-service" namespace: "default" spec: ports: - port: 80 targetPort: 80 protocol: TCP type: NodePort selector: app: "nginx"

nginx-ingress.yaml

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: namespace: "default" name: "nginx-ingress" annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing spec: rules: - http: paths: - path: / pathType: Prefix backend: service: name: "nginx-service" port: number: 80

index.html

<!DOCTYPE html> <html> <body> <h1>Welcome to your customized nginx!</h1> <p>You modified the file on this running pod</p> </body> </html>