Kubernetes v1.36: شاردینگ سمت سرور برای List و Watch
خلاصهٔ کاملتر
وقتی کلاسترهای کوبرنتیز به دهها هزار نود میرسن، کنترلرهایی که روی منابع پرتعداد مثل Pod واچ میذارن با یه دیوار مقیاسپذیری برخورد میکنن. مشکل اینه که هر رپلیکا از یه کنترلر افقیاسکیلشده، کل استریم رویدادها رو از API سرور دریافت میکنه؛ CPU و حافظه و پهنای باند صرف دیسریالایز کردن همه چیز میشه، بعد اون چیزی که مربوط به اون رپلیکا نیست دور ریخته میشه. یعنی اسکیل کردن کنترلر نهتنها کمکی نمیکنه، بلکه هزینه کلی رو چند برابر میکنه.
بعضی ابزارها مثل kube-state-metrics قبلاً یه نوع شاردینگ سمت کلاینت داشتن؛ هر رپلیکا یه بخشی از کیاسپیس رو قبول میکرد و بقیه رو رد میکرد. ولی این روش مشکل اصلی رو حل نمیکنه: داده همچنان از API سرور برای همه میره، پهنای باند با تعداد رپلیکاها رشد میکنه نه با سایز هر شارد، و CPU برای دیسریالایز کردن همون دادههایی که قرار بود دور ریخته بشن هدر میره.
کوبرنتیز v1.36 با فیچر آلفای KEP-5866 این فیلترینگ رو به داخل API سرور منتقل کرده. یه فیلد جدید به اسم shardSelector به ListOptions اضافه شده. هر رپلیکا یه بازه هش بهش میده و API سرور با یه هش تابع FNV-1a روی فیلد مشخصشده (مثل object.metadata.uid)، فقط آبجکتهایی که توی اون بازه هستن رو برمیگردونه. این هش تابع روی همه نمونههای API سرور یکسانه، پس با چند API سرور هم بدون مشکل کار میکنه. فیلدهایی که الان پشتیبانی میشن object.metadata.uid و object.metadata.namespace هستن.
برای استفاده در کنترلرها، میشه از WithTweakListOptions توی اینفورمر استفاده کرد:
shardSelector := "shardRange(object.metadata.uid, '0x0000000000000000', '0x8000000000000000')"
factory := informers.NewSharedInformerFactoryWithOptions(client, resyncPeriod,
informers.WithTweakListOptions(func(opts *metav1.ListOptions) {
opts.ShardSelector = shardSelector
}),
)برای یه دیپلوی دو رپلیکایی، هشاسپیس رو به دو نیمه تقسیم میکنیم؛ رپلیکا صفر نیمه پایینی و رپلیکا یک نیمه بالایی رو میگیره. همچنین میشه با || بازههای غیرپیوسته رو هم ترکیب کرد تا یه رپلیکا چند بخش از هشاسپیس رو پوشش بده.
برای اینکه بدونیم API سرور واقعاً شاردینگ رو اعمال کرده، جواب لیست یه فیلد shardInfo داخل متادیتا داره که سلکتور اعمالشده رو برمیگردونه. اگه این فیلد نبود یعنی سرور شاردینگ رو ساپورت نکرده و کلاینت باید خودش فیلترینگ سمت کلاینت رو انجام بده.
این قابلیت هنوز آلفاست و نیاز داره فیچرگیت ShardedListAndWatch روی API سرور فعال بشه. تیم کوبرنتیز دنبال فیدبک از نویسندههای کنترلر و اپراتورهای کلاسترهای بزرگه.
نکات کلیدی:
- مشکل اصلی: در شاردینگ سمت کلاینت، همه رپلیکاها کل داده رو دریافت میکنن و بخش اضافه رو دور میریزن
- راهحل: فیلتر کردن رویدادها در سطح API سرور بر اساس هش FNV-1a
- فیلد جدید
shardSelectorبهListOptionsاضافه شده - فیلدهای پشتیبانیشده:
object.metadata.uidوobject.metadata.namespace - وجود
shardInfoدر پاسخ نشون میده که سرور شاردینگ رو اعمال کرده - در مرحله آلفا؛ نیاز به فعالسازی فیچرگیت
ShardedListAndWatch




