- SUSE Hackweek 22 में WebAssembly modules चलाने वाले unikernel का POC बनाया गया, और implementation प्रक्रिया को कई भागों में व्यवस्थित किया गया
- सामान्य application को सीधे unikernel पर port करने के लिए dependencies भी compatible करनी पड़ती हैं, लेकिन WebAssembly platform में runtime द्वारा दी जाने वाली capabilities की boundary ज़्यादा स्पष्ट होती है
- Spiderlightning application को केवल Key/Value जैसी capabilities चाहिए होती हैं, और host उन्हें Redis या Azure Cosmos DB से implement करे, तब भी वही
.wasmmodule अंतर जानने की ज़रूरत नहीं रखता - आधार Rust unikernel RustyHermit है, और Wasmtime तथा Wasmer build नहीं हुए, इसलिए pure Rust runtime wasmi चुना गया
- Component Model और WIT के साथ तालमेल के लिए wit-bindgen में wasmi support जोड़ा गया, फिर host-side Key/Value capability scaffold करके
keyvalue-demoचलाया गया
Hackweek project और लक्ष्य
- SUSE के Hackweek 22 के दौरान WebAssembly चलाने वाला unikernel बनाना project किया गया
- पूरी implementation प्रक्रिया को एक ही लेख में समेटना लंबा होता, इसलिए इसे कई लेखों में बाँटा गया है, और यह लेख पहला भाग है
- POC code अलग जगह public किया गया है, लेकिन दिए गए body में वास्तविक link URL नहीं है
unikernel और WebAssembly को साथ इस्तेमाल करने की वजह
- application developers के लिए unikernel porting एक बड़ा बोझ है
- application और उसकी सभी dependencies को target unikernel support करना चाहिए
- पूरे application stack के भीतर patches की ज़रूरत पड़ सकती है
- unikernel maintainers को भी किसी भी arbitrary application को smoothly चलाने लायक बनाने में बहुत ऊर्जा लगानी पड़ती है
- क्योंकि यह predict करना मुश्किल होता है कि user application कौन-से system primitives इस्तेमाल करेगा
- इसके उलट, Spin या Spiderlightning जैसे WebAssembly platforms को target करने पर runtime को जो capability set देना है, वह स्पष्ट हो जाता है
- Spiderlightning scenario में application runtime से Key/Value store capability मांग सकता है
- host उस capability को Redis से implement करे या Azure Cosmos DB से, application के लिए यह transparent रहता है
- वही
.wasmmodule अलग-अलग host implementations पर चलाया जा सकता है
लक्ष्य architecture
- अगर unikernel application WebAssembly modules चलाए और Spiderlightning API set support करे, तो वही Spiderlightning application सामान्य
slightruntime और उस unikernel, दोनों पर चल सकता है - application developer को अतिरिक्त काम नहीं करना पड़ता, और Wasm module को भी यह जानने की ज़रूरत नहीं होती कि वह कहाँ चल रहा है
- complexity unikernel developer पर केंद्रित होती है, लेकिन implement करने का scope “सभी applications को चलाने का support” देने की तुलना में कहीं ज़्यादा स्पष्ट है
RustyHermit पर आधारित implementation
- आधार के रूप में RustyHermit चुना गया
- यह Rust में लिखा गया unikernel है
- यह Rust nightly में शामिल है, इसलिए development experience सामान्य Rust application लिखने जैसा मिलता है
- RustyHermit application build करना अपेक्षाकृत straightforward है
- documentation कुछ बिखरी हुई है, लेकिन quality अच्छी है, और examples काफी मदद करते हैं
- यह उम्मीद नहीं की जा सकती कि हर Rust crate RustyHermit पर ज्यों का त्यों काम करेगा, और इस limitation ने POC development को प्रभावित किया
WebAssembly runtime का चयन
- पसंदीदा Wasmtime RustyHermit पर build नहीं हुआ
- कई dependencies
libcया अन्य low-level libraries की अपेक्षा करती हैं
- कई dependencies
- wasmer में भी यही समस्या है
- WebAssembly Micro Runtime पर भी विचार किया गया, लेकिन Rust में लिखा runtime इस्तेमाल करके “पूरी RustyHermit experience” बनाए रखने का निर्णय लिया गया
- अंत में pure Rust WebAssembly runtime wasmi चुना गया
- यह RustyHermit पर अच्छी तरह काम करता है
- इसका design Wasmtime से प्रेरित है, इसलिए मौजूदा knowledge काफी reuse की जा सकी
WebAssembly Component Model और WIT
- Spiderlightning WebAssembly Component Model proposal का उपयोग करता है
- यह WebAssembly guest को capabilities देता है
- यह host को WebAssembly guest द्वारा दी जाने वाली capabilities consume करने देता है
- host और guest के बीच communication Wasm Interface Type से defined types का उपयोग करता है
- demo Component Model को इस flow में इस्तेमाल करता है
- guest host से HTTP server शुरू करने का अनुरोध करता है, और register किए जाने वाले HTTP routes तथा internal handler function names pass करता है
http-servertype इस्तेमाल होता है, और guest host-provided capability का उपयोग करता है
- host, guest द्वारा दी गई routing जानकारी से incoming HTTP requests process करता है
- HTTP handler WebAssembly guest द्वारा expose किया गया function है
- server guest-provided capability consume करता है और
http-handlertype से communicate करता है
- कुछ HTTP handlers Key/Value store के साथ interact करते हैं
- इस मामले में भी guest host-provided capability इस्तेमाल करता है और यह
keyvaluetype से defined है
- इस मामले में भी guest host-provided capability इस्तेमाल करता है और यह
- guest host से HTTP server शुरू करने का अनुरोध करता है, और register किए जाने वाले HTTP routes तथा internal handler function names pass करता है
wit-bindgen extension और demo चलाना
- हर WIT type के लिए guest-side SDK जैसे code और host-side implementation code की ज़रूरत होती है
- wit-bindgen एक CLI tool है जो
.witfiles से host/guest code generate करता है - इस POC में unikernel के अंदर केवल host-side interface implement करना था
wit-bindgenद्वारा generated code WebAssembly runtime का उपयोग करके low-level काम करता है- generated code programming language और host-side WebAssembly runtime पर निर्भर करता है
- क्योंकि
wasmi,wit-bindgenमें supported नहीं था, इसलिएwit-bindgenको extend करके wasmi handle करने लायक बनाया गया- code wasmi branch के fork में है
- इसके बाद Key/Value capability का host-side code scaffold किया गया और एक simple host trait implementation जोड़ी गई
- host code debug information print करने के स्तर का था
- इस स्थिति में Spiderlightning project का keyvalue-demo बिना modification चलाया जा सका
अगले भाग की झलक
- unikernel application द्वारा Spiderlightning
http-serverdemo चलाने की recording है - अगले भाग में Rust async, Redis और कुछ अजीब errors पर चर्चा होगी
1 टिप्पणियां
Hacker News की राय
क्या सबसे पहले https://www.destroyallsoftware.com/talks/the-birth-and-death... याद नहीं आता?
अगर कोई व्यक्ति operating system hacker नहीं है लेकिन unikernel चाहता है, तो सबसे ठोस approach क्या होगी?
जो विकल्प सूझते हैं वे हैं: application को Linux kernel module बनाकर सामान्य kernel पर चलाना और user space को नज़रअंदाज़ करना, Linux को बहुत घटाकर उसमें अपना code जोड़ना, GitHub के unikernel projects में से किसी एक से शुरू करना, या FreeBSD जैसे किसी दूसरे operating system को काट-छाँटकर छोटा करना
मुझे वह तस्वीर पसंद है जिसमें network card से जुड़े VM में x64 machine एक general-purpose compute resource की तरह काम करे, और network के ज़रिए data भेजकर jobs assign की जाएँ। user-space daemon की तुलना में यह अभी ज़्यादा झंझटभरा है इसलिए इसकी value अभी बहुत बड़ी नहीं रही, लेकिन कभी समय मिला तो मैं जानना चाहूँगा कि operating-system-level hacking कहाँ से शुरू करनी चाहिए
Unikernel Linux (UKL) की शुरुआत Linux की configurability का फायदा उठाने की कोशिश से हुई थी, और इसका लक्ष्य ऐसा kernel बनाना है जो general-purpose operating system से लेकर application- और hardware-specific unikernel तक को समेट सके। संबंधित क्षेत्रों के रूप में io_uring और eBPF का भी ज़िक्र है; io_uring system call cost को बाँटता है और eBPF सीमित रूप में ही सही, kernel space में code चलाने का एक और तरीका है
code: https://github.com/unikernelLinux/ukl
UKL, Linux और glibc पर छोटे patches का सेट है, जो कई programs को बिना बदलाव unikernel के रूप में build करने देता है। program को Linux kernel और अंतिम vmlinuz के साथ link किया जाता है, वह kernel space में चलता है, bare metal या VM पर boot हो सकता है, और Linux की लगभग सभी features और drivers का उपयोग कर सकता है
/initरखकर kernel के साथ bundle करके boot कर दीजिएतब app ही PID 1 होगा और व्यावहारिक रूप से वही एकमात्र process होगा, और कुछ kernel threads को छोड़ दें तो आप लगभग जो चाहें कर सकते हैं
यह कई languages और apps, x86/ARM64, QEMU/Firecracker को support करता है, और Linux पर build किए गए ELF को unikernel के रूप में भी चला सकता है: https://unikraft.org/guides/bincompat
Discord यहाँ है: https://unikraft.org/discord
अगर आप OCaml सीखना चाहते हैं और unikernel भी चाहते हैं, तो यह एक संभव रास्ता है
ज़्यादा विवरण Unikraft docs में देखा जा सकता है: https://unikraft.org/docs/concepts/design-principles#approac...
बढ़िया project है। WASM मुझे इसलिए पसंद है क्योंकि इसे शुरू से sandboxing और portability को ध्यान में रखकर design किया गया था
काश 90 के दशक में JavaScript की जगह WASM आया होता, और लगता है WASM दुनिया पर छा जाएगा। मेरी सबसे बड़ी उम्मीद persistence है। अभी बहुत से ऐसे programs हैं जिन्हें अब चलाया ही नहीं जा सकता, पुराने games इसका प्रमुख उदाहरण हैं। कोई simple spec लंबे समय तक टिकने की ज़्यादा संभावना रखती है, इसलिए नए features जुड़ने को लेकर थोड़ी चिंता है, लेकिन binaries का भविष्य दिलचस्प दिखता है
JS को शुरू में click handlers या form validation जैसी basic scripting तक सीमित रखने की वजह थी। उसका किसी और चीज़ में बदल जाना सिर्फ JS की design flaws की वजह से नहीं था, बल्कि उस पर ज़बरदस्ती लादे गए use cases भी कारण थे। browser को इस तरह के apps की delivery mechanism की तरह इस्तेमाल करना Tim Berners-Lee या Marc Andreesen की कल्पना से काफ़ी दूर था
उस समय “network is the computer” camp ने ज़्यादा समृद्ध apps के लिए thin X clients पेश किए थे: https://en.wikipedia.org/wiki/Network_Computer
WASM को लेकर मेरी भावनाएँ मिली-जुली हैं। अभी इसके ऊपर hype और novelty का परदा बहुत गहरा पड़ा है। अगर web browser को सिर्फ UI designers और developers द्वारा उस समय पसंद की जा रही भाषा-कल्पना के viewport की तरह माना जाएगा, तो accessibility, screen readers जैसे क्षेत्रों में बहुत बुरी चीज़ें होंगी
browser के बाहर WASM को एक universal VM की तरह लेने का रुझान भी 30 साल पहले आज़माया जा चुका रास्ता है। वही काम JVM करना चाहता था, लेकिन अब शायद वह “cool” नहीं माना जाता
बीच का इलाका कैसा दिखना चाहिए, या उसे क्यों चाहना चाहिए, यह मुझे ठीक से नहीं पता। लेकिन व्यावहारिक रूप से शायद WASM document content को भी निगल जाएगा, और तब ad blockers और reader mode के खत्म होने की अच्छी-खासी आशंका है
यह सच में बहुत पसंद आया। लिंक की गई तकनीकों में कई ऐसी थीं जिन्हें पहले नहीं देखा था, इसलिए सबको बुकमार्क कर लिया
अगला काम हाइपरवाइज़र पर WireGuard कनेक्शन सेट अप करके देखना है। कनेक्शन स्थापित करने के लिए Tailscale जैसी किसी चीज़ से होकर भी जाया जा सकता है
फिर इस मशीन का WebAssembly उस मशीन के WebAssembly से सीधे बात करेगा। यह उस तरीके जैसा नहीं होगा जहाँ कोई प्रोसेस मनमाने लोकेशन पर TCP कनेक्शन खोलता है, बल्कि पास की गई configuration और permissions के आधार पर संचार करने वाली संरचना होगी
देर से सही, लेकिन क्या किसी ने Zephyr को unikernel की तरह चलाने के बारे में सोचा है? https://docs.zephyrproject.org/latest/boards/x86/acrn/doc/in...
dedicated WASM hardware आने में कितना समय लगेगा?
हालांकि “ऊपर से wasm, लेकिन नीचे असल में RISC-V” जैसी कोई चीज़ कोई बना सकता है
लेकिन मेरा मानना है कि ऐसा hardware हमेशा niche ही रहेगा। आम off-the-shelf hardware पर WASM चलाना ज़्यादातर मामलों में अधिक तेज़ होगा। WASM खुद इसी तरह डिज़ाइन किया गया है कि वह सामान्य उपलब्ध hardware पर तेज़ चले, और general-purpose processors की economies of scale कहीं बेहतर हैं
International Conference on Functional Programming भी शुरू में Functional Programming and Computer Architecture नाम का सम्मेलन था, लेकिन बाद में लोगों ने Haskell जैसी lazy-evaluated functional languages को मौजूदा hardware पर कुशलता से compile करने के तरीके खोज लिए
Lisp और Java machines का मामला भी कुछ ऐसा ही है। आजकल ऐसी चीज़ें कम दिखने का एक कारण यह भी है कि compiler technology ने बहुत प्रगति कर ली है
unikernel और WASM के use cases क्या हैं?
unikernel की अहमियत मेरे हिसाब से 1) performance: जो ज़रूरी नहीं है उसे हटाकर, और जो ज़रूरी है उसे “ring 0” में खींचकर कुछ और cycles निचोड़ लेना, 2) simplification: गैर-ज़रूरी हिस्सों को हटाकर complexity कम करने की संभावना, 3) security: इसी तरह अनावश्यक चीज़ें घटाकर attack surface बदलने की संभावना
लेकिन मुझे नहीं लगता कि यह इस फ़ोरम के बहुत से लोगों द्वारा किए जाने वाले microservices या web app development के लिए सही तरीका है। इसका उपयोग database, load balancer जैसे infrastructure components बनाने में ज़्यादा उपयुक्त लगता है
इसलिए कुछ edge cloud providers, Docker images चलाते समय उन्हें micro VM में बदल देते हैं
हालांकि edge पर micro VM के अंदर चलने वाला WASM, edge के sandboxed WASM से प्रतिस्पर्धा करने में मुश्किल पा सकता है। provider के नज़रिए से देखें तो बाद वाले में उपयोगी boundary features और integrations जोड़ना शायद आसान होता है
बहुत पहले Birth & Death of Javascript में जैसा “पूर्वसंकेत” दिया गया था, विचार यह था कि कभी न कभी ऐसा unikernel आएगा जो kernel space में सुरक्षित garbage collection runtime चलाएगा, और तब CPU से virtual memory mapping support हटाकर उसे और तेज़ बनाया जा सकेगा
2014 में लेखक ने JS और asm.js की कल्पना की थी, लेकिन अब WASM उस दिशा जैसा दिखता है। उत्साहजनक है, हा हा
https://www.destroyallsoftware.com/talks/the-birth-and-death...
लेकिन बाद में हमने सीखा कि single-process browser सुरक्षा के लिहाज़ से एक दुःस्वप्न है, और आज के browser सही sandboxing के लिए अब single process नहीं हैं
फिर भी यह देखना अच्छा लगता है कि वह वीडियो उत्तर के कितना क़रीब था, और यह देखना भी दिलचस्प है कि वह किन तरीकों से ग़लत था
ठीक-ठीक कहना मुश्किल है, लेकिन यह कहीं न कहीं जाना-पहचाना लगता है। संकेत यह है कि वह भी “J” से शुरू होता है
https://en.wikipedia.org/wiki/JavaStation
किसी process का virtual उपयोग swapping की वजह से नहीं भी हो, तब भी RSS से अधिक हो सकता है, और operating system व allocator मिलकर सामान्य मामलों में इसे काफ़ी समझदारी से संभालते हैं
इसलिए इसे हटा देने से अपने-आप performance लाभ मिलेगा, ऐसा मानना मुश्किल है। ख़ासकर तब, जब उसके ऊपर काफ़ी धीमा WASM VM layer भी हो
कुछ applications, जैसे databases, में unikernel पर चलाना या kernel के और क़रीब जाकर MMU को सीधे access करना बड़ा लाभ दे सकता है: https://github.com/tuhhosg/exmap & https://github.com/viktorleis/vmcache & https://www.cs.cit.tum.de/fileadmin/w00cfj/dis/_my_direct_up...
लेकिन उन सामान्य applications के लिए, जो POSIX standard मानकर चलते हैं या यह मानते हैं कि execution environment एक आधुनिक सामान्य computer जैसा दिखता है, इस पर संदेह है। आख़िरकार, ऐसा लगता है कि VMM layer जो बहुत-सा काम करती थी, उसका बड़ा हिस्सा फिर से user code में लिखना पड़ेगा
JS engine, VMM पर निर्भर करते हैं और WASM भी कई तरह से ऐसा ही करता है। embedded को छोड़कर लगभग हर non-trivial program सूक्ष्म रूप से VMM को पूर्वधारणा मानता है। ख़ासकर micro VM के आसपास की कुछ VM technologies भी VMM का उपयोग करती हैं, और unikernel का असली मतलब भी तब बनता है जब उसे VM के रूप में इस्तेमाल किया जाए