mTLS Service Mesh Batch Processing Pipeline — ความปลอดภัย Batch Processing ด้วย mTLS
การจัดการความปลอดภัยในระบบ Batch Processing เป็นเรื่องที่องค์กรส่วนใหญ่มักมองข้าม โดยเฉพาะเมื่อต้องประมวลผลข้อมูลจำนวนมากในเวลากำหนด ปัญหาทั่วไป ได้แก่ การเชื่อมต่อระหว่าง Batch Job กับฐานข้อมูลไม่มีการเข้ารหัส การตรวจสอบตัวตนไม่เพียงพอ และการส่งข้อมูลไปยังบริการภายนอกอาจถูกสกัดกั้นได้ วิธีแก้ปัญหาแบบดั้งเดิมมักใช้ Username-Password หรือ API Key ซึ่งมีความเสี่ยงสูงต่อการรั่วไหล
mTLS (Mutual TLS) ร่วมกับ Service Mesh เช่น Istio นำเสนอวิธีการป้องกันที่แข็งแกร่งกว่า โดยใช้ Certificate ในการยืนยันตัวตนของทั้ง Client และ Server โดยอัตโนมัติ ระบบนี้ไม่เพียงแต่เข้ารหัสข้อมูล แต่ยังตรวจสอบว่าแต่ละ Service ที่เข้าถึงข้อมูลเป็นตัวตนจริงหรือไม่ ช่วยให้องค์กรสามารถปฏิบัติตามหลัก Zero Trust Security ได้อย่างมีประสิทธิภาพ
บทความนี้จะอธิบายวิธีการติดตั้งและใช้งาน mTLS ในระบบ Batch Processing บนแพลตฟอร์ม Kubernetes พร้อมเคล็ดลับการแก้ไขปัญหาทั่วไปและการจัดการ Certificate ให้สอดคล้องกับลักษณะของงาน Batch ที่มักใช้เวลานาน
mTLS คืออะไร และเหตุใดจึงสำคัญสำหรับ Batch Processing

mTLS ย่อมาจาก Mutual TLS (Transport Layer Security) ซึ่งหมายความว่าทั้ง Client และ Server ต้องยืนยันตัวตนของกันและกันด้วย Digital Certificate ต่างจากการเชื่อมต่อแบบเดิมที่เพียงแต่เข้ารหัสข้อมูล mTLS ช่วยให้แน่ใจว่าคนหรือระบบที่พยายามเข้าถึงข้อมูลเป็นตัวตนจริง
สำหรับ Batch Processing ความสำคัญของ mTLS มีดังนี้
- ความปลอดภัยของข้อมูล: Batch Job มักประมวลผลข้อมูลที่ไวต่อการเปิดเผย เช่น ข้อมูลลูกค้า รายได้ หรือข้อมูลส่วนบุคคล mTLS ช่วยป้องกันการสกัดกั้นข้อมูลระหว่างการส่งถ่ายเข้าและออกจากระบบ
- ยืนยันตัวตนโดยอัตโนมัติ: Sidecar Proxy (เช่น Envoy) จะจัดการการตรวจสอบ Certificate โดยอัตโนมัติ ไม่ต้องเขียนโค้ดเพิ่มเติมในแอปพลิเคชัน
- ปฏิบัติตามมาตรฐาน Zero Trust: หลักการนี้ถือว่าไม่มี Service ใดที่ไว้ใจได้โดยค่าเริ่มต้น ทุกการเชื่อมต่อต้องได้รับการตรวจสอบและอนุมัติ
- ตรวจสอบการเข้าถึง: ผ่าน AuthorizationPolicy สามารถกำหนดได้ว่า Batch Job ใดมีสิทธิ์เข้าถึง Service ใดบ้าง
สถาปัตยกรรมของ mTLS ใน Kubernetes Service Mesh
บทบาทของ Istio Control Plane และ Sidecar Proxy
Istio เป็น Service Mesh ที่ทำหน้าที่จัดการการสื่อสารระหว่าง Services ทั้งหมด ประกอบด้วยสองส่วนหลัก
- Control Plane (istiod): ส่วนกลางที่ออก Certificate ให้กับทุก Service และจัดการนโยบายความปลอดภัย (Security Policy) istiod ทำหน้าที่เป็น Certificate Authority (CA) ที่ลงนาม Certificate สำหรับทุก Pod ในระบบ
- Sidecar Proxy (Envoy): ทำงานในแต่ละ Pod ทำหน้าที่สกัดกั้น (intercept) การสื่อสารทั้งเข้าและออก จัดการการเข้ารหัส TLS และตรวจสอบ Certificate โดยอัตโนมัติ
เมื่อ Batch Job Pod ถูกสร้าง Istio จะอัตโนมัติฉีด (inject) Sidecar Proxy เข้าไป Sidecar นี้จะติดต่อ istiod เพื่อขอ Certificate ซึ่งจะได้รับ Certificate ที่มี SPIFFE Identity (เช่น spiffe://cluster.local/ns/batch-jobs/sa/batch-runner) ทุกครั้งที่ Pod พยายามเชื่อมต่อกับ Service อื่น Sidecar จะจัดการการเข้ารหัส TLS โดยอัตโนมัติ
ตัวอักษร SPIFFE Identity คืออะไร
SPIFFE (Secure Production Identity Framework for Everyone) เป็นมาตรฐานสำหรับการจัดการตัวตนของ Service ในสภาพแวดล้อมที่มีการเปลี่ยนแปลงอย่างรวดเร็ว เช่น Kubernetes ตัวอักษร SPIFFE Identity มีรูปแบบ spiffe://cluster.local/ns/{namespace}/sa/{service-account}
ตัวอย่างเช่น หากมี Batch Job ชื่อ etl-daily ทำงานในเนมสเปซ batch-jobs ด้วย Service Account batch-runner Identity ของมันจะเป็น spiffe://cluster.local/ns/batch-jobs/sa/batch-runner Identity นี้ถูกฝังอยู่ใน Certificate และใช้ในการตรวจสอบการเข้าถึงผ่าน AuthorizationPolicy
การตั้งค่า mTLS สำหรับ Batch Processing
ขั้นตอนที่ 1: เปิดใช้งาน mTLS STRICT Mode
การตั้งค่าแรกคือการบังคับให้ทุก Pod ในเนมสเปซ batch-jobs ใช้ mTLS โดยใช้ PeerAuthentication Policy ตัวอย่างการตั้งค่า
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: batch-jobs
spec:
mtls:
mode: STRICT
STRICT Mode หมายความว่า Pod ทั้งหมดในเนมสเปซนี้จะต้องใช้ mTLS เท่านั้น การเชื่อมต่อแบบ Plain Text (ไม่เข้ารหัส) จะถูกปฏิเสธ
เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง API Rate Limiting GitOps Workflow
ขั้นตอนที่ 2: กำหนดสิทธิ์การเข้าถึง (Authorization Policy)
หลังจากเปิด mTLS แล้ว ขั้นตอนถัดไปคือกำหนดว่า Service ใดมีสิทธิ์เข้าถึง Service ใด ตัวอย่างเช่น Batch Job ต้องเข้าถึงฐานข้อมูล PostgreSQL ในเนมสเปซ database
สรุปแนวคิด: apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: allow-batch-to-db namespace: database spec:
นโยบายนี้อนุญาตให้เฉพาะ Service Account batch-runner จากเนมสเปซ batch-jobs เท่านั้นที่เข้าถึงพอร์ต 5432 (PostgreSQL) Service อื่นจะถูกปฏิเสธโดยอัตโนมัติ
แนะนำเพิ่มเติม — ระบบเทรดของ iCafeForex
ขั้นตอนที่ 3: ตั้งค่า Sidecar Lifecycle สำหรับ Batch Job
Batch Job มีลักษณะพิเศษ คือต้องทำงานเสร็จแล้วสิ้นสุด ปัญหาทั่วไปคือ Pod ยังคงทำงานอยู่แม้ว่า Job ได้เสร็จแล้ว เนื่องจาก Sidecar Proxy (Envoy) ยังคงรันอยู่ การแก้ไขคือเพิ่ม Annotation ในการตั้งค่า Pod
สรุปแนวคิด: apiVersion: batch/v1 kind: Job metadata: name: etl-daily namespace: batch-jobs spec:
Annotation holdApplicationUntilProxyStarts: true บอกให้ Sidecar รอจนกว่า Envoy Proxy พร้อมแล้วจึงให้แอปพลิเคชันเริ่มต้น ป้องกันปัญหา Connection Refused ที่เกิดจากแอปพลิเคชันเริ่มเร็วกว่า Proxy
ตารางการตั้งค่า mTLS สำคัญ
ตารางต่อไปนี้สรุปการตั้งค่า mTLS ที่สำคัญที่สุดสำหรับ Batch Processing
| ส่วนประกอบ | วัตถุประสงค์ | การตั้งค่าสำคัญ | ใช้กับ |
|---|---|---|---|
| PeerAuthentication | บังคับใช้ mTLS ในเนมสเปซ | mtls.mode: STRICT | Namespace หรือ Mesh ทั้งหมด |
| AuthorizationPolicy | กำหนดสิทธิ์ Service-to-Service | source.principals + operation.ports | Namespace ของ Service ปลายทาง |
| DestinationRule | ตั้งค่า mTLS สำหรับ Destination | trafficPolicy.tls.mode: ISTIO_MUTUAL | ฐานข้อมูล บริการภายนอก |
| ServiceEntry | ลงทะเบียน External Service | hosts, endpoints, ports | API ภายนอก ฐานข้อมูล External |
| Sidecar Annotation | ควบคุม Lifecycle ของ Proxy | holdApplicationUntilProxyStarts: true | Batch Job Pod |
ปัญหาทั่วไปและวิธีแก้ไข
ปัญหา 1: Pod ค้างหลังจาก Job เสร็จสิ้น
อาการ: Status ของ Job แสดง Complete แต่ Pod ยังคง Running
สาเหตุ: Sidecar Proxy (Envoy) ไม่รู้ว่า Job เสร็จแล้ว จึงยังคงรันอยู่
วิธีแก้: ใช้ Istio 1.12 ขึ้นไป และเพิ่ม Annotation terminationDrainDuration ในการตั้งค่า Pod
เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง Envoy Proxy Chaos Engineering
ปัญหา 2: Connection Refused เมื่อ Job เริ่มต้น
อาการ: แอปพลิเคชัน Batch ล้มเหลวทันทีด้วยข้อความ Connection Refused
สาเหตุ: แอปพลิเคชันเริ่มเร็วกว่า Envoy Proxy พร้อม
วิธีแก้: เพิ่ม Annotation holdApplicationUntilProxyStarts: true ดังตัวอย่างข้างต้น
ปัญหา 3: Certificate หมดอายุระหว่าง Long-running Job
อาการ: TLS Handshake Error เกิดขึ้นหลังจากรัน Job นานๆ
สาเหตุ: Istio ใช้ Certificate Lifetime เริ่มต้น 24 ชั่วโมง หากงาน Batch ใช้เวลาเกิน 24 ชั่วโมง Certificate จะหมดอายุ
วิธีแก้: สำหรับ Long Job ควรตั้ง PILOT_CERT_DURATION เป็น 72 ชั่วโมง โดยแก้ไขการตั้งค่า istiod Deployment หรือ ConfigMap
แนะนำเพิ่มเติม — บทวิเคราะห์จาก XM Signal
ปัญหา 4: ไม่สามารถเชื่อมต่อ External Database
อาการ: Connection Refused เมื่อพยายามเข้าถึง Database ภายนอก Mesh
สาเหตุ: External Database ไม่อยู่ใน Mesh ไม่มี Certificate mTLS
วิธีแก้: ใช้ ServiceEntry เพื่อลงทะเบียน External Database เข้า Mesh แล้วใช้ DestinationRule เพื่อปิดการใช้ mTLS สำหรับ Destination นั้น (tls.mode: DISABLE หรือ SIMPLE)
ปัญหา 5: Sidecar ใช้ Memory มากเกินไป
อาการ: Pod ถูก OOMKilled (Out of Memory) หรือใช้ Resource มากกว่าที่คาดไว้
เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน HAProxy Advanced Monitoring และ Alerting
สาเหตุ: Envoy Proxy ใช้ Memory Default ซึ่งอาจไม่เหมาะกับ Batch Pod ที่ประมวลผลข้อมูลจำนวนมาก
วิธีแก้: เพิ่ม Annotation sidecar.istio.io/proxyMemory ในการตั้งค่า Pod เพื่อจำกัด Memory ให้เหมาะสม เช่น 128Mi หรือ 256Mi
การจัดการ Certificate

Lifetime ของ Certificate
Istio ออก Certificate ให้กับทุก Service ด้วย Lifetime เริ่มต้น 24 ชั่วโมง สำหรับ Batch Job ที่ทำงานสั้นๆ ค่านี้เพียงพอ แต่สำหรับงานที่ใช้เวลานาน ควรพิจารณาเพิ่มเป็น 72 ชั่วโมง
การตั้งค่า Lifetime ทำได้โดยแก้ไข Environment Variable PILOT_CERT_DURATION ใน istiod Deployment
Certificate Rotation
Istio จัดการการเปลี่ยน Certificate โดยอัตโนมัติ ก่อนหมดอายุ 50% ระบบจะขอ Certificate ใหม่โดยอัตโนมัติ สำหรับ Long-running Job ระบบนี้ช่วยให้ Job ไม่ขาดการเชื่อมต่อ
การใช้ Custom CA
สำหรับสภาพแวดล้อม Production ควรใช้ Custom CA แทน Self-signed CA ที่ Istio สร้างขึ้น สามารถใช้ cert-manager หรือ HashiCorp Vault เพื่อจัดการ Certificate ได้
การตรวจสอบและ Monitor
ตรวจสอบว่า mTLS ทำงานหรือไม่
ใช้คำสั่ง kubectl เพื่อตรวจสอบสถานะ mTLS
kubectl get peerauthentication -n batch-jobs
kubectl get authorizationpolicy -n database
kubectl describe pod <pod-name> -n batch-jobs
ตรวจสอบ Logs ของ Sidecar Proxy เพื่อดูรายละเอียด TLS Handshake
Monitor Certificate Expiry
ติดตั้ง Prometheus Alert เพื่อ Monitor Certificate Expiry Metric ชื่อ istio_agent_cert_expiry_seconds ตั้ง Alert เมื่อ Certificate จะหมดอายุภายใน 7 วัน
ตรวจสอบ Authorization Policy
ใช้ Kiali (Visualization Tool สำหรับ Istio) เพื่อดูการเชื่อมต่อระหว่าง Services และตรวจสอบว่า AuthorizationPolicy ทำงานถูกต้อง
เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน Weights Biases GitOps Workflow
เคล็ดลับและ Best Practices
1. ใช้ Service Account แยกต่อ Job Type
แทนที่จะใช้ Service Account เดียวสำหรับทุก Batch Job ให้สร้าง Service Account แยกต่อประเภท Job เช่น batch-runner สำหรับ ETL, data-processor สำหรับ Data Processing เป็นต้น ช่วยให้การควบคุมสิทธิ์การเข้าถึงละเอียดขึ้น
2. ตั้ง Resource Limit สำหรับ Sidecar
เพิ่ม Annotation เพื่อจำกัด CPU และ Memory ของ Sidecar Proxy ให้เหมาะสมกับลักษณะของ Batch Job
3. ใช้ Separate Namespace สำหรับ Batch Jobs
จัดกลุ่ม Batch Job ไว้ในเนมสเปซเดียว เช่น batch-jobs ช่วยให้การจัดการและการตรวจสอบง่ายขึ้น
4. ตั้ง Timeout สำหรับ TLS Handshake
สำหรับ Batch Job ที่เชื่อมต่อกับ External Service ควรตั้ง Timeout สำหรับ TLS Handshake เพื่อป้องกันการค้างอยู่
5. ทำ Regular Audit ของ AuthorizationPolicy
ตรวจสอบและอัปเดต AuthorizationPolicy อย่างน้อยทุกไตรมาส เพื่อให้แน่ใจว่าเฉพาะ Service ที่ต้องการเท่านั้นที่มีสิทธิ์เข้าถึง
ตัวอย่างการนำไปใช้งานจริง
สมมติว่าองค์กรมี Batch Job ชื่อ daily-etl ที่ต้องการประมวลผลข้อมูลลูกค้าจากฐานข้อมูล PostgreSQL ทุกวันเวลา 2 โมงเช้า และส่งผลลัพธ์ไปยัง Data Warehouse ในระบบ AWS
ขั้นตอนการตั้งค่า:
- สร้าง Namespace batch-jobs และ Service Account batch-runner
- เปิด PeerAuthentication STRICT Mode ในเนมสเปซ batch-jobs
- สร้าง AuthorizationPolicy ในเนมสเปซ database อนุญาตให้ batch-runner เข้าถึง PostgreSQL เท่านั้น
- สร้าง ServiceEntry สำหรับ AWS Data Warehouse และตั้ง DestinationRule ให้ปิด mTLS (เพราะ AWS ไม่อยู่ใน Mesh)
- สร้าง Batch Job Deployment พร้อม Annotation holdApplicationUntilProxyStarts: true
- ติดตั้ง Prometheus Alert สำหรับ Monitor Certificate Expiry
ผลลัพธ์: ข้อมูลระหว่าง daily-etl กับ PostgreSQL ถูกเข้ารหัสด้วย mTLS โดยอัตโนมัติ และมีการตรวจสอบตัวตนของทั้งสองฝ่าย Service อื่นไม่สามารถเข้าถึง PostgreSQL ได้ หากมี Attacker พยายามสกัดกั้นข้อมูล จะไม่สามารถถอดรหัสได้เพราะไม่มี Certificate ที่ถูกต้อง





