การเขียน Kubernetes Controller, Part 6 — โมเดลสำหรับ Multi-Tenancy
หลักจากสร้าง Controller ขึ้นมาแล้วก็ได้ feedback หลาย ๆ เรื่องรวมทั้งความจำเป็นที่ต้องสนับสนุน Multi-Tenancy
Multi-Tenancy คืออะไร
ในโลกของ GitOps, DevOps และ Kubernetes จะมี Concept ความเป็นเจ้าของตัวทรัพยากร, ขอบเขตการทำงานของทรัพยากร, และสิทธิ์ตามบทบาท
ใน Kubernetes ความเป็นเจ้าของตัวทรัพยากร สามารถระบุได้ด้วย ServiceAccount
ส่วนขอบเขตการทำงานของทรัพยากร สามารถระบุได้ด้วย Namespace
โดยสิทธิ์ทั้งหมดจะควบคุมผ่านกลไกของ RBAC
โดยปกติแล้ว RBAC ในรูปแบบที่ทำกันทั่ว ๆ ไปคือการสร้าง ServiceAccount, ทำ RoleBinding (หรือ ClusterRoleBinding)ให้กับ ServiceAccount นั้น ๆ แบบจำกัด แล้วให้ตัว Resource อยู่ใน Namespace ก็จะสามารถจำกัดขอบเขตการทำงาน, ระบุความเป็นเจ้าของ และกำหนดสิทธิ์ได้ ผ่านการเขียน YAML หรือ kubectl
แต่แบบนั้นมันก็ไม่ยืดหยุ่นสำหรับการทำงานระดับ Controller
ใน Controller ที่เป็นตัวควบคุมกลไกของ Resource อีกระดับนึง ยกตัวอย่างเช่น Kustomization Controller ของ Flux นั้น ตัว Controller เองจะรันอยู่ใน Cluster โดยใช้ ServiceAccount ของตัวเอง แต่ต้องสามารถ Impersonate หรือที่เรียกว่าการสวมบทบาทของ ServiceAccount อื่น เพื่อไปสร้างหรือจัดการ Resource ลงใน Cluster ภายใต้สิทธิ์ของ ServiceAccount นั้น ๆ ใน Namespace ทึ่กำหนดได้ (เรื่อง ระบุ Namespace ไม่ได้ยาก)
อันนั้นคือการจัดการ Kubernetes Resource
คราวนี้มาดูฝั่ง TF-controller และ Terraform Resource
ตัว TF-controller และ Terraform Resource จะขยับขึ้นไปอีก 1 Step เพราะ ตัว Terraform Object (Terraform Object คือ Kubernets Resource) จะต้องถูกสร้างอยู่ใน Namespace และตัว Terraform Object เป็นตัวคุม Terrafrom Resource ภายนอก Cluster
ความเป็นเจ้าของตัว Terraform Object จะต้องสามารถระบุได้ด้วย ServiceAccount เพื่อใช้ ServiceAccount เป็นตัวเชื่อมสิทธิ์ระหว่าง Pod ของตัวประมวลผลกับ IAM ของฝั่ง Cloud
ตอนนี้ตัวประมวลผลที่ว่าคือ TF-controller ทำให้การระบุ ServiceAccount ในระดับ Terraform Object ยังไม่สามารถทำได้ เพราะ Pod ที่รันอยู่ตอนนี้มี Pod เดียวคือ Pod ของตัว TF-controller
การเชื่อมสิทธิ์ยกตัวอย่าง เช่น IRSA ของ AWS
IRSA ของ AWS มีความสามารถที่จะยอมให้ระบุ IAM Role ไปยัง ServiceAccount เพื่อให้ Pod ภายใต้ ServiceAccount นั้นใช้ ServiceAccount Token เป็น Credentials เพื่อขอ Assume Role ผ่านบริการ STS และได้ Permission ตาม AWS Policy ที่กำหนด
แต่พอมี Pod ของ Controller อยู่แค่ Pod เดียวเลยไม่สามารถทำให้ยืดหยุ่นในระดับ Terraform Object ได้
ก็ต้องมาออกแบบตัวกลไกฝั่ง TF-controller ให้ดีพอสำหรับการสนับสนุน Multi-Tenancy
หน้าตาประมาณนี้ โดย Key ที่สำคัญก็คือ Terraform Runner Pod ที่จะเป็น Pod ซึ่งมี ServiceAccount ตามตัว Terraform Object ที่เป็นตัวต้นทาง โดย Terraform Runner Pod ก็จะถูกสร้างใน Namespace เดียวกับ Terraform Object เท่านั้น
และ Terraform Object ก็ควรจะเป็น Owner ของ Terraform Runner Pod
หน้าที่ของการสร้าง plan และ state ก็จะย้ายจากตัว TF-controller มาอยู่ที่ Terraform Runner Pod แทน
และการสร้าง Resource บน Cloud Provider ก็จะทำได้ยืดหยุ่นตามสิทธิ์ที่ต้องการ