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
บทที่ 5: ระบบประมวลผลขนาดใหญ่และการจัดลำดับงาน (Orchestration, Scale & Streaming)

การจัดการคอนเทนเนอร์และคลัสเตอร์ (Containers & Kubernetes)

5.4 การจัดการคอนเทนเนอร์และโฮสต์ (Docker & Kubernetes)

Kubernetes และ Docker คือมาตรฐานทองคำในการรัน Data Workloads ในปัจจุบัน บทนี้พาไปดูวิธีรัน Airflow, Spark, และ Flink บน K8s Cluster พร้อมระบบ Auto-scaling และ Health Management

Technical Architecture Diagram
Click to Zoom
3D Isometric Architecture Breakdown:
  • Step 1: Data Ingestion & Event Processing
  • Step 2: Distributed Computation & State Management
  • Step 3: Orchestration & Resource Allocation

1. กลไกเคอร์เนลของ Docker: Namespaces, Cgroups, และ Copy-On-Write

Learning Progression

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

Real-World Enterprise Scenario

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

ทฤษฎีและกลไกการทำงาน (How it works): เทคโนโลยีคอนเทนเนอร์ไม่ใช่การจำลอง OS ทั้งหมด (Virtual Machine) แต่เป็นโพรเซสของระบบปฏิบัติการโฮสต์ที่ถูกกักบริเวณด้วยฟีเจอร์ของ Linux Kernel: - **Namespaces**: กั้นขอบเขตการมองเห็น (Isolation) เช่น โปรเซส (PID), เน็ตเวิร์ก (NET), ดิสก์ (MNT) ไม่ให้มองเห็นกันข้ามคอนเทนเนอร์ - **Control Groups (Cgroups)**: บังคับโควต้าทรัพยากร (เช่น ห้ามกินแรมเกิน 4GB, จำกัด CPU cycles) - **Copy-On-Write (CoW)**: โครงสร้างไฟล์เลเยอร์ย่อยที่ยอมให้อ่านและเขียนเฉพาะส่วนต่าง ช่วยประหยัดพื้นที่ดิสก์และทำให้คอนเทนเนอร์สตาร์ทได้ในพริบตา

# Running a Docker container with strict CPU and RAM cgroup limits
docker run -d \
  --name etl-worker-prod \
  --memory="4g" \
  --cpus="2" \
  pipecraft/etl-runner:v1.0
                    

Use Case ในชีวิตจริง (Real-world Scenario): ในเซิร์ฟเวอร์รันระบบท่อข้อมูลหลักของบริษัทที่มีแรมจำกัด 32GB การใช้ Cgroups ของ Docker ครอบท่อประมวลผลช่วยป้องกันไม่ให้สคริปต์ Python ที่เผลอโหลดข้อมูลใหญ่เกินไปสูบแรมเครื่องแม่จนทำหน้าเว็บ API ล่มไปด้วย

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): คอนเทนเนอร์มีสถานะจัดเก็บชั่วคราว (Ephemeral) ข้อมูลในนั้นจะหายวับไปหากคอนเทนเนอร์ดับ แก้ไขโดยห้ามเซฟข้อมูลสำคัญลงในตู้ แต่ให้เขียนข้อมูลออกไปเก็บบน S3 หรือเชื่อมต่อ Docker Volumes เข้ากับโฮสต์

2. Docker Multi-stage Build Optimization

ทฤษฎีและกลไกการทำงาน (How it works): การสร้าง Docker Image สำหรับ Production ต้องการความเบาและปลอดภัย แนวทางปฏิบัติที่ดีที่สุดคือ **Multi-Stage Build**: ในเลเยอร์แรก (Builder Stage) เราจะติดตั้งคอมไพเลอร์ที่หนักหน่วงเพื่อบิวด์โค้ด จากนั้นในเลเยอร์ที่สอง (Runner Stage) เราจะดึงมาแค่ผลลัพธ์ (Binary/Libraries) ที่บิวด์เสร็จแล้ว มาใส่ใน OS เปล่าๆ (เช่น Alpine หรือ Distroless) ทิ้งเครื่องมือแฮกเกอร์ไว้เบื้องหลัง

# Production-ready Multi-Stage Dockerfile for a Python ETL job
# Stage 1: Build dependencies environment
FROM python:3.9-slim AS builder
WORKDIR /app
RUN apt-get update && apt-get install -y gcc python3-dev
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# Stage 2: Clean execution runtime
FROM python:3.9-slim AS runner
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY etl_script.py .
ENV PATH=/root/.local/bin:$PATH
USER 10001
CMD ["python", "etl_script.py"]
                    

Use Case ในชีวิตจริง (Real-world Scenario): อิมเมจรันโมเดล Machine Learning มีขนาด 2GB เมื่อเปลี่ยนมาใช้ Multi-Stage Build สามารถรีดขนาดเหลือเพียง 300MB ลดระยะเวลา Pull Image ลงระบบ Kubernetes จาก 2 นาทีเหลือ 15 วินาที

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ห้ามใช้สิทธิ์ `root` (สิทธิ์แอดมิน) รันกระบวนการในคอนเทนเนอร์ เพราะหากโดนเจาะระบบ แฮกเกอร์จะยึดเครื่องแม่ได้ แก้ไขโดยประกาศบรรทัด `USER 10001` เพื่อจำกัดสิทธิ์ในเลเยอร์รันไทม์เสมอ

3. สถาปัตยกรรม Kubernetes: Control Plane และ Worker Nodes

ทฤษฎีและกลไกการทำงาน (How it works): Kubernetes จัดการสเกลคลัสเตอร์เครื่องแม่ข่าย: - **Control Plane**: แกนกลางบริหารระบบ ประกอบด้วย `kube-apiserver` (รับคำสั่ง), `kube-scheduler` (ตัดสินใจว่าจะวาง Pod ที่เครื่องไหน), และ `etcd` (ฐานข้อมูลเก็บสถานะทั้งคลัสเตอร์) - **Worker Nodes**: เครื่องลูกข่ายที่มี `kubelet` คอยเปิดปิดตู้คอนเทนเนอร์ตามคำสั่ง - **Pod**: หน่วยประมวลผลย่อยที่สุดใน K8s ซึ่งอาจบรรจุได้ 1 หรือหลายตู้คอนเทนเนอร์ที่จำเป็นต้องแชร์ IP และ Volume ร่วมกัน

# Kubernetes Deployment defining resources for an API pod
apiVersion: apps/v1
kind: Deployment
metadata:
  name: data-api
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: api-server
        image: pipecraft/api:v2
        resources:
          requests: { memory: "512Mi", cpu: "500m" }
          limits: { memory: "1Gi", cpu: "1000m" }
                    

Use Case ในชีวิตจริง (Real-world Scenario): หากโหนด (Worker) ตัวหนึ่งฮาร์ดแวร์ไหม้และพังลง K8s Control Plane จะตรวจพบการขาดหายไปของจังหวะชีพจร และทำการคืนชีพ (Self-healing) โยกย้าย Pod ไปสร้างใหม่ที่โหนดอื่นอย่างรวดเร็วโดยไม่ต้องใช้คนสั่ง

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): หากไม่ได้ใส่คอนฟิก `resources.requests` และ `resources.limits` Pod อาจแย่งสูบแรมกันเองจนเครื่องแม่พังรหัส OOMKilled แก้ไขโดยต้องบังคับระบุโควต้าของทุกคอนเทนเนอร์อย่างเคร่งครัด

4. Kubernetes CRDs & Operators (Spark / Airflow Operators)

ทฤษฎีและกลไกการทำงาน (How it works): - **CRDs (Custom Resource Definitions)**: เป็นการสอนให้ K8s รู้จักอ็อบเจ็กต์ประเภทใหม่ๆ ที่ไม่ใช่แค่ Pod หรือ Deployment ทั่วไป - **K8s Operators**: เป็นโปรแกรม (Controller) ที่รันคอยเฝ้าดู CRDs เหล่านั้นและช่วยรันความซับซ้อนของการตั้งค่าซอฟต์แวร์แทนมนุษย์ (Automated Operations) เช่น การเปิดคลัสเตอร์ Spark หรือ Airflow บน Kubernetes

# SparkApplication CRD managed by Spark Operator
apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
  name: pyspark-etl-job
spec:
  type: Python
  pythonVersion: "3"
  mode: cluster
  image: "pipecraft/spark-job:latest"
  mainApplicationFile: "local:///opt/spark/jobs/main.py"
  driver:
    cores: 1
    memory: "1024m"
  executor:
    instances: 3
    cores: 2
    memory: "2048m"
                    

Use Case ในชีวิตจริง (Real-world Scenario): แทนที่จะต้องเขียนสคริปต์มาตั้งค่า Master/Worker ในคลัสเตอร์ Spark เอง ทีมข้อมูลแค่เขียน YAML สร้างอ็อบเจ็กต์ประเภท `SparkApplication` แล้วส่งให้ Spark Operator ตัว Controller จะทำการเปิด Pod Driver 1 ตัวและ Executor 3 ตัวให้เอง และปิดทิ้งทั้งหมดเมื่อรันจ๊อบสำเร็จ

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การลง Operator หลายตัวข้ามเวอร์ชันอาจเกิดการชนกันของสิทธิ์ Role-Based Access Control (RBAC) ภายในคลัสเตอร์ แก้ไขโดยจำกัด Namespace ของ Operators ให้อยู่เฉพาะพื้นที่ที่อนุญาตเท่านั้น

5. CSI Persistent Volumes & Stateful Storage ใน Kubernetes

ทฤษฎีและกลไกการทำงาน (How it works): ปกติ K8s เหมาะกับงานไร้สถานะ (Stateless) แต่ในโลกข้อมูลเราต้องการเก็บข้อมูลถาวร เช่น การรันระบบฐานข้อมูลบน K8s ระบบจะใช้มาตรฐาน **Container Storage Interface (CSI)** เพื่อสื่อสารกับผู้ให้บริการดิสก์ (เช่น AWS EBS, Google PD) โดยอัตโนมัติ โดยอ็อบเจ็กต์ **PersistentVolumeClaim (PVC)** จะทำการร้องขอขนาดพื้นที่ดิสก์ และ CSI จะทำการเสกดิสก์มาต่อเข้ากับ Pod ให้โดยตรง

# Requesting persistent storage via PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: database-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: premium-rwo # CSI driver provisions an SSD automatically
                    

Use Case ในชีวิตจริง (Real-world Scenario): รันระบบ Apache Kafka Broker บน Kubernetes หาก Pod ล่มและถูกสปินขึ้นที่เครื่องใหม่ ระบบ K8s จะสั่งให้ CSI ดึงเอาดิสก์ EBS ก้อนเดิมขนาด 500GB ถอดจากเครื่องเก่ามาแปะที่โหนดใหม่ (Detach/Attach) ทำให้ข้อมูลข้อความไม่สูญหายไปไหน

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): โหมดการเข้าถึง `ReadWriteOnce` อนุญาตให้ Pod เพียงตัวเดียวเมานท์ดิสก์เท่านั้น หาก Pod สร้างใหม่ติดสถานะค้าง (Pending) เพราะโหนดเก่าล่มและดิสก์ยังไม่หลุด แก้ไขโดยตั้งเวลารอให้ระบบเตะดิสก์หลุด (Timeout) หรือใช้โหมด `ReadWriteMany` (NFS) ถ้างานต้องการเปิดไฟล์ร่วมกัน

Weekend Sandbox Challenge: Deploy Spark Operator CRD

โจทย์ปฏิบัติการ: จงเขียนสเปคไฟล์ Kubernetes YAML โดยประยุกต์ใช้ SparkApplication CRD ในการสั่งจองทรัพยากรรันจ๊อบ Spark แบบกระจายโหนด

# spark-job.yaml
apiVersion: "sparkoperator.k8s.io/v1beta2"
kind: SparkApplication
metadata:
  name: monthly-aggregations
spec:
  type: Python
  pythonVersion: "3"
  mode: cluster
  image: "pipecraft/spark-aggregator:latest"
  mainApplicationFile: "local:///opt/spark/jobs/aggregate.py"
  driver:
    cores: 1
    memory: "512m"
  executor:
    instances: 2
    cores: 1
    memory: "1024m"
                    

Senior Technical Interview Q&A

Q1: ทำไมการใช้ Multi-Stage Build จึงเป็นมาตรฐานสำคัญในโลกของการทำ Containerization สำหรับ Data Engineering?

A1: การโหลดข้อมูล Data Pipeline มักใช้ไลบรารีทางคณิตศาสตร์เช่น Pandas, Numpy หรือ C++ binding ที่ต้องใช้คอมไพเลอร์ในการบิวด์ ซึ่งมีขนาดไฟล์ใหญ่เป็นกิกะไบต์ การใช้ Multi-Stage ช่วยแยกเลเยอร์ตอนคอมไพล์ ออกจากเลเยอร์รันไทม์ ทำให้ Image ปลายทางไม่มีเครื่องมือที่ไม่จำเป็น ลดพื้นผิวการโจมตีทางไซเบอร์ (Attack surface) และประหยัดเวลา/ค่าใช้จ่ายในการ Pull image มหาศาล

Q2: จงอธิบายกลไกของ Kubernetes Operators ว่ามีความแตกต่างจาก Deployments พื้นฐานอย่างไร?

A2: Deployment พื้นฐานใช้เปิด/ปิดแอปพลิเคชันแบบ Stateless ง่ายๆ แต่ระบบข้อมูลเช่น Spark หรือ Kafka มีสถานะและลำดับขั้นตอนสลับซับซ้อน (เช่น ต้องเปิด Zookeeper ก่อนแล้วค่อยเปิด Broker) Operators จะเขียนตรรกะระดับซอฟต์แวร์ลงใน Controller เสมือนมีวิศวกรเฝ้าคลัสเตอร์ตลอดเวลา (Human Operator) เพื่ออ่าน CRDs และบริหารจัดการสเกล/แบ็คอัป ของระบบแบบ Stateful อัตโนมัติ

Interactive Dockerfile Image Builder

Interactive Docker

เป้าหมาย: เติมคำสั่ง Dockerfile (เช่น FROM, COPY, CMD) เพื่อกำหนดสเปคแพ็กเกจโปรแกรม Python ETL Pipeline ให้รันบนคอนเทนเนอร์

Dockerfile Configuration:
python:3.9-slim
WORKDIR /app
. .
RUN pip install pandas requests
["python", "main.py"]

ข้อดี / จุดเด่น & ข้อเสีย / ข้อควรระวัง

ข้อดี / จุดเด่น

  • รับประกันการรันของสคริปต์ประมวลผลข้อมูลได้สม่ำเสมอในทุกเครื่องระบบปฏิบัติการ
  • ง่ายต่อการทำ Auto-scaling ขยายจำนวนประมวลผลและกู้คืนงานเมื่อพังอัตโนมัติ

ข้อเสีย / ข้อควรระวัง

  • มีอัตราการเรียนรู้วิธีตั้งค่าและบริหารคลัสเตอร์ Kubernetes ที่ยากและซับซ้อนมาก
  • การจัดการพื้นที่ดิสก์จัดเก็บอิมเมจเก่าๆ อาจทำให้เซิร์ฟเวอร์เต็มได้หากไม่มีระบบเก็บกวาด

ปฏิบัติการจริง (Lab Practice)

Bilingual Guide

แล็บ: เขียน Dockerfile และประกอบประกอบอิมเมจท่อข้อมูล

วิธีรันแล็บปฏิบัติการบนเครื่องจริง (Local Terminal Execution Blueprint)

เนื่องจากปฏิบัติการ Data Engineering / DevOps ระดับสูงต้องรันบน Environment จริง ขั้นตอนด้านล่างนี้คือคำสั่งสำหรับนำไปรันบน Terminal / Docker ในเครื่องของคุณ:

1. สร้างโฟลเดอร์ปฏิบัติการและเตรียมไฟล์ Environment
mkdir -p pipecraft-lab && cd pipecraft-lab
python3 -m venv venv && source venv/bin/activate
pip install --upgrade pip pandas polars pytest requests
2. จำลองการสร้างและรันระบบประมวลผล (Run Pipeline Command)
# Run execution pipeline test
python3 -c "
import polars as pl
print(' [PipeCraft Lab] Running local pipeline engine...')
df = pl.DataFrame({'id': [1, 2, 3], 'status': ['SUCCESS', 'SUCCESS', 'AUDITED']})
print(df)
" 
3. ตรวจสอบการผ่านเกณฑ์และการทำงาน (Data Quality Assertions)
# Verify clean execution exit status
echo " PipeCraft Local Lab Execution Completed Successfully!"

💡 คำแนะนำ & ทริกเด็ด

ในการเขียน Dockerfile ให้ระบุคำสั่งติดตั้ง Dependencies (เช่น RUN pip install) ไว้ตอนต้นก่อนคำสั่งก๊อปปี้โค้ด (COPY . .) เพื่อให้ Docker ช่วยทำ Cache เลเยอร์ติดตั้งห้องสมุด ช่วยย่นเวลาบิวด์อิมเมจในอนาคตเหลือเพียงหลักวินาที