Lasso เป็นเฟรมเวิร์กตัวควบคุม
Lasso มีความเท่าเทียมกันในการทำงานกับโปรเจ็กต์คอนโทรลเลอร์-รันไทม์ และสามารถใช้แทนคอนโทรลเลอร์-รันไทม์ได้
Lasso อยู่ในระดับต่ำ หากคุณต้องการจัดการคอนโทรลเลอร์ของคุณเอง คุณก็สามารถใช้งานได้ หากคุณกำลังมองหาความสะดวกสบายและฟังก์ชันการทำงานที่มากขึ้นสำหรับการสร้างประเภททรัพยากรของคุณเอง เราขอแนะนำให้ลองใช้ Wrangler
เฟรมเวิร์กตัวควบคุมหลักที่ใช้โดย Wrangler และ Norman
เอกสารนี้เขียนขึ้นโดยคำนึงถึงผู้ชมสองคน: ผู้ที่เพิ่งเริ่มใช้คอนโทรลเลอร์ Kubernetes และผู้ที่ไม่ได้ใหม่กับคอนโทรลเลอร์ Kubernetes แต่เพิ่งเริ่มใช้บ่วงบาศ
หากคุณอยู่ในหมวดหมู่ "บุคคลที่ไม่ใช่มือใหม่ในคอนโทรลเลอร์ Kubernetes" คุณสามารถข้ามไปที่ข้อเสนอคุณค่าของ Lasso ได้
หากคุณเพิ่งเริ่มใช้ตัวควบคุม Kubernetes ขอแนะนำอย่าข้ามส่วนใดๆ
หากคุณขาดความรู้พื้นฐานเกี่ยวกับ Kubernetes ขอแนะนำให้อ่านเอกสารประกอบอื่นๆ เกี่ยวกับพื้นฐานก่อน เช่น ภาพรวม Kubernetes
หมายเหตุ: นี่จะเป็นหลักสูตรเร่งรัดที่สั้นมาก เราขอแนะนำให้คุณค้นหาแหล่งข้อมูลอื่น ๆ ที่เกี่ยวข้องกับหัวข้อนี้ มีมากมาย! ทรัพยากรที่แนะนำ 2 รายการ ได้แก่ โครงการ Sample Controller และ Introduction To Kubernetes Controller Frameworks
จากเอกสาร Kubernetes
ใน Kubernetes ตัวควบคุมคือลูปควบคุมที่เฝ้าดูสถานะที่ใช้ร่วมกันของคลัสเตอร์ผ่าน apiserver และทำการเปลี่ยนแปลงโดยพยายามย้ายสถานะปัจจุบันไปยังสถานะที่ต้องการ
คำว่า "ผู้ควบคุม" ถูกใช้อย่างหลวมๆ มากกว่าที่คุณเชื่อในคำจำกัดความข้างต้น ในคำพูดของเราเอง: ตัวควบคุมคือตัวจัดการลูปที่ทำหน้าที่ตอบสนองต่อเหตุการณ์ทรัพยากร Kubernetes ใน Lasso เรายังใช้คำว่า "ตัวควบคุม" เพื่ออ้างถึงโครงสร้างทั้งหมดที่รับผิดชอบในการลงทะเบียนตัวจัดการลูปนี้ และจัดหาทรัพยากรที่ต้องการ กล่าวโดยสรุป คอนโทรลเลอร์คือโครงสร้างที่รวมทุกอย่างที่จำเป็นในการโต้ตอบและทำงานกับประเภท Kubernetes
เพื่อให้บรรลุเป้าหมายข้างต้น จะต้องบรรลุเป้าหมายย่อยบางประการ:
มีกรอบการทำงานมากมายเพื่อช่วยให้บรรลุเป้าหมายข้างต้น ลาสโซ่เป็นหนึ่งในนั้น สิ่งที่กรอบงานเหล่านี้ส่วนใหญ่มีเหมือนกัน รวมถึงบ่วงบาศก็คือกรอบงานเหล่านี้ใช้ฟังก์ชันการทำงานจากไคลเอนต์ไปเพื่อให้บรรลุเป้าหมายเหล่านี้ คุณสามารถบรรลุเป้าหมายเหล่านี้ได้โดยใช้เพียงแค่ client-go สำหรับส่วนที่เหลือของส่วนนี้ เราจะอธิบายวิธีการประกอบคอนโทรลเลอร์โดยใช้แนวคิด Client-Go
Informer ใช้เพื่อบรรลุเป้าหมายข้างต้นที่จำเป็นสำหรับตัวควบคุม Kubernetes ผู้แจ้งมีตัวจัดการเหตุการณ์และตัวสร้างดัชนี ตัวสร้างดัชนีมีฟังก์ชันร้านค้าและแผนที่สำหรับสร้างดัชนีวัตถุภายในร้านค้าที่เรียกว่าตัวสร้างดัชนี โครงสร้างที่อยู่ด้านล่างจะแตกต่างกัน แต่โครงสร้างเทียมจะแสดงอยู่ด้านล่างเพื่อแสดงสิ่งนี้:
Informer
EventHandler
Indexer
Store
Indexers
EventHandler สามารถมีตรรกะที่แตกต่างกันสำหรับการสร้าง อัปเดต และลบเหตุการณ์ ตัวจัดการเหตุการณ์คือจุดที่ตัวควบคุมเข้ามา คุณใช้เพื่อกำหนดค่าการสร้าง อัปเดต และลบตัวจัดการเหตุการณ์
ตัวสร้างดัชนีถูกใช้เป็นแคช
ร้านค้าเป็นที่ที่ตัวสร้างดัชนียังคงมีวัตถุอยู่
ตัวสร้างดัชนีเป็นฟังก์ชันที่ตัวสร้างดัชนีสามารถใช้เพื่อจัดทำดัชนีวัตถุที่ยังคงอยู่ เมื่อสร้างดัชนีด้วยตัวสร้างดัชนีแล้ว วัตถุสามารถดึงข้อมูลได้โดยใช้สตริงที่อธิบายคุณลักษณะที่ตัวสร้างดัชนีสนใจ
ตัวสร้างดัชนีมักจะใช้เพื่อดึงข้อมูลออบเจ็กต์ด้วยเมตาดาต้าธรรมดา เช่น เนมสเปซและชื่อ
ผู้แจ้งจะเติมข้อมูลตัวสร้างดัชนีก่อนโดยแสดงรายการทรัพยากรทั้งหมดที่ส่งคืนจากไคลเอนต์ จากนั้นผู้แจ้งจะเฝ้าดูทรัพยากร Kubernetes ที่ได้รับมอบหมาย เมื่อมีเหตุการณ์เกิดขึ้น ระบบจะใช้เหตุการณ์นั้นเพื่ออัปเดตตัวสร้างดัชนีและดำเนินการตัวจัดการเหตุการณ์
โดยปกติแล้วแอปพลิเคชันจะต้องการตัวควบคุมหลายตัว อย่างไรก็ตาม มันอาจไม่มีประสิทธิภาพสำหรับผู้ควบคุมทุกรายที่จะมีผู้แจ้งข้อมูลของตัวเองและดังนั้นจึงมีตัวสร้างดัชนีของตัวเอง SharedIndexerInformer จาก client-go สามารถใช้เพื่อเพิ่มตัวควบคุมหลายตัวที่ทั้งหมดใช้ตัวสร้างดัชนีเดียวกัน
มีภาพที่ดีเกี่ยวกับวิธีการทำงานของตัวควบคุม Kubernetes ใน repo ของ kubernetes/sample-controller
หมายเหตุ: ผู้แจ้งได้รับการทำให้ง่ายขึ้นเพื่อความกระชับ หากคุณสนใจวิธีการทำงานอย่างชัดเจน ขอแนะนำให้คุณอ่านโค้ด client-go
Lasso สร้างมาตรฐานว่าคอนโทรลเลอร์คืออะไรด้วยแพ็คเกจคอนโทรลเลอร์ Lasso แนะนำโรงงานสำหรับจัดการแคช ตัวควบคุม และไคลเอนต์ภายในโปรเจ็กต์ นี่เป็นสิ่งจำเป็นสำหรับเจ้าของฟาร์มที่ต้องจัดการอินสแตนซ์หลายประเภท
ตัวควบคุม Lasso ใช้คิวงาน Client-Go Lasso ลงทะเบียนตัวจัดการเหตุการณ์ที่ประมวลผลคิวงาน ตัวจัดการที่มุ่งเน้นคิวงานทำให้ต้องเพิ่มตัวจัดการเหตุการณ์เพียงตัวเดียวสำหรับ Kubernetes แต่ละประเภท ตอนนี้การลงทะเบียนตัวจัดการเพียงเพิ่มเข้าไปในรายการตัวจัดการของประเภทคอนโทรลเลอร์ การจัดคิวออบเจ็กต์จะเพิ่มออบเจ็กต์นั้นลงในคิวงาน แต่ละอ็อบเจ็กต์ในคิวงานจะถูกประมวลผลโดยผู้ปฏิบัติงานที่ทำงานใน goroutines ตัวจัดการเหตุการณ์ของคอนโทรลเลอร์จะจัดคิวออบเจ็กต์ใด ๆ ที่ทำให้ตัวจัดการของคอนโทรลเลอร์ตั้งแต่หนึ่งตัวขึ้นไปส่งคืนข้อผิดพลาดที่ไม่ใช่ประเภท ErrIgnore
คิวงานนี้ยังสามารถมีอ็อบเจ็กต์ที่จัดคิวจากแหล่งอื่นได้ ฟังก์ชันนี้แสดงผ่านฟังก์ชัน Enqueue ของคอนโทรลเลอร์ การดำเนินการนี้จะเปลี่ยนคอนโทรลเลอร์จากการโต้ตอบกับทรัพยากร Kubernetes และการซิงค์แคชซ้ำเท่านั้น มาเป็นโค้ดที่เรียกใช้ได้ด้วย
ประเภท sharedController จะฝังอินเทอร์เฟซของคอนโทรลเลอร์ไว้เพื่อแสดงฟังก์ชันการทำงานของคอนโทรลเลอร์ sharedController ยังเปิดเผยฟังก์ชัน RegisterHandler พร้อมกับฟังก์ชัน Client RegisterHandler เพิ่มตัวจัดการที่ส่งผ่านไปยังรายการตัวจัดการของตัวควบคุม และไคลเอ็นต์ส่งคืนไคลเอ็นต์สำหรับประเภททรัพยากรที่สอดคล้องกันของ sharedController sharedController มีฟิลด์ GVK (ประเภทเวอร์ชันกลุ่ม) ซึ่งระบุว่าเป็นประเภทใด
ลักษณะ "ที่ใช้ร่วมกัน" เริ่มต้นที่ตัวควบคุม Lasso ดั้งเดิมมากกว่า การใช้คิวงานทำให้สามารถแชร์ Event Handler หนึ่งชุดได้ เป็นต้น จากนั้น Lasso Shared Controller จะเพิ่มสิ่งนี้โดยเก็บไคลเอ็นต์ที่นำมาใช้ซ้ำได้สำหรับ GVK และเพิ่มวิธีในการลงทะเบียนตัวจัดการกับคอนโทรลเลอร์ด้านล่างด้วย RegisterHandler ได้อย่างง่ายดาย
sharedController สามารถสร้างคอนโทรลเลอร์พื้นฐานได้ โดยจะทำได้ก็ต่อเมื่อตัวจัดการลงทะเบียนกับ sharedController แล้วเท่านั้น
ห่อไคลเอ็นต์ Kubernetes ประกอบด้วยช่อง GVK สำหรับจัดการไคลเอ็นต์ในโครงสร้างหลัก เช่น sharedClientFactory เปิดเผยฟังก์ชันการทำงานเพิ่มเติมบางอย่าง เช่น การกำหนดค่าส่วนหัว User-Agent สำหรับไคลเอ็นต์ REST พื้นฐาน
Lasso Cache เป็นตัวห่อหุ้มเบา ๆ รอบ SharedIndexInformer จากไคลเอ็นต์ไป
ประโยชน์หลักของ Lasso Cache คือสามารถกำหนด Cache Factory ได้ ซึ่งจะจัดการ SharedIndexInformer ในหน่วยความจำโดย GVK เพื่อให้สามารถนำกลับมาใช้ใหม่ได้ เมื่อใช้ฟังก์ชัน Lasso Cache มันจะจัดการตัวเองภายใน CacheFactory ที่ถูกส่งต่อเพื่อสร้างมันขึ้นมา
โรงงานแคชที่ใช้ร่วมกันจะจัดเก็บแคชและอนุญาตให้จัดการผ่านโครงสร้าง GVK เมื่อแคชถูกสร้างขึ้นเมื่อสามารถนำกลับมาใช้ใหม่ได้
Shared Client Factory มีอยู่เพื่อให้ไคลเอ็นต์สำหรับ GVK สามารถนำมาใช้ซ้ำได้หลังจากที่ถูกสร้างขึ้นแล้ว
SharedControllerFactory เชื่อมโยงทุกสิ่งที่กล่าวมาข้างต้นเข้าด้วยกัน ช่วยให้เข้าถึงไคลเอนต์ แคช และตัวจัดการได้เพียงจุดเดียว ซึ่งทั้งหมดนี้จัดการให้คุณ เป็นไปได้ที่จะโต้ตอบกับโรงงานตัวควบคุมที่ใช้ร่วมกันเป็นหลัก มันจะสร้างตัวควบคุม ไคลเอนต์ และแคชที่จำเป็นทั้งหมดที่คุณต้องการ จะช่วยให้แน่ใจว่าไม่มีวัตถุเหล่านี้ซ้ำกัน มันจะป้องกันสภาพการแข่งขัน
เมื่อคุณใช้ ForObject, ForKind, ForResource หรือ ForResourceKind แล้ว SharedControllerFactory จะทำสิ่งต่อไปนี้:
deferredController เป็นฟังก์ชันที่เมื่อดำเนินการแล้ว จะสร้างและส่งคืนคอนโทรลเลอร์ มันจะสร้างคอนโทรลเลอร์โดยใช้แคชจาก SharedCacheFactory วัตถุประสงค์ของฟังก์ชัน deferredController คือระงับการเติมแคชจนกว่าจะจำเป็นจริงๆ วิธีนี้ช่วยให้แน่ใจว่าเฉพาะทรัพยากร Kubernetes ที่มีตัวจัดการที่ลงทะเบียน ถูกจัดคิว หรือมีการร้องขอแคชของตัวควบคุมเท่านั้นที่ถูกจัดเก็บไว้ในหน่วยความจำ
เมื่อคุณได้รับ sharedController จาก SharedControllerFactory มันจะยังไม่มีคอนโทรลเลอร์พื้นฐานที่สร้างอินสแตนซ์ขึ้นมา deferredController แทนเพื่อสร้างหนึ่งรายการเมื่อมีการดำเนินการอย่างใดอย่างหนึ่งตามที่กล่าวมา
ด้านล่างนี้เป็นขั้นตอนสำหรับวิธีที่ตรงไปตรงมาในการลงทะเบียนตัวจัดการและรันในรูปแบบบ่วงบาศ:
package main
import (
"context"
"github.com/rancher/lasso/pkg/controller"
appsv1 "k8s.io/api/apps/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
)
func main () {
config , err := clientcmd . BuildConfigFromFlags ( "" , os . Getenv ( "KUBECONFIG" ))
if err != nil {
panic ( err )
}
// Setup types you want to work with
scheme := runtime . NewScheme ()
appsv1 . AddToScheme ( scheme )
controllerFactory , err := controller . NewSharedControllerFactoryFromConfig ( config , scheme )
if err != nil {
panic ( err )
}
// ForObject, ForKind, ForResource, and ForResourceKind can all be used to retrieve the controller.
// They all accept different parameters but the first three all eventually call ForResourceKind.
// Refer to [How to use Lasso](#how-to-use-lasso) for more information on how ForResourceKind works.
sharedController , err := controllerFactory . ForObject ( & appsv1. Deployment {})
if err != nil {
panic ( err )
}
// Register a handler on a shared controller. If you need a dedicated queue then use controller.New()
sharedController . RegisterHandler ( context . TODO (), "my-handler" , controller . SharedControllerHandlerFunc ( func ( key string , obj runtime. Object ) (runtime. Object , error ) {
// obj is the latest version of this obj in the cache and MAY BE NIL when an object is finally deleted
dep , ok := obj .( * appsv1. Deployment )
if ! ok {
return obj , nil
}
// Do some stuff ...
// Get stuff from the cache
sharedController . Informer (). GetStore (). Get ( key )
result := & appsv1. Deployment {}
err := sharedController . Client (). Update ( ctx , dep . Namespace , dep , result , metav1. UpdateOptions {})
// return the latest version of the object
return result , err
}))
// the second, int parameter is the number of workers to be used for EACH controller.
err = controllerFactory . Start ( context . TODO (), 5 )
if err != nil {
panic ( err )
}
}
การทดสอบของ Lasso บางส่วนใช้ envtest เพื่อรัน Envtest อนุญาตให้การทดสอบทำงานกับเซิร์ฟเวอร์ kubernetes "ปลอม" โดยมีค่าใช้จ่ายเพียงเล็กน้อย/ไม่มีเลย
หากต้องการติดตั้งไบนารี setup-envtest
ที่จำเป็น ให้ใช้คำสั่งต่อไปนี้:
go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest
ก่อนที่จะรันการทดสอบ คุณต้องรันคำสั่งต่อไปนี้เพื่อตั้งค่าเซิร์ฟเวอร์ปลอม:
# note that this will use a new/latest version of k8s. Our CI will run against the version of k8s that corresponds to lasso's
# current client-go version, as seen in scripts/test.sh
export KUBEBUILDER_ASSETS= $( setup-envtest use -p path )
แหล่งข้อมูลต่อไปนี้มีประโยชน์ในการเขียนเอกสารเหล่านี้ ขอแนะนำอย่างยิ่งให้เรียนรู้มากกว่าสิ่งที่นำเสนอไว้ที่นี่: