ข้ามไปยังเนื้อหา

kubectl และ Declarative YAML

kubectl คือวิธีที่คุณส่ง desired state ให้ cluster และตรวจดูว่ากำลังทำอะไรอยู่ และเกือบทุกอย่างที่คุณส่งให้ cluster คือ YAML manifest ที่สร้างจากสี่ field หลักชุดเดียวกัน

kubeconfig ของคุณเก็บ credential ของหลาย cluster พร้อมกันได้ จัดกลุ่มเป็น context สลับว่าคำสั่งของคุณจะยิงไปที่ตัวไหนด้วย

Terminal window
kubectl config use-context my-cluster
kubectl get pods -n my-namespace

flag -n (หรือ --namespace) จำกัดขอบเขตคำสั่งให้อยู่ใน namespace เดียว ถ้าไม่ใส่จะยิงไปยัง namespace default ของ context ปัจจุบัน ซึ่งปกติคือ default นอกจากนี้ verb ชุดเล็ก ๆ ก็ครอบคลุมการใช้งาน kubectl ในชีวิตประจำวันส่วนใหญ่แล้ว

Terminal window
kubectl get pods
kubectl describe pod web-7d9f8c6b7-abcde
kubectl logs web-7d9f8c6b7-abcde
kubectl exec -it web-7d9f8c6b7-abcde -- sh

get แสดงรายการ object describe แสดงสถานะละเอียดและ event ล่าสุดของ object หนึ่งตัว (จุดแรกที่ควรดูเมื่อมีอะไรผิดปกติ) logs stream stdout/stderr ของ container ส่วน exec รันคำสั่งข้างใน container ที่กำลังรันอยู่ เหมาะเวลาต้องการ shell เร็ว ๆ เข้าไปดูข้างใน

ไม่ว่าจะสร้าง object แบบไหน Pod, Deployment, Service หรืออะไรก็ตาม YAML ของตัวเองมีโครงเดียวกัน

apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80

apiVersion กับ kind บอกว่าคุณหมายถึง API group และ object type ไหน metadata เก็บตัวตนและข้อมูลบัญชี เช่น name, namespace (ถ้ามี) และ labels กับ annotations ที่คุณติดเอง spec คือ desired state ที่คุณเขียนขึ้น ทุกอย่างข้างบนคือ spec ของ Pod ตัวนี้ Kubernetes เพิ่ม field ที่ห้าให้เองคือ status เมื่อ object ถูกสร้างแล้ว field นี้คุณไม่เคยเขียนเอง อ่านได้อย่างเดียว เพราะสะท้อนสิ่งที่สังเกตเห็นจริง ไม่ใช่สิ่งที่คุณขอ

kubectl apply -f file.yaml เป็นแบบ declarative โดย diff ไฟล์ของคุณกับ last-applied configuration ของ object (ที่ถูก track ไว้ใน annotation) แล้ว patch เฉพาะส่วนที่เปลี่ยน และสร้าง object ให้ถ้ายังไม่มี ทำให้รันคำสั่งเดิมซ้ำ ๆ ได้อย่างปลอดภัย นั่นคือสิ่งที่ต้องการพอดีใน script และ CI ส่วน kubectl create -f file.yaml เป็นแบบ imperative แทน คือสร้าง object ครั้งเดียวและจะ error ถ้ามี object นั้นอยู่แล้ว คอร์สนี้ใช้ apply ตลอดทั้งเล่ม

Terminal window
kubectl apply -f pod.yaml
kubectl create -f pod.yaml

label คือคู่ key-value ตามใจที่คุณติดไว้บน object เช่น app: web ใน Pod ด้านบน ตัว label เองไม่ทำอะไรเลย พลังของ label มาจาก selector นั่นคือสิ่งที่ object อื่นใช้หา Pod ที่ถูกติด label แบบนั้น Service ที่มี selector: { app: web } จะ route traffic ไปยังทุก Pod ที่มี label นั้น ส่วน ReplicaSet ของ Deployment ใช้ matchLabels selector เพื่อรู้ว่า Pod ไหนคือ Pod “ของตัวเอง” ที่ต้องรักษาให้อยู่ตาม replica count ที่ต้องการ pattern label-กับ-selector นี้คือวิธีพื้นฐานที่สุดที่ object ใน Kubernetes ใช้หากันเจอ และคุณจะเห็น pattern นี้อีกในเกือบทุก module ถัดไป

flowchart LR
  cmd["kubectl apply -f pod.yaml"] --> api["kube-apiserver"]
  api --> etcd["etcd"]
  api --> ctrl["Controllers notice the change and react"]
A declarative apply flows through the API server into etcd
เมื่อ object ปลายทางมีอยู่แล้ว kubectl apply กับ kubectl create ต่างกันยังไง
จริง ๆ แล้ว label selector ทำอะไร
manifest ของ Kubernetes object ทุกตัวมี top-level field สี่ตัวอะไรบ้าง
field ไหนบน Kubernetes object ที่ live อยู่ ถูกจัดการโดยระบบ และไม่ใช่สิ่งที่คุณเขียนเอง