昨天介紹完了 Cluster 今天來介紹如何使用 CDK 建立 EKS Service 往常我們如果使用 kubectl 要新增服務或是控制都會需要用到 yaml 檔案,但今天我們使用 CDK 部署 EKS 不用使用到 yaml,那我們要怎麼控制 Kubernetes(K8S)呢? 我們用 typescript 寫 CDK 當然就是直接寫 JSON 拉!是不是很神奇呢?快點跟著我看下去吧!
部署目標
在部署前我們先整理一下這次目標需要什麼
- 部署一個服務名稱:hello-kubernetes
- replicas 設定為:3
- Docker Image 使用:paulbouwer/hello-kubernetes:1.5
- Container 內部 port 為:8080
- 設定一個 LoadBalancer 外部 port 為 80 對接內部的 hello-kubernetes 服務
部署 EKS Service
定義 Deployment
整理好後我們先設定 Deployment 以部署 Kubernetes(K8S)的 YAML 來說,我們要處理 Container 名稱、數量、內部 Port
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes
spec:
replicas: 3
selector:
matchLabels: hello-kubernetes
template:
metadata:
labels: hello-kubernetes
spec:
containers:
- name: hello-kubernetes
image: 'paulbouwer/hello-kubernetes:1.5'
ports:
- containerPort: 8080
但我們說過我們這次的部署不需要 YAML 所以我們直接使用 TypeScript 來寫
const appLabel = { app: "hello-kubernetes" };
const deployment = {
apiVersion: "apps/v1",
kind: "Deployment",
metadata: { name: "hello-kubernetes" },
spec: {
replicas: 3,
selector: { matchLabels: appLabel },
template: {
metadata: { labels: appLabel },
spec: {
containers: [
{
name: "hello-kubernetes",
image: "paulbouwer/hello-kubernetes:1.5",
ports: [{ containerPort: 8080 }],
},
],
},
},
},
};
Deployment 部署方法可以參考 kubernetes Documentation
定義 Service
而在部署 Kubernetes(K8S)的 Service YAML,需要處理 LoadBalancer 外部 port 與內部 Service 的對應
apiVersion: v1
kind: Service
metadata:
name: hello-kubernetes
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector: hello-kubernetes
想好後轉換成 TypeScript 的程式
const service = {
apiVersion: "v1",
kind: "Service",
metadata: { name: "hello-kubernetes" },
spec: {
type: "LoadBalancer",
ports: [{ port: 80, targetPort: 8080 }],
selector: appLabel,
},
};
Service 部署方法可以參考 kubernetes Documentation
設定 Manifest
往常使用 Kubernetes(K8S)我們需要使用 kubectl apply -f hello-kubernetes.yaml
而在 CDK 我們可以直接使用 addManifest
塞入 cluster 就做完了!
cluster.addManifest("mypod", service, deployment);
顯示 Load Balancer
在使用 Kubernetes(K8S 需要使用 kubectl get rc,services
取得我們 Service 的位置,那使用 CDK 可以直接讓它在部署的時候用 Output 直接吐出來!從此可以不用再使用 kubectl 拉!ヽ(✿゚▽゚)ノ
new cdk.CfnOutput(this, "LoadBalancer", {
value: cluster.getServiceLoadBalancerAddress("hello-kubernetes"),
});
測試
說了這麼多我們來部署測試看看吧!雖然上面說我們不需要用到 kubectl
不過我們還是需要用它來進行測試確定系統有沒有如所想的部署執行一下 cdk deploy
等它 15 ~ 30 分鐘吧! ( • ̀ω•́ )
執行完後的 Output:
Outputs:
CdkEksStack.LoadBalancer = aba304eea204b4239abb905439ac8ec7-1947016485.us-west-2.elb.amazonaws.com
CdkEksStack.eksConfigCommandDB09280A = aws eks update-kubeconfig --name eksB49B8EA3-7fcd6a64ed934f00ae43ec1cb67a87fa --region us-west-2 --role-arn arn:aws:iam::869989823608:role/CdkEksStack-mastersRole634808EE-1I504Q4EPLS70
CdkEksStack.eksGetTokenCommand8952195F = aws eks get-token --cluster-name eksB49B8EA3-7fcd6a64ed934f00ae43ec1cb67a87fa --region us-west-2 --role-arn arn:aws:iam::869989823608:role/CdkEksStack-mastersRole634808EE-1I504Q4EPLS70
AWS Console 的 Load balancer
可以看到在 AWS Load balancer 建立了一個 classic 的服務而他的 DNS 如上面的 CDK Output
而在 Instances 可以看到我們的 Cluster 機器確實註冊在這個 Load balancer 後面
Tags 可以看到有些設定被定義
查看 Kubernetes replicas 數量
可以使用 kubectl get pods
看到我們的 replicas 確實有設定為 3
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-kubernetes-5655b546f8-cm66l 1/1 Running 0 49m
hello-kubernetes-5655b546f8-l8xkj 1/1 Running 0 49m
hello-kubernetes-5655b546f8-msjh6 1/1 Running 0 49m
mypod 1/1 Running 0 97m
查看 Kubernetes Services 的部署狀態
使用 kubectl get rc,services
查看我們的 Load Balancer 確實也與 AWS Console 顯示的一樣
$ kubectl get rc,services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/hello-kubernetes LoadBalancer 172.20.200.52 aba304eea204b4239abb905439ac8ec7-1947016485.us-west-2.elb.amazonaws.com 80:30139/TCP 35m
service/kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 3h35m
瀏覽一下 Kubernetes 部署的網頁
瀏覽一下剛剛部署的 LoadBalancer 可以看到我們的 pod id 每次都不一樣,如剛剛部署的 replicas 數量會有三個輪流吃到我們的 request
查看 pod log
雖然我們這邊主要不是介紹 Kubernetes 不過順便提一下如果想要看到 pod 的 log 可以使用 kubectl logs
帶上 id 查看 Log
$ kubectl logs hello-kubernetes-5655b546f8-cm66l
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
npm info lifecycle [email protected]~prestart: [email protected]
npm info lifecycle [email protected]~start: [email protected]
> [email protected] start /usr/src/app
> node server.js
Listening on: http://hello-kubernetes-5655b546f8-cm66l:8080
::ffff:10.0.255.11 - - [09/Oct/2020:11:17:29 +0000] "GET / HTTP/1.1" 200 667 "-" "curl/7.64.1"
::ffff:10.0.255.11 - - [09/Oct/2020:11:17:40 +0000] "GET /favicon.ico HTTP/1.1" 404 150 "http://aba304eea204b4239abb905439ac8ec7-1947016485.us-west-2.elb.amazonaws.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36"
今天介紹 CDK 可以神奇的處理很多原本要用 kubectl
才可以處理的事情是不是超神奇的啊!!!
《AWS CDK 完全學習手冊:打造雲端基礎架構程式碼 IaC》
第 12 屆 iT 邦幫忙鐵人賽 DevOps 組冠的《用 CDK 定 義 AWS 架構》
第 11 屆 iT 邦幫忙鐵人賽《LINE bot 好好玩 30 天玩轉 LINE API》
一個熱愛分享的雲端工程師!