เจาะลึก Taints และ Tolerations ใน Kubernetes เมื่อ Node ปฏิเสธ Pod
ทำความเข้าใจกลไก Taints และ Tolerations ใน Kubernetes คอนเซ็ปต์การปฏิเสธและยอมรับ Pod ของ Node พร้อมตัวอย่างการตั้งค่า NoSchedule และ NoExecute

ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
- Node selectors และ affinity เป็นการเลือกฝั่ง Pod แต่ Taints เป็นการผลัก Pod ออกจาก Node
- Taint ประกอบด้วย key, value และ effect ส่วน Toleration อยู่ฝั่ง Pod เพื่อยอมรับเงื่อนไข
- มี 3 ผลกระทบหลัก ได้แก่ NoSchedule, PreferNoSchedule และ NoExecute พร้อมค่าผ่อนผัน tolerationSeconds
- การมี Toleration ไม่ได้แปลว่า Pod จะต้องไปลงที่ Node นั้นเสมอไป แต่มันแค่ลบข้อจำกัดออก
หากคุณเคยใช้งาน Node selectors และ affinity มาก่อน คุณจะพบว่ามันเป็นการทำงานแบบ opt-in ซึ่งหมายความว่า Pod เป็นฝ่ายตัดสินใจเลือก Node ที่ต้องการ และตัว scheduler จะพยายามทำตามความต้องการนั้น แต่ในบางสถานการณ์ เรากลับต้องการผลลัพธ์ตรงกันข้ามโดยสิ้นเชิง เช่น Control-plane nodes ที่ไม่ควรมีแอปพลิเคชันพอดทั่วไปเข้าไปแย่งทรัพยากร
นั่นคือหน้าที่ของ Taints และ Tolerations แทนที่ Pod จะดึงตัวเองเข้าหา Node ตัว Node จะทำหน้าที่ผลัก Pod ออกไป และมีเพียง Pod ที่มี Toleration ระบุไว้เท่านั้นจึงจะได้รับอนุญาตให้ถูก scheduling เข้ามาได้ โดย Taint จะอาศัยอยู่บน Node ประกอบด้วย key, value และ effect ในรูปแบุก key=value:effect ขณะที่ Toleration จะอาศัยอยู่บน Pod เพื่อบอกว่ายินดีรับเงื่อนไขนี้
เพื่อให้เห็นภาพชัดเจน ลองจินตนาการว่า Taint เปรียบเสมือนสเปรย์ไล่แมลงที่ฉีดไว้บน Node ส่วน Toleration ก็คือแมลงที่มีภูมิคุ้มกันต่อน้ำยาสเปรย์สูตรเฉพาะนั้น โดยเอฟเฟกต์ทั้งสามรูปแบบจะพฤติกรรมแตกต่างกันออกไป เช่น คำสั่งตัวอย่างสำหรับการกำหนด taint บน Node:
kubectl taint nodes node-1 dedicated=gpu:NoSchedule
ภาพประกอบจากคลังภาพสต็อก ไม่ใช่ภาพจากเหตุการณ์จริง
ฝั่งของ Pod จะต้องประกาศ tolerations เพื่อยอมรับเงื่อนไขดังกล่าว เช่น ตัวอย่างการกำหนด pod ให้รองรับ operator แบบ Equal สำหรับ GPU:
apiVersion: v1
kind: Pod
metadata:
name: gpu-pod
spec:
tolerations:
- key: "dedicated"
operator: "Equal"
value: "gpu"
effect: "NoSchedule"
containers:
- name: nginx
image: nginxนอกจากนี้ operator ยังสามารถใช้ค่า Exists แทน Equal ได้เช่นกัน หากต้องการให้ Pod ยomรับ key นั้นๆ ได้ไม่ว่าจะมี value อะไรก็ตาม อีกหนึ่งพารามิเตอร์ที่น่าสนใจคือ tolerationSeconds ซึ่งจะใช้งานร่วมกับ NoExecute เท่านั้น โดยมันทำหน้าที่เป็นช่วงเวลาผ่อนผัน (grace period) ว่า Pod จะยังสามารถรันอยู่บน Node ต่อไปได้นานแค่ไหนหลังจากที่ Taint ปรากฏขึ้น ก่อนจะถูกขับออกไป (eviction) ตัวอย่างเช่นการตั้งค่าเวลา 3600 วินาที
ในมุมมองทางสถาปัตยกรรมของ Kubernetes การทำความเข้าใจความแตกต่างระหว่าง Node Affinity และ Taints ถือเป็นเรื่องสำคัญมาก เพราะแม้ทั้งสองฟีเจอร์จะแก้ปัญหาคล้ายกันแต่มาจากคนละทิศทาง Affinity เปรียบเสมือนแรงดึงดูด ในขณะที่ Taint เป็นแรงผลัก การผสมผสานทั้งสองกลไกเข้าด้วยกันจึงเป็นแนวทางปฏิบัติยอดนิยมเมื่อต้องการควบคุมการจัดวาง workload ที่มีความต้องการทรัพยากรเฉพาะทางสูง เช่น GPU nodes
ข้อผิดพลาดที่พบบ่อยที่สุดคือความเข้าใจผิดว่าการมี Toleration หมายความว่า Pod จะต้องถูก Scheduling ไปที่ Node นั้นเสมอ ทั้งที่จริงแล้วมันเป็นแค่การปลดล็อกข้อจำกัด ไม่ได้แสดงความต้องการ (preference) นอกจากนี้ การเพิ่ม NoExecute Taint ให้กับ Node ที่กำลังให้บริการรับส่งข้อมูลอยู่แล้ว อาจส่งผลให้ Pod ที่รันอยู่ถูกขับออกโดยไม่มีการเตือนล่วงหน้า ดังนั้นจึงควรตรวจสอบให้แน่ใจก่อนว่าระบบกำลังรันอะไรอยู่บ้าง
ที่มา: Dev.to
พบข้อมูลผิดพลาดในบทความนี้? แจ้งปัญหาบทความนี้
ความคิดเห็น
แสดงความคิดเห็น