RAILSHOT.
العودة إلى القاعة

Railshot

AI deployment & operations platform

نشر تطبيق ويب مبني محليًا على بيئات سحابية ومحلية مُعدّة، ثم تشغيله.

منصة نشر وتشغيل بالذكاء الاصطناعي تنقل تطبيق ويب مبنيًا محليًا إلى بيئات سحابية أو محلية مُعدّة وتواصل تشغيله.

2026.09.28 — 2026.10.04 · مكتمل

مشروع جماعي · دوري: تخطيط CI وتطبيقه، وعناقيد CSP وواجهة Ansible، والتشغيل، ومراجعة شيفرة الفريق والتكامل

SoftBank Hackathon 2026 powered by KOREC & Progateمشارك في التصفيات · يُعلن اختيار النهائيات في 2026.10.26 (حتى 2026.10.07)

  • الويبمُطبَّق · هاكاثون
  • خادم MCPمُطبَّق · بعيد · محلي

عنقود التشغيل وعناقيد تطبيقات العملاء منفصلة، والمسار العام مفصول عن التحكم في النشر.

في K3s الخاص بالتشغيل، توضع لوحة المعلومات وAPI المنتج وbuild controller على عُقد بدور platform، وJobs الخاصة بـ runner على عقدة بدور build، بينما يتولى Argo CD النشر. وتعمل تطبيقات العملاء في namespace مخصص من عنقود K3s + Cilium منفصل بعقدة واحدة لكل هدف مسجّل.

خريطة العنقود · مرسومة من الإعلانات والشيفرة عند الإيداع العام 645e28a
خريطة عنقود التشغيل وعنقود العملاء في Railshotعنقود K3s للتشغيل وعنقود تطبيقات عميل مسجّل. في عنقود التشغيل، توضع في namespace المسمّى railshot-system لوحةُ المعلومات وAPI المنتج وMCP البعيد (عند توفير صورته فقط) وbuild controller على عُقد بدور platform، وتتسلّم Jobs الخاصة بـ runner في namespace المسمّى railshot-build مهامَّ GitHub Actions على عقدة دور build الموسومة بـ taint. وتنشر مهمة release مستضافة على GitHub الـ bundle المُختبَر إلى GHCR. ويودِع API المنتج workload في config Git ويُجري sync لـ Application في namespace المسمّى argocd، ويطبّق Argo CD موارد Deployment وNodePort Service وNetworkPolicy على namespace المسجّل في عنقود العميل. وتدخل طلبات التطبيق عبر نقطة دخول L7 لدى المزوّد إلى NodePort وService على العقدة، ثم إلى Pod التطبيق. ولا يستند حكم النشر إلا إلى حالة Argo وفحص URL العام، أما تشخيصات Pod والسجلات والمقاييس فتُقرأ إشاراتٍ منفصلة. وتُفصل مُدخلات تثبيت المشغّل وتسجيله عن حمولة تطبيق المستأجر.مستخدم Railshotلوحة المعلومات · MCPbootstrap المشغّلالتثبيت · التسجيل · SecretGHCRصور digestمستودع config Gitworkload.json · revisionنقطة دخول L7 لدى المزوّدALB · GCP LB · Amphoraمستخدم التطبيقHTTPS عامVM المراقبةخارج K3s العميل · Composerailshot-systemdashboard · nginxMCP البعيد · مع صورة فقطbuild controller · CronJobAPI المنتج · cd.js → bridge.pyargocdArgo CD · ApplicationAppProject · cluster SecretCronJob للتجديد · كل 2 hrailshot-buildrunner Job · hostNetwork · Docker socketrailshot-deploy.ymlloop job · self-hosted runnerrelease job · GitHub-hosted<app namespace>Deployment · Pod · صورة digestNodePort Service · LocalNetworkPolicy · CIDRs المدرجةrailshot-argocd SA · رمز مميّزkube-systemCilium · Helm · VXLANrailshot-observabilitynode-exporterkube-state-metricsعنقود التشغيل · K3sAWS · عُقد حسب الدورعُقد بدور platformnodeSelectorعقدة بدور buildNoSchedule taintGitHubActions · GHCRعنقود تطبيقات العميل · مثالواحد لكل هدف مسجّلعقدة K3s واحدة · serverCilium · مع الإبقاء على kube-proxy1workflow_dispatch2تجديد runner Job3تسلّم الـ job4bundle مُختبَر5 النشر بحسب digest · release job · GitHub-hosted → GHCR51workload commit · push2revision3 Application sync · API المنتج · cd.js → bridge.py → Argo CD · Application34التطبيق على namespace5السحب بحسب digest1HTTPS 4432NodePort3 إلى Pod · NodePort Service · Local → Deployment · Pod · صورة digest34 فرض السياسة · Cilium · Helm · VXLAN → NetworkPolicy · CIDRs المدرجة45 لوحة المعلومات · API · مستخدم Railshot → dashboard · nginx51 revision · health · الصور · API المنتج · cd.js → bridge.py → Argo CD · Application12فحص HTTPS العام3تشخيص Pod · ليس الحكم4ذيل السجل · 100 سطر لكل Pod5scrape · منافذ NodePort6Blackbox probe1توليد platform · Secret2bootstrap التسجيل3تثبيت K3s · Cilium4TokenRequest · 6 h

البناء → نشر الصورة

يطلب API المنتج تشغيل GitHub Actions، فيتسلّم runner على عقدة build الـ job ويفحصه. ولا ينشر release job المستضاف على GitHub إلى GHCR إلا bundle اجتاز الفحوص نفسها.

  1. API المنتج · cd.js → bridge.pyrailshot-systemتشغيل · تطبيق: workflow_dispatchloop job · self-hosted runnerrailshot-deploy.yml

    يطلب API المنتج تشغيل GitHub Actions بـ tenant وapp وsource commit وtarget. ولا يستدعي API أي runner Job مباشرة أبدًا.

  2. build controller · CronJobrailshot-systemتشغيل · تطبيق: تجديد runner Jobrunner Job · hostNetwork · Docker socketrailshot-build

    ينشئ CronJob الخاص بـ build controller (كل دقيقة، على عقدة platform) runner Jobs في namespace المسمّى railshot-build. ولا يسمح Role الخاص به إلا بـ get وlist وcreate على Job، وget وupdate وpatch على Secret تسجيل runner الوحيد، ولا يستطيع إنشاء namespaces أو Secrets أخرى.

  3. runner Job · hostNetwork · Docker socketrailshot-buildتشغيل · تطبيق: تسلّم الـ jobloop job · self-hosted runnerrailshot-deploy.yml

    يتسلّم runner على عقدة دور build (بـ hostname محدد وtoleration من نوع NoSchedule) الـ loop job بحسب وسوم self-hosted ويشغّله. ويعمل مصدر العميل في حاويات Docker المقيّدة القائمة للبناء والفحص.

  4. runner Job · hostNetwork · Docker socketrailshot-buildبيانات: bundle مُختبَرrelease job · GitHub-hostedrailshot-deploy.yml

    يترك loop job الـ bundle الذي اجتاز الفحوص نفسها، ولا يأخذ release job إلا ذلك الـ bundle.

  5. release job · GitHub-hostedrailshot-deploy.ymlبيانات: النشر بحسب digestGHCR

    ينشر release job مستضاف على GitHub (ubuntu-24.04) صورة الـ bundle المُختبَر إلى GHCR دون إعادة بنائها. ولا يحدث نشر الصور أبدًا داخل عنقود تطبيقات العميل.

config Git → Argo → namespace العميل

يحمل config Git الموارد المطلوبة، ويحمل GHCR بايتات الصورة. ولا يطبّق Argo CD إلا على namespace العميل المسجّل.

  1. API المنتج · cd.js → bridge.pyrailshot-systemبيانات: workload commit · pushمستودع config Git

    يشغّل cd.js الملف bridge.py، الذي لا يودِع workload.json ولا يدفعه إلا حين يتفق سجل النشر والهدف المسجّل، ثم يعيد قراءة revision البعيدة. ويحمل Git الموارد المطلوبة، ويحمل GHCR بايتات الصورة.

  2. مستودع config Gitبيانات: revisionArgo CD · Applicationargocd

    لا يقرأ Application إلا مستودع config والمسار وrevision المقيّدة الخاصة به.

  3. API المنتج · cd.js → bridge.pyrailshot-systemتشغيل · تطبيق: Application syncArgo CD · Applicationargocd

    يُضبط Application المسمّى عبر server-side apply، ويُطلب sync لـ revision واحدة محددة دون prune. ويحمل ServiceAccount المسمّى railshot-product الخاص بـ API المنتج كلًّا من صلاحيات registration bootstrap التي ثبّتها المشغّل (create لـ Secrets وAppProjects وApplications في argocd، وget وupdate وescalate على Roles مسمّاة) وصلاحيات get وpatch تُضاف بالاسم الدقيق لكل هدف مُتحقَّق منه. ولا يمكن حصر create في Kubernetes بالاسم، لذا يُبقي التحقق من مُدخلات المنتج الأسماءَ ضمن النطاق أيضًا.

  4. Argo CD · Applicationargocdتشغيل · تطبيق: التطبيق على namespace<app namespace>

    يطبّق Argo CD على namespace المحدد في عنقود العميل ببيانات اعتماد cluster Secret المسجّل. ولا يسمح AppProject إلا بأنواع ضمن namespace، ولا بموارد على مستوى العنقود.

  5. Deployment · Pod · صورة digest<app namespace>بيانات: السحب بحسب digestGHCR

    تُسحب صورة الـ digest المنشورة بـ pull Secret مُشار إليه بالاسم في namespace نفسه. ولا تدخل قيم Secret أبدًا في المُخرَج ولا في config Git.

مسار الطلب العام

تمر طلبات التطبيق: نقطة دخول L7 لدى المزوّد → NodePort على العقدة → Service → Pod التطبيق. وفرض السياسة في Cilium ضابط منفصل، لا قفزة تحمل الطلب. والدخول إلى لوحة التشغيل مسار منفصل.

  1. مستخدم التطبيقبيانات: HTTPS 443نقطة دخول L7 لدى المزوّد

    يصل مستخدمو التطبيق إلى نقطة دخول L7 لدى المزوّد عبر hostname المسجّل. ويطبّق كل مزوّد نقطة دخوله الخاصة.

  2. نقطة دخول L7 لدى المزوّدبيانات: NodePortNodePort Service · Local<app namespace>

    تمرّر نقطة الدخول إلى العنوان الخاص للعقدة وNodePort. وNodePort هو المخصَّص عند تسجيل الهدف.

  3. NodePort Service · Local<app namespace>بيانات: إلى PodDeployment · Pod · صورة digest<app namespace>

    يرسل Service الطلب إلى Pod التطبيق (Deployment) على العقدة نفسها. ومع externalTrafficPolicy Local، يصل عنوان المصدر إلى فحص CIDR المسجّل في NetworkPolicy دون تغيير.

  4. Cilium · Helm · VXLANkube-systemتشغيل · تطبيق: فرض السياسةNetworkPolicy · CIDRs المدرجة<app namespace>

    يفرض Cilium سياسة NetworkPolicy: الدخول فقط من CIDRs المسجّلة إلى منفذ التطبيق، ولا خروج افتراضيًا إلا إلى عنوان قاعدة بيانات معتمد. وتظل جدران الحماية السحابية وقواعد المضيف مهمة.

  5. مستخدم Railshotبيانات: لوحة المعلومات · APIdashboard · nginxrailshot-system

    يدخل المستخدمون عبر نقطة دخول التشغيل إلى لوحة nginx، ويقف nginx أمام API المنتج. ولا يكون Service الخاص باللوحة NodePort إلا عند إعطاء node port معتمد، ويبقى API من نوع ClusterIP.

التحقق · المراقبة

لا يستند حكم النشر إلا إلى حالة Argo وفحص URL العام. أما تشخيصات Pod والسجلات الحالية ومقاييس التشغيل فإشارات منفصلة لا تغيّره أبدًا.

  1. API المنتج · cd.js → bridge.pyrailshot-systemمراقبة: revision · health · الصورArgo CD · Applicationargocd

    يتطلب deployed وجود sync revision الخاصة بـ Application، وSynced وHealthy، وoperation Succeeded، وأن تساوي مراجع الصور المسجّلة في حالة Argo Application صورَ digest الخاصة بـ Deployment المراجَع. وليس بوابة مباشرة على imageID لدى Pod، ولا تُثبت حالة Argo الخضراء وحدها هذا التطابق.

  2. API المنتج · cd.js → bridge.pyrailshot-systemمراقبة: فحص HTTPS العامنقطة دخول L7 لدى المزوّد

    يُفحص URL العام المسجّل دون إعادة توجيه. ولا يُسجَّل succeeded إلا بحكم Argo وهذا الفحص معًا.

  3. API المنتج · cd.js → bridge.pyrailshot-systemمراقبة: تشخيص Pod · ليس الحكمDeployment · Pod · صورة digest<app namespace>

    بعد حكم Argo والفحص العام، تُقرأ Deployment وReplicaSets وPods على حدة ببيانات الاعتماد المسجّلة، ويُضاف imageID والجاهزية تشخيصًا بقيمة ready أو progressing أو unavailable. ولا يغيّر التشخيص الفاشل أو المختلف حكم deployed أو succeeded أبدًا.

  4. API المنتج · cd.js → bridge.pyrailshot-systemمراقبة: ذيل السجل · 100 سطر لكل PodDeployment · Pod · صورة digest<app namespace>

    فقط لـ operation المنشورة حاليًا، بالـ config الموثوق وبيانات الاعتماد المسجّلة. ولكل Pod حالي (ثلاثة على الأكثر) يجب أن يساوي digest الصورة العاملة الـ digest المتوقع، ثم يُقرأ ما يصل إلى 100 سطر منقّح لكل Pod ضمن حد للبايتات. وتُجيب المحاولة الأقدم بـ superseded، ومن دون إعداد بـ not_configured. وليس هذا تجميعًا للسجلات.

  5. VM المراقبةمراقبة: scrape · منافذ NodePortrailshot-observability

    يجمع Prometheus على VM المراقبة بيانات node-exporter وkube-state-metrics عبر منفذي NodePort مقيّدين بجدار الحماية. والقيم المفقودة أو القديمة غير معروفة، لا صفر.

  6. VM المراقبةمراقبة: Blackbox probeنقطة دخول L7 لدى المزوّد

    يعني probe_success=1 استجابة 2xx في موضع الفحص ذاك. ولا يثبت وصول كل مستخدم ولا النسخة المنشورة، ولا يرقّي published إلى deployed أبدًا.

تثبيت المشغّل · التسجيل

تثبيت العنقود، وbootstrap التسجيل ومُدخلات الهدف، وSecrets، وإعداد تجديد بيانات الاعتماد، كلها مُدخلات للمشغّل، وليست أبدًا جزءًا من حمولة تطبيق المستأجر.

  1. bootstrap المشغّلتشغيل · تطبيق: توليد platform · Secretrailshot-system

    يولّد المشغّل إعلان platform باستخدام render-platform.py، ويوفّر إعداد التشغيل الخاص وSecrets. ولا يُدرج MCP البعيد إلا عند توفير صورته، ولا البوابة الشخصية (WireGuard) إلا مع --personal.

  2. bootstrap المشغّلتشغيل · تطبيق: bootstrap التسجيلAppProject · cluster Secretargocd

    يثبّت المشغّل Role الخاص بـ bootstrap التسجيل وRole فارغًا للتسجيلات في argocd، ويُعِدّ مُدخلات الهدف. ثم تكتب أدوات التسجيل المساعدة التي يشغّلها API المنتج (environment.py، applications.py) الـ Secret المسمّى railshot-<target> ببيانات اعتماد محددة النطاق (clusterResources false، مع إدراج namespaces المسموح بها)، وتُلحق الأسماء الدقيقة المُتحقَّق منها بـ Role التسجيلات. ويربط التسجيل لكل تطبيق namespace باسم app-<id> بـ AppProject يحمل الاسم نفسه.

  3. bootstrap المشغّلتشغيل · تطبيق: تثبيت K3s · CiliumCilium · Helm · VXLANkube-system

    يثبّت install-k3s.sh خادم K3s بعقدة واحدة (مع تعطيل flannel وnetwork policy وtraefik وservicelb، والإبقاء على kube-proxy)، ويُثبَّت Cilium بوصفه Helm release (kubeProxyReplacement false، وVXLAN، وتعطيل Hubble).

  4. CronJob للتجديد · كل 2 hargocdتشغيل · تطبيق: TokenRequest · 6 hrailshot-argocd SA · رمز مميّز<app namespace>

    يطلب CronJob المسمّى railshot-credentials رمزًا جديدًا صالحًا ست ساعات لـ SA العميل كل ساعتين. ولا يسمح Role على جهة العميل إلا بـ token create لـ SA الخاص به. والساعات الست هي TTL للرمز الواحد، لا موعد انتهاء وصول المشغّل.

كل الروابط بالسماكة نفسها. اختر مسارًا لإبراز طريقه وحده، مع خطوات مرقّمة.

  • خط متصل · اتجاه تدفق الطلبات والـ bundles والصور والإعلانات
  • خط متقطع · طلبات التشغيل، التطبيق، التثبيت، بيانات الاعتماد
  • شرطة طويلة ونقطة · قراءة الحالة والسجلات وprobes والمقاييس، بمعزل عن الحكم
  • خط أسود سميك · المسار المختار، والأرقام تبيّن الترتيب
  • مربع · namespace، واسمه في الترويسة (ليس عقدة)
  • شريحة داخلية · مكوّن في ذلك الـ namespace
  • مربع متقطع · خارج العناقيد
  • railshot-system · المنتج
  • argocd · سلطة النشر
  • railshot-build · سلطة Docker على المضيف
  • GitHub · عنقود العميل

قرار التوزيع بتاريخ October 2 في docs/architecture (عقدتا دور) ومخطط README العام تاريخ، وهذه الخريطة تتبع الإعلانات والشيفرة عند 645e28a. والأسهم تُظهر السبب والاتجاه، لا دليلًا على أن كل مسار مزوّد يعمل الآن.

Namespaces والعُقد
الـ namespace نطاق تسمية: ليس عتادًا، ولا حدًّا أمنيًا بحد ذاته. ودورا platform وbuild توزيع جدولة عبر nodeSelector وtaint، ولا تحدد هذه الخريطة عدد عُقد عنقود التشغيل. وتوزيع Argo CD على العُقد فحص منفصل أيضًا.
سلطة عقدة build
تعمل runner Jobs بـ hostNetwork ومقبس Docker على المضيف وNET_ADMIN وroot. ولا يُزيل namespace أو taint أو RBAC سلطة Docker على المضيف، فهذا ليس عزلًا عن مسؤول VM ولا sandbox لشيفرة عشوائية.
namespace العميل
يستخدم كل هدف مسجّل namespace وAppProject غير افتراضيين (مثلًا tenant-demo، أو app-<id> لكل تطبيق). ولا يُنشأ إلا Deployment لخدمة واحدة (مع تعطيل التحميل التلقائي لرمز ServiceAccount) وNodePort Service وNetworkPolicy، إضافة إلى PVC أو migration Job اختياريين، ولا يُشار إلى Secrets إلا بالاسم (pull Secret وDATABASE_URL معتمد)، ولا تُنشأ أبدًا.
نقطة دخول AWS
Route 53 Alias → ALB مشترك HTTPS 443 → العنوان الخاص لعقدة العميل وNodePort. وتعيد تطبيقات كثيرة استخدام عقدة واحدة، لكلٍّ منها namespace وApplication وNodePort خاص بها.
نقطة دخول GCP
HTTPS LB عام من نوع EXTERNAL_MANAGED → NEG نطاقي من نوع GCE_VM_IP_PORT → NodePort الخاص بالـ VM القائم. وتأتي الشهادات من Certificate Manager مع تفويض DNS. ولا تملك الوحدة الـ VM ولا الـ VPC، ويبقى الـ VM الواحد نقطة إخفاق وحيدة.
نقطة دخول OpenStack
Amphora TLS listener 443 مع سياسات L7 حسب Host والمسار → HTTP NodePort. والعنوان الافتراضي VIP خاص، وOctavia وK3s وقاعدة البيانات وDNS خارج الوحدة. ويحتاج الوصول العام وجاهزية Amphora في الموقع إلى قبول منفصل، ولم يُتحقَّق بعد من أي تطبيق في الموقع بهذه الوحدة.
عبر المزوّدين
نقاط الدخول الثلاث تطبيقات منفصلة، بلا failover أو نسخ متماثل تلقائي بين المزوّدين. وعنقود تطبيقات العميل مثال على هدف مسجّل، لا ادعاء بأن النشر نفسه يعمل على كل سحابة في آن واحد.
خيارات المشغّل
لا تنضم البوابة الشخصية (WireGuard) إلى platform إلا حين يفعّل المشغّل --personal، وليست مسارًا مطلوبًا لسحابات العملاء. وفي وضع direct المدعوم، يمكن أن يتشارك VM المراقبة مع VM التحكم في التشغيل.