ประสบการณ์ของเราในการพัฒนาไดรเวอร์ CSI ใน Kubernetes สำหรับ Yandex.Cloud

ประสบการณ์ของเราในการพัฒนาไดรเวอร์ CSI ใน Kubernetes สำหรับ Yandex.Cloud

เรามีความยินดีที่จะแจ้งให้ทราบว่า Flant กำลังขยายการสนับสนุนไปยังเครื่องมือโอเพ่นซอร์สสำหรับ Kubernetes ด้วยการเปิดตัว เวอร์ชันอัลฟ่าของไดรเวอร์ CSI (อินเทอร์เฟซการจัดเก็บคอนเทนเนอร์) สำหรับ Yandex.Cloud

แต่ก่อนที่จะไปยังรายละเอียดการใช้งาน เรามาตอบคำถามว่าทำไมจึงจำเป็นในเมื่อยานเดกซ์มีบริการอยู่แล้ว บริการที่ได้รับการจัดการสำหรับ Kubernetes.

การแนะนำ

ทำไมเป็นเช่นนี้?

ภายในบริษัทของเรา ตั้งแต่เริ่มใช้ Kubernetes ในการผลิต (เช่น เป็นเวลาหลายปีแล้ว) เราได้พัฒนาเครื่องมือของเราเอง (deckhouse) ซึ่งนอกจากนี้ เรายังวางแผนที่จะเปิดให้บริการเป็นโครงการ Open Source เร็วๆ นี้ . ด้วยความช่วยเหลือนี้ เราจึงกำหนดค่าและกำหนดค่าคลัสเตอร์ทั้งหมดของเราอย่างสม่ำเสมอ และในปัจจุบันมีคลัสเตอร์มากกว่า 100 คลัสเตอร์ในการกำหนดค่าฮาร์ดแวร์ที่หลากหลายและในบริการคลาวด์ที่มีอยู่ทั้งหมด

คลัสเตอร์ที่ใช้ Deckhouse มีส่วนประกอบทั้งหมดที่จำเป็นสำหรับการดำเนินงาน: บาลานเซอร์ การตรวจสอบด้วยแผนภูมิ ตัวชี้วัดและการแจ้งเตือนที่สะดวก การตรวจสอบผู้ใช้ผ่านผู้ให้บริการภายนอกสำหรับการเข้าถึงแดชบอร์ดทั้งหมด และอื่นๆ การติดตั้งคลัสเตอร์ “ที่เต็มประสิทธิภาพ” ดังกล่าวในโซลูชันที่ได้รับการจัดการนั้นไม่มีประโยชน์ เนื่องจากมักเป็นไปไม่ได้หรืออาจนำไปสู่ความจำเป็นในการปิดใช้งานส่วนประกอบครึ่งหนึ่ง

NB: นี่เป็นประสบการณ์ของเรา และค่อนข้างเฉพาะเจาะจง เราไม่ได้แนะนำว่าทุกคนควรปรับใช้คลัสเตอร์ Kubernetes ด้วยตนเอง แทนที่จะใช้โซลูชันสำเร็จรูป อย่างไรก็ตาม เราไม่มีประสบการณ์จริงในการใช้งาน Kubernetes จาก Yandex และเราจะไม่ให้การประเมินบริการนี้ในบทความนี้

มันคืออะไรและเพื่อใคร?

ดังนั้นเราจึงได้พูดคุยเกี่ยวกับแนวทางที่ทันสมัยในการจัดเก็บข้อมูลใน Kubernetes แล้ว: ซีเอสไอทำงานอย่างไร? и ชุมชนมาได้อย่างไร สำหรับแนวทางนี้

ปัจจุบัน ผู้ให้บริการระบบคลาวด์รายใหญ่หลายรายได้พัฒนาไดรเวอร์สำหรับการใช้ดิสก์ระบบคลาวด์ของตนเป็น Persistent Volume ใน Kubernetes หากซัพพลายเออร์ไม่มีไดรเวอร์ดังกล่าว แต่มีฟังก์ชันที่จำเป็นทั้งหมดให้ผ่าน API จะไม่มีสิ่งใดขัดขวางไม่ให้คุณใช้งานไดรเวอร์ด้วยตนเอง นี่คือสิ่งที่เกิดขึ้นกับ Yandex.Cloud

เรายึดถือมาเป็นพื้นฐานในการพัฒนา ไดรเวอร์ CSI สำหรับคลาวด์ DigitalOcean และไอเดียเล็กๆ น้อยๆ จาก ไดรเวอร์สำหรับ GCPเนื่องจากการโต้ตอบกับ API ของคลาวด์เหล่านี้ (Google และ Yandex) มีความคล้ายคลึงกันหลายประการ โดยเฉพาะ API และ GCPและ Yandex ส่งคืนวัตถุ Operation เพื่อติดตามสถานะของการดำเนินการที่ใช้เวลานาน (เช่น การสร้างดิสก์ใหม่) หากต้องการโต้ตอบกับ Yandex.Cloud API ให้ใช้ Yandex.Cloud Go SDK.

ผลลัพธ์ของงานที่ทำ เผยแพร่บน GitHub และอาจมีประโยชน์สำหรับผู้ที่ใช้การติดตั้ง Kubernetes ของตนเองบนเครื่องเสมือน Yandex.Cloud (แต่ไม่ใช่คลัสเตอร์ที่มีการจัดการสำเร็จรูป) ด้วยเหตุผลบางประการ และต้องการใช้ (สั่งซื้อ) ดิสก์ผ่าน CSI

การดำเนินงาน

คุณสมบัติหลัก

ปัจจุบันไดรเวอร์รองรับฟังก์ชันต่อไปนี้:

  • การสั่งซื้อดิสก์ในทุกโซนของคลัสเตอร์ตามโทโพโลยีของโหนดในคลัสเตอร์
  • การถอดแผ่นดิสก์ที่สั่งไว้ก่อนหน้านี้
  • ปรับขนาดออฟไลน์สำหรับดิสก์ (Yandex.Cloud ไม่สนับสนุน เพิ่มดิสก์ที่ติดตั้งกับเครื่องเสมือน) สำหรับข้อมูลเกี่ยวกับวิธีการแก้ไขไดรเวอร์เพื่อให้การปรับขนาดไม่ยุ่งยากเท่าที่จะเป็นไปได้ โปรดดูด้านล่าง

ในอนาคต เราวางแผนที่จะใช้การสนับสนุนสำหรับการสร้างและการลบสแน็ปช็อตของดิสก์

ความยากลำบากหลักและวิธีการเอาชนะมัน

การขาดความสามารถในการเพิ่มดิสก์แบบเรียลไทม์ใน Yandex.Cloud API เป็นข้อ จำกัด ที่ทำให้การดำเนินการปรับขนาดสำหรับ PV (Persistent Volume) ซับซ้อนขึ้น: ในกรณีนี้ จำเป็นต้องหยุดพ็อดแอปพลิเคชันที่ใช้ดิสก์ และอาจทำให้แอปพลิเคชันหยุดทำงานได้

ตามที่ ข้อมูลจำเพาะของซีเอสไอหากตัวควบคุม CSI รายงานว่าสามารถปรับขนาดดิสก์ได้เฉพาะ "ออฟไลน์" (VolumeExpansion.OFFLINE) จากนั้นกระบวนการเพิ่มดิสก์ควรเป็นดังนี้:

หากปลั๊กอินมีเพียง VolumeExpansion.OFFLINE ความสามารถในการขยายและปริมาณได้รับการเผยแพร่หรือพร้อมใช้งานบนโหนดแล้ว ControllerExpandVolume ต้องถูกเรียกหลังจาก:

  • ปลั๊กอินมีตัวควบคุม PUBLISH_UNPUBLISH_VOLUME ความสามารถและ ControllerUnpublishVolume ได้รับการเรียกใช้เรียบร้อยแล้ว

หรืออย่างอื่น

  • ปลั๊กอินไม่มีตัวควบคุม PUBLISH_UNPUBLISH_VOLUME ความสามารถปลั๊กอินมีโหนด STAGE_UNSTAGE_VOLUME ความสามารถและ NodeUnstageVolume เสร็จสมบูรณ์แล้ว

หรืออย่างอื่น

  • ปลั๊กอินไม่มีตัวควบคุม PUBLISH_UNPUBLISH_VOLUME ความสามารถหรือโหนด STAGE_UNSTAGE_VOLUME ความสามารถและ NodeUnpublishVolume สำเร็จแล้ว

ซึ่งหมายความว่าคุณต้องถอดดิสก์ออกจากเครื่องเสมือนก่อนที่จะขยาย

อย่างไรก็ตามน่าเสียดาย การดำเนินงาน ข้อมูลจำเพาะของ CSI ผ่านรถเทียมข้างรถจักรยานยนต์ไม่เป็นไปตามข้อกำหนดเหล่านี้:

  • ในตู้คอนเทนเนอร์สำหรับรถเทียมข้างรถจักรยานยนต์ csi-attacherซึ่งควรรับผิดชอบต่อการมีช่องว่างที่ต้องการระหว่างการเมานท์ ฟังก์ชันนี้ไม่ได้นำไปใช้ในการปรับขนาดออฟไลน์ การอภิปรายเกี่ยวกับเรื่องนี้ได้เริ่มต้นขึ้น ที่นี่.
  • คอนเทนเนอร์ไซด์คาร์ในบริบทนี้คืออะไรกันแน่? ปลั๊กอิน CSI เองไม่ได้โต้ตอบกับ Kubernetes API แต่ตอบสนองต่อการเรียก gRPC ที่ส่งไปโดยคอนเทนเนอร์ไซด์คาร์เท่านั้น ล่าสุด กำลังได้รับการพัฒนา โดยชุมชน Kubernetes

ในกรณีของเรา (ปลั๊กอิน CSI) การดำเนินการเพิ่มดิสก์จะมีลักษณะดังนี้:

  1. เราได้รับสาย gRPC ControllerExpandVolume;
  2. เรากำลังพยายามเพิ่มดิสก์ใน API แต่เราได้รับข้อผิดพลาดเกี่ยวกับความเป็นไปไม่ได้ในการดำเนินการเนื่องจากดิสก์ถูกเมาท์
  3. เราจัดเก็บตัวระบุดิสก์ไว้ในแผนที่ซึ่งประกอบด้วยดิสก์ที่จำเป็นต้องดำเนินการเพิ่ม ด้านล่างนี้ เพื่อความกระชับ เราจะเรียกแผนที่นี้ว่า volumeResizeRequired;
  4. ลบพ็อดที่ใช้ดิสก์ด้วยตนเอง Kubernetes จะรีสตาร์ท เพื่อให้ดิสก์ไม่มีเวลาเมานต์ (ControllerPublishVolume) ก่อนที่จะดำเนินการเพิ่มให้เสร็จสิ้นเมื่อพยายามเมาต์ เราจะตรวจสอบว่าดิสก์ที่ระบุยังคงอยู่ volumeResizeRequired และส่งคืนข้อผิดพลาด
  5. โปรแกรมควบคุม CSI พยายามที่จะดำเนินการปรับขนาดอีกครั้ง หากการดำเนินการสำเร็จ ให้นำดิสก์ออก volumeResizeRequired;
  6. เพราะ รหัสดิสก์หายไป volumeResizeRequired, ControllerPublishVolume ผ่านสำเร็จ ดิสก์ถูกเมาท์ พ็อดเริ่มทำงาน

ทุกอย่างดูเรียบง่ายพอ แต่ก็มีข้อผิดพลาดเช่นเคย ขยายดิสก์ ตัวปรับขนาดภายนอกซึ่งในกรณีที่เกิดข้อผิดพลาดระหว่างการทำงาน ใช้คิว ด้วยการเพิ่มเวลาหมดเวลาแบบทวีคูณสูงสุด 1000 วินาที:

func DefaultControllerRateLimiter() RateLimiter {
  return NewMaxOfRateLimiter(
  NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
  // 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item)
  &BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
  )
}

ซึ่งอาจส่งผลให้การดำเนินการขยายดิสก์ขยายออกไปเป็นเวลา 15+ นาทีเป็นระยะๆ และทำให้พ็อดที่เกี่ยวข้องไม่พร้อมใช้งาน

ตัวเลือกเดียวที่ช่วยให้เราลดเวลาหยุดทำงานที่อาจเกิดขึ้นได้อย่างง่ายดายและไม่ลำบากคือการใช้ตัวปรับขนาดภายนอกเวอร์ชันของเราที่มีการจำกัดการหมดเวลาสูงสุด ภายใน 5 วินาที:

workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 5*time.Second)

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

จะเริ่มใช้งานได้อย่างไร?

ไดรเวอร์นี้รองรับ Kubernetes เวอร์ชัน 1.15 และสูงกว่า เพื่อให้ผู้ขับขี่ทำงานได้ ต้องปฏิบัติตามข้อกำหนดต่อไปนี้:

  • ธง --allow-privileged ตั้งค่าเป็นค่า true สำหรับเซิร์ฟเวอร์ API และ kubelet
  • รวมอยู่ด้วย --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true สำหรับเซิร์ฟเวอร์ API และ kubelet
  • การขยายพันธุ์เมานต์ (ติดการขยายพันธุ์) จะต้องเปิดใช้งานบนคลัสเตอร์ เมื่อใช้ Docker จะต้องกำหนดค่า daemon เพื่ออนุญาตการเมานต์แบบแชร์

ขั้นตอนที่จำเป็นทั้งหมดสำหรับการติดตั้งนั้นเอง อธิบายไว้ใน README. การติดตั้งเกี่ยวข้องกับการสร้างออบเจ็กต์ใน Kubernetes จากไฟล์ Manifest

เพื่อให้ผู้ขับขี่ทำงานได้ คุณจะต้องมีสิ่งต่อไปนี้:

  • ระบุตัวระบุไดเรกทอรีในรายการ (folder-id) ยานเดกซ์.คลาวด์ (ดูเอกสารประกอบ);
  • ในการโต้ตอบกับ Yandex.Cloud API ไดรเวอร์ CSI จะใช้บัญชีบริการ ในรายการความลับ คุณต้องผ่าน กุญแจที่ได้รับอนุญาต จากบัญชีบริการ ในเอกสารประกอบ อธิบายไว้, วิธีสร้างบัญชีบริการและรับกุญแจ

ทั้งหมดเลย- ความพยายามและเรายินดีที่จะรับข้อเสนอแนะและ ปัญหาใหม่หากคุณพบปัญหาใดๆ!

การสนับสนุนเพิ่มเติม

ด้วยเหตุนี้ เราขอแจ้งให้ทราบว่าเราได้นำไดรเวอร์ CSI นี้ไปใช้ ไม่ใช่เพื่อความปรารถนาอย่างยิ่งที่จะมีความสนุกสนานในการเขียนแอปพลิเคชันใน Go แต่เป็นเพราะความจำเป็นเร่งด่วนภายในบริษัท ดูเหมือนจะไม่เป็นประโยชน์สำหรับเราที่จะรักษาการใช้งานของเราเอง ดังนั้นหากยานเดกซ์แสดงความสนใจและตัดสินใจที่จะสนับสนุนไดรเวอร์ต่อไป เรายินดีที่จะโอนพื้นที่เก็บข้อมูลให้พวกเขา

นอกจากนี้ Yandex อาจมีการใช้งานไดรเวอร์ CSI ของตัวเองในคลัสเตอร์ Kubernetes ที่มีการจัดการซึ่งสามารถเผยแพร่ในโอเพ่นซอร์ส นอกจากนี้เรายังเห็นตัวเลือกการพัฒนานี้เป็นอย่างดี ชุมชนจะสามารถใช้ไดรเวอร์ที่ได้รับการพิสูจน์แล้วจากผู้ให้บริการ ไม่ใช่จากบริษัทบุคคลที่สาม

PS

อ่านเพิ่มเติมในบล็อกของเรา:

ที่มา: will.com

เพิ่มความคิดเห็น