5. Kubernetes & Cloud Platform (AWS / GCP)
ทำไมหัวข้อนี้สำคัญกับ interview
K8s เป็น platform ที่ SRE ต้อง debug บ่อยที่สุด. คำถามจริงมักเป็นเชิงปฏิบัติ: "pod ขึ้น CrashLoopBackOff จะไล่ยังไง", "liveness ต่างจาก readiness ยังไง", "traffic ไม่ถึง pod เกิดจากอะไรได้บ้าง". ตอบให้ดีต้องรู้ทั้ง architecture และ คำสั่ง debug จริง.
ในฐานะ Cloud Engineer มองง่าย ๆ: K8s คือ control loop ขนาดใหญ่ที่พยายามทำให้ actual state = desired state ตลอดเวลา. งาน debug ส่วนใหญ่คือ "ทำไม reconcile ไม่สำเร็จ".
Core Concepts
Architecture
- kube-apiserver — ประตูเดียวเข้าสู่ cluster (ทุกอย่างคุยผ่าน API นี้).
- etcd — เก็บ state ทั้งหมด (key-value). พังเมื่อไร cluster เสียความจำ.
- scheduler — เลือก node ให้ pod ใหม่ตาม resource/constraint.
- controller-manager — รัน control loop (เช่น ทำให้ ReplicaSet มี pod ครบจำนวน).
- kubelet — agent บน node ที่รัน/ดูแล pod ตามที่ apiserver บอก.
- kube-proxy — จัดการ network rule ให้ Service routing ทำงาน.
Workload objects (ลำดับชั้น)
Deployment → ReplicaSet → Pod. เขียน Deployment กำหนด desired replicas + template; ReplicaSet คุมจำนวน pod; Pod คือหน่วยรันจริง (1+ container ที่ใช้ network/namespace ร่วมกัน).
apiVersion: apps/v1
kind: Deployment
metadata:
name: checkout
spec:
replicas: 3
selector:
matchLabels: { app: checkout }
template:
metadata:
labels: { app: checkout }
spec:
containers:
- name: checkout
image: registry/checkout:1.4.2 # อย่าใช้ :latest ใน prod
resources:
requests: { cpu: "250m", memory: "256Mi" } # ใช้ schedule
limits: { cpu: "500m", memory: "512Mi" } # เกินโดน throttle/OOMKilled
readinessProbe:
httpGet: { path: /healthz, port: 8080 }
initialDelaySeconds: 5
livenessProbe:
httpGet: { path: /livez, port: 8080 }
initialDelaySeconds: 15Service vs Ingress & Networking
- Service (ClusterIP) — IP/DNS ภายในที่คงที่ + load balance ไปยัง pod ที่ตรง selector.
- NodePort / LoadBalancer — เปิดออกนอก (LoadBalancer มัก provision cloud LB ให้).
- Ingress — L7 routing (host/path) เข้าหลาย Service ผ่าน controller ตัวเดียว.
- CoreDNS — service discovery ภายใน (เช่น
checkout.default.svc.cluster.local). - CNI — plugin ที่ให้ pod มี IP และคุยข้าม node ได้.
liveness vs readiness — ข้อที่ถามเกือบทุกครั้ง
Readiness = "พร้อมรับ traffic ไหม" — ถ้า fail จะถูกถอดออกจาก Service endpoint (ไม่ส่ง traffic เข้า) แต่ ไม่ restart. Liveness = "ตายค้างไหม" — ถ้า fail kubelet จะ restart container. ตั้ง liveness ไวเกิน = ระบบที่แค่ช้าโดน kill วนไปเป็น restart loop.
Debug: อาการยอดฮิต
| อาการ | สาเหตุที่พบบ่อย | ดูตรงไหน |
|---|---|---|
| CrashLoopBackOff | app exit ทันที (config/ENV ผิด, dependency ไม่พร้อม, liveness fail) | kubectl logs, describe |
| ImagePullBackOff | image ผิด/tag ไม่มี/ไม่มีสิทธิ์ registry | describe (events) |
| OOMKilled | ใช้ memory เกิน limit | describe (last state), metrics |
| Pending | ไม่มี node พอ (resource/taint/affinity), PVC ไม่ bound | describe (scheduler events) |
| traffic ไม่ถึง pod | selector/label ไม่ตรง, readiness fail, port ผิด | get endpoints, describe svc |
kubectl get pods -n prod # ดูสถานะรวม
kubectl describe pod checkout-xxxx -n prod # events + last state (OOMKilled ฯลฯ)
kubectl logs checkout-xxxx -n prod --previous # log ของ container ที่เพิ่ง crash
kubectl get endpoints checkout -n prod # Service มี pod อยู่หลังไหม (ว่าง = ไม่มี ready pod)
kubectl exec -it checkout-xxxx -n prod -- sh # เข้าไปเช็กในนั้นเชื่อมกับ AWS / Cloud ที่คุณรู้อยู่แล้ว
| แนวคิด K8s | บริการ AWS ที่ map |
|---|---|
| Managed control plane | Amazon EKS (จัดการ apiserver/etcd ให้) |
| Node | Managed Node Groups หรือ Fargate (serverless pods) |
| LoadBalancer / Ingress | AWS Load Balancer Controller → ALB/NLB |
| Persistent storage | EBS CSI / EFS CSI |
| Pod identity → IAM | IRSA (IAM Roles for Service Accounts) แทนการฝัง key |
| Registry | Amazon ECR |
| Metrics/logs | CloudWatch Container Insights, Fluent Bit |
จุดที่ทำให้ตอบได้ลึก
บน EKS control plane เป็น managed (คุณไม่ต้องดู etcd เอง) แต่คุณยังรับผิดชอบ node, networking (VPC CNI ให้ pod ได้ IP จริงใน VPC), และ IAM. ประเด็น IRSA มักถูกถาม: มันผูก IAM role กับ ServiceAccount ผ่าน OIDC เพื่อให้ pod เรียก AWS API ได้แบบ least privilege โดยไม่ต้องฝัง access key.
คำถาม interview ที่เจอบ่อย + แนวคำตอบ
-
"เกิดอะไรขึ้นเมื่อ
kubectl applyDeployment?" → apiserver เขียน desired state ลง etcd → controller สร้าง ReplicaSet/Pod → scheduler จับ pod ลง node → kubelet บน node ดึง image และรัน container → probe ผ่านแล้วเข้า Service. -
"pod เป็น CrashLoopBackOff จะ debug ยังไง?" →
describeดู events + last state,logs --previousดู log ก่อน crash. เช็ก config/ENV, dependency, และ liveness probe ที่อาจ kill เร็วเกิน. "BackOff" = kubelet หน่วง restart ถี่ขึ้นเรื่อย ๆ. -
"liveness ต่างจาก readiness ยังไง?" → readiness คุมการรับ traffic (fail = ถอดจาก endpoint, ไม่ restart); liveness คุมการ restart (fail = kill+restart). ใช้ readiness ตอน warmup/พึ่งพา dependency; liveness ตอน deadlock.
-
"requests กับ limits ต่างกันยังไง เกี่ยวกับ OOMKilled?" → requests ใช้ตัดสิน scheduling (จองขั้นต่ำ); limits คือเพดาน. เกิน memory limit → OOMKilled; เกิน CPU limit → ถูก throttle (ไม่ kill). ไม่ตั้ง limit = noisy neighbor.
-
"traffic ไม่ถึง pod เป็นเพราะอะไรได้บ้าง?" → selector/label ไม่ตรง (Service ไม่มี endpoint), readiness fail (pod ไม่เข้า pool), port/targetPort ผิด, NetworkPolicy บล็อก, หรือ DNS/Ingress config ผิด. เริ่มจาก
kubectl get endpoints.
Pitfalls — จุดที่ผู้สมัครมักพลาด
ระวังกับดักเหล่านี้
- ไม่ตั้ง resource requests/limits → scheduling มั่ว, noisy neighbor, OOM.
- liveness probe ไวเกิน → app ที่แค่ช้าโดน restart วน (CrashLoop ปลอม ๆ).
- ไม่ตั้ง readiness → traffic ถูกส่งเข้า pod ที่ยัง warmup ไม่เสร็จ → error ช่วง deploy.
- ใช้ image tag
:latest→ rollback/reproduce ไม่ได้, pod แต่ละตัวอาจคนละเวอร์ชัน. - ฝัง AWS access key ใน env แทนใช้ IRSA → เสี่ยง credential leak.
- สับสน "pod restart แก้ได้" กับ root cause → OOM/CrashLoop ต้องแก้ที่ config/limit จริง.
Quiz ท้ายบท
Quiz ท้ายบท
ตอบแล้ว 0/71.pod อยู่ในสถานะ Pending นานผิดปกติ สาเหตุที่เป็นไปได้มากที่สุดคือข้อใด?
2.ความต่างที่ถูกต้องระหว่าง liveness และ readiness probe คือข้อใด?
3.container ถูก OOMKilled เกิดจากอะไร และต่างจากการเกิน CPU limit อย่างไร?
4.Service ตัวหนึ่งมี traffic ส่งไปไม่ถึง pod เลย คำสั่งใดควรเช็กเป็นอันดับแรก?
5.บทบาทของ etcd ใน Kubernetes คืออะไร?
6.บน Amazon EKS วิธีที่แนะนำให้ pod เรียก AWS API แบบ least privilege คือข้อใด?
7.ทำไมจึงไม่ควรใช้ image tag ':latest' ใน production?
Cheat Sheet — อ่านก่อนเข้าห้องสัมภาษณ์
สรุปเร็ว 30 วินาที
- Control plane: apiserver (ประตู) · etcd (state) · scheduler · controller-manager; Node: kubelet · kube-proxy
- Deployment → ReplicaSet → Pod; Service (ClusterIP) → Ingress (L7); CoreDNS = discovery
- readiness = รับ traffic ไหม (ไม่ restart) · liveness = restart เมื่อค้าง
- requests = schedule · limits = เพดาน; เกิน mem → OOMKilled, เกิน CPU → throttle
- Debug:
describe(events/last state) ·logs --previous·get endpoints(traffic ไม่ถึง pod) - อาการ: CrashLoopBackOff · ImagePullBackOff · OOMKilled · Pending
- AWS: EKS · Node Group/Fargate · ALB Controller · EBS/EFS CSI · IRSA · ECR · Container Insights