Extend Kubernetes ตอนที่ 1

Prawit Chaivong
Zeabix
Published in
3 min readJan 5, 2023

การสร้าง CRD & Operator เพื่อเพิ่มความสามารถให้ Kubernetes cluster

เป็นเรื่องที่ปฏิเสธไม่ได้เลย ถ้าเราพูดถึงเรื่อง microservices สิ่งหนึ่งที่จะต้องพูดถึงเหมือนๆกัน ก็คือ Kubernetes เนื่องจากมันทำให้การ operate microservices จำนวนเยอะๆ เป็นเรื่องที่ง่ายขึ้นมาก ถึงแม้ว่าในตลาดจะไม่ได้มีแค่ kubernetes เท่านั้น แต่ kubernetes เอง ก็ครองตลาดไปค่อนข้างเยอะ และก็ได้รับการยอมรับในระดับสูง ซึ่งเราจะสังเกตได้ว่า Hyperscaler cloud providers เกือบทุกเจ้า จะต้องมี managed kubernetes ไว้ให้บริการลูกค้า

สิ่งหนึ่งที่ทำให้ Kubernetes เฉิดฉายเหนือเหล่าบรรดา container orchestration tools เจ้าอื่นๆก็คือ extensibility นั่นก็คือว่าเราสามารถ customize kubernetes ของเราให้เข้ากับ working process ของทีมเราได้อยากมากมาย นอกจากนี้แล้วยังมี 3rd party vendor หรือ oss อื่นๆ ที่ใช้ technique เดียวกันนี้ในการทำ ส่วนต่อขยายต่างๆขึ้นมา เพื่อให้การใช้งาน kubernetes ง่ายยิ่งขึ้น

ยกตัวอย่างเช่น ElasticSearch ก็ได้สร้าง ECK stack (Elastic Cloud on Kubernetes) ออกมาเพื่อให้การติดตั้งและการ config component ต่างๆ ทำได้สะดวกมาขึ้น (การมานั่งเขียน kubernetes manifest สำหรับการลง ElasticSearch Clusters mode บน Kubernetes ไม่ใช่เรื่องง่ายๆเลย)

บทความนี้เป็นตอนที่ 1 ของ Series การ Extend kubernetes ด้วย CRD/Operator และ Admission Controllers เพราะคิดว่าเอาทั้งหมดมายัดรวมกันในบทความเดียว ท่าทางจะยาวมาก ดังนั้นผมจะขออนุญาติแบ่งออกมาเป็นตอนๆ แล้วกันนะครับ

CRD คืออะไร

CRD ย่อมาจาก Custom Resource Definition, ก่อนอื่นต้องเข้าในก่อนว่า Kubernetes มองทุกอย่างเป็น Resource ยกตัวอย่างเช่น Pod ก็ถือว่าเป็น Resource หนึ่งที่เราสร้างขึ้นมา ซึ่งจะถูกเก็บไว้ใน etcd แล้วก็จะมีตัว component ตัวหนึ่งที่จะพยายาม reconcile สิ่งที่เรา define ไว้กับสิ่งที่มีอยู่ใน clusters ให้มันเท่ากัน และนี่ก็เป็นเหตุผลว่าทำไม เวลาเราสร้าง deployment ขึ้นมาด้วย จำนวน replicas จำนวนนึง (สมมติว่า replicas = 1 ก็แล้วกัน) ถึงแม้ว่าเราก็พยายามลบ pod ทิ้งไป ตัว kubernetes ก็จะพยายามทำให้จำนวน replicas มันเท่ากับ 1 ให้ได้โดยการ start pod ขึ้นมาใหม่ ซึ่งนี่ก็เป็นการทำให้ microservices ที่ run บน kubernetes มี resiliency ที่สูงมาก

ตัว Pod, Deployment, Service, Ingress และอีกหลายๆอย่าง ก็คือ Resource แต่ว่าเป็น Resource ที่มาจาก Kubernetes เอง แบบ Out-of-the-Box เลย ดังนั้นแค่เรา setup Kubernetes ขึ้นมาเปล่าๆเลย เราก็จะมี Resource พวกนี้ที่เราสามารถสร้างได้เองทันที

ตัว Custom Resource Definition คือสิ่งที่เราจะกำหนดขึ้นมาเองทีหลังเพื่อเอาไว้ตอบโจกย์การใช้งานของเราเอง ตัวอย่างที่เห็นได้ง่ายๆ ถ้าเคยลองลง argoCD ใน Kubernetes cluster เราจะสามารถสร้าง Resource ที่ชื่อว่า Application ได้ ซึ่ง Resource ตัวนี้เป็นสิ่งที่ argoCD กำหนดขึ้นมาใช้งานเอง

Operator คืออะไร

ถึงแม้ว่าเราจะสามารถสร้าง CRD ขึ้นมาได้เองแล้ว ในทางปฏิบัติ ก็แทบจะไม่มีประโยชน์อะไร เพราะว่าไม่มีอะไรเกิดขึ้นมาเลยนอกจากมีแค่มี CRD Resource ถูก create แล้วเก็บไว้เฉยๆ Operator คือส่วนที่เป็นโปรแกรมที่เราจะพัฒนาขึ้นมาเพื่อจะมาคอย monitor CRD ที่เราสร้างขึ้นมานั้นเพื่อทำอะไรซักอย่างตามที่เราจะให้มันทำซึ่งตัว program ดังกล่าวก็จะ run อยู่ข้างใน kubernetes cluster เลย ที่อธิบายมาบางท่านอาจจะยังมองไม่เห็นภาพ ผมขอยกตัวอย่าง rds_controller (ตาม link ข้างล่าง)

เช่นเราสร้าง Resource ที่ชื่อว่า DBInstance ตัว rds_controller ที่ว่ามาก็จะไปสร้าง RDS instance จริงๆใน AWS ให้เราเลย นี่เป็นแค่ตัวอย่างเดียว อีกตัวอย่างหนึ่งก็คือ argoCD ก็ใช้หลักการแบบเดียวกัน

เราจะเห็นได้ว่า ตัว CRD มักจะไม่ได้มาเดี่ยวๆ แต่มักจะมาเป็นแพ็คพร้อมกับตัว operator มันถึงจะสามารถทำงานได้

สำหรับในตอนต่อไป ของ Series นี้ เราจะมา handon กันนะครับ อาจจะเหมาะกับคนที่มีพื้นฐานการใช้งาน kubernetes มาบ้าง ใช้ docker desktop เป็น และที่สำคัญ อาจจะมีพื้นฐานด้าน programing โดยเฉพาะ golang เพราะว่าเราจะเขียนไอ้เจ้า CRD กับ operator ขึ้นมาเองเลย เป็น pilot project

Pilot use case

สิ่งที่เราจะลองทำกันดูในตอนต่อไป จะสร้างขึ้นมาเพื่อลองตอบโจกย์การใช้งาน kubernetes ง่ายๆ อาจจะโดนใจหลายๆคน โดยที่สถาณการณ์มีอยู่ว่า

ในการทำงานกับ microservices ปัจจุบันนี้ ผมมั่นใจว่าหลายๆที่ ที่การใช้งานใน development environment (หรือว่าใน non-production) ถึงแม้ว่าเราจะ follow ตาม practice ของ microservice ที่ว่าไม่ใช่ database ร่วมกัน แต่ว่าเราก็มาแชร์ db instance กันอยู่ เพื่อเป็นการประหยัด cost ซึ่งก็เป็นสิ่งที่สมเหตุสมผล

ลองจินตการดูว่า ถ้า developer อยากจะสร้าง microservice ขึ้นมาใหม่ นอกจากจะต้องเขียน code แล้ว ยังมีสิ่งที่ devops ต้องทำมีอะไรบ้าง

  • สร้าง database ใน instance สำหรับ non-production, dev, qa หรือ environment ใดๆก็ตาม
  • สร้าง user/credential
  • สร้าง secrets
  • ตกลงกับ developers ว่าจะให้ inject เข้าไป environment variable ชื่อว่าอะไร
  • สร้าง manifest ในการ deploy แล้วต้อง inject สิ่งที่อยู่ใน secrets เข้าไปใน environment variable ตามที่ได้ตกลงกัน เพื่อให้ application เอาไปใช้ได้

สิ่งที่เราจะทำก็คือ เราจะสร้าง CRD ขึ้นมา 2 ตัว

  • MySQLServer (represent ตัว database instance สมมติว่าตอนนี้เราใช้ MySQL อยู่)
  • Database (represent database ที่เราจะสร้างใน instance นั้นๆ)

โดยที่จะมี operator ตัวนึ่งที่จะ

  • เข้าไปสร้าง database สำหรับ application ตัวใหม่ให้
  • สร้าง user/credential
  • grant permission สำหรับ user กับ database ตัวที่สร้างขึ้น
  • แล้วในที่สุด ก็จะเอา credential ที่สร้างได้เอาไปใส่ใน secrets ให้

อันนี้เป็นเพียงแค่ส่วนแรกที่เราจะทำกันในตอนต่อไปที่จะถึงนี้ หลังจากนั้นก็เป็นใน ส่วนของ admission controller ที่จะมาเติมเต็ม ที่จะทำให้งานของ devops ใน pilot use case นี้ง่ายขึ้นอีกหลายเท่า โปรดติดตามกันนะครับ

Reference:

บทความใน series ตอนอื่นๆ

--

--