Kubernetes Zero-2-Hero EP.3 สร้าง Service Ingress และการทำ Horizontal Pod Autoscaler
สวัสดีครับ กลับมาเจอกันอีกครั้งกับ Series “Kubernetes Zero-2-Hero” ใน EP.3 นี้ยังอยู่ในเรื่องของ Resource Type ของ Kubernetes Cluster ซึ่งสิ่งที่เราจะมาแนะนำให้รู้จักในวันนี้มีดังต่อไปนี้
Service
Ingress
Horizontal Pod Autoscaler
Service
มาเริ่มกันที่ Service กันก่อนเลยนะครับ โดยเราได้พูดถึง Service ไปเล็กน้อยแล้วใน EP.2 ใครที่ยังไม่ได้อ่านก็สามารถกด ลิงค์ เพื่อย้อนกลับไปอ่านกันก่อนได้นะครับ
Service เปรียบเสมือนตัวบอกทางภายใน Kubernetes Cluster ที่จะทำให้ Pod สามารถสื่อสารกันได้ภายใน Cluster และ ยังสามารถให้ User ภายนอกเข้ามาใช้งาน Pod ของเราภายใน Cluster ได้อีกด้วย โดยประเภทของ Service ที่เราจะมาทำความรู้จักกันในวันนี้ก็จะมีอยู่ด้วยกัน 3 ประเภท คือ ClusterIP LoadBalancer และ Nodeport
บางคนอาจจะสงสัยว่า “ทำไมถึงต้องมี Service คอยจัดการเรื่องการสื่อสารภายใน Cluster ด้วย Pod สามารถสื่อสารกันเองได้รึเปล่า” คำตอบคือ Pod สามารถสื่อสารกันเองได้ภายใน Cluster ด้วยหมายเลข IP ของ Pod แต่ที่จำเป็นต้องมี Service เข้ามานั้น เพราะว่า Pod มีโอกาสที่จะถูกเพิ่มหรือถูกลบได้ตลอดเวลา เมื่อ Pod ถูกลบ แล้วถูกสร้างขึ้นมาใหม่ IP ของ Pod ก็จะถูกเปลี่ยนไปด้วย ดังนั้น Pod ที่เคยสื่อสารกันด้วย IP เก่าที่เคยกำหนดไว้ก็จะไม่สามารถสื่อสารกันได้อีก จึงจำเป็นต้องมี Service ที่คอยบอกทาง เป็นตัวกลางในการสื่อสารของ Pod ภายใน Cluster
กรณีที่ไม่ใช้งาน Service
กรณีที่ใช้งาน Service
โดยการทำงานของ Service จะไม่เชื่อมต่อกับ Pod โดยใช้ IP โดยตรง แต่จะใช้ Label ภายในตัว Pod เป็นตัวระบุว่า Service นี้จะเข้าไปคุยกับ Pod ไหนตามตัวอย่างดังนี้
จะสังเกตุว่า Config ในส่วนของ Service จะมีการใช้ Selector เพื่อกำหนดให้ Service เชื่อมต่อไปยัง Pod ที่มี Label “run: first-pod” และได้มีการกำหนดให้ Service เข้าใช้งาน Container ภายใน Pod ที่ Port 80
ต่อไปเราก็จะพูดถึง Service แต่และประเภทว่าคืออะไร สามารถใช้งานได้อย่างไรบ้าง
ClusterIP
ClusterIP เป็น Service ที่เป็นตัวกลางการสื่อสารของ Pod ภายใน Cluster สื่อสารกันภายใน User ภายนอกไม่สามารถเข้ามาใช้งาน Pod ผ่าน ClusterIP ได้
สำหรับการใช้งานเราสามารถสร้าง Service ได้จากทั้ง Command และสร้างจากไฟล์ โดยสามารถสร้างจาก Command ได้ดังนี้
# kubectl expose <pod|deployment> <POD_NAME | DEPLOYMENT_NAME> --name=<SERVICE_NAME> --port=<SERVICE_PORt> --target-port=<CONTAINER_PORT>kubectl expose deployment first-deployment --name=first-svc --port=80 --target-port=80# output
service/first-svc exposed
หรือจะสร้างจากไฟล์ YAML
kubectl create -f <FILENAME>
โดยมี Config ภายในดังนี้
# first-svc.yamlapiVersion: v1
kind: Service # ประเภทของ Resource
metadata:
name: first-svc # ชื่อของ Service
spec:
ports:
- port: 80 # Port ของ Service
protocol: TCP # Protocol
targetPort: 80 # Port ของ container ที่จะให้ Service นั้นเชื่อมต่อ
selector: # ส่่วนทที่ใช้ระบุ Label ของ Pod
app: first-deployment # ชื่อ Label ของ Pod ที่จะให้ Service นั้นเชื่อมต่อ
หากเราไม่ได้กำหนดประเภทให้แก่ Service ทุกๆ Service ที่เราสร้างขึ้นมาจะได้มาเป็นประเภท ClusterIP
หากใช้ Command ในการสร้าง เราสามารถสร้าง Service จาก Deployment หรือ Pod ก็ได้ โดย Selector ก็จะกำหนดการเชื่อมต่อไปยัง Label ของ Pod เองโดยอัตโนมัติ
Pod ที่เราใช้งานนั้นจะมาจาก EP ที่แล้วนะครับ ใครยังไม่ได้อ่าน สามารถคลิกที่ ลิงค์เพื่อความต่อเนื่องในการศึกษาเรียนรู้นะครับ
เราสามารถดู Service ทั้งหมดได้ด้วย Command ดังนี้
kubectl get service# output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
first-svc ClusterIP 10.96.9.254 <none> 80/TCP 3m54s
NodePort
NodePort เป็น Service ที่สามารถทำให้ User ภายนอก เข้ามาใช้งาน Pod ภายใน Cluster ได้ โดยที่ User สามารถเข้าถึงได้โดยการใช้ IP ของ Node ภายใน Cluster และ NodePort ที่ถูกกำหนดไว้ที่ตั้งแต่หมายเลข 30000–32767
เราสามารถสร้าง Service ที่เป็น NodePort ได้ด้วย Command หรือ ไฟล์ YAML ก็ได้นะครับ แต่ถ้าเราสร้างผ่าน Command เราจะไม่สามารถกำหนดหมายเลขของ NodePort ได้ โดยหมายเลขก็จะถูกสุ่มขึ้นมาตั้งแต่ 30000–32767 แต่เราก็สามารถเข้าไปแก้ไขหมายเลข NodePort ในภายหลังได้ โดยวิธีการสร้างก็จะมีดังนี้
สร้าง Service ประเภท NodePort จาก Command
kubectl expose deployment first-deployment --name=first-svc-np --type=NodePort --target-port=80 --port=80# output
service/first-svc-np exposed
จากนั้นเมื่อเรียก Service ออกมาดูจะพบว่า TYPE ของ Service จะถูกระบุไว้ว่าเป็น NodePort และมีหมายเลขของ NodePort เพิ่มเข้ามาในส่วนของคอลัมน์ PORT ดังนี้
kubectl get service first-svc-np# output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
first-svc-np NodePort 10.100.50.88 <none> 80:32570/TCP 29s
โดยเราสามารถเข้าใช้งาน Pod ได้ผ่าน IP ของ Node และหมายเลขของ NodePort ซึ่งตอนนี้เราใช้ Kubernetes Cluster แบบ Local อยู่ เราก็สามารถเข้าได้ผ่าน localhost ตามด้วยหมายเลขของ NodePort ได้ดังนี้
curl http://localhost:32570# output
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
หมายเลข NodePort อาจจะไม่เหมือนกันนะครับ ให้ใช้หมายเลข NodePort ของตัวเอง
หรือเราจะสร้างผ่านไฟล์ YAML ที่เป็น Config สำหรับการสร้าง Service ที่เป็น NodePort และยังสมารถกำหนดหมายเลข NodePort ได้อีกด้วย
# first-svc-np.yamlapiVersion: v1
kind: Service
metadata:
labels:
run: second-pod-svc-np
name: second-pod-svc-np
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30200 # กำหนดหมายเลข NodePort (30000-32767)
selector:
run: second-pod
type: NodePort # เพิ่มเติมในส่วนของประเภทให้เป็น NodePort
LoadBalancer
LoadBalancer เป็น Service ที่สามารถทำให้ภายนอกเข้ามาใช้งาน Pod ภายใน Cluster ได้ แต่จะต้องใช้ External Load Balancer ของ Cloud Provider เพื่อให้ Service ประเภท LoadBalancer นั้นทำงานได้ ไม่เช่นนั้น ในส่วนของ EXTERNAL-IP เมื่อเราเรียก Service ออกมาดูจะขึ้น “pending” อยู่ตลอดเวลา ตามตัวอย่างดังนี้
kubectl expose deployment first-deployment --name=first-svc-lb --type=LoadBalancer --port=80 --target-port=80# output
service/first-svc-lb exposed
หรือเราสามารถสร้างจากไฟล์ YAML
# first-svc-lb.yamlapiVersion: v1
kind: Service
metadata:
labels:
run: first-pod
name: first-svc-lb
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
run: first-pod
type: LoadBalancer # เพิ่ม Type เข้ามาให้เป็น LoadBalancer
จากนั้นเมื่อเราเรียก Service ออกมาดูจะพบผลลัพธ์ดังนี้
kubectl get service# output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
first-svc-lb LoadBalancer 10.106.71.153 <pending> 80:32207/TCP 75s
Ingress
Ingress ทำหน้าที่เหมือนเป็นประตูทางเข้าสำหรับ User ที่จะเข้ามาใช้งาน Pod ที่อยู่ภายใน Cluster คล้ายๆ กับ NodePort และ LoadBalancer แต่สามารถทำให้ User ที่เข้ามาไม่จำเป็นต้องเข้าใช้งานผ่าน IP แต่สามารถเข้าใช้งานด้วย Host Name ได้ และ Ingress ยังสมารถจัดการในเรื่องของการทำ TLS หรือ HTTPs ในการทำ Connection แบบ Secure ได้
ซึ่งก่อนที่เราจะใช้งาน Ingress ได้ เราต้อง Install Plugin เสริมเข้าไป เพื่อที่จะสามารถใช้งาน Ingress ได้ดังนี้
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml# output
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ตรวจสอบว่า Ingress ได้ทำการ Install เสร็จแล้วภายใน Cluster ของเรา ผลลัพธ์จะออกมาดังนี้
kubectl get all -n ingress-nginx# output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller LoadBalancer 10.109.194.32 localhost 80:30597/TCP,443:31099/TCP 89s
service/ingress-nginx-controller-admission ClusterIP 10.106.106.155 <none> 443/TCP 89sNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ingress-nginx-controller 1/1 1 1 89sNAME DESIRED CURRENT READY AGE
replicaset.apps/ingress-nginx-controller-c4f944d4d 1 1 1 89sNAME COMPLETIONS DURATION AGE
job.batch/ingress-nginx-admission-create 1/1 6s 89s
job.batch/ingress-nginx-admission-patch 1/1 6s 89s
เราสามารถสร้าง Ingress ได้จาก YAML ดังนี้
# first-ingress.yamlapiVersion: networking.k8s.io/v1
kind: Ingress # ประเภทของ Resource
metadata:
name: first-ingress # ชื่อของ Ingress
spec:
rules: # ส่วนของการกำหนด Rule ให้กับ Ingress
- host: "first-pod.example.com" # Hostname ที่จะให้ User เข้าใช้งาน
http:
paths:
- path: / # Path ที่จะให้เข้ามาใช้งาน Pod
pathType: Prefix # ประเภทของการ Match Path
backend: # ส่วนของการระบุ Service ที่จะให้นำทางไปยัง Pod
service:
name: first-svc # ชื่อของ Service
port:
number: 80 # Port ของ Servicekubectl create -f first-ingress# output
ingress.networking.k8s.io/first-ingress created
จากนั้นเราสามารถตรวจสอบ Ingress ภายใน Cluster ได้ ดังนี้
kubectl get ingress# output
NAME CLASS HOSTS ADDRESS PORTS AGE
first-ingress <none> first-pod.example.com localhost 80 50s
ทดสอบการใช้งาน Pod ด้วย Ingress
# แก้ไขไฟล์ Host เพิ่ม hostname ที่ถูกสร้างขึ้นมาด้วย Ingress เข้าไป ดังนี้
127.0.0.1 kubernetes.docker.internal first-pod.example.com# จากนั้นทดสอบการเข้าถึง Pod ด้วย Hostname
curl http://first-pod.example.com# output
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
จะเห็นได้ว่าเราสามารถเข้าใช้งาน Pod ผ่าน Hostname โดยไม่ต้องเข้าผ่าน IP ได้
ต่อไปเราจะสร้าง Ingress ที่เป็น HTTPs กัน
ก่อนอื่นต้องสร้างไฟล์ Cert และ Key เพื่อนำไปใช้สร้าง Ingress แบบ HTTPs
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ingress.key -out ingress.cert -subj "/CN=example.com/O=example.com"# output
Generating a 2048 bit RSA private key
...............+++
.................+++
writing new private key to 'ingress.key'
-----
สร้าง Secret สำหรับเก็บไฟล์ Key และ Cert
kubectl create secret tls ingress-tls --key ingress.key --cert ingress.cert# output
secret/ingress-tls created
Secret เป็นหนึ่งใน Resource ใน Kubernetes แต่ใน EP เราจะยังไม่พูดถึงรายละเอียด ขอเก็บเอาไว้พูดใน EP ถัด ๆ ไปแทนนะครับ
# first-ingress-tls.yamlapiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: first-ingress-tls
spec:
tls: # เพิ่มในส่วนของการทำ HTTPs เข้ามา
- hosts:
- first-pod-tls.example.com # ระบุ Host สำหรับการทำ HTTPs
secretName: ingress-tls # ชื่อของ Secret ที่เก็บไฟล์ KEY และ CERT ไว้
rules:
- host: first-pod-tls.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: first-svc
port:
number: 80kubectl create -f first-ingress-tls.yaml# output
ingress.networking.k8s.io/first-ingress-tls created
จากนั้นตรวจสอบ Ingress ที่สร้างขึ้นมา
kubectl get ingress# output
NAME CLASS HOSTS ADDRESS PORTS AGE
first-ingress <none> first-pod.example.com localhost 80 27m
first-ingress-tls <none> first-pod-tls.example.com 80, 443 45s
ทดสอบการใช้งาน Pod ด้วย Ingress
# แก้ไขไฟล์ Host เพิ่ม hostname ที่ถูกสร้างขึ้นมาด้วย Ingress เข้าไป ดังนี้
127.0.0.1 kubernetes.docker.internal first-pod.example.com first-pod-tls.example.com
สามารถทดสอบที่ Browser จะพบว่า Ingress ที่ไม่ได้ทำ TLS หรือ HTTPs ไว้ จะไม่สามารถเข้าใช้งานผ่าน HTTPs ได้ ดังรูปภาพ
Horizontal Pod Autoscaler
Horizontal Pod Autoscaler (HPA) เป็นเครื่องมือที่สามารถทำให้ Pod ภายใน Cluster ของเราเพิ่ม หรือลดลงได้ตามจำนวนความต้องการใช้งานของ User โดย HPA จะคอยตรวจสอบการทำงานของ Pod ว่ามีการใช้ทรัพยากรไปเท่าไหร่แล้ว จากนั้นเมื่อ HPA เห็นว่า Pod ใช้ทรัพยากรไปมากจนถึงจุดที่เรากำหนดให้ทำการขยายจำนวน Pod ก็จะถูกสร้างเพิ่มขึ้นมาตามที่เรากำหนดไว้เองโดยอัตโนมัติ โดยหลังจากที่ Pod ทำงานจนการใช้งานทรัพยากรลดลงแล้ว Pod ก็จะถูกทำลายให้เหลือเท่าที่กำหนดไว้ในตอนแรก
โดยวิธีการทำ HPA นั้นก็ไม่ได้ยุ่งยากอย่างที่คิด
ก่อนอื่นต้องติดตั้ง Metric Server Plugin เข้าไป เพื่อที่จะให้ Cluster ของเรามีเครื่องมือที่คอยตรวจสอบการใช้งานทรัพยากรของ Cluster ได้ ถ้าหากไม่มี Metric Server นั้น Cluster ก็จะไม่สามารถรู้ได้เลยว่า Pod ของเราได้ใช้งานทรัพยากรไปเท่าไหร่แล้ว จึงไม่สามารถที่จะทำการตรวจสอบ และคอยเพิ่ม หรือลดจำนวนของ Pod ได้นั่นเอง
kubectl apply -f https://gitlab.com/settakit.sirisoft/k8s-101-workshop/-/raw/master/workshop/metric-server/metric-server.yaml# output
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
ตรวจสอบว่า Metric Server พร้อมทำงานดังนี้
kubectl get po -n kube-system# output
NAME READY STATUS RESTARTS AGE
coredns-f9fd979d6-lfqks 1/1 Running 10 41d
coredns-f9fd979d6-n2kkp 1/1 Running 10 41d
etcd-docker-desktop 1/1 Running 12 41d
kube-apiserver-docker-desktop 1/1 Running 12 41d
kube-controller-manager-docker-desktop 1/1 Running 12 41d
kube-proxy-mtrsq 1/1 Running 11 41d
kube-scheduler-docker-desktop 1/1 Running 147 41d
metrics-server-7bb5df7cc4-2lppw 1/1 Running 0 19s
storage-provisioner 1/1 Running 182 41d
vpnkit-controller 1/1 Running 10 41dkubectl top node# output
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
docker-desktop 1128m 28% 2283Mi 55%
จากนั้นสร้าง Deployment ขึ้นมาโดยใช้งาน Config ดังนี้
# deployment-hpa.yamlapiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: deployment-hpa
name: deployment-hpa
spec:
replicas: 1
selector:
matchLabels:
app: deployment-hpa
template:
metadata:
creationTimestamp: null
labels:
app: deployment-hpa
spec:
containers:
- image: paulbouwer/hello-kubernetes:1
name: hello-kubernetes
ports:
- containerPort: 8080
resources: # เพิ่มในส่วนของ Reources
requests: # Request Resource สำหรับ Container
memory: "64Mi"
cpu: "128m"
limits: # Limit Resource สำหรับ Container
memory: "128Mi"
cpu: "256m"kubectl create -f deployment-hpa.yaml# output
deployment.apps/deployment-hpa created
จากนั้นตรวจสอบว่า Pod ของเราได้ถูกสร้างขึ้นมาแล้ว
kubectl get po -l app=deployment-hpa# output
NAME READY STATUS RESTARTS AGE
deployment-hpa-6d8b4f849f-mc6vb 1/1 Running 0 71s
จากนั้นทำการสร้าง HPA จากไฟล์ YAML ดังนี้
# hpa-cpu.yamlapiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler # Type ของ Resource
metadata:
name: deployment-hpa # ชื่อของ HPA
spec:
maxReplicas: 5 # จำนวน Pod มากสุด
minReplicas: 1 # จำนวน Pod น้อยสุด
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: deployment-hpa # ชื่อของ Deployment
targetCPUUtilizationPercentage: 1 # Percent CPU ที่จะให้เริ่ม Scale Podkubectl create -f hpa-cpu.yaml# output
horizontalpodautoscaler.autoscaling/deployment-hpa created
ตรวจสอบว่า HPA ของเราได้ถูกสร้างขึ้นมาแล้ว
kubectl get hpa# output
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
deployment-hpa Deployment/deployment-hpa <unknown>/10% 1 5 0 31s
จากนั้นสร้าง Service เพื่อให้สามารถเข้าใช้งานได้จากภายนอก และจะได้ทำการทดสอบเรื่องของการทำ HPA ด้วย
kubectl expose deployment deployment-hpa --name=deployment-hpa-svc --type=NodePort --port=8080 --target-port=8080# output
service/deployment-hpa-svc exposed# ตรวจสอบว่า Service ถูกสร้างขึ้นมาแล้ว
kubectl get svc # output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
deployment-hpa-svc NodePort 10.103.14.40 <none> 8080:31761/TCP 17s
จากนั้นใช้ Command ด้านล่างเพื่อตรวจสอบว่า Pod ของเราจะเพิ่มจำนวนตามที่เราต้องการหรือไม่ (อย่าลืมเปลี่ยนหมายเลข NodePort ด้วยล่ะ)
for i in `seq 1 1000`; do echo $i; curl -H 'Cache-Control: no-cache' http://localhost:<NodePort> | grep deployment-hpa; done# output...
995
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 793 100 793 0 0 99125 0 --:--:-- --:--:-- --:--:-- 99125
<td>deployment-hpa-7df4d6fd59-g69mf</td>
996
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 793 100 793 0 0 88111 0 --:--:-- --:--:-- --:--:-- 79300
<td>deployment-hpa-7df4d6fd59-hh9wx</td>
997
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 793 100 793 0 0 99125 0 --:--:-- --:--:-- --:--:-- 99125
<td>deployment-hpa-7df4d6fd59-v8b58</td>
998
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 793 100 793 0 0 110k 0 --:--:-- --:--:-- --:--:-- 110k
<td>deployment-hpa-7df4d6fd59-v8b58</td>
999
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 793 100 793 0 0 88111 0 --:--:-- --:--:-- --:--:-- 88111
<td>deployment-hpa-7df4d6fd59-9sqk7</td>
1000
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 793 100 793 0 0 79300 0 --:--:-- --:--:-- --:--:-- 79300
<td>deployment-hpa-7df4d6fd59-v8b58</td>
จะสังเกตุเห็นว่าใน Tag <td> จะได้ชื่อของ Pod ที่ไม่ซ้ำกันออกมา นั้นหมายความว่า Pod ของเราได้ทำการสร้างขึ้นมาใหม่แล้วตามจำนวนที่เรากำหนดไว้
ตรวจสอบ Pod ก็จะพบว่า Pod ได้ถูกสร้างขึ้นมาโดยอัตโนมัติเมื่อมีการเรียกใช้งาน Pod (เปิด Terminal ขึ้นมาอีกหนึ่งอันเพื่อดูความเปลี่ยนแปลงเบบ Real Time)
kubectl get po -l app=deployment-hpa -w# output
NAME READY STATUS RESTARTS AGE
deployment-hpa-7df4d6fd59-g69mf 1/1 Running 0 28m
deployment-hpa-7df4d6fd59-9sqk7 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-v8b58 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-9sqk7 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-v8b58 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-9sqk7 0/1 ContainerCreating 0 0s
deployment-hpa-7df4d6fd59-v8b58 0/1 ContainerCreating 0 0s
deployment-hpa-7df4d6fd59-9sqk7 1/1 Running 0 4s
deployment-hpa-7df4d6fd59-v8b58 1/1 Running 0 5s
deployment-hpa-7df4d6fd59-fg6qx 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-hh9wx 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-fg6qx 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-hh9wx 0/1 Pending 0 0s
deployment-hpa-7df4d6fd59-fg6qx 0/1 ContainerCreating 0 0s
deployment-hpa-7df4d6fd59-hh9wx 0/1 ContainerCreating 0 0s
deployment-hpa-7df4d6fd59-fg6qx 1/1 Running 0 4s
deployment-hpa-7df4d6fd59-hh9wx 1/1 Running 0 5s
deployment-hpa-7df4d6fd59-v8b58 1/1 Terminating 0 8m5s
deployment-hpa-7df4d6fd59-9sqk7 1/1 Terminating 0 8m5s
deployment-hpa-7df4d6fd59-hh9wx 1/1 Terminating 0 7m4s
deployment-hpa-7df4d6fd59-fg6qx 1/1 Terminating 0 7m4s
deployment-hpa-7df4d6fd59-hh9wx 0/1 Terminating 0 7m11s
deployment-hpa-7df4d6fd59-fg6qx 0/1 Terminating 0 7m11s
deployment-hpa-7df4d6fd59-hh9wx 0/1 Terminating 0 7m12s
...
การทำ HPA สามารถดูได้จากทั้งการใช้งาน Memory และ CPU ซึ่งก็ขึ้นอยู่กับว่าเราจะใช้งานในรูปแบบใด ในที่นี้เราขอเลือกใช้งานเป็นดูจาก CPU
ประโยชน์ของ HPA ก็คือ Pod จะถูก Scale ตามความต้องการใช้งานของ User เมื่อ Request ที่เข้ามาภายใน Pod น้อย Pod ก็ไม่จำเป็นต้องมีหลาย Pod เพื่อช่วยกันทำงาน จึงช่วยประหยัดทรัพยากรในส่วนนี้ได้ ใช้ทรัพยากรเฉพาะช่วงเวลามี Request เข้ามายัง Pod เยอะเท่านั้น
Conclusion
- เราได้รู้ว่า Service สามารถใช้งานเป็นตัวกลางการสื่อสารของ Pod ภายใน Cluster จัดการปัญหาในเรื่องของจำนวน Pod ที่ไม่แน่นอน และ IP ของ Pod ที่สามารถเปลี่ยนแปลงไปได้เรื่อยๆ เพื่อให้การสื่อสารภายในนั้นเป็นไปได้อย่างไม่มีปัญหา และยังทำให้ User ภายนอกสามารถเข้ามาใช้งาน Pod ภายใน Cluster ได้
- Ingress เราได้รู้ว่าการทำงานจะคล้ายกับ Service ที่เป็น NodePort และ LoadBalancer ที่จะทำตัวเป็นประตูเพื่อให้ User สามารถเข้ามาใช้งาน Pod ภายใน Cluster ได้ แต่จะแตกต่างตรงที่ Ingress สามารถสร้าง Hostname และ สร้าง TLS สำหรับการทำ HTTPs ได้
- เราได้รู้ว่าวิธีการการทำ HPA และรู้ว่า HPA นั้นเข้ามาช่วยในเรื่องของการทำ Auto Scaling Pod เพื่อเป็นการประหยัดทรัพยากรเมื่อไม่มี Request เข้ามายัง Pod
ก็จบไปอีกหนึ่งตอนใน EP.3 นี้นะครับ สำหรับตอนถัดไปเราจะมาพูดถึงการจัดการค่า Config ต่าง ๆ สำหรับนำเอาไปใช้ภายใน Pod และเรื่องของการทำพื้นที่เก็บข้อมูลสำรองให้กับ Pod
เพื่อนๆสามารถติดตามกันได้ที่ https://www.facebook.com/sirisoft แล้วพบกันใหม่เร็วๆนี้ ขอบคุณครับ 👋🏻👋🏻👋🏻
ALL EPISODE
EP.1 มารู้จักกับ Kubernetes พร้อมหลักการทำงาน ไปจนถึงวิธีการติดตั้งบนเครื่อง Local !!
EP.2 ทำความรู้จัก Resource Type และ การ Deploy Application บน Kubernetes
EP.3 สร้าง Service Ingress และการทำ Horizontal Pod Autoscaler
EP.4 สร้าง Secret ConfigMap และสำรองข้อมูลด้วย PersistentVolume
EP.5 สร้าง Health Check ด้วย Liveness Readiness และ การใช้งาน Rollout