
بيئة تشغيل حاويات بدون صلاحيات الجذر وصندوق حماية يشغّل صور OCI المفروضة عبر النواة في أجزاء من الثانية دون الحاجة إلى daemon، ويتضمن ملفات تعريف للموارد، وقوائم سماح seccomp، ودعم compose للتعليمات البرمجية غير الموثوقة والمولّدة بالذكاء الاصطناعي.
kern: بيئة تشغيل سريعة وrootless (بدون صلاحيات الجذر) للعزل (sandbox) والموارد الافتراضية، لأي عبء عمل، بما في ذلك الشيفرة غير الموثوقة والمولّدة بالذكاء الاصطناعي.
حاوية حقيقية يفرضها النواة (kernel) في ~3.5 مللي ثانية، من ثنائي واحد بحجم 1.52 MB وبدون daemon.
0 رام في وضع الخمول · لا daemon، لا socket، لا شيء ليُشغَّل · ثنائي ثابت واحد، libc هو اعتماد Rust الوحيد له
# install the release binary (static, 1.52 MB, checksum-verified by the script)
curl -fsSL https://raw.githubusercontent.com/getkern/kern/main/install.sh | sh
# a throwaway shell in a real OCI image: rootless, kernel-enforced, a few ms
kern box dev --image alpine -it -- sh
لا يوجد إصدار أصلي لنظام Windows: استخدم WSL2. التثبيت.
ثنائي واحد يدير الموارد، والعزل أولها. لذلك لا يوجد صف واحد لـ kern في جدول مقارنة: فهو بيئة تشغيل حاويات (container runtime)، وsandbox، ومقسّم موارد، ومشغّل مكدسات في الوقت نفسه، بحجم 1.52 MB وبدون daemon.
حاوية حقيقية. صور OCI حقيقية: pull وbuild من Dockerfile وcommit وpush وsave/load. يبدأ صندوق (box) من صورة خلال ~3.5 مللي ثانية.
sandbox دائمًا rootless. مساحات أسماء (namespaces) للمستخدم وPID والتركيب (mount) والشبكة وUTS وIPC، وجذر overlay أو للقراءة فقط يتم التحويل إليه (pivot)، وقائمة سماح seccomp افتراضها الرفض (deny-by-default)، وحدود cgroup v2. علَم واحد، --security-profile untrusted، هو حزمة التحصين بأكملها.
ملفات تعريف الموارد، وليس العزل فقط. وحدة المعالجة (vcpu:) والذاكرة والقرص (vdisk:) والأجهزة (vgpio:) تُعرَّف مرة واحدة في kern.toml وتُرفق بالاسم. يطبّق kern run السقوف نفسها على عملية على المضيف، دون أي sandbox إطلاقًا.
شجرة اعتماديات Rust بأكملها هي libc: تُحلَّل بيانات JSON وOCI الوصفية يدويًا، ويلجأ أمر pull إلى curl وtar الموجودين أصلًا على الجهاز بدلًا من ربط حزمة TLS. (1.52 MB هو إصدار release المحسَّن من حيث الحجم؛ بينما cargo install العادي من المصدر ينتج 1.91 MB.)
ليس hypervisor. الحد الفاصل هو نواة Linux، لذا فإن أي خلل في تصعيد الامتيازات بالنواة يعني هروبًا. يتشارك Docker وPodman في هذه الحالة، ولهذا وُجد gVisor وFirecracker.
اقرأها مع الشعار الرئيسي، وستجد أنها عبارة واحدة تُرى من الجانبين: الشيفرة غير الموثوقة والمولّدة بالذكاء الاصطناعي هي ما صُنع kern من أجله، لأنك اخترت تشغيلها وتتحمّل نطاق الانفجار (استدعاءات أدوات الوكلاء، ومهام CI، وخطوات البناء، وخلايا الشيفرة). أما ما لم يُصنع له فهو الشيفرة العدائية من الغرباء، متعددة المستأجرين، على نواة تخدم منها مستأجرين آخرين. يبدأ kern دائمًا rootless، بينما هو في Docker اختياري.
ليس خاليًا من المقايضة بـ userns. عزلته مبنية على مساحة اسم مستخدم غير مميزة (unprivileged user namespace)، وهي مصدر خصب لثغرات LPE في النواة. يذكر SECURITY.md هذا قبل أي ادعاء.
ليس جدارًا حول ما تُدخله بالتركيب (mount). يمنح -v $HOME:/host الصندوقَ دليلَ منزلك: فالتركيب قرار ثقة تتخذه أنت، وليس حدًّا يفرضه kern. --net host و--privileged هما خيارا إلغاء صريحان بالاسم. (المسار الوحيد الذي يرفض kern ربطه هو سجل (registry) وقت التشغيل الخاص به.)
ليس إعادة تنفيذ لمحرك Docker. يتحدث صيغ Docker، لا API الخاص به: لا شبكات overlay، لا إضافات (plugins)، لا Swarm. المصفوفة: docs/DOCKER-COMPAT.md.
ليس بيئة تشغيل Kubernetes. لا CRI. استخدم containerd أو CRI-O.
لا يشحن شرائح GPU. إنها على خارطة الطريق، ولا يوجد كود GPU في هذه النسخة، لذا لا يوجد شيء هنا يمكن الوثوق به أو مهاجمته بعد.
ما لا يعرفه kern أو لا يفعله بعد موثّق في OPEN_ITEMS.md بدلًا من أن تكتشفه بنفسك.
يحتاج kern إلى نواة Linux مع مساحات أسماء مستخدم غير مميزة وcgroup v2. يعمل على Linux وWSL2 ولوحات ARM (Raspberry Pi · Jetson · Arduino UNO Q)؛ ولا يوجد إصدار أصلي لنظام Windows، استخدم WSL2 (يشحن kern نظام جذر WSL جاهزًا مسبقًا).
أسرع طريقة هي ثنائي الإصدار (release): ملف ثابت واحد، دون سلسلة أدوات (toolchain)، ويتحقق السكربت من SHA256 الخاص به قبل تثبيته.
curl -fsSL https://raw.githubusercontent.com/getkern/kern/main/install.sh | sh
يختار لك x86_64 أو aarch64، ويُثبّت في ~/.local/bin (/usr/local/bin عند التشغيل كجذر، أو KERN_INSTALL_DIR)، ويرفض تثبيت أي تنزيل لا يتطابق مع checksum. أما التحقق يدويًا فسطران:
curl -fsSLO https://github.com/getkern/kern/releases/latest/download/kern-x86_64-unknown-linux-musl.tar.gz{,.sha256}
sha256sum -c kern-x86_64-unknown-linux-musl.tar.gz.sha256 && tar xzf kern-x86_64-unknown-linux-musl.tar.gz
من المصدر هو الطريق الآخر، وشجرة الاعتماديات بأكملها عبارة عن crate واحد (libc)، لذا فهي قصيرة: استغرق الاستنساخ والبناء والتثبيت 36 ثانية على حاسوب مكتبي (i7-14700KF)، وأطول على لوحة ARM صغيرة.
# if you do not have Rust yet
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install --git https://github.com/getkern/kern getkern --locked
يضع ذلك kern في ~/.cargo/bin، ويضيفه rustup إلى PATH الخاص بك (افتح نافذة طرفية جديدة، أو نفّذ source "$HOME/.cargo/env"، إذا لم يُعثر على kern).
يشحن الإصدار أيضًا ثنائي aarch64، ووسيط تشغيل Windows .exe، ونظام جذر WSL جاهزًا مسبقًا، ولكل منها ملف .sha256 خاص بها؛ والوسم (tag) موقّع بـ GPG وله طابع زمني مستقل (provenance/).
يخبرك kern doctor ما إذا كانت الصناديق ستعمل هنا قبل أن تجرب. اللوحات وWSL2 والصيغة الكاملة: docs/INSTALL.md. الأسئلة الشائعة (Docker وbubblewrap وyouki وE2B وWindows ونموذج التهديد): docs/FAQ.md.
kern box dev --image alpine -it -- sh # a throwaway shell in a real OCI image
kern run --memory 256M --cpus 0.5 -- ./crunch # cap a process, no sandbox
kern box svc --image nginx:alpine -d -p 8080:80 \ # a service: published, restarted, health-checked
--restart --health-cmd 'wget -qO- localhost:80' -- nginx -g 'daemon off;'
kern ps # what is running, with PORTS and HEALTH
kern exec svc -it -- sh # shell into it
kern stop svc # its signal, its grace, then the code it exited with
kern top # live TUI: boxes, CPU/RAM, profiles, volumes
kern compose stack.toml up # a multi-box stack (examples/) or a compose.yml
kern compose stack.toml down # and take it down again
شيفرة غير موثوقة، علَم واحد للحزمة كاملة:
kern box job --image python:3.12-slim --security-profile untrusted --memory 256m \
-v ./job:/w -- python3 /w/x.py
--security-profile untrusted يجمع قائمة سماح seccomp (allowlist) مع --cap-drop ALL و--read-only في علَم واحد اختياري (اذكرها يدويًا إن فضّلت)؛ أضف --require-limits لرفض البدء ما لم تُفرَض حدود memory/pids فعلًا. لا شبكة إلا إذا طلبتها، وإسقاط للقدرات الخطيرة، وseccomp مفعّل دائمًا. تسعون مثالًا قابلًا للتشغيل، كل واحد يفعل شيئًا واحدًا: examples/.
كل فعل قراءة يستجيب أيضًا بصيغة JSON، فلا حاجة لتحليل أي جدول:
kern ps --json | jq '.[] | select(.health == "unhealthy") | .name'
kern volume ls --json # ps · images · stats · inspect · builds · pod ls · config list · diff
يتحدث kern لغة docker-compose.yml. وجّهه إلى المكدس الذي تملكه بالفعل وسيشغّله kern compose up دون daemon ودون Docker Desktop، وعلى النحو نفسه على Linux وWSL2 ولوحات ARM.
# compose.yaml - a real stack, unchanged
services:
db:
image: postgres:alpine
environment: { POSTGRES_PASSWORD: secret, POSTGRES_DB: app }
web:
image: adminer
ports: ["8080:8080"]
depends_on: [db]
kern compose compose.yaml up
تبدأ الصورتان الرسميتان، وتصل web إلى db باسم الخدمة، ويُعلَن المنفذ (port) على المضيف. عند التدفئة (الصور مخزنة مؤقتًا) تخدم طبقة الويب خلال ~0.3 ثانية، وتكلفة المكدس هي فقط ما تستهلكه postgres وadminer فعلًا (~66 MB هنا) مع صفر daemon إضافي، بينما Docker Desktop جهاز افتراضي في الخلفية حتى قبل أول حاوية لك.
الصور الرسمية التي تنتقل إلى مستخدم غير جذر (postgres، redis، ...) تتطلب uidmap وسطرًا في /etc/subuid، أما عمليات سحب الصور الصادرة فتتطلب pasta؛ وكلاهما apt install واحد على جهاز تطوير، ويذكر kern doctor أيهما مفقود. هذه حلقة التطوير المحلية، وليست منسّق إنتاج: لا Swarm، لا شبكات overlay.
شغّل شيفرة الوكلاء أو الشيفرة المولّدة بـ LLM من برنامجك الخاص عبر kern-sandbox، وهو غلاف رفيع بلا اعتماديات فوق ثنائي kern. كل استدعاء يعمل في صندوق معزول جديد: الشبكة مغلقة، وحدود للذاكرة وpid، وإسقاط للقدرات، وإخراج محدود، ومهلة زمنية يفرضها الربط (binding) نفسه.
pip install kern-sandbox # PyPI · needs the `kern` binary above, on PATH or $KERN_BIN
npm install kern-sandbox # npm · same
from kern_sandbox import run_code
r = run_code("import platform; print(platform.python_version())")
print(r.stdout) # ran in a fresh box; a timeout / OOM / blocked escape is data on r.fault
الأعطال بيانات، لا استثناءات: المهلة الزمنية، أو القتل بسبب OOM، أو استدعاء نظام محظور هو حقل في النتيجة، وليس استثناءً مرفوعًا. صندوق جديد لكل استدعاء افتراضيًا؛ يحتفظ Sandbox بمساحة عمل عبر الاستدعاءات، ويحتفظ kernel() الدافئ بمفسِّر واحد لخلايا دون الميلي ثانية (عزل أضعف، عن قصد).
نتائج غنية دون نواة Jupyter: التعبير الأخير، وdisplay()، وأشكال matplotlib تعود ملتقطة، مثل خلية دفتر ملاحظات.
يشحن خادم MCP (kern-mcp): خادم stdio بلا اعتماديات يمنح Claude Desktop أو Cursor أو أي عميل MCP مفسِّر شيفرة محليًا. وجّه العميل إليه:
{ "mcpServers": { "kern": { "command": "kern-mcp" } } }
الأدوات: run_code (python/bash/node) وwrite_file وread_file وlist_files. كل استدعاء هو صندوق جديد بشبكة مغلقة؛ وتستمر الملفات عبر الاستدعاءات في مساحة عمل على القرص. أمر الإعداد والصورة والخيارات الأخرى: bindings/python/README.md.
واجهة API الكاملة، Python وNode: bindings/python/README.md · bindings/node/README.md.
تُعرَّف الشريحة (slice) مرة واحدة في ~/.config/kern/kern.toml وتُرفق بالاسم، سواءً بصندوق مُعزَل أو بعملية مجردة، بالرمز نفسه (token).
ثلاثة أنواع: vcpu: (وحدة المعالجة والذاكرة)، وvdisk: (قرص scratch بسقف حجم)، وvgpio: (عُقد الأجهزة). إليك اثنان منها، والمراسي (anchors) التي تُقتطع منها:
[[cpu]] # the host budget a slice is carved from
id = "cpu:0"
cores = 8.0
[[vcpu]] # 1.5 cores and 512 MiB -> attach as vcpu:heavy
name = "heavy"
backend = "cpu:0"
cpus = 1.5
memory = "512m"
[[gpio]] # a controller anchor
id = "gpio:0"
[[vgpio]] # exactly one device node -> attach as vgpio:sensor
name = "sensor"
backend = "gpio:0"
i2c = ["/dev/i2c-1"]
kern validate ~/.config/kern/kern.toml # check it before anything runs
kern box train --image alpine vcpu:heavy vdisk:scratch -- ./train.sh
kern run vcpu:heavy -- ./train.sh # the same slice, no sandbox
kern box iot --image alpine vgpio:sensor -- ls /dev
تتآلف ملفات التعريف: يمكن ربط عدة ملفات منها بصندوق واحد، والعلَم الصريح يتفوّق على قيمة ملف التعريف نفسه. كل مفتاح يُكتب مثل علَم CLI الخاص به، لذا cpus يقابل --cpus وmemory يقابل --memory. أي backend يشير إلى pool غير معلن يُرفض عند قراءة الإعداد، لا عند تشغيل الصندوق. يحتوي docs/RESOURCES.md على المخطط حقلًا بحقل.
يكون vdisk: نظام tmpfs مدعومًا بالرام عندما يعمل kern rootless، مهما قال backend الخاص به، وصورة ext4 على loop بحصة حقيقية عندما يعمل بصلاحيات (privileged). يخبرك kern أيًّا من الاثنين حصلت عليه، لكل ملف تعريف، بدلًا من أن يتركك تفترض، ويُفرض سقف الحجم في الحالتين.
vgpio: على مستوى الشريحة (chip)، لا على مستوى الخط. طلب pins يربط /dev/gpiochipN بأكمله، ويعرّض ذلك الجهاز الحرفي (character device) كل خط من خطوط المتحكّم. pins = [17] لا يقيّد الصندوق بالخط 17: فالنواة لا تملك حد تركيب على مستوى الخط، لذا قائمة الخطوط هي بيانات وصفية تعاونية وليست حدًّا. أما تسمية عقدة جهاز، كما يفعل i2c أعلاه، فتمنح تلك العقدة فقط ولا شيء غيرها.
Intel i7-14700KF، وLinux 7.0.0، وثنائي الإصدار، وسكربت واحد يمكنك تشغيله بنفسك: python3 examples/benchmark.py. ستختلف أرقامك حسب معالجك ونواتك ونظام ملفاتك.
ثلاثة آلاف في آنٍ واحد تستغرق ~2.2 ثانية، ويكلّف الصندوق الحي ~0.3 MB من الذاكرة.
ملاحظتان صادقتان. لا أحد يفوز بزمن استجابة الطلقة الواحدة بشكل قاطع: الحد الأدنى لـunshare + exec هو 1 إلى 2 مللي ثانية، لذا تقع الطبقة العليا بأكملها داخل ضجيجها الخاص، وbubblewrap مجرد مشغِّل (launcher) بلا صور أو سقوف (caps) أو دورة حياة. أما الفجوة ذات الدلالة فهي مع المحركات (engines)، بفارق مرتبتين من حيث الحجم.
المنهجية، والتفصيل لكل مرحلة، وأرقام اللوحات، وكل تحفّظ: BENCHMARKS.md.
مساحات أسماء (namespaces)، وpivot_root، وإسقاط 16 قدرة خطيرة قبل exec، وقائمة سماح seccomp مفعّلة دائمًا افتراضيًا (مرشّح moby الافتراضي نفسه ناقصًا استدعاءات هروب kern البالغة 35، والتي تظل مقتولة بقوة؛ أي استدعاء نظام خارج المجموعة المدققة يعيد ENOSYS، أما قائمة الحظر الأوسع فهي الخيار البديل عبر KERN_SECCOMP=denylist)، وحدود cgroup v2 (--require-limits يرفض البدء ما لم تكن مفروضة)، و/dev يرفض افتراضيًا. وعندما يكون الحد تعاونيًا لا تفرضه النواة، يوضح SECURITY.md ذلك ويسمّي الالتفاف.
لا يتعين عليك أن تأخذ ذلك على سبيل الثقة: يضم pentest/ أربع مجموعات اختبارات عدائية تتحقق من تلك الحدود ضد النواة نفسها لا ضد تقارير kern الخاصة، وتعمل دون حساب registry أو شبكة.
sh pentest/run-with-local-registry.sh ./target/release/kern pentest/pentest-ports.sh
أبلغ عن ثغرة أمنية على انفراد عبر GitHub Security Advisories أو [email protected].
النواة مكتملة. كل ما سبق يعمل اليوم: 840 اختبارًا بلغة Rust و78 بلغة Python و61 بلغة Node، نظيف من clippy، ونظيف من cargo-deny، على أجهزة حقيقية: Linux وWSL2 وRaspberry Pi 5 وJetson Orin Nano وArduino UNO Q. v0.7.0 هو أول إصدار منشور. يمكن أن تتغير واجهة CLI وسطح الإعدادات بعد، ويُشار إلى ذلك دائمًا في CHANGELOG.md.
نرحّب بالقضايا (issues) وطلبات السحب (pull requests). يوضح CONTRIBUTING.md سير العمل والبوابات (gates)؛ وتُغطى المساهمات بموجب CLA.
Alex، @realexhub. تأتي الالتزامات (commits) من @getkerndev، هوية الالتزام الخاصة بالمشروع.
الالتزامات غير موقّعة، أما وسم الإصدار (TAG) فموقّع. هذا ما يجب التحقق منه: نفّذ git verify-tag v0.7.0 مقابل المفتاح في provenance/، الذي توجد بصمته في SECURITY.md.
Apache-2.0. انظر LICENSE وTRADEMARK.md.
مكدسات (Stacks)، بصيغة kern الخاصة أو بصيغة Docker. يأخذ kern compose <file> up ملف kern-compose.toml (جداول [box.NAME]، مع ملفات تعريف الموارد أعلاه) أو ملف docker-compose.yml الذي تملكه بالفعل، ويُقرأ كما هو مكتوب. مكدس واحد مقابل pod واحد، وتتواصل الخدمات مع بعضها بالاسم.
الأدوات المحيطة بها. ps وlogs وexec وstats وinspect وwait وtop (واجهة TUI مباشرة) وdoctor، بالإضافة إلى SDK لكل من Python وNode وخادم MCP للوكلاء (agents).
| kern | Docker | Podman |
|---|
| الخفي (Daemon) | لا | نعم (dockerd + containerd) | لا |
| Rootless | نعم، دائمًا | اختياري | نعم |
| بدء التشغيل البارد، صندوق مجرد | ~2.3 مللي ثانية | ~297 مللي ثانية | ~293 مللي ثانية |
| بدء التشغيل البارد، من صورة OCI | ~3.5 مللي ثانية | ~297 مللي ثانية | ~293 مللي ثانية |
| إيقاف خدمة (init يتعامل مع SIGTERM) | ~1.9 مللي ثانية | ~310 مللي ثانية | ~380 مللي ثانية |
| الذاكرة المقيمة، لا شيء يعمل | 0 | 154 إلى 160 MB | 0 |
| البصمة (Footprint) | ثنائي واحد بحجم 1.52 MB | حزمة daemon | تثبيت متعدد الثنائيات |
| صور OCI، سحب / بناء / دفع | نعم | نعم | نعم |
docker-compose.yml | نعم، تُقرأ كما هي | نعم | جزئي |
| شبكات overlay وSwarm وCRI | لا | نعم | جزئي |
| GPU | على خارطة الطريق | نعم | نعم |
| kern | bubblewrap | runc | podman | docker |
|---|
| بدء تشغيل بارد (صندوق مجرد) | ~2.3 مللي ثانية | ~2.3 مللي ثانية | ~18.6 مللي ثانية | ~293 مللي ثانية | ~297 مللي ثانية |
| 200 صندوق بالتوازي | ~0.11 ثانية | ~0.16 ثانية | ~0.35 ثانية | ~44.8 ثانية | ~16.2 ثانية |
| docs/INSTALL.md | التثبيت على Linux وWSL2 ولوحات ARM، من المصدر |
| docs/DOCKER-COMPAT.md | ما الذي يعمل من Docker، وما لا يعمل، وأين يختلف |
| docs/RESOURCES.md · docs/CONFIG.md · docs/STORAGE.md · docs/EGRESS.md | نموذج الفعلين، ومخطط kern.toml، ووحدات التخزين والإخراج (egress) |
| docs/THREAT_MODEL.md · SECURITY.md · OPEN_ITEMS.md | نموذج التهديد (منظم، ثم لكل آلية)، والفجوات المعروفة |
| BENCHMARKS.md · EDGE.md | القياسات، والتشغيل على Pi أو Jetson أو UNO Q |
| examples/ · blog/ | تسعون سكربتًا قابلًا للتشغيل، ومقالات أطول |
| bindings/python/README.md · bindings/node/README.md | SDK الخاص بـkern-sandbox: تضمين kern في Python أو Node |