การเขียน Kubernetes Controller, Part 6 — โมเดลสำหรับ Multi-Tenancy

Chanwit Kaewkasi
2 min readJan 25, 2022

--

หลักจากสร้าง 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 ก็จะทำได้ยืดหยุ่นตามสิทธิ์ที่ต้องการ

--

--

Chanwit Kaewkasi
Chanwit Kaewkasi

Written by Chanwit Kaewkasi

Technical Advisor at ConfigHub Inc. ex-weaveworks. Go nut since r57 (pre v1)

No responses yet