- Docker जिन कंटेनरों को abstract करके आसान बनाता है, उनकी बुनियाद Linux namespaces, cgroups और
chroot कमांड से खुद जोड़कर यह देखा जाता है कि isolation और execution environment कैसे बनते हैं
- लक्ष्य Docker का विकल्प बनाना नहीं, बल्कि उसके सिद्धांत को समझना है; इसलिए layered images, networking, orchestration और व्यापक operations tools को इसमें लागू नहीं किया गया है
- isolation की शुरुआत
unshare --uts --pid --net --mount --ipc --fork से होती है, जो UTS, PID, network, mount और IPC namespaces को अलग करता है
- resource control के लिए
/sys/fs/cgroup/cpu/container1 में cgroup बनाया जाता है और cpu.cfs_quota_us तथा tasks सेट करके मौजूदा shell और child processes को CPU limit के दायरे में रखा जाता है
debootstrap से Ubuntu 20.04 Focal Fossa root file system बनाया जाता है, फिर /proc, /sys, /dev को mount करके chroot के अंदर Nginx install और run किया जाता है
इस प्रैक्टिस का उद्देश्य और दायरा
- Docker, Linux namespaces, cgroups और
chroot का उपयोग करके isolation, resource management और security देता है
- यह प्रैक्टिस theory से ज़्यादा वास्तविक command flow पर फोकस करती है और Docker जैसे एक बुनियादी container environment को हाथ से बनाती है
- लक्ष्य Docker की पूरी functionality को दोहराना नहीं, बल्कि यह समझना है कि containerization की core foundational technologies आपस में कैसे काम करती हैं
- Docker की निम्नलिखित features इस प्रैक्टिस के दायरे में शामिल नहीं हैं
- layered images
- networking
- container orchestration
- व्यापक deployment और operations tools
चरण 1: namespaces से isolation environment बनाना
- नया isolated environment
unshare कमांड से शुरू होता है
unshare --uts --pid --net --mount --ipc --fork
- दिए गए namespaces कंटेनर को अलग system identifiers और resource instances देते हैं
--uts
--pid
--net
--mount
--ipc
unshare कमांड के बारे में विस्तार से man page में देखा जा सकता है
चरण 2: cgroups से CPU usage सीमित करना
- cgroups containerized processes के लिए system resources के allocation और usage को नियंत्रित करते हैं
- उदाहरण में
container1 नाम का नया cgroup बनाकर CPU quota limit सेट की जाती है
mkdir /sys/fs/cgroup/cpu/container1
echo 100000 > /sys/fs/cgroup/cpu/container1/cpu.cfs_quota_us
echo 0 > /sys/fs/cgroup/cpu/container1/tasks
echo $$ > /sys/fs/cgroup/cpu/container1/tasks
- पहली पंक्ति
/sys/fs/cgroup/cpu/ के नीचे container1 directory बनाती है, जिसे कंटेनर के cgroup के रूप में इस्तेमाल किया जाता है
- दूसरी पंक्ति
/sys/fs/cgroup/cpu/container1/cpu.cfs_quota_us में 100000 लिखकर CPU quota limit तय करती है
- तीसरी पंक्ति
tasks फ़ाइल में 0 लिखकर पहले से assigned processes को हटाती है
- चौथी पंक्ति
$$, जो मौजूदा shell या script का PID है, उसे tasks फ़ाइल में लिखती है
- मौजूदा process
container1 cgroup में assign हो जाती है
- इसके बाद shell या script द्वारा बनाए गए child processes भी उसी cgroup में रहते हैं
- उन processes का resource usage तय की गई CPU quota limit के अधीन रहता है
चरण 3: root file system बनाना
- कंटेनर का file system
debootstrap से ubuntu-rootfs directory में एक minimal Ubuntu environment install करके बनाया जाता है
debootstrap focal ./ubuntu-rootfs http://archive.ubuntu.com/ubuntu/
- पहला argument
focal install की जाने वाली Ubuntu release को बताता है
- दूसरा argument
./ubuntu-rootfs वह directory है जहाँ Ubuntu environment install होगा
- तीसरा argument
http://archive.ubuntu.com/ubuntu/ installation के लिए इस्तेमाल होने वाला Ubuntu repository URL है
debootstrap के बारे में विस्तार से man page में देखा जा सकता है
चरण 4: ज़रूरी file systems mount करना और chroot में प्रवेश
- कंटेनर root file system के अंदर
/proc, /sys, /dev जैसे ज़रूरी file systems mount किए जाते हैं
- इसके बाद
chroot से root directory को कंटेनर file system में बदला जाता है
mount -t proc none ./ubuntu-rootfs/proc
mount -t sysfs none ./ubuntu-rootfs/sys
mount -o bind /dev ./ubuntu-rootfs/dev
chroot ./ubuntu-rootfs /bin/bash
proc file system को ./ubuntu-rootfs/proc पर mount किया जाता है
- यह processes और system resources की जानकारी virtual files के रूप में देता है
./ubuntu-rootfs/ environment के अंदर के processes process-related system information तक पहुँच सकते हैं
sysfs file system को ./ubuntu-rootfs/sys पर mount किया जाता है
- यह devices, drivers और kernel से जुड़ी जानकारी hierarchical structure में देता है
- अंदर के processes
sysfs interface के ज़रिए system-related information तक पहुँच सकते हैं
/dev को ./ubuntu-rootfs/dev पर bind mount किया जाता है
/dev में physical और virtual devices को दर्शाने वाली device files होती हैं
- अंदर के environment से access की गई device files host system के संबंधित devices से जुड़ती हैं
- अंदर के processes ज़रूरी devices को ऐसे इस्तेमाल कर सकते हैं जैसे वे host पर सीधे उपलब्ध हों
chroot ./ubuntu-rootfs /bin/bash root directory को ./ubuntu-rootfs/ में बदल देता है, जिसे Docker कंटेनर में docker exec से प्रवेश करने जैसा समझा जा सकता है
चरण 5: कंटेनर के अंदर application चलाना
- कंटेनर environment तैयार हो जाने पर उसके अंदर applications install और run की जा सकती हैं
- उदाहरण में Nginx web server install करके यह देखा जाता है कि application कंटेनर के अंदर कैसे चलती है
(container) $ apt update
(container) $ apt install nginx
(container) $ service nginx start
- पूरी प्रैक्टिस Linux namespaces, cgroups और
chroot को मिलाकर एक बुनियादी container environment बनाने का command flow दिखाती है
2 टिप्पणियां
Hacker News की राय
जब भी मैं देखता हूँ कि container इतनी सरल तकनीक है, तो एक बात मन में आती है: अगर मकसद सिर्फ एक single binary चलाना है, तो container के अंदर अभी भी पूरा OS filesystem क्यों चाहिए?
dependencies या dynamic libraries इसके लिए ठीक कारण हो सकते हैं, लेकिन क्या खाली filesystem से शुरू करके binary को चलाने के लिए जो फाइलें सचमुच ज़रूरी हों उन्हें धीरे-धीरे जोड़ने वाला bottom-up approach ज़्यादा समझदारी भरा नहीं होगा? अभी तो तरीका लगभग उलटा है: एक पूरे OS filesystem से शुरू करो और फिर गैर-ज़रूरी चीजें हटाओ
सिद्धांत में bottom-up सही है, लेकिन जैसे ही dynamic loading, plugins और runtime loading support आ जाता है, व्यवहार में इसे करना लगभग नामुमकिन हो जाता है। इसलिए आम तौर पर लोग ऐसे base image से शुरू करते हैं जिसमें ज़रूरी चीजें पहले से हों। BSD jail या chroot भी इसी तरह काम करते हैं, लेकिन complex applications में configuration सचमुच दर्दनाक हो जाती है
systemd-nspawnमें--directory=/ --volatile=yesदेने पर ऐसा container बनाया जा सकता है जो अपना root filesystem होस्ट से ही लेता हैइसमें container root पर
tmpfsmount होता है, और host का/usrcontainer के/usrपर read-only mount किया जाता है। container मशीन में इंस्टॉल किए गए सारे software चला सकता है, और writes कोtmpfsकी ओर redirect कर दिया जाता हैया
--directory=/की जगह/var/lib/machines/debian-bookwormया/var/lib/machines/fedora-38जैसी किसी दूसरी directory को दे सकते हैं जिसमें OS image हो। writes हर container केtmpfsमें जाती हैं, इसलिए कई containers एक ही image को पारदर्शी तरीके से share कर सकते हैंhttps://0pointer.net/blog/running-an-container-off-the-host-...
और हाँ, आपने जो approach बताई वह Nix के काम करने के तरीके से मिलती-जुलती है, और Nix से OCI images भी बनाई जा सकती हैं
FROM Scratchपूरी तरह खाली image से शुरू करता है, इसलिए यह सबसे छोटा होता है, लेकिन application को support files के बिना चलना आना चाहिए। उदाहरण के लिए, वह statically compiled binary होना चाहिएDistroless में standard OS support files थोड़ी मात्रा में होती हैं, लेकिन package manager नहीं होता, इसलिए यह उन मामलों के लिए ठीक है जहाँ बहुत सारे OS packages इंस्टॉल करने की ज़रूरत नहीं होती
Wolfi अपेक्षाकृत नया है, और खास उद्देश्यों के लिए minimal image ecosystem बना रहा है
अगर आपका program ऐसा नहीं है, जैसे ज़्यादातर Rust या Go programs जो statically linked single binary होते हैं, तो शुरू से ही Docker इस्तेमाल करने की बहुत कम वजह है
आप कह सकते हैं, “फिर भी containerize तो करना है” या “orchestration का क्या?”, और अब ये side effects भी मौजूद हैं, लेकिन अंततः यह ज़्यादा उस स्थिति जैसा है जहाँ सबको app चलाने के लिए लगभग Docker इस्तेमाल करने पर मजबूर कर दिया गया। Docker खराब software के लिए एक workaround है
यह लेख ChatGPT से जनरेट किया हुआ लगता है
मैं इस workflow से काफ़ी संतुष्ट हूँ। कच्चे रूप में विचार उँडेलने के अलावा मुझे ज़्यादा चिंता नहीं करनी पड़ती, इसलिए मैं ज़्यादा बार लिख पाता हूँ
इसे ऐसे समझिए जैसे Markdown files से static pages बनाकर वेब पर आसानी से deploy करने के लिए Astro या TailwindCSS जैसे tools का इस्तेमाल करना
https://media.tenor.com/1PMq-CFZno4AAAAC/avengers-endgame-hu...
Linux kernel-स्तर की सुविधाओं से Docker isolation को दोहराने वाले लेख Docker जितने ही पुराने हैं, और मेरे अनुभव में वे लगभग हमेशा Docker ecosystem के सबसे महत्वपूर्ण हिस्सों में से एक को छोड़ देते हैं। वह है आसानी से hack और extend किए जा सकने वाला container image format
container-आधारित architecture की लोकप्रियता सिर्फ namespace, cgroup, और chroot का चतुराई से उपयोग करके “मजबूत isolation, resource management, security” बनाने की वजह से नहीं है, बल्कि image format को आसानी से extend कर पाने की वजह से भी है। image format के बिना Docker बहुत कम दिलचस्प होता, और यह कहना भी मुश्किल होता कि “मैंने खुद Docker बना लिया”
Docker में कई शानदार features हैं, लेकिन इसका killer feature बिना किसी शक के app packaging और deployment है। chroot जैसी सुविधाएँ बहुत पहले से मौजूद थीं, लेकिन वे Docker जितनी लोकप्रिय नहीं हो सकीं, और इसकी वजह है। वे उस समस्या को हल नहीं कर सकीं जिसे ज़्यादातर लोगों को अपने app को containerize करने से पहले पहले सुलझाना पड़ता है
Dockerकोcontainerdसे बदल दें, तो बात बिल्कुल फिट बैठती हैBocker की याद आ गई
[0]: https://github.com/p8952/bocker
लेखक ने माना कि उसने यह लेख लिखने में ChatGPT का इस्तेमाल किया, इसे कैसे लेना चाहिए, मैं समझ नहीं पा रहा हूँ
विषय मेरी दिलचस्पी से बिल्कुल मेल खाता है, लेकिन आगे से मैं संभव हो तो ChatGPT-लिखे लेख नहीं पढ़ना चाहूँगा
इस साल मैं Linux को सीधे explore कर रहा हूँ, इसलिए इन दिनों उसी तरफ के content पर ज़्यादा ध्यान दे रहा हूँ
फिर भी, मैं उस भावना को पूरी तरह समझता हूँ। अगर पसंद न आए तो छोड़ सकते हैं, कोई बुरा मानना नहीं। बस, जब तक मुझे इस तरीके को और बेहतर बनाने का कोई बेहतर उपाय नहीं मिल जाता, मैं इसे इस्तेमाल करता रहूँगा :)
लेकिन शर्त यह है कि उसमें काफ़ी चयन और संपादन हुआ हो। ऐसा नहीं होना चाहिए कि “Linux namespace को manually इस्तेमाल करने पर एक लेख लिखो...” कहकर उसे सीधे blog में paste कर दिया जाए
मैंने कई सालों से ऐसे बहुत से लेख देखे हैं। फिर भी Docker बना हुआ है। शायद container ecosystem बनाने में Linux internals से निपटना सबसे कठिन हिस्सा नहीं है
हाथ से करके सीखने वाली practice के रूप में यह दिलचस्प है, लेकिन मुझे ठीक से समझ नहीं आता कि ऐसे लेख बार-बार नए होकर क्यों घूमते रहते हैं
यह विषय Docker developer Jérôme Petazzoni की Dockercon 2015 प्रस्तुति में बहुत अच्छी तरह समेटा गया है। यह एक प्रस्तुति है जो समझाती है कि containerization कैसे काम करती है
वीडियो देखने के बाद ही मुझे साफ़ तौर पर समझ आया कि बहुत से लोग शुरू में जैसा सोचते हैं, उसके विपरीत यह virtualization बिल्कुल नहीं है
https://www.youtube.com/watch?v=sK5i-N34im8
क्या यह असल में नीचे दिया गया चलाने जैसा काफ़ी नहीं है?
debootstrap focal ./ubuntu-rootfs http://archive.ubuntu.com/ubuntu/systemd-nspawn -D ./ubuntu-rootfsमुझे यह concept पसंद है, लेकिन मैं हमेशा इसे बस ऐसे सरल तरीके से संभालता आया हूँ कि सभी dependencies को application के उसी folder root में compile करके डाल देता हूँ। इससे ज़्यादा जटिलता की कभी ज़रूरत नहीं पड़ी। application developers ने सिर्फ package manager इस्तेमाल करने की ज़िद में इसे बेवजह जटिल बनाया है
nginx, Apache, PHP, Perl, Python आदि को भी application के उसी root में isolate किया जा सकता है, और configuration केpathparameter के साथ compile करें तो हर application के लिए कई instances रखे जा सकते हैंलेख में बताए गए बुनियादी container की तुलना में Docker अतिरिक्त रूप से कौन-सी सुविधाएँ देता है?
rebootsystem call करना हो, तो यह permission स्पष्ट रूप से जोड़ी जा सकती हैऔर अधिक जटिल sandboxing तकनीकों में sockets, pipes, files आदि के handles पहले से खोलकर रखना, फिर उन पर seccomp filter को और सख्त करके नए handles खोलने से रोक देना शामिल है। इस तरह कोई container volume के तयशुदा files को पढ़ और लिख तो सकता है, लेकिन नए files खोलने जैसी filesystem interaction की क्षमता बिल्कुल नहीं रखेगा। क्योंकि filesystem से जुड़े system calls को पूरी तरह disable किया जा सकता है
[1] https://github.com/moby/moby/blob/master/profiles/seccomp/de...
[2] https://docs.docker.com/engine/security/#linux-kernel-capabi...
उसके बाद
buildऔरpushचलाकर image को व्यापक रूप से उपयोग योग्य बनाने वाला workflow था। Linux jail, jailer, debootstrap, lxc जैसे विकल्पों की तुलना में collaboration बहुत आसान थावैसे, लेख भी किसी specific product की ओर link नहीं करता, सिर्फ Docker company के first page पर link करता है। मुझे उस first page पर जो link सबसे पहले दिखता है वह “Docker Desktop for Linux” है, और यह शायद virtualization-based system लगता है
कुछ तो सूक्ष्म सा...?!