PipeCraft

Roadmap Progress

ข้อมูลเบื้องต้นเกี่ยวกับวิศวกรรมข้อมูล (Introduction to Data Engineering) Python สำหรับ Data Engineering พื้นฐาน Linux & CLI สำหรับวิศวกรข้อมูล Git สำหรับระบบงานข้อมูลและทีมพัฒนา พื้นฐานเครือข่าย เว็บเทคโนโลยี และระบบกระจายศูนย์ (Web Fundamentals, Networking & Distributed Systems) SQL ขั้นสูง (Window Functions & Optimization) ฐานข้อมูลไม่ใช่เชิงสัมพันธ์ (NoSQL Databases & Modern Stores) การออกแบบโครงสร้างข้อมูล (Star/Snowflake & SCD) โครงสร้างพื้นฐานเครือข่ายระบบคลาวด์ (Cloud-based Networking) สถาปัตยกรรม Data Lakehouse (Apache Iceberg & MinIO) Local-first Data Engineering ด้วย DuckDB โครงสร้างพื้นฐานในรูปแบบโค้ด (IaC ด้วย Terraform) การแปลงข้อมูลระดับโปรด้วย dbt-core ข้อตกลงร่วมด้านข้อมูล (Data Contracts) การบริการและการส่งต่อข้อมูลวิเคราะห์ (Data Serving & Reverse ETL) การประมวลผลข้อมูลขนาดใหญ่แบบกระจายด้วย Apache Spark ระบบจัดการเวิร์กโฟลว์ข้อมูล (Airflow, Dagster & Prefect) การประมวลผลข้อมูลแบบเรียลไทม์ด้วย Kafka & Redpanda การจัดการคอนเทนเนอร์และคลัสเตอร์ (Containers & Kubernetes) ระบบ CI/CD และการเฝ้าระวังคุณภาพข้อมูล (CI/CD, Monitoring & Testing) ระบบความปลอดภัยและการควบคุมข้อมูล (Security, Governance & Privacy) ระบบปฏิบัติการและประมวลผลโมเดล (Machine Learning & MLOps) รากฐานของ AWS VPC การจัดการเส้นทางขั้นสูงและ NAT Gateway การเชื่อมต่อหลาย VPC และ Hybrid Cloud VPC Endpoints (PrivateLink) ระบบรักษาความปลอดภัยขอบเขตเครือข่าย สถาปัตยกรรมเครือข่ายสำหรับ EKS IPv6 และการจัดการ IP Address สถาปัตยกรรมเครือข่ายระดับโลก แก่นแท้ของสถาปัตยกรรม Kubernetes สถาปัตยกรรมเครื่องและคอมโพเนนต์ เลเยอร์ที่เชื่อมต่อได้ (Pluggable Layers) การรันบนโปรดักชันระดับองค์กร Apache Flink Stateful Stream Processing Real-Time CDC & Event Sourcing at Scale Low-Latency Stream-Table Joins & Windowing Data Lineage & Metadata Graph Engineering Statistical Anomaly Detection & Data Drift Data Incident Management & Automated DLQ Remediation Cloud Data FinOps & Cost Optimization Mechanics Data Mesh & Multi-Tenant Platform Architecture Vector Databases & AI-Ready Data Infrastructure API Fundamentals, Architectures & Core Components API Versioning, Docs, Real-Time & Microservices Production Reliability, Security & Resiliency World-Class Master Architecture & Traffic Management
บทที่ 7: สถาปัตยกรรม Kubernetes (Kubernetes Architecture)

แก่นแท้ของสถาปัตยกรรม Kubernetes

Chapter 1: The Core Model (แก่นแท้ของสถาปัตยกรรม Kubernetes)

1. What Kubernetes Actually Is (ปฐมบทแห่ง Orchestration)

Learning Progression

  • 🟢 Basic Level: ปูพื้นฐานภาษาเข้าใจง่าย - เข้าใจคอนเซปต์ภาพรวมและการแก้ปัญหาเบื้องต้น
  • 🟡 Intermediate Level: โค้ด/คอนฟิกไวยากรณ์จริง - การเขียนโค้ดเพื่อใช้งานจริงในระบบ
  • 🔴 Professional Level: Under-the-hood & Performance/FinOps - กลไกเบื้องลึกและการรีดประสิทธิภาพ

🏢 Real-World Enterprise Scenario

เคสระบบการเงิน/Big Tech: การรองรับ Transaction จำนวนมหาศาลต่อวินาทีพร้อมประกัน Data Integrity สูงสุด โดยใช้สถาปัตยกรรมที่ยืดหยุ่นและการมอนิเตอร์ระดับสูง

ทฤษฎีและกลไกการทำงาน (How it works):
ในยุคก่อนหน้านี้ เทคโนโลยี Container (เช่น Docker) เข้ามาแก้ปัญหา "โค้ดรันบนเครื่องโปรแกรมเมอร์ได้ แต่พังบน Production" โดยการแพ็กโค้ดและไลบรารีทั้งหมดไว้ในกล่องเดียว (Container) แต่ปัญหาที่ Docker แก้ไม่ได้คือ สเกล (Scale) เมื่อคุณมี Container หลักร้อยตัวกระจายอยู่บนเซิร์ฟเวอร์หลักสิบเครื่อง คำถามคือ: ใครจะเป็นคนสั่งว่า Container ตัวไหนควรไปรันบนเครื่องไหน? ถ้าเครื่องเซิร์ฟเวอร์ดับตอนตีสาม ใครจะปลุก Container ขึ้นมาใหม่? และจะตั้งชื่อ (DNS) ให้พวกมันคุยกันเองข้ามเครื่องได้อย่างไร?

Kubernetes (K8s) ถือกำเนิดขึ้นมาเพื่อรับช่วงต่อปัญหานี้ มันไม่ใช่แค่เครื่องมือรัน Container แต่เป็น Container Orchestration Platform หน้าที่ของมันคือการนำเซิร์ฟเวอร์หลายๆ เครื่อง (Nodes) มารวมกันเป็น "สระทรัพยากร (Resource Pool)" ก้อนเดียวที่เรียกว่า Cluster จากนั้นมันจะทำหน้าที่เป็น "ผู้จัดการศูนย์กลาง" ที่คอยแจกจ่ายงาน (Scheduling), ซ่อมแซมตัวเอง (Self-healing), และจัดสรรเครือข่ายให้โดยอัตโนมัติ โดยเปลี่ยนเครื่องเซิร์ฟเวอร์ให้กลายเป็นทรัพยากรที่ใช้แล้วทิ้ง (Interchangeable components)

# เราไม่ต้องเขียนสคริปต์ Bash เพื่อ SSH ไปรัน Docker ทีละเครื่อง
# แต่เราสร้าง Deployment ประกาศสิ่งที่เราต้องการให้ K8s จัดการแทน
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-frontend
spec:
  replicas: 3 # ฉันต้องการ 3 ตัวเสมอ! (K8s จะไปหาวิธีทำมาให้เอง)
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        

Use Case ในชีวิตจริง (Real-world Scenario):
บริษัท E-commerce รันแคมเปญ 11.11 ในช่วงเวลาปกติพวกเขาอาจรัน Web Server แค่ 5 ตัวกระจายบน 2 เครื่อง แต่เมื่อถึงเวลาเที่ยงคืน ทราฟฟิกพุ่งสูงขึ้น 10 เท่า ระบบ Auto-scaler ของ Kubernetes จะตรวจจับโหลดและสั่งเพิ่มจำนวน Web Server เป็น 50 ตัวโดยอัตโนมัติ และจะทำการกระจาย (Schedule) ไปยังเซิร์ฟเวอร์เครื่องอื่นๆ ที่ยังว่างอยู่ทันที โดยทีมงานไม่ต้องตื่นมากดรันสคริปต์ขยายระบบด้วยตนเองเลย

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): ผู้เริ่มต้นมักจะพยายามนำแนวคิดเดิมๆ (เช่น การ SSH เข้าไปแก้ไฟล์คอนฟิกสดๆ ภายใน Container) มาใช้กับ Kubernetes เมื่อ Container ตายและถูกสร้างใหม่ การแก้ไขด้วยมือทั้งหมดจะหายวับไป (Ephemeral nature)
* Mitigation (วิธีแก้): ต้องเปลี่ยนกรอบความคิด (Mindset) สู่ Immutable Infrastructure ห้ามเข้าไปแก้ไขอะไรภายใน Container เด็ดขาด หากต้องการเปลี่ยนคอนฟิก ให้แก้ที่ต้นทาง (เช่น ConfigMap หรือแก้ไข Docker Image ใหม่) แล้วสั่ง Deploy ทับลงไปแทน

2. The Core Idea (Desired State & Reconciliation Loop)

ทฤษฎีและกลไกการทำงาน (How it works):
ความลับที่ทำให้ Kubernetes ทรงพลังและไม่มีวันตาย คือกลไกที่เรียกว่า Level-triggered Control Loop หรือ Reconciliation
ในระบบทั่วๆ ไป (Edge-triggered) เมื่อเกิดเหตุการณ์บางอย่าง (เช่น แอปล่ม) ระบบจะส่ง Event ไปกระตุ้นให้สคริปต์ทำงาน แต่ถ้าเครือข่ายพังและ Event นั้นส่งไปไม่ถึง สคริปต์ก็จะไม่ทำงาน และระบบจะพังคาอยู่อย่างนั้น

แต่ Kubernetes ใช้หลักการ "เปรียบเทียบสถานะ (Level-triggered)":
1. Desired State: สถานะอุดมคติที่คุณประกาศไว้ใน YAML (เช่น "ต้องมี Web Server 3 ตัว")
2. Observed State: สถานะความเป็นจริงที่เกิดขึ้นบนเซิร์ฟเวอร์ในวินาทีนี้ (เช่น "มี Web Server รันอยู่แค่ 2 ตัว เพราะตายไป 1 ตัว")

ระบบย่อยของ Kubernetes (Controllers) จะตื่นขึ้นมาวนลูป (Loop) เพื่อตรวจสอบและเปรียบเทียบสองสถานะนี้ตลอดเวลาแบบไม่รู้จบ เมื่อใดที่พบว่า "ความจริง (Observed)" ไม่ตรงกับ "ความฝัน (Desired)" มันจะออกคำสั่ง "ดึงความจริงให้ตรงกับความฝัน (Reconcile)" ทันที (ในกรณีนี้คือการสั่งรัน Container เพิ่มอีก 1 ตัว)

# เมื่อคุณสั่งลบ Pod ด้วยมือ (เพื่อจำลองว่า Pod ตาย)
$ kubectl delete pod web-frontend-abcd1

# Reconciliation Loop จะเห็นว่า Observed = 2 แต่ Desired = 3
# มันจะสร้าง Pod ใหม่ขึ้นมาแทนที่ภายในเสี้ยววินาทีทันที
$ kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
web-frontend-5b4d7c5897   3         3         3       5m
        

Use Case ในชีวิตจริง (Real-world Scenario):
ธนาคารแห่งหนึ่งมีระบบ Core Banking ที่ต้องการความเสถียร 99.999% หากเซิร์ฟเวอร์ฮาร์ดแวร์หลักเกิดไฟไหม้และดับไป 1 Node (ซึ่งมี Pod รันอยู่ 50 ตัว) ภายในเสี้ยววินาทีที่ Node นั้นขาดการติดต่อ (Node NotReady) Control Loop ของ Kubernetes จะรับรู้ว่า Observed State หายไป 50 Pods มันจะทำการจัดตาราง (Reschedule) และเสก 50 Pods นั้นไปเกิดใหม่บน Node เครื่องอื่นๆ ที่ยังรอดชีวิตทันที โดยแทบไม่ต้องพึ่งพามนุษย์

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): ถ้าคุณตั้งค่า Desired State ที่เป็นไปไม่ได้ เช่น ขอ CPU 100 Cores ให้กับ Pod เดียว แต่ในคลัสเตอร์คุณมีเครื่องละแค่ 8 Cores ลูป Reconciliation จะทำงานตลอดเวลา และ Pod ของคุณจะค้างอยู่ในสถานะ Pending ชั่วกัลปาวสาน
* Mitigation (วิธีแก้): เฝ้าระวังสถานะ Pending หรือ CrashLoopBackOff ผ่านระบบ Monitoring (เช่น Prometheus/Grafana) เสมอ เพราะมันคือสัญญาณเตือนว่าระบบพยายาม Reconcile แล้วแต่ทำไม่สำเร็จเนื่องจากติดข้อจำกัดบางอย่างทางฟิสิกส์หรือลอจิก

3. The Object Model (Spec vs Status)

ทฤษฎีและกลไกการทำงาน (How it works):
ทุกสรรพสิ่งใน Kubernetes ไม่ว่าจะเป็น Pod, Service, Volume หรือ Rule ต่างๆ ถูกจัดเก็บในรูปแบบฐานข้อมูลเชิงวัตถุ (API Objects) และทุกๆ Object จะถูกบังคับให้มีโครงสร้างทางสถาปัตยกรรม (Anatomy) ที่เหมือนกันเป๊ะ คือแบ่งออกเป็น 2 ส่วนหลัก:

1. Spec (Specification): พื้นที่ที่คุณ (หรือระบบ CI/CD) เป็นคนเขียน เพื่อบอกว่าคุณต้องการอะไร
2. Status: พื้นที่สงวนที่ ห้ามมนุษย์เขียนเด็ดขาด (Read-only สำหรับมนุษย์) มีเพียง Controllers ของ Kubernetes เท่านั้นที่มีสิทธิ์เขียนทับลงไป เพื่ออัปเดตว่าปัจจุบันสถานะของวัตถุชิ้นนี้เป็นอย่างไร

ความสม่ำเสมอ (Uniformity) นี้ทำให้เครื่องมือและ API ของ Kubernetes สามารถจัดการกับวัตถุทุกชนิดได้ด้วยมาตรฐานเดียวกัน (เช่น ใช้ kubectl apply ได้กับทุกสิ่ง) นอกจากนี้ วัตถุต่างๆ จะถูกจัดกลุ่มด้วย API Groups และมี Versioning (เช่น v1, v1beta1, v1alpha1) เพื่อให้ระบบสามารถวิวัฒนาการเพิ่มฟีเจอร์ใหม่ๆ ได้โดยไม่ทำลายโค้ดเก่าที่ลูกค้ารันอยู่

# ผลลัพธ์จากการรัน: kubectl get pod nginx-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec: # <--- [ฝั่งของคุณ] คุณเป็นคนกำหนดสิ่งนี้
  containers:
  - image: nginx:latest
    name: nginx
status: # <--- [ฝั่งของ K8s] Controller เป็นคนอัปเดตสิ่งนี้
  conditions:
  - status: "True"
    type: Ready
  containerStatuses:
  - image: nginx:latest
    ready: true
    restartCount: 0
  hostIP: 192.168.1.10
  phase: Running
  podIP: 10.244.1.5
        

Use Case ในชีวิตจริง (Real-world Scenario):
ทีม DevOps ต้องการเขียนโปรแกรมเพื่อแสดงผล Dashboard ของตัวเอง พวกเขาไม่ต้องไปเจาะฐานข้อมูลลึกๆ เพียงแค่ยิง HTTP GET ไปที่ Kubernetes API และอ่านค่าจากฟิลด์ status.phase ของวัตถุต่างๆ ก็สามารถรู้สุขภาพแบบเรียลไทม์ของทั้งคลัสเตอร์ได้ทันที รูปแบบ Object Model ที่เป็นมาตรฐานนี้ ทำให้เกิด Ecosystem ของเครื่องมือเสริม (เช่น ArgoCD, Helm) ที่เติบโตอย่างมหาศาล

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): ผู้ใช้ที่พยายามเอาไฟล์ YAML ที่ Export ออกมาจากคลัสเตอร์ (ซึ่งติดส่วน status และ metadata ที่ K8s สร้างขึ้นเช่น uid, resourceVersion มาด้วย) ไป Apply ใส่คลัสเตอร์ใหม่ จะทำให้เกิด Error พังพินาศ เพราะคุณกำลังพยายามแก้ไขค่าที่ K8s ห้ามมนุษย์ยุ่ง
* Mitigation (วิธีแก้): เมื่อทำการแบ็กอัปหรือย้ายระบบ ห้ามคัดลอกส่วน status ไปเด็ดขาด หรือให้ใช้คำสั่งอย่าง kubectl neat (ปลั๊กอินยอดฮิต) เพื่อทำการ "ล้าง" ฟิลด์ที่มนุษย์ไม่ได้สร้างออกไปให้หมด ก่อนจะนำไฟล์ไปจัดเก็บใน Git Repository (GitOps)

4. How the Parts Talk (Watch and Reconcile Fabric)

ทฤษฎีและกลไกการทำงาน (How it works):
ความเข้าใจผิดที่ใหญ่ที่สุดของมือใหม่คือ คิดว่าส่วนประกอบต่างๆ ของ K8s โทรคุยกันตรงๆ (เช่น Scheduler โทรไปสั่ง Kubelet ให้เปิด Pod) ความจริงคือ ไม่มีการคุยตรงแบบนั้นเลยแม้แต่น้อย!

ใน K8s API Server คือหัวใจและศูนย์กลางเพียงหนึ่งเดียว (The Single Source of Truth) ทุกคอมโพเนนต์ (Scheduler, Kubelet, Controllers) จะทำตัวเป็นคนหูหนวกตาบอดที่คุยได้เฉพาะกับ API Server เท่านั้น

กลไกที่ใช้ประสานงานคือสิ่งที่เรียกว่า "Watch Mechanism" (การเปิดสตรีม HTTP ขาลงทิ้งไว้)
ตัวอย่างเช่น: Kubelet ประจำเครื่อง Node-A จะเปิดการ Watch ไปที่ API Server พร้อมบอกว่า *"ถ้ามี Pod หน้าใหม่ที่ถูกกำหนดให้มารันบนเครื่อง Node-A ช่วยกระซิบบอกฉันด้วยนะ"*
เมื่อ API Server มีการอัปเดตข้อมูลลงฐานข้อมูล (etcd) มันก็จะส่งสัญญาณสตรีมกลับไปหา Kubelet ตัวนั้นทันที สถาปัตยกรรมแบบ Event-driven (Star topology) นี้ ทำให้ระบบไม่มีอาการคอขวดจากการที่คอมโพเนนต์คุยกันเองจนเกิด Deadlock

# เปิด Terminal ช่องที่ 1: สั่ง Watch การเปลี่ยนแปลงของ Pods ในแบบเรียลไทม์
# สังเกตว่าคำสั่งนี้จะไม่ยอมหยุดทำงาน (Hangs) เพราะมันเปิดสตรีมรอรับข้อมูล
$ kubectl get pods --watch

# เปิด Terminal ช่องที่ 2: สร้าง Pod ใหม่
$ kubectl run test-pod --image=nginx

# กลับมาดูที่ Terminal 1: คุณจะเห็นเหตุการณ์ (Events) ไหลเข้ามาอัตโนมัติ
test-pod   0/1   Pending   0     0s
test-pod   0/1   Pending   0     0s
test-pod   0/1   ContainerCreating   0     0s
test-pod   1/1   Running   0     2s
        

Use Case ในชีวิตจริง (Real-world Scenario):
การออกแบบผ่าน Watch Fabric ทำให้ Kubernetes มีความยืดหยุ่นสูงต่อภาวะ Network Partition (เน็ตหลุด) สมมติว่า Kubelet ที่ Node หนึ่งเกิดเน็ตหลุดไป 5 นาที มันจะคุยกับ API Server ไม่ได้ (แต่ Pod ยังคงรันให้บริการลูกค้าต่อไปได้ตามปกติ) เมื่อเน็ตกลับมา Kubelet จะเชื่อมต่อ Watch ใหม่ และ API Server จะทำการส่ง History (Event แบบรวบยอด) ย้อนหลังไปให้ เพื่อให้ Kubelet ปรับสถานะตัวเองให้ทันเหตุการณ์ (Level-based reconciliation)

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): ถ้ามี Custom Controller เขียนไม่ดี และพยายามยิงคำสั่ง GET ข้อมูล Pod ทั้งหมดทีละตัวๆ ในลูปเพื่ออัปเดตสถานะ (Polling) จะทำให้ API Server ทำงานหนักจนพังคามือ (API Throttling/Overload)
* Mitigation (วิธีแก้): ห้ามเขียนโค้ดที่ทำ Polling เด็ดขาด การพัฒนา Controller ใน K8s (ผ่าน client-go) ต้องอาศัยเครื่องมือที่เรียกว่า Informers ซึ่งจะทำการใช้ Watch Mechanism ดึงข้อมูลมาแคช (Cache) ไว้ในหน่วยความจำเครื่องตัวเอง และจะได้รับการอัปเดตเฉพาะจังหวะที่มี Event เปลี่ยนแปลงเท่านั้น (Delta compression) ช่วยลดภาระ API Server ไปได้ 99%

5. End-to-End Coordination (วัฏจักรการเกิดของ Pod)

ทฤษฎีและกลไกการทำงาน (How it works):
เพื่อขมวดปมทั้งหมดให้เห็นภาพชัดเจน ลองตามรอยชีวิตของการสั่ง Deploy แอปพลิเคชันหนึ่งตัว:
1. คุณ (User): สั่ง kubectl apply -f deployment.yaml คำสั่งนี้จะวิ่งไปที่ API Server
2. API Server: ตรวจสอบสิทธิ์ (Auth/RBAC) และบันทึก Deployment ลงฐานข้อมูล etcd
3. Deployment Controller: หูผึ่ง (ผ่าน Watch) เห็น Deployment มาใหม่ มันคำนวณและตอบสนองโดยการส่งคำสั่งสร้าง ReplicaSet คืนกลับไปให้ API Server
4. ReplicaSet Controller: หูผึ่ง เห็น ReplicaSet มาใหม่ มันพบว่าต้องการ 3 Pods แต่วินาทีนี้มี 0 มันจึงส่งคำสั่งสร้าง Pod เปล่าๆ 3 ตัว (สถานะ Pending, ยังไม่มีที่อยู่) คืนกลับไปที่ API Server
5. Scheduler: หูผึ่ง เห็น Pod ที่ยังไม่มีที่อยู่ (Unscheduled) มันวิเคราะห์ทรัพยากร แล้วเลือก Node ที่เหมาะสมที่สุด จากนั้นอัปเดตข้อมูลบอก API Server ว่า "Pod ตัวนี้จงไปอยู่ Node-A"
6. Kubelet (บน Node-A): หูผึ่ง เห็น Pod ถูกกำหนดชื่อให้มาตกที่เครื่องตัวเอง มันรับคำสั่งและหันไปคุยกับ Container Runtime (เช่น containerd) เพื่อดาวน์โหลด Image และสตาร์ทคอนเทนเนอร์ จากนั้นอัปเดต Status กลับไปที่ API Server ว่า "Running แล้วนะ"

ทุกขั้นตอนไม่มีใครคุยกันเองเลย ทุกคนคุยกับ API Server ล้วนๆ นี่คือสุดยอดสถาปัตยกรรมการประสานงาน (Coordination) แบบหลวมๆ (Decoupled) ของ Kubernetes

# เมื่อเราดูรายละเอียดของ Pod เราจะเห็นร่องรอยการทำงานของแต่ละคอมโพเนนต์
$ kubectl describe pod web-frontend-abcd1

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  # Scheduler รับบทบาทจัดสรรที่อยู่
  Normal  Scheduled  15s   default-scheduler  Successfully assigned default/web-frontend-abcd1 to ip-10-0-1-5
  # Kubelet รับบทบาทดาวน์โหลดและรัน
  Normal  Pulling    14s   kubelet            Pulling image "nginx:1.24"
  Normal  Pulled     10s   kubelet            Successfully pulled image "nginx:1.24"
  Normal  Created    9s    kubelet            Created container nginx
  Normal  Started    9s    kubelet            Started container nginx
        

Use Case ในชีวิตจริง (Real-world Scenario):
รูปแบบวัฏจักรที่แยกส่วนนี้เปิดโอกาสให้เกิดการ สับเปลี่ยนอะไหล่ (Pluggability) ได้อย่างอิสระ องค์กรวิจัยด้าน AI สามารถปลด default-scheduler มาตรฐานทิ้งไป แล้วเขียน custom-scheduler ของตัวเองขึ้นมาเสียบแทน เพื่อให้มันอ่านค่า GPU แบบพิเศษ แล้วเลือก Node ได้ฉลาดขึ้น โดยไม่ต้องรื้อโค้ดในส่วนของ API Server หรือ Kubelet เลยแม้แต่บรรทัดเดียว นี่คือสาเหตุที่ K8s ครองโลก

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): กระบวนการทำงานแบบ Asynchronous (ไม่รอซึ่งกันและกัน) หมายความว่า เมื่อคุณสั่ง kubectl apply แล้วได้ข้อความว่า deployment.apps/web-frontend created ไม่ได้แปลว่าแอปคุณรันสำเร็จแล้ว มันแปลแค่ว่า "รับทราบคำสั่งและบันทึกลงฐานข้อมูลแล้ว" เท่านั้น แอปอาจจะพังคาดึง Image ไม่ได้อยู่เบื้องหลังก็ได้
* Mitigation (วิธีแก้): ในระบบ CI/CD Pipeline (เช่น Jenkins หรือ GitHub Actions) ห้ามจบการทำงานแค่คำสั่ง apply เด็ดขาด คุณต้องเพิ่มคำสั่ง kubectl rollout status deployment/web-frontend --timeout=90s ต่อท้ายเสมอ เพื่อให้ Pipeline หยุดรอจนกว่าลูป Reconciliation จะรันจนเสร็จสมบูรณ์จริงๆ และแอปพลิเคชันพร้อมให้บริการ (Ready) ค่อยผ่านสถานะเป็น Success

6. etcd Compaction & State Persistence

ทฤษฎีและกลไกการทำงาน:
etcd คือสมองของ Kubernetes ที่เก็บ State ทั้งหมด มันทำงานแบบ Append-only (เขียนต่อท้ายไปเรื่อยๆ) เพื่อรักษาประวัติเวอร์ชัน (MVCC) เมื่อมีการอัปเดต Pod เป็นพันๆ ครั้ง ฐานข้อมูลจะโตขึ้นจนอาจทำให้ประสิทธิภาพตก K8s จึงมีกลไก etcd Compaction ซึ่งจะทำการกวาดล้างประวัติเก่าๆ ที่ไม่ใช้แล้วทิ้งแบบอัตโนมัติ เพื่อรักษาขนาดของ Database และความเร็วในการตอบสนอง

# สั่งทำ Compaction แบบ Manual (หากพบปัญหาพื้นที่เต็ม)
ETCDCTL_API=3 etcdctl compact 
ETCDCTL_API=3 etcdctl defrag
        

Use Case ในชีวิตจริง:
คลัสเตอร์ขนาดใหญ่ที่มีการสร้าง/ลบ Job นับแสนงานต่อวัน เจอสถานการณ์ "etcd space quota exceeded" ทำให้ API Server ไม่รับคำสั่งใหม่ ทีมแอดมินจึงรัน etcd defragmentation เพื่อคืนพื้นที่ดิสก์และตั้งค่า Auto-compaction ให้กวาดล้างประวัติทุกๆ 5 นาที ทำให้ระบบกลับมาทำงานลื่นไหล

ข้อควรระวังและวิธีแก้:
* Pitfall: หากพื้นที่เก็บข้อมูล etcd ทำงานบน Disk ที่ช้า (เช่น HDD ธรรมดา) การทำ Compaction จะทำให้ I/O ล้น และ Cluster รวนทั้งหมด
* Mitigation: ต้องวาง etcd ไว้บนดิสก์ Enterprise SSD (NVMe) เสมอ เพื่อรับประกันค่า IOPS ที่เสถียร

🛠️ Weekend Sandbox Challenge: "The Reconciliation Watcher"

โจทย์ปฏิบัติการ: โจทย์ท้าทายความสามารถ:
1. สร้าง Minikube หรือ KinD cluster บนเครื่องของคุณ
2. ใช้คำสั่ง kubectl create deployment demo-nginx --image=nginx --replicas=2
3. ความท้าทายที่ 1: เปิด Terminal 2 หน้าต่าง หน้าต่างแรกสั่ง kubectl get pods --watch ทิ้งไว้
4. ความท้าทายที่ 2: ในหน้าต่างที่สอง ให้พยายามใช้คำสั่ง kubectl delete pod <ชื่อ-pod-ตัวใดตัวหนึ่ง>
5. พิสูจน์ผลลัพธ์: สังเกตในหน้าต่าง Watch ว่าเกิดเหตุการณ์อะไรขึ้น (คุณควรจะเห็น K8s สร้าง Pod ใหม่ขึ้นมาแทนที่แบบทันทีทันใด) ให้บันทึกความเข้าใจว่าชั่ววินาทีนั้น ReplicaSet Controller คิดและทำอะไรกับ API Server

💼 Senior Technical Interview Q&A

Q1: "ในแง่ของสถาปัตยกรรม ทำไม Kubernetes ถึงเลือกใช้ Level-triggered approach (เปรียบเทียบ State) แทนที่จะเป็น Edge-triggered (ทำงานตาม Event แบบ Publisher/Subscriber)?"

A: ระบบที่ใช้ Edge-triggered (เช่น ส่ง Message เข้าคิว) จะเปราะบางต่อสภาวะเครือข่ายล่มครับ หาก Message ร่วงหายกลางทาง ระบบจะเสียสมดุลไปตลอดกาล แต่ Level-triggered ของ Kubernetes จะพึ่งพาการดึงสถานะล่าสุด (Current State) มาเทียบกับความต้องการ (Desired State) เสมอ ทำให้ทนทานต่อการล่ม (Fault-tolerant) หาก Controller ดับไปและตื่นขึ้นมาใหม่ มันไม่ต้องสนใจเลยว่ามันพลาด Event อะไรไปบ้าง มันแค่ดูโลกความเป็นจริง ณ วินาทีนั้น และออกคำสั่งแก้ปัญหาให้ตรงกับ Spec ก็เพียงพอครับ

Q2: "อธิบายกลไกการแยกส่วนระหว่าง Spec และ Status พร้อมยกตัวอย่างสถานการณ์ที่สองสิ่งนี้มีค่าไม่ตรงกัน?"

A: Spec คือ 'ความต้องการ' ที่กำหนดโดยมนุษย์ ส่วน Status คือ 'ความจริง' ที่ K8s รับรู้ครับ สถานการณ์ที่ไม่ตรงกันมักจะเกิดขึ้นในช่วง Transition เช่น เรากำหนด Spec ให้ replicas=5 แต่ปัจจุบันระบบเพิ่งรันได้แค่ 2 (Status readyReplicas=2) ความต่างนี้คืองาน (Delta) ที่ Controller ต้องนำไป Reconcile หรือกรณีเกิดพัง เช่น เครื่อง Node ดับ Status ของ Pod จะกลายเป็น Unknown/Terminating ซึ่งขัดแย้งกับ Spec ที่ต้องการให้มันรันอยู่ ส่งผลให้ระบบเสก Pod ใหม่ขึ้นมาทดแทนครับ ### 💻 Weekend Sandbox Challenge: "The Reconciliation Watcher" โจทย์ท้าทายความสามารถ: 1. สร้าง Minikube หรือ KinD cluster บนเครื่องของคุณ 2. ใช้คำสั่ง kubectl create deployment demo-nginx --image=nginx --replicas=2 3. ความท้าทายที่ 1: เปิด Terminal 2 หน้าต่าง หน้าต่างแรกสั่ง kubectl get pods --watch ทิ้งไว้ 4. ความท้าทายที่ 2: ในหน้าต่างที่สอง ให้พยายามใช้คำสั่ง kubectl delete pod <ชื่อ-pod-ตัวใดตัวหนึ่ง> 5. พิสูจน์ผลลัพธ์: สังเกตในหน้าต่าง Watch ว่าเกิดเหตุการณ์อะไรขึ้น (คุณควรจะเห็น K8s สร้าง Pod ใหม่ขึ้นมาแทนที่แบบทันทีทันใด) ให้บันทึกความเข้าใจว่าชั่ววินาทีนั้น ReplicaSet Controller คิดและทำอะไรกับ API Server

Deep Dive & Production Architecture

Architecture Diagram
Technical Architecture Diagram block with Step-by-Step Breakdown

🟢 Basic Level (ปูพื้นฐานภาษาเข้าใจง่าย / Core Concepts)

ทฤษฎีและกลไกการทำงาน (Theory & Mechanism): แนวคิดพื้นฐานของการวางโครงสร้างระบบให้ทำงานได้อย่างถูกต้อง ตั้งแต่การเชื่อมต่อเครือข่าย การกำหนดขอบเขตทรัพยากร ไปจนถึงการสื่อสารระหว่างส่วนประกอบต่างๆ ในระบบคลาวด์

ตัวอย่างโค้ดหรือการตั้งค่า (Code/Config Example): โครงสร้างการตั้งค่าเบื้องต้น

# Basic Structural Configuration
apiVersion: v1
kind: ConfigMap
metadata:
  name: basic-system-config
data:
  mode: "development"
  log_level: "info"

Use Case ในชีวิตจริง (Real-world Scenario): ระบบแอปพลิเคชันภายในองค์กร หรือบริการทั่วไปที่มีปริมาณการใช้งานคงที่ ที่เน้นความง่ายในการจัดการและแก้ไขปัญหา

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การละเลยการตั้งค่าความปลอดภัยพื้นฐาน แนะนำให้ใช้เครื่องมือตรวจสอบอัตโนมัติ (Linter/Scanner) ตั้งแต่ขั้นตอนการพัฒนา

🟡 Intermediate Level (โค้ด/คอนฟิกไวยากรณ์จริง / Real Implementation)

ทฤษฎีและกลไกการทำงาน (Theory & Mechanism): การออกแบบสถาปัตยกรรมระดับกลางที่คำนึงถึงความทนทาน (Resiliency) การขยายตัว (Scalability) และการควบคุมเส้นทางการส่งข้อมูลเครือข่ายอย่างมีประสิทธิภาพ

ตัวอย่างโค้ดหรือการตั้งค่า (Code/Config Example): การกำหนด Network Policy และ Resource Limits

# Intermediate Access Control & Scaling
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: api-gateway-policy
spec:
  podSelector:
    matchLabels:
      role: api
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: myproject

Use Case ในชีวิตจริง (Real-world Scenario): แพลตฟอร์มอีคอมเมิร์ซที่มียอดผู้ใช้งานเพิ่มขึ้นแบบฉับพลันในบางช่วงเวลา (Spike Traffic) เช่น ช่วงแคมเปญส่งเสริมการขาย

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การคอนฟิก Policy ผิดพลาดอาจทำให้ Service ตัดขาดจากระบบ เฝ้าระวังด้วยการทดสอบการเชื่อมต่อ (Connectivity Test) ทุกครั้งที่เปลี่ยนค่า

🔴 Professional Level (Under-the-hood & Performance/FinOps)

ทฤษฎีและกลไกการทำงาน (Theory & Mechanism): การวิเคราะห์เชิงลึกไปถึงการทำงานระดับ Kernel (เช่น eBPF) และการทำ Optimization ทรัพยากรคลาวด์ พร้อมกับการนำแนวคิด FinOps มาใช้ควบคุมค่าใช้จ่ายโดยไม่ลดทอนประสิทธิภาพ

ตัวอย่างโค้ดหรือการตั้งค่า (Code/Config Example): การปรับจูน Resource ควบคู่กับ HPA และ Node Affinity

# Professional FinOps & Performance Tuning
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: high-performance-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: data-processor
  minReplicas: 3
  maxReplicas: 150
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300

Use Case ในชีวิตจริง (Real-world Scenario): ระบบ Streaming Data Platform ระดับโลกที่ต้องประมวลผลข้อมูลระดับ Petabytes ต่อวัน พร้อมจัดการ Cost Optimization ขั้นสูง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การเกิด OOMKilled แบบเงียบๆ หรือปัญหา Cloud Cost Spikes ควรตั้งแจ้งเตือนผ่าน Budget Alerts และทำ Profiling ประสิทธิภาพแอปพลิเคชันอย่างสม่ำเสมอ

🏢 Real-World Enterprise Scenario (เคสระบบการเงิน/Big Tech)

ทฤษฎีและกลไกการทำงาน (Theory & Mechanism): โครงสร้างระบบสำหรับองค์กรขนาดใหญ่ที่เน้น Multi-Region Active-Active, การทำ Disaster Recovery (DR) อัตโนมัติ, และการปฏิบัติตามมาตรฐานความปลอดภัยขั้นสูงสุด (Compliance & Governance)

ตัวอย่างโค้ดหรือการตั้งค่า (Code/Config Example): Infrastructure as Code (IaC) สำหรับ Enterprise Environment

# Enterprise Multi-AZ Infrastructure
module "enterprise_core_network" {
  source  = "terraform-aws-modules/vpc/aws"
  version = "~> 5.0"
  
  name = "prod-banking-core-vpc"
  cidr = "10.100.0.0/16"
  azs  = ["ap-southeast-1a", "ap-southeast-1b", "ap-southeast-1c"]
  
  private_subnets = ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
  public_subnets  = ["10.100.101.0/24", "10.100.102.0/24", "10.100.103.0/24"]
  
  enable_nat_gateway = true
  single_nat_gateway = false
  one_nat_gateway_per_az = true
  
  enable_vpn_gateway = true
}

Use Case ในชีวิตจริง (Real-world Scenario): ระบบ Core Banking ของธนาคารข้ามชาติ หรือระบบ Payment Gateway ที่ต้องมี Uptime 99.999% และห้ามมีข้อมูลสูญหาย (Zero Data Loss)

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ความล้มเหลวระดับศูนย์ข้อมูล (Data Center Outage) แก้ไขด้วยสถาปัตยกรรม Multi-Region failover อัตโนมัติ และซ้อมแผน Disaster Recovery ทุกไตรมาส