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)

เลเยอร์ที่เชื่อมต่อได้ (Pluggable Layers)

Chapter 3: The Pluggable Layers (เลเยอร์สับเปลี่ยนได้และเครือข่าย)

1. Networking & the CNI (สถาปัตยกรรมเครือข่าย 4 เลเยอร์)

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):
ความจีเนียสของ Kubernetes คือมันกำหนด "กฎ" ของเครือข่ายเอาไว้ แต่ มันไม่ยอมลงมือสร้างเครือข่ายเอง กฎที่ว่ามีเพียง 3 ข้อ:
1. ทุก Pod ต้องมี IP Address เป็นของตัวเอง
2. Pod ทุกตัวต้องคุยข้ามหากันได้โดยไม่ต้องทำ NAT (Network Address Translation)
3. IP ที่ Pod มองเห็นตัวเอง ต้องเป็น IP เดียวกันกับที่คนอื่นมองเห็นมัน

เมื่อ K8s กำหนดกฎเสร็จ มันเปิดช่องเสียบปลั๊กที่เรียกว่า CNI (Container Network Interface) เพื่อให้บริษัทภายนอก (เช่น Calico, Flannel, Cilium) มาเขียนโปรแกรมสร้างเครือข่ายตามกฎนี้ เลเยอร์เครือข่ายของ K8s ซ้อนกันเป็น 4 ชั้น:
* Layer 1 (ในสุด): คอนเทนเนอร์ใน Pod เดียวกัน คุยกันผ่าน localhost (127.0.0.1)
* Layer 2 (Pod Network): เสกโดย CNI ทำให้ Pod ข้ามเครื่อง Node คุยกันได้ด้วย IP ประจำตัว
* Layer 3 (Service Network): สร้าง Virtual IP หน้าบ้านเพื่อรับโหลดบาลานซ์ (เพราะ IP ของ Pod เปลี่ยนแปลงตลอดเวลา)
* Layer 4 (นอกสุด): รับทราฟฟิกจากผู้ใช้งานจริงนอกคลัสเตอร์เข้าสู่ระบบผ่าน Ingress หรือ NodePort

# คุณจะเห็น Pod ของ CNI (เช่น calico-node หรือ aws-node) ฝังตัวอยู่ทุกๆ เครื่องในฐานะ DaemonSet
$ kubectl get pods -n kube-system -o wide | grep -E "calico|flannel|cilium|aws-node"

calico-node-abc12   1/1   Running   0   10d   10.0.1.5   node-1
calico-node-xyz98   1/1   Running   0   10d   10.0.1.6   node-2
        

Use Case ในชีวิตจริง (Real-world Scenario):
บริษัท FinTech แห่งหนึ่งต้องการระบบเครือข่ายที่มีความเร็วสูงปรี๊ดและกิน CPU ต่ำ พวกเขาตัดสินใจถอดปลั๊ก Flannel ที่เป็น CNI ดั้งเดิมออก แล้วเสียบปลั๊ก Cilium (ซึ่งใช้เทคโนโลยี eBPF ทำงานระดับ Kernel) เข้าไปแทน การเปลี่ยน CNI นี้ทำให้พวกเขาลด Latency ลงได้ 40% และได้ฟีเจอร์ Network Security ระดับลึกมาใช้ฟรีๆ โดยไม่ต้องไปยุ่งกับ Source Code ของ Kubernetes Core เลยแม้แต่นิดเดียว

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): ปัญหา "IP Address Exhaustion" มือใหม่มักเลือก CIDR Block (ช่วงของ IP) ให้กับ Pod Network เล็กเกินไป (เช่น /24 ซึ่งมีแค่ 254 IPs) เมื่อสเกลระบบจนจำนวน Pod เกิน 254 ตัว ระบบจะไม่สามารถสร้าง Pod ใหม่ได้อีก ค้างอยู่ที่สถานะ ContainerCreating
* Mitigation (วิธีแก้): การออกแบบ IPAM (IP Address Management) ต้องทำตั้งแต่ก่อนสร้างคลัสเตอร์ (Day 0) ควรเผื่อ CIDR ของ Pods ให้ใหญ่พอ (เช่น /16 หรือขี้เหร่สุดคือ /20) หากคลัสเตอร์รันไปแล้ว การเปลี่ยน CIDR ของ Pod Network ภายหลังแทบจะเป็นไปไม่ได้โดยไม่เกิด Downtime ขนาดใหญ่

2. Storage & the CSI (การจัดการพื้นที่เก็บข้อมูลถาวร)

ทฤษฎีและกลไกการทำงาน (How it works):
Pod เกิดมาเพื่อตาย (Ephemeral) ถ้าคุณเซฟรูปลงไปในโฟลเดอร์ของคอนเทนเนอร์ เมื่อ Pod รีสตาร์ท รูปนั้นจะหายวับไปตลอดกาล เพื่อแก้ปัญหานี้ K8s จึงมีระบบ Persistent Storage ซึ่งใช้หลักการ "ถอดปลั๊กสับเปลี่ยนได้" เช่นเดียวกัน เรียกว่า CSI (Container Storage Interface)

สถาปัตยกรรมแบ่งออกเป็น 3 ชิ้นส่วนหลักที่ทำงานประสานกัน:
1. StorageClass: แคตตาล็อกสินค้าที่บอกว่าคลัสเตอร์นี้มีดิสก์แบบไหนให้เบิกบ้าง (เช่น fast-ssd บน AWS EBS, nfs-slow สำหรับเก็บ Log)
2. PersistentVolumeClaim (PVC): "ใบเบิกของ" ที่ Developer เขียนขอสเปก (เช่น ขอ SSD ขนาด 10GB)
3. PersistentVolume (PV): ดิสก์ก้อนจริงที่ถูกสร้างและดึงมาผูกติด (Bound) กับใบเบิก PVC เมื่อพร้อมใช้งาน Kubelet จะเมาท์ (Mount) ดิสก์ก้อนนี้เข้าไปใน Pod

การแยก PVC (คนขอ) ออกจาก PV (ของจริง) เป็นสถาปัตยกรรมที่ช่วยแยกหน้าที่ (Decoupling) ระหว่าง Developer และ Infrastructure Admin ได้อย่างหมดจด

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: database-storage-pvc
spec:
  accessModes:
    - ReadWriteOnce # อนุญาตให้เมาท์เข้ากับ Node เดียวเท่านั้น (เหมาะกับ Database)
  storageClassName: aws-ebs-gp3 # ระบุรุ่นของดิสก์ในแคตตาล็อก
  resources:
    requests:
      storage: 10Gi
        

Use Case ในชีวิตจริง (Real-world Scenario):
ระบบ Machine Learning สมัยใหม่มักจะมีการอ่าน Dataset ขนาดยักษ์พร้อมๆ กัน ทีม Data Science จะสร้าง PVC โดยระบุ accessModes: ReadWriteMany เพื่อขอเบิก Storage แบบ Network File System (เช่น AWS EFS หรือ NFS) ทำให้ Pod ประมวลผลจำนวน 50 ตัว สามารถเมาท์โฟลเดอร์เดียวกันและแชร์ไฟล์อ่านร่วมกันได้ในเวลาเดียวกัน

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): หากคุณเผลอลบ PVC ทิ้ง ดิสก์จริง (PV) จะปลิวหายไปพร้อมข้อมูลสำคัญหรือไม่? คำตอบขึ้นอยู่กับนโยบาย Reclaim Policy หากตั้งไว้เป็น Delete (ค่า Default ของ Cloud หลายเจ้า) ข้อมูลคุณจะหายสาบสูญไปพร้อมกับใบเบิกทันที
* Mitigation (วิธีแก้): สำหรับข้อมูลที่มีความสำคัญอย่างยิ่งยวด (เช่น Database) ผู้ดูแลระบบต้องตั้งค่า StorageClass หรือ Patch ตัว PV ให้มี persistentVolumeReclaimPolicy: Retain เสมอ เมื่อ PVC ถูกลบ PV จะเปลี่ยนสถานะเป็น Released (ไม่ลบข้อมูลทิ้ง) รอให้แอดมินมาตรวจสอบและจัดการแบ็กอัปด้วยตนเอง

3. ConfigMaps & Secrets (แยกคอนฟิกออกจากโค้ด)

ทฤษฎีและกลไกการทำงาน (How it works):
ตามหลักการ 12-Factor App (การเขียนแอปยุคใหม่) เราต้อง ห้ามฮาร์ดโค้ด (Hardcode) ตัวแปรสภาพแวดล้อมหรือรหัสผ่านลงไปใน Source Code เด็ดขาด Kubernetes จึงเตรียม Object 2 ชนิดไว้ให้:
1. ConfigMap: ใช้เก็บข้อมูลทั่วไปที่เปิดเผยได้ (เช่น URL ของ Database, ค่า Timeout, Nginx config)
2. Secret: ใช้เก็บข้อมูลความลับ (เช่น รหัสผ่าน, API Keys, TLS Certificates)

เมื่อคุณสร้าง ConfigMap/Secret ไว้ในคลัสเตอร์ Kubelet สามารถฉีด (Inject) ข้อมูลเหล่านี้เข้าไปใน Pod ได้ 2 วิธี คือ
* แปลงเป็นตัวแปร Environment Variables
* แปลงเป็น ไฟล์ (Volume Mount) ไปวางแปะไว้ในโฟลเดอร์ของคอนเทนเนอร์ (อัปเดตไฟล์แบบ Hot-reload ได้เมื่อค่าเปลี่ยน)

spec:
  containers:
  - name: my-app
    image: my-app:latest
    env:
      - name: DB_HOST
        valueFrom:
          configMapKeyRef: # ดึงจาก ConfigMap
            name: app-config
            key: db_url
      - name: DB_PASSWORD
        valueFrom:
          secretKeyRef: # ดึงจาก Secret
            name: db-credentials
            key: password
        

Use Case ในชีวิตจริง (Real-world Scenario):
ทีมพัฒนาสร้าง Docker Image เพียงตัวเดียว (build once) แล้วนำไป Deploy ใน 3 สภาพแวดล้อม (Dev, Staging, Prod) ได้เลย โดยอาศัยการสับเปลี่ยน ConfigMap ตามแต่ละ Environment ทำให้มั่นใจได้ว่าโค้ดที่ผ่านการทดสอบจาก Dev จะเป็นโค้ดชุดเดียวกันเป๊ะกับที่รันบน Production (Immutable Image) ลดปัญหา "โค้ดรันได้แค่เครื่องผม" ลงได้อย่างสิ้นเชิง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): อคติที่ว่า "Secret ปลอดภัยขั้นสุด" ความจริงคือ Secret ใน K8s โดย Default เป็นแค่การเข้ารหัสแบบ Base64 Encoding เท่านั้น (ซึ่งใครๆ ก็ Decode กลับมาอ่านได้ด้วยคำสั่ง echo "..." | base64 -d) มันไม่ได้ถูกเข้ารหัสทางคณิตศาสตร์ (Encryption) แต่อย่างใด
* Mitigation (วิธีแก้): ในระดับ Enterprise ต้องเปิดใช้งาน Encryption at Rest บน API Server เพื่อให้ข้อมูล Secret ถูกเข้ารหัสจริงๆ ก่อนลงไปเก็บใน etcd และควรบูรณาการใช้เครื่องมือภายนอกอย่าง HashiCorp Vault หรือ AWS Secrets Manager ร่วมกับปลั๊กอิน External Secrets Operator เพื่อดึงรหัสผ่านลงมาที่คลัสเตอร์ในระดับรันไทม์

4. Services & Ingress (ทางเข้าสู่คลัสเตอร์)

ทฤษฎีและกลไกการทำงาน (How it works):
เนื่องจาก Pod เกิดและตายตลอดเวลา IP ของพวกมันจึงเปลี่ยนไปเรื่อยๆ คุณไม่สามารถชี้ Traffic ไปหา IP ของ Pod ตรงๆ ได้ K8s จึงสร้างคอนเซปต์ Service ซึ่งเป็น "ป้ายทะเบียนเสมือน (Virtual IP)" ที่ไม่มีวันเปลี่ยนแปลง
Service จะใช้ Selector (เช่น หาตัวที่มี Label app: web) เพื่อกวาดหา IP ของ Pod ทุกตัวที่ตรงเงื่อนไข (เรียกว่า Endpoints) แล้วทำหน้าที่รับ Traffic และกระจายโหลด (Load Balance) ไปยัง Pod เหล่านั้น

ประเภทของ Service และ Ingress:
1. ClusterIP: เปิดให้คุยกันได้แค่ *ภายใน* คลัสเตอร์เท่านั้น (ปลอดภัยสุด ใช้กับ Database)
2. NodePort: เปิดพอร์ตสูงๆ (30000-32767) ทะลุทะลวงเข้ามาที่ทุกเครื่อง Node (ทางเข้าสำหรับชาวบ้าน)
3. LoadBalancer: ไปสั่ง Cloud Provider ให้เสก Load Balancer ของจริงมาครอบ NodePort อีกที
4. Ingress: ไม่ใช่ Service แต่เป็น "ยามเฝ้าประตู (Reverse Proxy Layer 7)" ตัวเดียวที่รับ Traffic ขาเข้า (HTTP/HTTPS) แล้วอ่าน URL/Domain เพื่อกระจาย (Route) ไปยัง Service ต่างๆ ในคลัสเตอร์ ช่วยประหยัดค่า Load Balancer ไปได้มหาศาล

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: main-ingress
spec:
  rules:
  - host: api.mycompany.com
    http:
      paths:
      - path: /v1/users
        pathType: Prefix
        backend:
          service:
            name: user-service # โยนไปหา Service ของ User
            port:
              number: 80
      - path: /v1/payments
        pathType: Prefix
        backend:
          service:
            name: payment-service # โยนไปหา Service ของ Payment
            port:
              number: 80
        

Use Case ในชีวิตจริง (Real-world Scenario):
บริษัทยักษ์ใหญ่ที่มี Microservices กว่า 100 ตัว หากพวกเขาใช้ LoadBalancer Service สำหรับทุกแอป พวกเขาจะต้องจ่ายค่าเช่า Load Balancer ของคลาวด์ถึง 100 ตัว (สิ้นเปลืองมาก) พวกเขาจึงใช้ Ingress Nginx เพียง 1 ตัวรับ Load Balancer แล้วใช้กฎของ Ingress (Host/Path) โยนทราฟฟิกไปหา 100 บริการที่อยู่ด้านหลัง ประหยัดค่าใช้จ่ายมหาศาลและจัดการ SSL Certificate ได้ที่จุดศูนย์กลางจุดเดียว

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): Asymmetric Routing เมื่อใช้ NodePort ทราฟฟิกจะวิ่งเข้ามาที่ Node-A แต่อาจจะถูก SNAT (Source NAT) และโยนไปให้ Pod ที่อยู่บน Node-B ทำให้ IP ต้นทางของลูกค้าที่แท้จริง (Client IP) สูญหายไป แอปพลิเคชันจะเห็นว่า Request ทุกอันมาจาก IP ของ K8s Node
* Mitigation (วิธีแก้): หากแอปพลิเคชันของคุณต้องการบันทึก IP ลูกค้าที่แท้จริง (เพื่อทำ Rate Limit หรือ Security Log) คุณต้องตั้งค่า Service ให้เป็น externalTrafficPolicy: Local ซึ่งจะบังคับให้ทราฟฟิกตกใส่เฉพาะ Node ที่มี Pod ตัวนั้นรันอยู่เท่านั้น (ข้าม Node ไม่ได้) เพื่อหลีกเลี่ยงการทำ SNAT กลางทาง

5. Scaling Mechanisms (การสเกลระบบอัตโนมัติ)

ทฤษฎีและกลไกการทำงาน (How it works):
ความฝันสูงสุดของการทำ Orchestration คือความสามารถในการรับมือกับความผันผวนของทราฟฟิกโดยไม่ต้องใช้มนุษย์ K8s มีแก๊ง 3 ทหารเสือในการทำ Autoscaling:
1. HPA (Horizontal Pod Autoscaler): หน้าที่คือ "เพิ่ม/ลดจำนวน Pod" (สเกลแนวนอน) โดยอ่านค่าจาก Metrics API เช่น ถ้า CPU เฉลี่ยของกลุ่ม Pod เกิน 70% ให้เพิ่มจำนวน Pod เข้าไปหารภาระ
2. VPA (Vertical Pod Autoscaler): หน้าที่คือ "เพิ่ม/ลดสเปก (Requests/Limits)" ของ Pod (สเกลแนวตั้ง) เหมาะกับแอปที่สเกลแนวนอนไม่ได้ (เช่น Database บางชนิด) มันจะประเมินการกินทรัพยากรจริง แล้วจับ Pod รีสตาร์ทเพื่อฉีดสเปกใหม่ที่ใหญ่กว่าเดิมให้
3. Cluster Autoscaler (CA): หน้าที่คือ "เพิ่ม/ลดจำนวนเครื่องเซิร์ฟเวอร์ (Node)" เมื่อ HPA เสก Pod ออกมาเยอะจนเต็มทุก Node แล้ว Pod ใหม่จะติดสถานะ Pending ตัว CA จะเห็นสถานะนี้ และวิ่งไปสั่ง Cloud ให้เปิด VM ใหม่มารับโหลดทันที

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web-frontend-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web-frontend
  minReplicas: 2 # อย่างน้อยต้องมี 2 ตัวเสมอ
  maxReplicas: 10 # ขยายได้สูงสุดไม่เกิน 10 ตัว
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70 # ถ้า CPU เฉลี่ยทะลุ 70% ให้งอก Pod ใหม่
        

Use Case ในชีวิตจริง (Real-world Scenario):
ในวัน Black Friday ระบบ HPA ตรวจจับได้ว่า CPU ของเว็บพุ่งแตะ 80% มันจึงเริ่มเสก Pod เพิ่มจาก 2 เป็น 5 เป็น 10 จนกระทั่งเครื่องเซิร์ฟเวอร์ในคลัสเตอร์เต็ม (CPU จองเต็มขีดจำกัด) Pod ตัวที่ 11 จะขึ้นสถานะ Pending ทันใดนั้น Cluster Autoscaler ทำงาน สั่งเปิดเครื่อง Node ใหม่ใช้เวลา 2 นาที เมื่อ Node พร้อม Pod ตัวที่ 11-20 ก็หลั่งไหลเข้าไปรันบนเครื่องใหม่ และเมื่อผ่านพ้นช่วงโปรโมชัน ทราฟฟิกหดหาย HPA ลด Pod ลงมาเหลือ 2 ตัว CA เห็นว่ามีเครื่อง Node ว่างงานเกิน 10 นาที ก็จะสั่งลบเครื่องนั้นทิ้งเพื่อประหยัดเงินบริษัท (Scale-to-zero principles)

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations):
* Pitfall (ปัญหา): "HPA สู้กับ VPA (The Scaling Fight)" มือใหม่เผลอเปิดใช้ HPA (สเกลจำนวนอิง CPU) และ VPA (สเกลสเปกอิง CPU) กับ Deployment ตัวเดียวกันพร้อมๆ กัน สิ่งที่เกิดคือ เมื่อ CPU สูง HPA จะเสก Pod เพิ่ม ในขณะเดียวกัน VPA จะจับ Pod รีสตาร์ทเพื่อเพิ่มสเปก ทำให้ระบบรวนและเกิด Downtime ขึ้นอย่างน่าประหลาด
* Mitigation (วิธีแก้): ห้ามใช้ HPA และ VPA อ่านค่า Metrics เดียวกัน (เช่น CPU) ใน Workload ตัวเดียวกันเด็ดขาด หากจำเป็นต้องใช้คู่กัน HPA ควรอ่านค่า Custom Metrics (เช่น จำนวนคิวใน RabbitMQ) แทนที่จะอ่าน CPU ปล่อยให้ VPA เป็นคนดูแลไซส์ CPU/Memory ไปตัวเดียว

6. Cilium & eBPF CNI Concepts

ทฤษฎีและกลไกการทำงาน:
เดิมที K8s Network ต้องพึ่งพา iptables ซึ่งมีความซับซ้อนและล่าช้าเมื่อคลัสเตอร์ใหญ่ขึ้น เทคโนโลยีใหม่ล่าสุดอย่าง eBPF (Extended Berkeley Packet Filter) ยอมให้เรารันโปรแกรม Sandboxed ระดับ Kernel ได้โดยตรง
CNI สมัยใหม่อย่าง Cilium ใช้ eBPF ในการจัดการ Network, Security และ Observability โดยลัดขั้นตอน iptables ทำให้ Route แพ็กเก็ตได้ด้วยความเร็วเทียบเท่า Native OS

# การดูสถานะของ Cilium และ eBPF Maps ในระบบ
cilium status
cilium bpf tunnel list
        

Use Case ในชีวิตจริง:
บริษัท FinTech มี Services กว่า 2,000 ตัว ทำให้ iptables rules มีขนาดใหญ่ทะลุหมื่นบรรทัด คลัสเตอร์จึงมีอาการหน่วงเวลาเพิ่ม Pod ใหม่ พวกเขาตัดสินใจเปลี่ยน CNI มาใช้ Cilium ทำให้เวลาในการโหลด Network Policies ลดจาก 10 วินาทีเหลือต่ำกว่า 50 มิลลิวินาที

ข้อควรระวังและวิธีแก้:
* Pitfall: eBPF เป็นเทคโนโลยีที่ผูกติดกับ Linux Kernel สมัยใหม่ หากรันบน OS เก่าๆ (เช่น CentOS 7) จะใช้งาน Cilium แบบเต็มประสิทธิภาพไม่ได้
* Mitigation: ต้องอัปเกรด Linux Kernel ของ Node ให้ใหม่เพียงพอ (อย่างน้อย Kernel 4.19+) ก่อนที่จะเปลี่ยนมาใช้ Cilium

🛠️ Weekend Sandbox Challenge: "The Autoscaling Chain Reaction"

โจทย์ปฏิบัติการ: โจทย์ท้าทายความสามารถ:
1. ติดตั้ง Metrics Server ลงใน Minikube ของคุณ
2. สร้าง Deployment ของแอปพลิเคชันจำลอง (เช่น k8s.gcr.io/hpa-example) พร้อมระบุ CPU Requests ให้ชัดเจน (เช่น 200m)
3. รันคำสั่งผูก HPA: kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10
4. ความท้าทาย: เปิด Terminal เพื่อ Load Test (ใช้ busybox ยิง wget รัวๆ เข้าหา Service)
5. พิสูจน์ผลลัพธ์: สังเกตดู kubectl get hpa -w และ kubectl get pods -w คุณต้องอธิบายให้ได้ว่า ภายในกี่วินาทีที่ HPA อ่านค่า CPU ทะลุเป้า และมันค่อยๆ สเกล Pod เพิ่มขึ้นทีละกี่ตัว (Algorithm ของมันมี Cooldown period อย่างไร)

💼 Senior Technical Interview Q&A

Q1: "ระหว่าง ClusterIP, NodePort, และ LoadBalancer ทราฟฟิกไหลผ่าน Service แต่ละประเภทอย่างไร และทำไมเราถึงไม่ใช้ LoadBalancer สำหรับ Service ทุกตัวในระบบ?"

A: ClusterIP เป็นเลเยอร์ในสุดที่เข้าถึงได้จากแค่ในคลัสเตอร์เท่านั้นครับ NodePort จะเปิดพอร์ตบนทุกเครื่อง Node เพื่อโยนทราฟฟิกเข้ามาหา ClusterIP อีกที ส่วน LoadBalancer คือการสั่งให้ Cloud Provider สร้าง external load balancer มาครอบ NodePort ครับ สาเหตุที่เราไม่ใช้ LoadBalancer กับทุก Service เพราะ 1. มันเปลืองเงินมหาศาล (1 LB ต่อ 1 Service) 2. มันยากต่อการจัดการ SSL และเส้นทาง เราจึงนิยมสร้าง LoadBalancer ให้กับ 'Ingress Controller' เพียงตัวเดียว เพื่อรับทราฟฟิกเข้าคลัสเตอร์ แล้วใช้ Ingress จัดการทำ Host/Path routing โยนทราฟฟิกไปยัง ClusterIP ของแต่ละ Service ด้านในแทนครับ

Q2: "หาก Pod ของคุณติดสถานะ Pending อย่างต่อเนื่อง คุณจะเรียงลำดับขั้นตอนในการ Troubleshoot อย่างไรเพื่อหาสาเหตุที่แท้จริง?"

A: สถานะ Pending แปลว่า Scheduler ไม่สามารถหาบ้าน (Node) ให้ Pod นี้อยู่ได้ครับ ขั้นตอนแรกผมจะใช้ kubectl describe pod <pod-name> เพื่อดู Events ด้านล่างสุด สาเหตุหลักที่พบบ่อยคือ 1. Insufficient Resources (Node มี CPU/Mem ไม่พอรับ Requests ที่ขอ) 2. ติด Taints/Tolerations (Node ปฏิเสธไม่ให้ลง) 3. ไม่ตรงเงื่อนไข NodeAffinity 4. หากใช้ PVC อาจะเกิดจาก StorageClass ไม่สามารถ provision ตัว PV ออกมาผูกได้สำเร็จ หากเป็นเพราะทรัพยากรไม่พอจริงๆ เราต้องตรวจสอบว่า Cluster Autoscaler ทำงานอยู่หรือไม่ หรือเราจอง Resource Requests สูงเกินความจำเป็นหรือเปล่าครับ ### 💻 Weekend Sandbox Challenge: "The Autoscaling Chain Reaction" โจทย์ท้าทายความสามารถ: 1. ติดตั้ง Metrics Server ลงใน Minikube ของคุณ 2. สร้าง Deployment ของแอปพลิเคชันจำลอง (เช่น k8s.gcr.io/hpa-example) พร้อมระบุ CPU Requests ให้ชัดเจน (เช่น 200m) 3. รันคำสั่งผูก HPA: kubectl autoscale deployment php-apache --cpu-percent=50 --min=1 --max=10 4. ความท้าทาย: เปิด Terminal เพื่อ Load Test (ใช้ busybox ยิง wget รัวๆ เข้าหา Service) 5. พิสูจน์ผลลัพธ์: สังเกตดู kubectl get hpa -w และ kubectl get pods -w คุณต้องอธิบายให้ได้ว่า ภายในกี่วินาทีที่ HPA อ่านค่า CPU ทะลุเป้า และมันค่อยๆ สเกล Pod เพิ่มขึ้นทีละกี่ตัว (Algorithm ของมันมี Cooldown period อย่างไร)

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 ทุกไตรมาส