[EKS] 於AWS建立Kubernetes 原生叢集 | Building Amazon EKS

1. 部署機EC2 安裝相關工具

要部署完整的EKS,需要整合一些相關工具集來滿足,其中動作包含

而各別對應的工具直接寫在後面

  • 操作AWS operation → awscli
  • 建立EKS → eksctl
  • 以及操控Kubernetes → kubectl

step1. kubectl

  • Kubernetes 使用名為kubectl 的命令列公用程式與叢集API 伺服器通訊(master node)
1
#1 download kubectl tool
2
3
sudo curl --location -o /usr/local/bin/kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.16.8/2020-04-16/bin/linux/amd64/kubectl
4
5
#2 使kubectl 成為可以執行檔
6
sudo chmod +x /usr/local/bin/kubectl
7
8
#3 確認kubectl 已正確安裝
9
kubectl version --short --client

安裝訊息以及測試kubectl是否成功

Untitled.png

step2. eksctl

  • Amazon EKS 世界中可以快速操控Kubernetes 叢集,eksctl 命令列公用程式提供最快且最簡單的方式,讓您使用的節點建立新的叢集Amazon EKS
1
curl --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
2
3
#2
4
sudo mv -v /tmp/eksctl /usr/local/bin
5
6
#3
7
eksctl version

安裝結束訊息以及測試eksctl是否成功

Untitled1.png

以上的部驟皆是前置作業,我們準好了操作AWS operation 的awscli,建立EKS 的 eksctl,以及操控Kubernetes 的 kubectl


2. 部署 AWS EKS cluster

step1. 透過eksctl 部署EKS 叢集

  • EKS 是很彈性的,你可以建立正規的3台EC2為基底的EKS,你也可以建立1台的EC2的EKS

參數說明

  • -name 可讓您指定 Amazon EKS 叢集的名稱
  • -nodegroup-name 可讓您指定 Amazon EKS 節點群組的名稱
  • `-node-type` 指定工作者節點使用的執行個體類型,而完整的EC2支援清單請見awslabs/amazon-eks-ami[1]
  • -nodes 指定在所需的自動調整規模定義期間部署的節點數目
  • -nodes-min針對節點群組設定 Amazon EC2 Autoscaling 組態中的節點數目下限
  • -nodes-max針對節點群組設定 Amazon EC2 Autoscaling 組態中的節點數目上限
  • -managed 建立 Amazon EKS 受管節點群組
  • -version 指定要在 Amazon EKS 叢集上部署哪個版本的 Kubernetes
  • -region 指定要部署 Amazon EKS 叢集和節點群組的 AWS 區域。如果未包含arg旗標資訊,eksctl 公用程式會預設為 us-west-2 區域
1
2
#1 EKS with 3 nodes
3
export AWS_REGION=us-west-2
4
5
eksctl create cluster \
6
--name dev-cluster \
7
--nodegroup-name dev-nodes \
8
--node-type t3.small \
9
--nodes 3 \
10
--nodes-min 1 \
11
--nodes-max 4 \
12
--managed \
13
--version 1.16 \
14
--region ${AWS_REGION}
15
16
# Thin cluster with EKS
17
18
eksctl create cluster \
19
    --name dev-cluster \
20
    --nodegroup-name dev-nodes \
21
    --node-type t3.micro \
22
    --nodes 1 \
23
    --managed \
24
    --version 1.16 \
25
    --region ap-southeast-1

命令執行i 會在你的本機下 ~/.kube/config 建立組態檔案,也稱為 kubeconfig。kubeconfig 包含有關 Amazon EKS 叢集的詳細資訊,包括叢集名稱身分驗證方法

建立叢集的 IAM 角色或使用者會自動新增到 Kubernetes RBAC 組態中的 system:masters 群組,使其成為 Kubernetes 叢集的全權管理員。在授與其他許可之前,它也是唯一可以存取叢集的角色或使用者。本此實驗中,EC2堡壘主機擔任的 IAM 角色就是建立叢集的角色,所以我們把system:masters綁給K8s RBAC

部署觀察

時間

  • 開始時間07-39 → 結束時間08:00 一共花費 21分鐘

  • *官方說明叢集花費時間為15 - 20分鐘,依我自已的經驗不論是1個node或是3個node都要花費走過15分鐘

    • 1個node ECS 共花費 17分鐘

    • 3個node ECS 共花費 21分鐘

      Untitled2.png

參數執行

  • 其中3個node, EC2 平均分散在us-west-2a, us-west-2b, us-west-2c,此舉協助EKS提高HA保護
  • 每一個node 中都會使用一對網路,分別為public subnet, private subnet
  • 接下來透過CloudFormation幫忙設定K8s和 instance group
  • 透過AWS 代管的EKS Control Plane,也在此生成Kubernetes API Endpoint供你的worker node 管理,直到三個node 安裝所有kuberntes stack套件
  • 部署的尾聲 eksctl 會協助建立新的kubeconfig,它一個kubernetes登入檔,位置在 /home/ssm-user/.kube/config
  • 最後你可以用kubectl get nodes 來確認EKS 狀態

Untitled3.png

step2. 測試EKS cluster

  • 透過 kubectl get nodes 來確認EKS, 底層EC2 worker node狀態
1
kubectl get nodes

Untitled4.png

透過UI 檢視底層EC2 worker node狀態

Untitled5.png

Untitled6.png


#1 測試:部署Application to EKS from ECR

Amazon Elastic Container Registry (ECR) 是一個全受管的Docker 容器登錄檔,可讓開發人員輕鬆存放、管理以及部署Docker 容器映像。

step1. Image URI

Untitled7.png

step2. kubectl run

  • 最直接的測試方試就是使用kubectl run 指定你的docker image位置,也就是上面所述的 image URI
1
kubectl run demo-aws --image=[199679544872.dkr.ecr.ap-southeast-1.amazonaws.com/demo-aws](http://199679544872.dkr.ecr.ap-southeast-1.amazonaws.com/demo-aws)

Untitled8.png

step3. 透過AWS Load Balance 對外公開服務

  • 預設的kubernetes 生起service endpoint,只能是對內的服務更白話的說,就是只能在叢集內溝通。我們可以透過kubectl expose 結合AWS Load Balance 對外公開服務,指令可以自動配對Classic Load Balancer
  • 或許你會好奇,為什麼AWS可以如何簡單介接到AWS Load Balance?因為,EKS為代管的control plane,它本身就是API Endpoint,而AWS EKS在你一開始做授權的動作時,就可以讓EKS可以跟你的NLB溝通
  • 當然你的service,若是L7層級的,你也可以交換Load balance種類為ALB[7]
1
2
kubectl expose pod demo-aws --type=LoadBalancer --name=demo-aws-service --port 80
3
4
#Exposed:
5
[http://a84693be9eb304dd1bb31dad9ab07e73-1331634835.ap-southeast-1.elb.amazonaws.com/](http://a84693be9eb304dd1bb31dad9ab07e73-1331634835.ap-southeast-1.elb.amazonaws.com/)

執行結果,並產生URL

Untitled9.png

step4. 驗證 demo-aws 網頁內容

  • 上面部驟準備的docker image是封裝 node.js 網頁服務
  • 因此,你可以在網頁上看到 “Hello World” 文字

Untitled10.png

網路相關設定

Load Balancer 設計

  • 透過kubectl expose 產生的URL後,他會對應到在ap-southeast backend 的三台instance
  • 你必須確定backend它們的status為InService,以及Heathly 為Yes,代表為load balance的分流路徑走向是正確的
  • 筆者在之前實驗中,使用1個node EKS,造成Instance ID status 為OutofService,此情形即使LB 產生URL,但你依究無法讓request 導入backend

Untitled11.png

EKS VPC 設計

Untitled12.png

eksctl 建立時 EKS時,每一個node 中都會使用一對網路,分別為public subnet, private subnet,因此預設會建立一個新的 VPC,其中包含

  • 三個公有(public)子網路和三個新的私有(private)子網路
  • 所以你能在EKS Networking看到Subnets 出現6組subnet

Untitled13.png


#2 測試:部署Application to EKS by yaml

Untitled12.png

step1. 取得workload, service sample

  • 從git 取得workload, service sample code
1
cd ~
2
3
git clone https://github.com/brentley/ecsdemo-frontend.git
4
git clone https://github.com/brentley/ecsdemo-nodejs.git
5
git clone https://github.com/brentley/ecsdemo-crystal.git

查看deployment,並且部署至EKS

1
cd ~/ecsdemo-nodejs
2
3
cat kubernetes/deployment.yaml

step2. 檢視 deployment workload

其中deployment yaml 中有以下資訊

  • metadata: 部署一個名個 ecsdemo-node.js
  • replicas: 僅運行一個pod
  • container image: 來從node.js:latest 一個網頁的docker

Untitled14.png

step3. 部署deployment, service

  • 執行 kubectl apply 對deployment.yaml 定義的workload 進行部署
  • 同時也對service.yaml 定義的endpoint 產生URL
1
kubectl apply -f kubernetes/deployment.yaml
2
kubectl apply -f kubernetes/service.yaml
3
4
kubectl get deployment ecsdemo-nodejs
5
kubectl get services

執行結果

Untitled15.png

step1. crystal 服務

  • 另一隻名為crystal服務,我們必須切換至正確對應的目錄(ecsdemo-crystal)
1
cd ~/ecsdemo-crystal
2
3
cat kubernetes/deployment.yaml

其中deployment yaml 中有以下資訊

  • metadata: 部署一個名個 ecsdemo-crystal
  • replicas: 僅運行一個pod
  • container image: ecsdemo-crystal
  • container port: REST API 對外埠為TCP 3000

Untitled16.png

step2. 部署deployment, service

  • 執行 kubectl apply 對deployment.yaml 定義的workload 進行部署
  • 同時也對service.yaml 定義的endpoint 產生URL
  • deployment產生的workload 有時不會即時產出,你可以觀察deploy READY 狀態是否為 1/1
1
kubectl apply -f kubernetes/deployment.yaml
2
kubectl apply -f kubernetes/service.yaml
3
4
# 監控部署進度,並確認其成功完成
5
kubectl get deployment ecsdemo-crystal

執行結果

Untitled17.png

step3. 部署 ecsdemo-frontend

  • 前端使用的是Ruby
  • 檢視一下 frontend yaml
1
cd ~/ecsdemo-frontend
2
3
cat kubernetes/deployment.yaml

其中deployment yaml 中有以下資訊

  • metadata: 部署一個名個 ecsdemo-frontend
  • replicas: 僅運行一個pod
  • container port: REST API 對外埠為TCP 3000
  • env: 定義二個環境變數,告知crystal_URL, ecsdemo-node.js 關系服務URL
    • ecsdemo-crystal.default.svc.cluster.local/crystal
    • ecsdemo-nodejs.default.svc.cluster.local

Untitled18.png

其中service yaml 中有以下資訊

  • metadata: 部署一個名個 ecsdemo-frontend service
  • label: 篩選條件為 key-value = app:frontend
  • expose service type: Load Balancer

檢視service.yaml 內容

Untitled19.png

step4. 部署ecsdemo workload, services

1
kubectl apply -f kubernetes/deployment.yaml
2
kubectl apply -f kubernetes/service.yaml
3
4
kubectl get deployment ecsdemo-frontend
5
kubectl get service ecsdemo-frontend

執行結果

  • 正常的service 執行結果會一組聯合 AWS LB產生出的endpoint,它的值組成.elb.amazonaws.com結尾的DNS 名稱
  • 請用產生的endpoint a2ae2a36089184………….us-west-2.elb.amazonaws.com 進行連線測試

*Load balance可能需要幾分鐘才能開始將流量傳送至前端

Untitled20.png

Load Balancer 產生的設定

  • 檢視的load balance type 為 Classic,為我自轉換L4 內容
  • 此load balance背後服務的特定VPC ID,服務的區域為特定的regional us-west-2a /b /c

Untitled21.png

  • 這邊顯示的instances,代表的就是EKS的底層三台workload ECS

Untitled22.png

step5. 確認所有的workload, service

  • 透過kubectl get service 取得所以上述部署的services
1
kubectl get deployments
2
3
kubectl get service ecsdemo-frontend -o wide

你格以看到所有的services endpoint一共會有三組,分別為

  • ecsdemo-crystal
  • ecsdemo-frontend
  • ecsdemo-nodjs

Untitled23.png

於瀏灠器檢視 DNS Endpoiont

  • 可以正常顯示網頁內容

Untitled24.png


References

[1] awslabs/amazon-eks-ami

[2] https://www.eksworkshop.com/

[3] AWS Documentation whole products

[4] AWS Global Infrastructure

[5] Find the hands-on tutorials for your AWS needs

[6] Amazon Lightsail

[7] Network load balancing on Amazon EKS