Horizontal Pod Autoscaling & Vertical Pod Autoscaling
ကျွန်တော်ဒီနေ့ ရေးမယ့်အကြောင်းအရာကတော့ kubernetes ပေါ်မှာရှိတဲ့ pod တွေကို autoscaling လုပ်နည်းပဲဖြစ်ပါတယ်။ ကျွန်တော်တို့ production အတွက် deployment တွေ လုပ်တဲ့အခါ pod template ထဲမှာ resources အ တွက် cpu နဲ့ memory တွေကို request ၊ limit ပမာဏတွေသတ်မှတ်ပေးပြီး resource quota တွေကိုကန့်သတ်ပေးထားပါတယ်။ အဲ့ဒီအခါမှသာ pod တစ်ခုထဲက node ရဲ့ cpu memory resource တွေကို သူတစ်ခုထဲအတွက် သုံးတာကို ကာကွယ်နိုင်ပါမယ်။ pod တွေ deployment တွေ create တဲ့အခါ quota မှာ request ဆိုတာက သတ်မှတ်ထားတဲ့ amount ကိုပေးနိုင်တဲ့ node အပေါ်မှာသာ pod တွေကို deploy လုပ်ပေးမှာဖြစ်ပြီး limit က အဲ့ amount အထိသာ pod အတွက် resource ကိုပေးသုံးမှာဖြစ်ပါတယ်။
Prequities
kubernetes cluster
Prepare A Kubernetes Cluster
autoscaling တွေစမ်းဖို့အတွက် kubernetes cluster တစ်ခု create ပေးရပါမယ်။ ကျွန်တော်ကတော့ aks cluster တစ်ခု create လုပ်လိုက်ပါမယ်။
az group create --name kube --location eastus
az aks create --name demo -g kube --location eastus --node-count 2
az aks get-credentials --name demo -g kube
ပြီးသွားရင်တော့ kubectl get nodes နဲ့ကြည့်လိုက်ပါမယ်။ node တွေ ready ဖြစ်နေရင် autoscaling အကြောင်းကို စစမ်းလို့ရပါပြီ။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
aks-nodepool1-23943392-vmss000000 Ready agent 100s v1.19.11
aks-nodepool1-23943392-vmss000001 Ready agent 99s v1.19.11
Horizontal Pod Autoscaling
HPA ဆိုတာက pod တွေရဲ့ replicas အရေအတွက်ကို autoscale လုပ်ပေးတာဖြစ်ပါတယ်။ ကျွန်တော်တို့သတ်မှတ်ခဲ့တဲ့ resource quota ရဲ့ request cpu ၊ memory utilization တွေအပေါ်မူတည်ပြီး pods တွေကို scale in ၊ scale out လုပ်ပေးတာဖြစ်ပါတယ်။ အရင်ဆုံး pod တွေ nodes တွေရဲ့ resource utilization ကိုသိဖို့ဆို metric-server ကို deploy လုပ်ပေးရပါမယ်။ aks မှာတော့ default သွင်းထားပြီးသားဖြစ်ပါတယ်။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system azure-ip-masq-agent-7rhvx 1/1 Running 0 12m
kube-system azure-ip-masq-agent-xjcsb 1/1 Running 0 12m
kube-system coredns-76c97c8599-fgqfj 1/1 Running 0 12m
kube-system coredns-76c97c8599-qr92j 1/1 Running 0 13m
kube-system coredns-autoscaler-599949fd86-45twt 1/1 Running 0 13m
kube-system kube-proxy-ljdnx 1/1 Running 0 12m
kube-system kube-proxy-wp6b7 1/1 Running 0 12m
kube-system metrics-server-77c8679d7d-vk8n8 1/1 Running 0 13m
kube-system tunnelfront-544cd5b988-cshrh 1/1 Running 0 13m
HPA ကို စမ်းဖို့ဆို autoscale လုပ်ချင်တဲ့ deployment ကို resource quota တွေသတ်မှတ်ပေးဖို့လိုပါတယ်။ ပထမဆုံးအနေနဲ့ demo ဆိုတော့ nginx deployment တစ်ခုနဲ့ပဲစမ်းကြည့်ကြမယ်။ ဘာ deployment မှမလုပ်ခင် nodes တွေရဲ့ cpu memory usage ပဲဖြစ်ပါတယ်။
thaunghtikeoo@thaunghtikeoo:~$ kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
aks-nodepool1-23943392-vmss000000 50m 2% 673Mi 14%
aks-nodepool1-23943392-vmss000001 129m 6% 651Mi 14%
nginx deployment တစ်ခုကို create ပါမယ်။ cpu 250m ကို request ထားပြီး 500m အထိ limit ပေးထားပါတယ်။ ပြီးရင် kubectl create နဲ့ deployment ကို create လိုက်ပါ။
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
run: nginx
name: nginx
spec:
replicas: 1
selector:
matchLabels:
run: nginx
template:
metadata:
labels:
run: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
resources:
requests:
cpu: 250m
limits:
cpu: 500m
ပြီးရင်တော့ default namespace မှာ nginx deployment တစ်ခု run နေတာကိုတွေ့ရမှာဖြစ်ပါတယ်။
haunghtikeoo@thaunghtikeoo:~$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/nginx-fdb6cfbc5-fwggl 1/1 Running 0 32s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 29m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx 1/1 1 1 33s
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-fdb6cfbc5 1 1 1 34s
အခုချိန်မှာ pod ရဲ့ cpu usage က 0% ဖြစ်နေပါတယ်။ ဒါဆိုအခု hpa ကိုစစမ်းကြည့်ပါမယ်။ အောက်က yaml file ကိုကြည့်ပါ။ request ထားတဲ့ 250m ရဲ့ 50% အထိ pod က cpu utilization တက်လာတဲ့အခါ pod ကို maximum 5 ခုအထိ scale out လုပ်မှာဖြစ်ပြီး cpu usage ပြန်ကျသွားရင်တော့ minimun 1 ခုအဖြစ်ပြန် scale in လုပ်လိုက်မှာဖြစ်ပါတယ်။
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: nginx
spec:
maxReplicas: 5
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx
targetCPUUtilizationPercentage: 50
kubectl apply နဲ့ create လိုက်ပါမယ်။ အခုချိန်မှာ cpu က သုညပဲဖြစ်နေပါသေးတယ်။ kubectl cmd နဲ့ လည်း hpa ကို အောက်ပါအတိုင်း create နိုင်ပါသေးတယ်။
kubectl autoscale deployment nginx --cpu-percent=50 --min=1 --max=5
thaunghtikeoo@thaunghtikeoo:~$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 0%/50% 1 5 1 2m44s
ကျွန်တော်တို့ nginx service ကို အပြင်ကခေါ်လို့ရအောင် loadbalancer အနေနဲ့ expose လိုက်ပါမယ်။
kubectl expose deploy nginx --type LoadBalancer --target-port 80 --port 80
thaunghtikeoo@thaunghtikeoo:~$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 40m
nginx LoadBalancer 10.0.36.206 20.72.185.88 80:31934/TCP 7s
ပြီးသွားရင်တော့ cpu overload ဖြစ်အောင် test ဖို့အတွက် siege tool ကို install ပေးရပါမယ်။
apt update -y && apt install siege -y
ဒါဆိုရင်ကျွန်တော်တို့ nginx deployment က pods တွေကို cpu usage တက်လာအောင် အောက်ကအတိုင်းစမ်းပါမယ်။ nginx service url ကို 2 minute အထိ cpu တက်အောင်လုပ်လိုက်ပါမယ်။
siege -q -c 5 -t 2m 20.72.185.88
ခဏကြာတော့ cpu load ဖြစ်လာပြီး hpa မှာ percent တွေတက်လာပြီး replicas တွေ scale out ဖြစ်လာပါပြီ။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
nginx Deployment/nginx 110%/50% 1 5 4 2m14s
အသစ်ထွက်လာတဲ့ pods တွေကလည်းတစ်ခုပြီး တစ်ခု CPU usage တွေတက်လာပြီး နောက်ဆုံးမှာ maximum သတ်မှတ်ခဲ့တဲ့ 5 ခုအထိ တိုးသွားပါတယ်။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-fdb6cfbc5-2dvxg 1/1 Running 0 6m55s
nginx-fdb6cfbc5-9cjn7 1/1 Running 0 16s
nginx-fdb6cfbc5-h8h85 1/1 Running 0 16s
nginx-fdb6cfbc5-lmfdw 1/1 Running 0 16s
nginx-fdb6cfbc5-8cvtq 1/1 Running 0 16s
thaunghtikeoo@thaunghtikeoo:~$ kubectl top pods
NAME CPU(cores) MEMORY(bytes)
nginx-fdb6cfbc5-2dvxg 178m 11Mi
nginx-fdb6cfbc5-8cvtq 180m 9Mi
nginx-fdb6cfbc5-9cjn7 177m 10Mi
nginx-fdb6cfbc5-h8h85 169m 9Mi
nginx-fdb6cfbc5-lmfdw 180m 10Mi
၂ မိနစ်ပြည့်တဲ့အခါ siege ကအချိန်ပြည့်သွားပြီး cpu loading ကို ရပ်လိုက်ပါတယ်။ အောက်မှာကြည့်ကြည့်ပါ။
thaunghtikeoo@thaunghtikeoo:~$ kubectl top pods
NAME CPU(cores) MEMORY(bytes)
nginx-fdb6cfbc5-2dvxg 0m 11Mi
nginx-fdb6cfbc5-8cvtq 0m 9Mi
nginx-fdb6cfbc5-9cjn7 0m 10Mi
nginx-fdb6cfbc5-h8h85 0m 9Mi
nginx-fdb6cfbc5-lmfdw 0m 10Mi
CPU usage တွေပြန်ကျသွားတော့ hpa က 0% ပြန်ဖြစ်သွားပြီး minimum သတ်မှတ်ခဲ့တဲ့ pod တစ်ခုကိုပဲ ထားခဲ့ပြီးကျန်တာအကုန် terminated လိုက်ပါတယ်။ ဒါကတော့ hpa (သို့) horizontal pod autoscaling အကြောင်းကိုကျွန်တော်နားလည်သလောက်ရေးလိုက်တာပါ။
Vertical Pod Autoscaler
vpa ဆိုတာက ကျွန်တော်တို့ရဲ့ pod တွေအတွက် resource quota တွေကို vpa ကနေ စဥ်းစားပေးတာဖြစ်ပြီး autoscale လုပ်ပေးသွားတာပါ။ vpa က hpa တုန်းကလို scale in ၊ scale out လုပ်တာမျိုးမဟုတ်ပဲ မှန်ကန်တဲ့ resource usage ကိုသူကိုယ်တိုင် ဆုံးဖြတ်ပြီး old pod တွေကို evict ပြီး new instance တွေကို create လုပ်ပေးတာပါ။ ဒါဆို vpa ကိုစမ်းဖို့ vpa ကို အရင် install လုပ်ပေးရပါမယ်။
git clone https://github.com/kubernetes/autoscaler.git
./autoscaler/vertical-pod-autoscaler/hack/vpa-up.sh
vpa install ပြီးရင် hpa တုန်းကလိုပဲ deployment တစ်ခု create လိုက်ပါမယ်။ cpu request က 100m ဖြစ်ပြီး memory request က 50Mi ဖြစ်ပါတယ်။ kubectl create နဲ့ create လိုက်ပါမယ်။
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-auto-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-auto-deployment
template:
metadata:
labels:
app: my-auto-deployment
spec:
containers:
- name: my-container
image: k8s.gcr.io/ubuntu-slim:0.1
resources:
requests:
cpu: 100m
memory: 50Mi
command: ["/bin/sh"]
args: ["-c", "while true; do timeout 0.5s yes >/dev/null; sleep 0.5s; done"]
ဒါဆိုရင် deployment တစ်ခုရလာပါပြီ။ kubectl get နဲ့ တစ်ချက်ကြည့်ပါ။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/my-auto-deployment-9bf598bdb-jt2v6 1/1 Running 0 11s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2m23s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/my-auto-deployment 1/1 1 1 14s
NAME DESIRED CURRENT READY AGE
replicaset.apps/my-auto-deployment-9bf598bdb 1 1 1 14s
ပြီးရင် vpa တစ်ခုကို create ကြည့်ပါမယ်။ vpa က deployment အတွက် မှန်ကန်တဲ့ resource usage ကို recommend ပေးပြီး update mode ‘auto’ ပေးထားတဲ့အတွက် autoscale ဖြစ်သွားတာပါ။ vpa ကိုအောက်ကလို kubectl create နဲ့ create လိုက်ပါ။
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: my-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: my-auto-deployment
updatePolicy:
updateMode: "Auto"
ခဏကြာတော့ vpa တစ်ခုထွက်လာပါပြီ။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get vpa
NAME MODE CPU MEM PROVIDED AGE
my-vpa Auto 587m 262144k True 32s
kubectl describe နဲ့ ကြည့်တဲ့အခါ events မှာ vpa ကနေ deployment အတွက် recommend ပေးတဲ့ resource ကိုအခုလိုတွေ့ရမှာဖြစ်ပါတယ်။
Status:
Conditions:
Last Transition Time: 2021-07-15T17:03:14Z
Status: True
Type: RecommendationProvided
Recommendation:
Container Recommendations:
Container Name: my-container
Lower Bound:
Cpu: 86m
Memory: 262144k
Target:
Cpu: 587m
Memory: 262144k
Uncapped Target:
Cpu: 587m
Memory: 262144k
Upper Bound:
Cpu: 939787m
Memory: 18411500k
Events: <none>
lower bound က request ကိုပြောတာဖြစ်ပြီး upper က limit ကိုပြောတာပါ။ Target က pod ကောင်းမွန်စွာအလုပ်လုပ်နိုင်မယ့် ပမာဏကိုတွက်ချက်ပြီး ထုတ်ပေးလိုက်တာပါ။ အနည်းဆုံး cpu request က 587m ရှိရမှာပါ။ ကျွန်တော်အရင်က 100m ကိုသာ request ခဲ့ပါတယ်။ ဒါကြောင့် pod ကို terminated ပြီး Target resource နဲ့ pod အသစ်တစ်ခုအောက်ကလိုထွက်လာမှာပါ။ မိနစ် အနည်းငယ်ကြာတဲ့အခါ အရင်ရှိတဲ့ pod က terminate ဖြစ်ပြီး pod အသစ်တစ်ခု running ဖြစ်နေတာကိုတွေ့ရပါလိမ့်မယ်။
thaunghtikeoo@thaunghtikeoo:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-auto-deployment-9bf598bdb-kqp7n 1/1 Running 0 15s
my-auto-deployment-9bf598bdb-lxzhw 1/1 Terminating 0 3m10s
pod အသစ်ကို kubectl describe နဲ့ ကြည့်လိုက်ရင် cpu နဲ့ memory request ကိုအောက်ပါအတိုင်းပဲတွေ့ရမှာပါ။
State: Running
Started: Thu, 15 Jul 2021 23:35:14 +0630
Ready: True
Restart Count: 0
Requests:
cpu: 587m
memory: 262144k
Environment: <none>
Mounts:
ဒါဆိုရင် vertical pod autoscaling အကြောင်းကလည်းဒီလောက်ပါပဲ။ deployment တွေအတွက်မှန်ကန်တဲ့ resource amount ကို vpa ကိုသုံးပြီး သတ်မှတ်ပေးနိုင်ပါတယ်။ အားလုံးကိုကျေးဇူးတင်ပါတယ်ခင်ဗျာ။
Thanks for reading …