อะไรคือ Kubernetes ง่าย?

Chanwit Kaewkasi
2 min readAug 20, 2022

หลังจากสร้าง Controller มาอย่างจริงจังในระดับที่ใช้งานได้และมีคนอยากเอาไปใช้งาน คิดว่าถึงตอนนี้ผมสามารถพอจะอธิบายให้ตัวผมเองฟังแล้วว่า อะไรคือคำว่า “Kubernetes ยาก” และอะไรคือคำว่า “Kubernetes ง่าย”

มาที่ประเด็น Kubernetes ยาก ก่อน

จริง ๆ แล้ว Kubernetes ยากด้วยตัวมันเอง ตั้งแต่ architecture ยาก, security ยาก การติดตั้ง(จาก 0 ด้วยตัวเอง)ยาก และการดูแล (administrate) มันก็ยาก

ตัว Component ที่ทำงานบน Kubernetes ตามใจเรา ช่วยเราจัดการ workload ก็คือ Controller

การเขียน Kubernetes Controller ก็ยาก ผมใช้เวลาฝึกเป็นปี กว่าจะเริ่มเขียน Controller ที่มีคุณภาพแตะระดับพอใช้ อันนี้ไม่นับรวมเวลาการเขียนภาษา Go ที่หัดมานานและก็มั่นใจว่าเข้าใจในภาษา Go ได้ดีในระดับนึง

แล้วอะไรคือ Kubernetes ง่าย?

ประเด็นนี้เป็นประเด็นที่เคยได้ยินมาในช่วงแรก ๆ ของการมี Kubernetes ว่าถ้าใช้เป็น Kubernetes จะทำให้ชีวิตง่ายขึ้น

Kubernetes ในปัจจุบัน ถ้าเป็น managed service (เช่น EKS, GKE, AKS) เราสร้างได้ง่าย ดูแลได้ง่าย อันนี้เริ่มจริง แต่ความยากก็ยังหลงเหลืออยู่ใน architecture และ security model ของมันอยู่ดี

มันก็ยังยากอยู่ดีนะแหละ

แล้วที่บอกว่าผมเข้าใจแล้วว่าอะไรคือคำว่าง่ายของ Kubernetes คืออะไร

โจทย์ที่ไม่น่าจะทำได้

โจทย์ที่ผมต้องแก้คือ การทำให้ระบบ ๆ นึง สามารถ provision ตัว Terraform module ได้พร้อม ๆ กันอย่างน้อย 1,000 module

Terraform module คืออะไร ก็คือชุดของ Terraform file (.tf) ที่ใช้เพื่อ provision infrastructure ที่คนฝั่ง infra ทำกันนะแหละครับ ไล่ทำไปที่ละ step ตั้งแต่ init, plan, apply

แต่ว่าตัวที่ผมทำคือสร้างขึ้นมาเป็น Kubernetes Controller แล้วก็ใส่ Concept ของ GitOps เข้าไป แทนที่เราเก็บ state ด้วย backend แบบ local ก็ใช้ Kubernetes เป็นตัวเก็บ (หรืออาจจะใช้ backend แบบ s3 ก็ได้) การ plan การ apply แทนที่จะทำด้วยมือ ก็ทำด้วย YAML จะได้ใช้งานแบบ GitOps ได้

ถ้าลองค้น ๆ ดูใน GitHub เราจะเจอ Terraform Controller มากมาย และแทบทั้งหมดจะใช้ Kubernetes Job เป็นตัว init, plan และ apply Terraform ให้ ผมตั้งคำถามมาตลอดว่าทำไม Controller พวกนั้นใช้ Job เป็นตัวคุม Pod อีกทีนึง จุดนึงที่เป็นไปได้คือ การจัดการ lifecycle ของ Pod ด้วยตัวเองเป็นเรื่องที่น่ากลัว คนสร้าง Controller พวกนี้เลยเลี่ยงที่จะทำกัน

แต่ผมออกแบบ Controller สำหรับ Terraform ด้วยแนวคิดแบบ Software Engineering สุดขั้ว ในทุก ๆ feature ของ 50 release แรก ผมเขียนแบบใช้ Test นำ หรือ TDD ทั้งหมด เพื่อให้ทุก ๆ พฤติกรรมของ Controller ที่สร้างขึ้นมัน predictable แล้วก็ค่อย ๆ เพิ่มการจัดการ lifecycle ของ Pod เข้ามา และในที่สุดก็มีการจัดการ lifecycle ของ Pod ที่นิ่งมาก แต่ก็ scale ยังไม่ขึ้น สามารถรันได้แค่ 1 Pod ต่อรอบการทำงาน

Scale ตัว Controller ให้จัดการ 1,000 Object พร้อม ๆ กัน

พอเริ่มจะลอง Scale ตัว Controller ให้จัดการ Object มากกว่า 1 ตัว ก็ต้องทำให้มันรัน Pod มากกว่า 1 Pod พร้อม ๆ กัน

ปรากฏว่าพังไม่เป็นท่า เกิด race condition ขึ้นเป็น 10 ๆ จุด ใน code

แต่ละ Go routine แย่งกันเขียน / อ่าน Kubernetes resource จนติด rate limit ของตัว API Server ส่งผลต่อให้ Pod ที่ต้อง manage ค้างอยู่เป็น 100 ตัวใน Cluster

แต่ความรู้เรื่อง Go channel ก็ช่วยชีวิตไว้ ผมออกแบบการ communicate ระหว่าง Go routine ใหม่หมดด้วย Go channel (<- struct{})

จากนั้นก็เพิ่มการ cache resource เข้าไป แล้วก็ใช้ let it crash model (เอามาจาก หลักการนึงของ Actor pattern) ช่วย ทำให้ตัว Controller และ Pod มีลักษณะความเป็น Stateless ให้มากที่สุด

แล้วก็ทำความเข้าการใช้ Kubernetes API เพื่อ manage lifecycle ของ Pod เพิ่มเติมว่าต้องสร้างมันยังไง ต้องรอ state มันแบบไหน แล้วจะ terminate Pod ยังไง แบบทั้งทีเดียวจบ กับแบบ graceful

พอเอาทุกอย่างมารวมกัน รวมทั้งใช้การดู Go routine ที่กำลังถูก blocked ด้วย pprof ใน Cluster จริงได้ ทำให้ระบบสามารถ Scale ได้แบบ Linear โดยผมทดสอบทะลุ 1,000 ไปจนถึง 1,500 Terraform modules ก็คิดได้ว่า พอเถอะ 555

Kubernetes ง่าย

พอถึงจุดที่ต้องนั่งมอง Controller ทำงานใน Kubernetes เห็นมันสร้างแล้วก็ลบ Pod เป็น 1,000 ตัวทุก ๆ 2 นาที บน EKS เป็นเวลากว่าครึ่งเดือน โดยที่ตัว Controller ไม่ Crash เลย, Upgrade ได้ ทำงานต่อได้ ตัว Pod Capacity ของ Kubernetes Cluster ก็เต็มที่ และ Cluster ไม่พัง

ก็เลยบรรลุธรรมไปอีกข้อว่า แทบจะเป็นไปไม่ได้เลยที่จะสร้าง Controller ที่ใช้จัดการ workload ระดับนี้ได้โดยไม่ใช้ Kubernetes

เลยรู้แล้วว่าคำว่า Kubernetes ง่าย ที่คนบางกลุ่มพูด ๆ กันมันหมายความว่าอะไร คือจริงๆ แล้ว มันไม่ได้ง่าย มันแค่ทำให้ของที่แทบเป็นไปไม่ได้ ลดความยากลงไปได้มหาศาลต่างหาก

--

--

Chanwit Kaewkasi

Creator Weave TF-controller, Kubernetes & GitOps for Terraform, SNR SE @weaveworks, Go nut since r57 (pre v1)