Kubernetes Basic (LV.1)
Kubernetes Object Management
kubectl เป็น CLI ที่รองรับการจัดการ Kubernetes objects ในหลายๆแบบ
Imperative command
user กระทำกับ object โดยตรง เป็นวิธีที่ใช้ learning curve น้อยที่สุด
Imperative object configuration
user สร้าง file ที่ define object ในรูปแบบ YAML หรือ JSON และคำสั่งในการดำเนินการเช่น create, replace, delete เป็นวิธีที่ใช้ learning curve ปานกลาง
Declarative object configuration
user สร้าง file YAML หรือ JSON ทั้งหมด แล้วเก็บไว้ใน directory และใช้เพียงคำสั่ง kubectl apply เป็นวิธีที่ใช้ learning curve มากที่สุด
Kubernetes Workloads
Pods
Pod คือหน่วยที่เล็กที่สุดที่สามารถ deploy ได้ใน Kubernetes โดย Pod ประกอบด้วยคอนเทนเนอร์อย่างน้อย 1 container โดย container ที่อยู่ใน Pod เดียวกันจะแชร์ IP Address และ Network เดียวกัน และสามารถสื่อสารกันได้โดยใช้ localhost
container ที่รันคู่กับ container หลัก เรามักจะเรียกว่า sidecar
ReplicaSets
ReplicaSet เป็นตัวควบคุมจำนวนของ Pods ที่ทำงานอยู่ในช่วงเวลาเดียวกัน โดย ReplicaSet จะทำให้แน่ใจว่า Pod ที่มีจำนวนกำหนดจะถูกสร้างและทำงานอยู่เสมอ หาก Pod ใดถูกลบหรือเกิดการขัดข้อง ระบบจะทำการสร้าง Pod ใหม่ขึ้นมาแทนที่โดยอัตโนมัติ
Deployments
เป็น Workload ที่ใช้กับ Stateless application ไม่สนใจว่า Pod ใดที่ถูก control ภายใต้ Deployment นั้นจะ start ก่อนหรือหลังอีก Pod หนึ่ง มักจะใช้กับ application ส่วนมาก
StatefulSets
เป็น Workload ที่สนใจ State ของแต่ละ Pod มีการ control ให้ Pod ถูกสร้างและลบ ตามลำดับที่กำหนด มักจะใช้กับงานประเภท database หรือ cluster application
DaemonSets
เป็น Workload ที่จะ control ให้มีการ Deploy Pod ลงบนทุก Node ใน cluster โดย deploy 1 Pod ต่อ node เสมอ ดังนั้นหากมีการเพิ่ม node ใหม่เข้ามาใน cluster ก็จะมีการ deploy Pod บน node นั้นโดยอัตโนมัติ มักจะถูกใช้กับงานประเภท เก็บ log หรือ monitor node resource
Jobs และ CronJobs
Job เป็น Workload ใช้กับงานที่รันครั้งเดียวจบ จะมีการสร้าง Pod ขึ้นมารัน และหยุดไปเมื่อทำงานเสร็จ หรือหมดเวลา
Cronjob เป็น Workload ที่จะสร้าง Job ตาม Schedule ที่กำหนด
Workshop Kubernetes Workloads
Deployment
สร้าง YAML file จากคำสั่งดังนี้
deploy ด้วยคำสั่งดังนี้
ตรวจสอบ deployment และ pod
ลองอ่านไฟล์ nginx.yaml
ดู
replicas
เป็นตัวกำหนดจำนวน Pod ที่จะถูกสร้างใน cluster
selector
เป็นวิธีที่ Pod ใช้ในการหาว่า Pod ใดบ้างที่จะถูก manage โดย Deployment นี้
ในตัวอย่างจะเป็น Pod ที่ถูก label app=nginx
template
เป็นตัวระบุ config เพื่อสร้าง Pod
ในตัวอย่างจะสร้าง Pod โดยมี label app=nginx
และใช้ image nginx จาก Dockerhub และเนื่องจากไม่มีการระบุ tag จึงจะใช้ image tag latest
Update Deployment
ลองทำการแก้ไขไฟล์ เปลี่ยนไปใช้ image nginx:1.27
ดังนี้
apply change
ReplicaSets
ดู ReplicaSet ด้วยคำสั่งดังนี้
จะพบว่ามี 2 ReplicaSet
เราสามารถดูรายละเอียดของ ReplicaSet ได้จากคำสั่งดังนี้
โดย nginx-xxx
คือ ชื่อ ReplicaSet ที่ได้มาจากก่อนหน้านี้
แต่ละ ReplicaSet คือ template ในการสร้าง Pod ReplicaSet จะคอยดูแลจำนวนของ Pod ให้แน่ใจว่าตรงตามจำนวนที่กำหนด การเปลี่ยนแปลง Deployment เช่น image version จะทำให้เกิดการสร้าง ReplicaSet ตัวใหม่, scale up ReplicaSet อันใหม่ และ scale down ReplicaSet เก่า
Cleanup Deployment
StatefulSets
StatefulSets ใช้ในการ manage stateful application มีการการันตีลำดับของการสร้าง Pod Pod จะถูกสร้างตาม spec ที่กำหนดไว้ และไม่สามารถเปลี่ยนแปลงได้หลังสร้างไปแล้ว
สร้าง StatefulSet YAML ในชื่อ sts.yaml
ดังนี้
config ส่วนใหญ่จะคล้าย Deployment แต่ต่างกันตรง
- kind
เป็น StatefulSet
- เพิ่ม field serviceName
- ตัด field strategy
ทิ้ง
ใน StatefulSet เราอาจจะใส่ volumeClaimTemplates
เพิ่มขึ้นมา เพื่อทำ dynamic allocate volume ให้กับ Pod ได้เช่นกัน
ลอง list StatefulSet
จะพบว่า Pod ถูกสร้างทีละ Pod ตามลำดับ
พฤติกรรมเช่นนี้จึงเหมาะกับการทำ cluster database มาก โดยมี Pod แรก bootstrap cluster ขึ้นมา แล้วค่อยมี Pod อื่นๆมาขอ join cluster
Cleanup StatefulSet
DaemonSets
DaemonSet เป็น Workload ที่ทำให้เรามั่นใจได้ว่าทุก node จะมี Pod ตามที่กำหนดทำงานอยู่ ถ้ามี node ใหม่เพิ่มเข้ามา ก็จะมี Pod deploy ไปยัง node ที่เพิ่มเข้ามาโดยอัตโนมัติ
สร้าง DaemonSet YAML ในชื่อ ds.yaml
ดังนี้
config ส่วนใหญ่จะคล้าย Deployment แต่ต่างกันตรง
- kind
เป็น DaemonSet
- ตัด field strategy
ทิ้ง
ลองตรวจข้อมูล DaemonSet และ Pod ดังนี้
จะได้ผลลัพธ์ดังนี้
แสดงให้เห็นว่า Pod ของ DaemonSet จะทำงานอยู่คนละ node เสมอ
Cleanup DaemonSet
Jobs
สร้าง 1 Pod หรือมากกว่านั้น เมื่อทำงานจนเสร็จ จะ down ไป ถ้า process มี exit code เป็น 0 จะถือว่า Job success ถ้า process มี exit code เป็น non-zero จะถือว่า failed และอาจจะมีการ re-run อีกครั้ง (หากกำหนด restartPolicy ไว้)
สร้าง Job YAML ในชื่อ job.yaml
ดังนี้
ลองดูข้อมูลของ Job และ Pod ดังนี้
จะได้ผลลัพธ์ดังนี้
ตรง STATUS แสดงเป็น Completed
หมายถึง Job ทำงานเสร็จแล้ว และ Success
ส่วน READY 0/1
หมายถึง Job ทำงานเสร็จ และหยุดไปแล้ว ซึ่งจะทำให้ไม่ consume compute resource แล้ว
Cleanup Job
CronJobs
Cronjob จะสร้าง Job ตาม Schedule ที่กำหนด
โดย default Cronjob จะทำงานตามเวลา timezone ของ kube-controller-manager แต่ใน Kubernetes version 1.27 เป็นต้นไป สามารถระบุ timezone ที่ต้องการได้ใน spec เลย
สร้าง Cronjob ในชื่อ cronjob.yaml
ดังนี้
จากตัวอย่าง schedule มี pattern ดังนี้
หมายความว่า cron ตามตัวอย่าง จะสร้าง jobs ขึ้นมาทุกเวลาที่หาร 2 ลงตัว
หากลองดูข้อมูลของ CronJob, Job และ Pod
จะได้ผลลัพธ์ดังนี้
Cleanup CronJob
Environment variable
Environment Variables ใน Kubernetes เป็นวิธีการส่งค่าคอนฟิกหรือข้อมูลเข้าสู่ Container ภายใน Pod เพื่อให้แอปพลิเคชันที่รันอยู่ใน Container สามารถใช้งานค่าที่กำหนดได้ โดย Environment Variables เหมาะสำหรับการส่งค่าที่เป็นข้อมูลการตั้งค่า เช่น ชื่อแอปพลิเคชัน, URL ของฐานข้อมูล, หรือค่าอื่น ๆ ที่แอปพลิเคชันต้องการ
env
เป็นการกำหนดค่า variable ลงไปตรงๆ
envFrom
เป็นการ refer ค่าจาก configMap หรือ secret โดยค่าต้องเก็บอยู่ในรูป key-value pair เท่านั้น
ตัวอย่างการใช้งาน env
สร้างไฟล์ชื่อ static-env.yaml
ดังนี้
สร้าง resource ด้วยคำสั่ง
ทดสอบ exec เข้าไปใน pods
ลองอ่านค่า environment variable
จะได้ผลลัพธ์ตาม value ที่ set ไป
cleanup env
ตัวอย่างการใช้งาน envFrom
สร้างไฟล์ชื่อ cm-env.yaml
ดังนี้
ทดสอบ exec เข้าไปใน pods
ลองอ่านค่า environment variable
จะได้ผลลัพธ์ตาม value ที่ set ไป
cleanup envFrom
Kubernetes Services and Networking
Service เป็นวิธีการที่ Kubernetes ใช้ในการเปิดให้เข้าถึง application ที่รันอยู่ภายใน cluster ได้ มีด้วยกันหลายชนิด ดังนี้
ClusterIP
ClusterIP เป็น Service ที่เปิดให้ application อื่นๆ เข้าถึง application ที่กำหนด ได้จากภายใน cluster เองเท่านั้น เป็น default ของ Kubernetes หากมีการสร้าง Service ขึ้นโดยไม่ระบุ type
ตัวอย่าง YAML
NodePort
NodePort เป็น Service ที่เปิดให้ traffic จากภายนอก cluster สามารถเข้ามาสู่ application ภายใน cluster ได้ผ่านทาง node ip & port โดยจะ forward traffic นั้นมายัง service ตามที่กำหนด
Port บน node จะเป็น high port ตั้งแต่ 30000 จนถึง 32767 และทุก node ใน cluster จะเปิด port หมายเลขนั้น โดยไม่สนใจว่า Pod อยู่บน node นั้นหรือไม่ ภายนอกจึงสามารถส่ง traffic มาที่ node ใดก็ได้ใน cluster แล้ว cluster จะ forward traffic ไปยัง Pod ที่รันอยู่เอง
ตัวอย่าง YAML
LoadBalancer
LoadBalancer เป็น Service ที่จะติดต่อกับ cloud provider เพื่อให้สร้าง loadbalancer ขึ้นมา และเปิดให้เข้าถึง application ผ่านทาง endpoint ของ loadbalancer แทน มีข้อดีกว่า NodePort ตรงที่ endpoint มีความแน่นอน เป็น dns name หรือ ip ของ load balancer เอง ซึ่งจะตายตัวกว่าการเรียกผ่าน node ip ที่เครื่องอาจจะมีการเปลี่ยนแปลง ip ได้ตลอดเมื่อ cloud มีการ scale node เพิ่มลด และยังสามารถ expose port เป็น low port number ได้อีกด้วย เช่น http-80 และ https-443
ดังนั้น loadbalancer จึงเทียบได้กับ superset ของ NodePort เอง
ตัวอย่าง YAML
ExternalName
เป็น Service ที่จะ map service name เข้ากับ DNS หนึ่ง เมื่อมีการเรียกใช้ service จะมีพฤติกรรมเหมือนกับ DNS resolve มากกว่าการทำ proxy หรือการ forward traffic มีประโยชน์ในการ refer resource นอก cluster ซึ่งใช้ร่วมกันในหลายๆ application หรือในการเตรียมทำ migration เข้ามาอยู่เป็น service หนึ่งใน cluster
ตัวอย่าง YAML
Ingress
Ingress เป็นวิธีในการ expose HTTP และ HTTPS route จากภายนอก cluster เข้าสู่ application ที่กำหนด Traffic routing ถูกควบคุมโดย rule ที่ประกาศไว้ใน Kubernetes resource ที่ชื่อ Ingress Ingress ยังสามารถกำหนด config ในแง่ของ URL, path, และการ terminate SSL/TLS ได้อีกด้วย
การที่ Ingress จะสามารถทำงานได้ จำเป็นต้องอาศัย Ingress Controller ซึ่งต้องติดตั้งเพิ่ม Ingress Controller ที่ได้รับความนิยม คือ Nginx, Traefik และ Kong เลือกติดตั้ง Ingress Controller เพียงชนิดเดียว หรือติดตั้งหลายๆ Ingress Controller ก็ได้ แต่ default IngressClass ต้องมีเพียงตัวเดียว
การติดตั้ง Nginx Ingress Controller
Nginx Ingress Controller มี 2 ค่าย คือ ของ Kubernetes community และของ F5 Nginx วิธีในตัวอย่างนี้เป็นของ Kubernetes Community
สิ่งที่ต้องระวังคึอ ทั้ง 2 ค่ายรองรับ feature และ annotation ไม่เหมือนกัน และใช้คนละ document ของ Kubernetes Community จะใช้ document ดังนี้
ทดสอบ Ingress Controller
สร้างไฟล์ ingress-example.yaml
ดังนี้
apply ด้วยคำสั่งดังนี้
จากตัวอย่าง จะสร้าง deployment และ service ของ nginx และ apache และมีการสร้าง rule nginx ให้ เวลาเรียก path /nginx มีการส่ง traffic ไปยัง pod ของ nginx ส่วน rule apache เมื่อเรียก path /apache มีการส่ง traffic ไปยัง pod ของ apache โดยทั้งสอง rule จะมีการทำ rewrite url path ที่ขึ้นต้นจาก /apache และ /nginx ให้เหลือเพียง / เท่านั้น
ทดสอบเปิด browser เข้า path /apache และ /nginx ดู
ลบทิ้งด้วยคำสั่งดังนี้
ข้อดีหนึ่งของการใช้ Ingress แทนการใช้ หลายๆ service LoadBalancer คือช่วยให้เราสามารถประหยัด cost ของ LoadBalancer ได้ เพราะเราสามารถใช้เพียง 1 LoadBalancer แทนการสร้าง LoadBalancer จำนวนมากในการรับ http/https request ของทุกๆ service
Kubernetes Storage
Kubernetes มีการรองรับพื้นที่ Storage แบบต่างๆทั้ง Long-term Storage และ พื้นที่ Storage ชั่วคราว (Ephemeral Storage) หลายๆแบบ ดังนี้
Ephemeral Volumes
Ephemeral Volumes คือ Volumes ที่มีอายุการใช้งานชั่วคราวและเชื่อมโยงกับ lifecycle ของ Pod เมื่อ Pod ถูกสร้างขึ้น Volumes เหล่านี้จะถูกสร้างตามไปด้วย และเมื่อ Pod ถูกลบหรือยุติการทำงาน Volumes เหล่านี้ก็จะถูกลบไปด้วย
Ephemeral Volumes ที่ใช้งานบ่อยใน Kubernetes ได้แก่
emptyDir: allocate พื้นที่เปล่าเมื่อ Pod ถูกสร้าง โดยอาศัยพื้นที่จาก kubelet base directory (ปกติเป็น root disk) หรือจาก RAM
configMap & secret: inject ข้อมูลคอนฟิกหรือข้อมูลที่มีความลับ เข้ามาใน Pod
ตัวอย่าง emptyDir
สร้าง YAML ชื่อ redis.yaml โดยมี content ดังนี้
สั่ง apply เพื่อสร้าง
หลังจากนั้นทำการสร้าง pod busybox เพื่อทดสอบใช้งาน redis ในเคสนี้เลือก busybox image เพราะมีติดตั้ง command telnet ไว้อยู่แล้ว
หลังจากนั้น access เข้า redis
จะพบว่าสามารถ set และ get ข้อมูลออกมาได้
หลังจากนั้นใช้อีก terminal terminate redis pod ด้วยคำสั่งดังนี้
ใน busybox จะถูกตัดการเชื่อมต่อ ให้รอสักพัก แล้ว connect ไปใหม่
จะพบว่าไม่มี KEY แล้ว และไม่สามารถ get ข้อมูลออกมาได้ เนื่องจาก emptyDir เป็นพื้นที่ซึ่งผูกกับ lifecycle ของ Pod ดังนั้นเมื่อ Pod ถูก terminate ก็จะถูกลบทิ้งไปด้วย
cleanup
ตัวอย่าง configMap
ตัวอย่างการ mount เป็น config file
สร้างไฟล์ mock.yaml
ดังนี้
จากตัวอย่างจะเป็นการสร้าง deployment mock-server และใช้ configmap ในการจัดเก็บ config ของ mock-server ซึ่งจะถูก mount เป็นไฟล์ภายใน pod เมื่อ pod ถูกสร้างขึ้นมา
การเก็บเป็น configmap นี้จะไม่มีการ encrypt หรือ decode และการส่งข้อมูลระหว่าง control-plane ไปยัง worker node ก็จะไม่มีการ encrypt เช่นกัน ดังนั้นจึงไม่ควรใส่ sensitive data ไว้ในรูป configmap
ทำการสร้าง resource ด้วยคำสั่งดังนี้
ทดสอบการทำงานด้วย pod alpine
ติดตั้ง curl ใน alpine และทดสอบเรียก mock
จะพบว่า mock-server สามารถทำงานได้ตาม config จาก configmap
cleanup ด้วยคำสั่งดังนี้
ตัวอย่าง secret
สร้างไฟล์ชื่อ redis-secret.yaml
ดังนี้
จากตัวอย่างจะเป็นการสร้าง deployment redis และให้อ่าน password จากไฟล์ /secret/password
โดย /secret
มาจากการ mount Kubernetes secret
ชื่อ key ใดๆก็ตามใน secret จะกลายเป็นชื่อไฟล์ และ value ซึ่งอยู้ในรูป base64 encode จะถูก decode เป็น content ของไฟล์นั้นๆ
ในตัวอย่าง bXlzZWNyZXQ=
จะเทียบเท่าคำว่า mysecret
เมื่อผ่าน base64 decode
Access เข้า redis
ทดสอบเรียกคำสั่งดังนี้
จะพบว่า redis แจ้งว่าต้อง Authen
ทำการ Authen
จะพบว่าสามารถเรียกใช้งานได้ปกติ
หลังจากนั้น disconnect และทำการ cleanup
Persistent Volumes (PV) และ Persistent Volume Claims (PVC)
Storage Classes และ Dynamic Provisioning
Last updated
Was this helpful?