Drasi و شکار دریفت کوبرنتیز با Cypher
خلاصهٔ کاملتر
Drasi کوئری Cypher (یعنی همون زبون کوئری گراف) رو به شکل «همیشهفعال» روی گراف زندهٔ منابع کلاستر نگه میداره، با توابع زمانی مثل trueFor و نتیجهای که خودش بهروز میمونه. به گفتهٔ نویسنده جای ابزارهای موجود رو نمیگیره: Gatekeeper و Kyverno موقع admission جلوی کانفیگ بد رو میگیرن، Flux و Argo فاصلهٔ گیت و کلاستر رو نشون میدن و Prometheus روی متریک هشدار میده. هیچکدوم سوال رابطهای بین چند نوع منبع رو جواب نمیدن و دقیقاً همینجا جای Drasi باز میشه.
نویسنده شش قانون رو اول از روی مستندات نوشت، بعد روی یه کلاستر واقعی AKS با نقض عمدی تستشون کرد. فقط دو تا بدون تغییر جواب داد، دو تا بازنویسی شد و سه تا کلاً حذف شد. حذفشدهها مشکل منطقی نداشتن: سورس کوبرنتیز Drasi یه لیست ثابت دوازدهتایی از منابع رو واچ میکنه و Namespace، NetworkPolicy، PodDisruptionBudget و Secret توش نیستن. هیچ دسترسی RBAC هم این لیستو عوض نمیکنه، پس راه دور زدنش انتخاب یه منبع دیگهست، نه کوئری هوشمندتر.
قانون «Deployment کمرپلیکای ماندگار» فقط بعد از اضافهشدن coalesce سالم موند، چون readyReplicas وسط rollout مقدار null داره و کوئری بدون اون ارور میده. تابع drasi.trueFor هم نقش debounce رو بازی میکنه: نوسان عادی موقع rollout هیچی رو شلیک نمیکنه، ولی خرابی واقعی بعد از پنج دقیقه خودشو نشون میده.
MATCH (d:Deployment)
WHERE d.spec.replicas > coalesce(d.status.readyReplicas, 0)
AND drasi.trueFor(d.spec.replicas > coalesce(d.status.readyReplicas, 0),
duration({ minutes: 5 }))
RETURN d.metadata.name AS name, d.metadata.namespace AS namespace,
d.spec.replicas AS desired, coalesce(d.status.readyReplicas, 0) AS readyقانون دوم دنبال ایمیجهایی میگرده که از رجیستری مجاز نیومدن. اینجا نویسنده فهمید STARTS WITH و CONTAINS و ENDS WITH تو این نسخهٔ پارسر Cypher اصلاً وجود ندارن، پس با left() همون کارو کرده. این قانون دو نکتهٔ واقعی رو هم لو داد: سایدکارهای Dapr خودشون رو با پیشوند docker.io/daprio/ معرفی میکنن و باید صراحتاً تو allowlist بیان، و کامپوننتهای Calico ایمیجشون فقط یه دیجست sha256: بدون پیشوند رجیستریه، یعنی هر قانون مبتنی بر پیشوند نسبت بهشون کور میمونه.
MATCH (p:Pod)-[:HAS]->(c:Container)
WHERE left(c.image, 22) <> 'ghcr.io/drasi-project/'
AND left(c.image, 18) <> 'mcr.microsoft.com/'
RETURN p.metadata.namespace AS namespace, p.metadata.name AS pod, c.image AS imageجمعبندی نویسنده اینه که یه رولبوک سالم باید حوصلهسربر باشه: روی کلاستر سالم همهٔ قانونها خالی میمونن و فقط لحظهای که نقض واقعی از آستانه رد شد یه ردیف ظاهر میشه، و بهمحض رفع مشکل هم بلافاصله پاک میشه. اگه قانونی مدام شلیک میکنه احتمالاً coalesce جا افتاده یا پنجرهٔ debounce کوتاهه، و اگه هیچوقت چیزی برنمیگردونه اول باید چک کنی اون نوع منبع اصلاً تو لیست واچ هست یا نه.
نکات کلیدی:
- سورس کوبرنتیز فقط ۱۲ نوع منبع رو واچ میکنه؛ Namespace، NetworkPolicy، PodDisruptionBudget و Secret جزوشون نیستن و RBAC هم چیزی رو عوض نمیکنه.
- STARTS WITH، CONTAINS، ENDS WITH، regex با =~ و سابکوئری EXISTS { MATCH } تو این پارسر پشتیبانی نمیشن.
- چیزهایی که کار میکنن: left()، coalesce()، OPTIONAL MATCH همراه با aggregation و میدلور unwind.
- بلوک میدلور باید زیر sources: بیاد نه spec:، وگرنه apply بیسروصدا شکست میخوره.
- تغییر Kubernetes Source یعنی حذف و ساخت دوباره، بهعلاوهٔ ساخت دوبارهٔ همهٔ کوئریهای وابسته.
- از شش قانون اولیه، پنج قانون کاربردی موند که چهارتاش روی نقض واقعی روی کلاستر تست شده.




