P
PipeCraft

Roadmap Progress

ข้อมูลเบื้องต้นเกี่ยวกับวิศวกรรมข้อมูล (Introduction to Data Engineering) Python สำหรับ Data Engineering พื้นฐาน Linux & CLI สำหรับวิศวกรข้อมูล Git สำหรับระบบงานข้อมูลและทีมพัฒนา ระบบเครือข่ายและระบบประมวลผลแบบกระจายศูนย์ (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)
บทที่ 5: ระบบประมวลผลขนาดใหญ่และการจัดลำดับงาน (Orchestration, Scale & Streaming)

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

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

เพื่อรับประกันว่าสภาพแวดล้อมในการทดสอบตรงกับระบบงานจริง การห่อหุ้มสคริปต์ (Containerization) ช่วยคัดแยกไลบรารีและจำกัดทรัพยากรการรันอย่างมีระเบียบ

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

ทฤษฎีและกลไกการทำงาน (How it works): เทคโนโลยีคอนเทนเนอร์ไม่ใช่การเปิดจำลองระบบ OS ทั้งหมด (Virtual Machine) แต่เป็นโปรเซสของระบบปฏิบัติการโฮสต์ปกติ ที่ถูกกักกันด้วยคุณสมบัติหลักของ Linux Kernel: - **Namespaces**: แยกมุมมองทรัพยากร เช่น โพรเซส (PID), เครือข่าย (NET), ดิสก์รูท (MNT) ไม่ให้มองเห็นกันข้ามคอนเทนเนอร์ - **Control Groups (Cgroups)**: ล็อกขีดจำกัดหน่วยประมวลผลและการใช้สิทธิ์หน่วยความจำแรม (เช่น ห้ามกินแรมเกิน 4GB) - **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 การใช้ Docker ครอบท่อประมวลผลช่วยป้องกันไม่ให้สคริปต์ที่รันขัดข้องแย่งดึงหน่วยความจำจนดึงระบบความปลอดภัยอื่นล่ม

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

2. การออกแบบไฟล์คอนเทนเนอร์แบบ Multi-Stage เพื่อความปลอดภัยและมีขนาดไฟล์เล็ก

ทฤษฎีและกลไกการทำงาน (How it works): การสร้างไฟล์คอนเทนเนอร์ระดับระบบจริง (Production Image) ต้องการขนาดไฟล์ที่สั้นกระชับที่สุดและไม่มีเครื่องมือที่ไม่จำเป็นสำหรับการรัน (เช่น GCC, Curl) เพื่อปิดช่องทางแฮกเกอร์โจมตี แนวทางปฏิบัติที่ดีที่สุดคือดีไซน์คอนเทนเนอร์แบบ **Multi-Stage Build**: ในเลเยอร์แรกใช้ติดตั้งคอมไพล์ไลบรารีและเครื่องมือหนาแน่น พอมาเลเยอร์รันจริงจะดึงโคลนเฉพาะไบนารีและสคริปต์ที่บิวด์เรียบร้อยแล้วมาครอบรัน บนอิมเมจระบบปฏิบัติการขั้นพื้นฐานที่มีขนาดเล็กระดับเมกะไบต์ (เช่น 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 --no-install-recommends 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 built packages from builder layer
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): อิมเมจวิเคราะห์ข้อมูลที่บิวด์ตามปกติมีขนาดเกือบ 1.2GB ย้ายมาเขียนจัดรูปโครงสร้าง Multi-Stage บีบย่นขนาดอิมเมจปลายทางเหลือเพียง 150MB ช่วยย่นระยะเวลาการดึงอิมเมจรันข้ามระบบ CI/CD ลงได้กว่าสิบเท่า

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): สิทธิ์การประมวลผลไฟล์ภายในตู้ที่ใช้ root (`USER root`) ซึ่งหากโดนเจาะระบบ แฮกเกอร์จะสามารถควบคุมโฮสต์หลักได้ แก้ไขโดยการสถาปนารหัสสิทธิ์ใช้งานที่ไม่ใช่สิทธิ์แอดมิน (`USER 10001` หรือ `USER nobody`) ปลายทาง Dockerfile เสมอ

3. สถาปัตยกรรมกลุ่มเครื่อง Kubernetes: ส่วนควบคุม โหนดหลัก และโพรเซสทำงานของ Pod

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

# Conceptual architecture of Kubernetes cluster node communication
[Control Plane (apiserver + scheduler + etcd)]
                      |
           (Directs Node Kubelet)
                      |
                      v
[Worker Node (Kubelet + Container Runtime)]
   ├── Pod 1: [Container (Spark Executor)]
   └── Pod 2: [Container (dbt Runner)]
                    

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

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

4. การจัดการจ๊อบกระจายศูนย์: คอนฟิกการทำงานด้วย K8s Jobs, CronJobs, และ ConfigMaps/Secrets

ทฤษฎีและกลไกการทำงาน (How it works): ต่างจากงานบริการ API ที่ต้องเปิดระบบค้างไว้ 24 ชั่วโมง งานข้อมูลประเภท ETL ต้องการรันจนจบภารกิจแล้วปิดตัวลง Kubernetes มีคอนเซ็ปต์: - **K8s Jobs**: รันตู้คอนเทนเนอร์ประมวลผลจนสำเร็จ (Completed) แล้วเคลียร์ปิดตัว - **CronJobs**: ตั้งเวลารัน Job ประจำคาบเวลา (เช่น รันทุก 4 ทุ่มตรง) - **ConfigMaps / Secrets**: สำหรับส่งตัวแปรสภาพแวดล้อมและรหัสลับฐานข้อมูลให้คอนเทนเนอร์โดยไม่ต้องฝังไปในไฟล์อิมเมจ

# Kubernetes CronJob YAML deployment template for daily ETL execution
apiVersion: batch/v1
kind: CronJob
metadata:
  name: daily-sales-extractor
spec:
  schedule: "0 22 * * *" # Runs every night at 10 PM
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: extractor
            image: pipecraft/daily-loader:v1.3
            envFrom:
            - secretRef:
                name: database-credentials-secret # Access keys kept out of code
          restartPolicy: OnFailure
                    

Use Case ในชีวิตจริง (Real-world Scenario): จ๊อบส่งสรุปอีเมลโปรโมชันไปหาลูกค้าทุกคืนเวลาตีสองตรง โดยดึงรหัสความลับผ่าน Kubernetes Secrets เพื่อต่อ API ของบริษัทส่งจดหมายได้อย่างปลอดภัย

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): ปัญหาระบบงาน CronJob ค้างคาหาก Task เดิมยังประมวลผลไม่จบจนกระทั่งรอบเวลาถัดมารันชนกัน แก้ไขโดยปรับตั้งค่าคอนฟิก `concurrencyPolicy: Forbid` เพื่อยกเลิกรอบใหม่หากจ๊อบเก่ารันไม่จบ

5. การจัดสรรโควต้าทรัพยากรการประมวลผล และการปรับขนาดพื้นที่จัดเก็บแบบชั่วคราว

ทฤษฎีและกลไกการทำงาน (How it works): เพื่อคุมต้นทุนฮาร์ดแวร์ระบบ และค้ำประกันความเสถียรในคลัสเตอร์ขนาดใหญ่ Kubernetes เปิดโอกาสให้ผู้พัฒนาจัดระเบียบโควต้าการจัดสรร: - **Resource Quotas**: จำกัดพื้นที่หน่วยประมวลผลแรมและขนาด CPU สูงสุดในระดับ Namespace - **Ephemeral Storage Limits**: บังคับขอบเขตการเขียนข้อมูลล็อกและไฟล์ส่วนต่างชั่วคราวลงในระบบดิสก์โหนด เพื่อจำกัดการเกิดปัญหากล่องคอนเทนเนอร์ประมวลผลเขียนไฟล์ล็อกขยะบวมจนเครื่องโฮสต์หลักหน่วยจัดเก็บเต็ม

# Specifying storage bounds inside container resources template
resources:
  requests:
    memory: "2Gi"
    cpu: "1000m"
    ephemeral-storage: "1Gi"
  limits:
    memory: "4Gi"
    cpu: "2000m"
    ephemeral-storage: "2Gi" # Hard cap on temporary write disk space
                    

Use Case ในชีวิตจริง (Real-world Scenario): จ๊อบสแกนวิเคราะห์ภาพผู้ใช้ที่มีบั๊กตัวลูปไม่ยอมเคลียร์และยิงเขียนภาพบันทึกพังดิสก์บวม ระบบ K8s ตรวจพบขนาด Ephemeral Storage เกิน 2GB ที่กำหนด และสั่งสกัดทำลาย Pod ทิ้ง เพื่อไม่ทำร้ายดิสก์เครื่องแม่ล่ม

ข้อควรระวังและวิธีแก้ (Pitfalls & Mitigations): การจำกัดแรมต่ำเกินไปทำให้เกิดปัญหาสคริปต์พังและระเบิดทิ้งกลางคันด้วยสัญลักษณ์ `OOMKilled` แก้ไขโดยมอนิเตอร์ระดับกราฟการดึงทรัพยากรย้อนหลังเพื่อปรับสเปค Limits ให้เหมาะสมตามจริง

🛠️ Weekend Sandbox Challenge: Deploy Kubernetes Job for ETL Batch

โจทย์ปฏิบัติการ: จงเขียนสเปคไฟล์ Kubernetes Job YAML เพื่อสั่งเปิดรันตู้คอนเทนเนอร์ประมวลผลข้อมูลจนเสร็จสิ้น (Completed) โดยจำกัดหน่วยความจำและขีดเขียนข้อมูลลง S3

# etl-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: pipecraft-batch-etl
spec:
  template:
    spec:
      containers:
      - name: etl-runner
        image: pipecraft/batch-etl-runner:latest
        resources:
          limits:
            memory: "2Gi"
            cpu: "1"
      restartPolicy: OnFailure
                    

💼 Senior Technical Interview Q&A

Q1: สถาปัตยกรรมตู้คอนเทนเนอร์ Docker แตกต่างจากการรันเครื่องเสมือน (VMs) เชิงความคุ้มค่าทรัพยากรอย่างไร และ Namespace ป้องกันอะไรในระบบ?

A1: เครื่องเสมือน VMs จะต้องโคลนจำลองระบบปฏิบัติการ (Guest OS) ขึ้นมาเปลืองแรมและใช้หน่วยเก็บดิสก์ขนาดใหญ่ ในขณะที่ Docker คอนเทนเนอร์ จะแชร์เคอร์เนลของเครื่องแม่ (Host OS) ตรงๆ โดยใช้ Namespace คอยคัดแยกขอบเขตมุมมองโพรเซสและเน็ตเวิร์กไม่ให้กวนกัน ประหยัดค่าแรม Compute อย่างมหาศาล

Q2: ระหว่าง Kubernetes Jobs และ CronJobs มีความสอดคล้องกับพฤติกรรมการใช้งานท่อส่งข้อมูลประเภท Batch ETL และ Streaming อย่างไร?

A2: Kubernetes Jobs รันโปรเซสจนเสร็จสิ้นแล้วจบการทำงาน เหมาะสมอย่างยิ่งสำหรับงานประมวลผล Batch ETL ประจำสัปดาห์หรือจ๊อบซ่อมประวัติ ส่วน CronJobs ทำหน้าที่ตามเวลารอบที่ตั้งไว้ ส่วนงาน Streaming แบบเรียลไทม์ ต้องการ Deployments ปกติที่ต้องรันค้าง 24 ชั่วโมง

🐳 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 และประกอบประกอบอิมเมจท่อข้อมูล

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

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