Dezkubeدزکوب

معماری

چطور کار می‌کند

نمای کامل معماری دزکوب — از مسیر یک درخواست تا مرزهای امنیتی، و چهار تصمیمی که همه‌چیز از آن‌ها آمد.

سه صفحه، سه مسئولیت

پنل وب · API · CLI · MCPتوکن اسکوپ‌دارکنترل‌پلن دزکوبمجوزدهی — نقش، شرط، مالکیتسرویس‌های دامنهدرگاه واحد KubernetesKubernetesمنبع حقیقتPostgreSQLprojectionنوشتنwatchخواندناپلیکیشن · ماشین مجازی · مدل هوش مصنوعی
فلشِ نوشتن یک‌طرفه است و فلشِ خواندن از projection می‌آید. این جهت‌گیری، دلیلِ اصلیِ نبودِ واگرایی بین آنچه پلتفرم نشان می‌دهد و آنچه واقعاً در کلاستر است.

چرا دیتابیس ما منبع حقیقت نیست

رایج‌ترین معماری در این دسته از محصولات این است: حالت را در دیتابیس نگه دار و کلاستر را همگام با آن نگه دار. این ساده است و در دموی اول عالی کار می‌کند. مشکل، ماه سوم شروع می‌شود.

کافی است یک بار کسی مستقیم در کلاستر تغییری بدهد، یا یک عملیات نیمه‌کاره بماند. از آن لحظه، دیتابیس یک چیز می‌گوید و کلاستر چیز دیگری. هر قابلیتی که به آن حالت تکیه دارد — سهمیه، مالکیت، صورتحساب، بکاپ — بی‌صدا اشتباه می‌شود. ما جهت را برعکس کردیم.

· مدل «دیتابیس = حقیقت» · مدل دزکوب
مدل «دیتابیس = حقیقت»مدل دزکوب
نوشتنبه دیتابیس، بعد تلاش برای همگام‌سازیمستقیم به Kubernetes
خواندناز دیتابیساز projection که با watch از کلاستر ساخته می‌شود
تغییر دستی در کلاستربی‌صدا واگرایی می‌سازدreconciler می‌بیند: یا برمی‌گرداند یا گزارش می‌دهد
بازسازی پس از فاجعهباید دیتابیس را با کلاستر آشتی دادprojection از خودِ کلاستر بازساخته می‌شود
سرعت خواندنسریعسریع — همان projection

چطور مطمئنیم کار می‌کند؟

یک تست آشوب در مجموعهٔ تست‌ها هست که عمداً منبعی را در کلاستر دستکاری می‌کند و انتظار دارد اصلاح خودکار رخ بدهد. اگر reconciler خاموش بماند، آن تست قرمز می‌شود و تغییر مرج نمی‌شود.

تمام تماس با کلاستر از یک در می‌گذرد

هیچ سرویسی در دزکوب مستقیم با Kubernetes حرف نمی‌زند. همه از یک واسطِ واحد عبور می‌کنند.

قابلیت تست

چون کلاستر پشت یک واسط است، سرویس‌ها را می‌شود بدون کلاستر واقعی تست کرد. بخش بزرگی از آن ۱۵٬۰۰۰ تست به همین دلیل ممکن شد.

مرز امنیتی واحد

همهٔ manifestها از یک نقطه اعمال می‌شوند — یعنی یک جای واحد برای اعمال گاردریل، برچسب مالکیت و بررسی سیاست.

کنترل انفجار

حجم درخواست به API server از یک نقطه قابل اندازه‌گیری و محدودسازی است، نه از سی نقطهٔ پراکنده.

کجاها مرز کشیده‌ایم

مرز · چه چیزی را از چه چیزی جدا می‌کند · مکانیزم
مرزچه چیزی را از چه چیزی جدا می‌کندمکانیزم
مستأجر ↔ مستأجربار کاری دو سازمان مختلفnamespace، سیاست شبکهٔ default-deny، سهمیه، و ServiceAccount اختصاصی
اپلیکیشن ↔ اپلیکیشندو اپلیکیشن در یک محیطسیاست شبکهٔ L3/L4 و در صورت نیاز L7
بار کاری ↔ هستهکد مستأجر از هستهٔ نودسطوح ایزوله: عادی، gVisor، یا Kata (ماشین مجازی سبک)
کاربر ↔ کلاستردسترسی مستقیم به API کلاسترهیچ کاربری credential کلاستر نمی‌گیرد؛ همه‌چیز از کنترل‌پلن
کنترل‌پلن ↔ کلاسترخودِ کنترل‌پلننقش حداقلی به‌جای cluster-admin
ترافیک داخل ↔ بیرونخروج به اینترنتسیاست خروج سلسله‌مراتبی؛ هیچ سطحی سقف بالادست را باز نمی‌کند
مستأجرِ سختگیر ↔ بقیهمشتری‌ای که کلاستر مجازی می‌خواهدvcluster — کنترل‌پلن مجازی مستقل

بلوک اثبات

ماتریسِ تستِ نفوذِ ایزوله‌سازی، به‌ازای هر جفتِ نقش و هر منبع، بررسی می‌کند که آیا دسترسی متقابل ممکن است یا نه. این ماتریس بخشی از مجموعهٔ تست است، نه یک بررسی دستیِ یک‌باره.

یک درخواست، از اول تا آخر

مثال: یک توسعه‌دهنده دکمهٔ استقرار را می‌زند.

  1. اعتبارسنجی توکن

    نسخهٔ توکن با نسخهٔ فعلی کاربر مقایسه می‌شود. توکن باطل‌شده ← ۴۰۱

  2. بررسی مجوز

    نقش در آن پروژه، شرایط ABAC، و مالکیت خودِ منبع. رد شدن ← ۴۰۳ با نامِ سطحی که رد کرد

  3. بررسی سهمیه

    پیش از هر کار سنگین. عبور از سقف ← ۴۲۹ با عددِ باقی‌مانده

  4. اعتبارسنجی ورودی

    با schema سختگیرانه. خطا ← ۴۰۰ با نام دقیق فیلد

  5. ثبت ممیزی

    یک ردیف نوشته می‌شود — پیش از انجام کار

  6. بیلد

    در صف قرار می‌گیرد و در یک Job ایزوله و rootless اجرا می‌شود

  7. بازرسی و امضا

    ایمیج اسکن، SBOM تولید، و امضا می‌شود. آسیب‌پذیریِ مسدودکننده ← توقف

  8. اعمال

    manifest از درگاه واحد به کلاستر اعمال می‌شود. خطای کلاستر با پیام واقعی، نه ۵۰۰ خالی

  9. همگام‌سازی

    watch تغییر را می‌بیند و projection را به‌روز می‌کند؛ اختلاف توسط reconciler دیده می‌شود

گام ۵ عمداً قبل از گام ۶ است.

اگر ممیزی بعد از انجام کار نوشته شود، هر عملیاتی که وسطش خطا بدهد، ردی از خودش باقی نمی‌گذارد. تلاشِ ناموفق هم باید ثبت شود — برای ممیز، تلاش رد شده گاهی مهم‌تر از تلاش موفق است.

وقتی چیزی می‌افتد

سناریو · چه اتفاقی می‌افتد
سناریوچه اتفاقی می‌افتد
یک نودِ کاری می‌افتدبار کاری روی نودهای دیگر جدول‌بندی می‌شود؛ ماشین‌های مجازیِ تحت HA با ترتیبِ حصارکشی راه‌اندازی مجدد می‌شوند
یک نودِ کنترلی می‌افتدetcd با quorum ادامه می‌دهد؛ کنترل‌پلن روی نودهای باقی‌مانده
نمونهٔ کنترل‌پلن می‌افتدانتخاب رهبر، مالکیتِ کارهای دوره‌ای را جابه‌جا می‌کند — هیچ کار زمان‌بندی‌شده‌ای دو بار اجرا نمی‌شود
کارِ صف شکست می‌خوردتلاش مجدد با backoff؛ پس از سقف، به صف نامه‌های مرده می‌رود و قابل بازپخش است
دیسک replica از دست می‌رودLonghorn بازسازی می‌کند؛ چیدمانِ آگاه به zone مانع می‌شود همهٔ replicaها در یک domain باشند
کل کلاستر از دست می‌رودبازیابی از اسنپ‌شات etcd و بکاپ‌های آبجکت‌استوریج، با سطح تعهد RTO/RPO مشخص

نکتهٔ طراحی

سه سازوکاری که ماشین مجازی جابه‌جا می‌کنند — HA، توزیع مجدد بار، و مانور آشوب — یک بودجهٔ حرکتِ مشترک دارند، نه سه بودجهٔ جدا. اگر سه‌تا جدا بودند، در بدترین لحظه هر سه هم‌زمان شروع به جابه‌جایی می‌کردند. HA در این بودجه اولویت دارد، چون اول اجازه می‌گیرد.

تصمیم‌هایی که «نه» بودند

چه چیزی · چرا نه
چه چیزیچرا نه
مدل کاملاً اعلامی (GitOps خالص)مدل ما امری است و منبع حقیقتش کلاستر است. چسباندنِ یک موتور GitOps بالای آن، دو مالک برای یک شیء می‌سازد. اگر تیم شما GitOps دارد، به‌عنوان یک حالتِ اختیاری پشتیبانی می‌شود، نه به‌عنوان موتور اصلی.
فرمت اختصاصی برای تعریف بار کاریهر چیزی که می‌سازیم، در نهایت یک شیء استاندارد Kubernetes است. اگر روزی دزکوب را کنار بگذارید، کلاستر شما همچنان کار می‌کند.
سرویس بیرونی برای هر قابلیتهر وابستگیِ سرویسی یک نقطهٔ شکست، یک مسیر ارتقا و یک سطح حمله اضافه می‌کند. کتابخانهٔ درون‌پروسه ترجیح دارد مگر ارزش سرویسِ جدا عظیم باشد.
اعتماد به آنچه پادِ بیلد دربارهٔ خودش می‌گویدپادِ بیلد کد مستأجر را اجرا می‌کند. اطلاعاتِ اصالت را کنترل‌پلن می‌سازد، نه خودِ پاد — وگرنه در همان مدلِ تهدیدی که provenance را ارزشمند می‌کند، قابل جعل است.

سؤال‌های سخت‌تری دارید؟

جلسهٔ فنی بگذارید. با تیم مهندسی صحبت می‌کنید، نه تیم فروش.