🎧 Listen to this article: हिंदी · English · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · ଓଡ଼ିଆ · 日本語 · 中文
🌍 Read this in your language: हिंदी · தமிழ் · తెలుగు · ಕನ್ನಡ · മലയാളം · ଓଡ଼ିଆ · 日本語 · 中文
ଜାଣିବା ଏବଂ ନିର୍ମାଣ କରିବା ମଧ୍ୟରେ ଥିବା ବ୍ୟବଧାନ
ଆପଣ ଏକ Docker ପରୀକ୍ଷାରେ ଉତ୍ତୀର୍ଣ୍ଣ ହୋଇପାରନ୍ତି, ସଠିକ୍ ଶବ୍ଦଗୁଡ଼ିକ କହିପାରନ୍ତି—namespaces, cgroups, images, layers, PID 1, Kubernetes Pods—ଏବଂ ତଥାପି ବାସ୍ତବରେ ଏକ container ନିର୍ମାଣ କରିବାକୁ ଚେଷ୍ଟା କରିବା ସମୟରେ ଆପଣ କ’ଣ କରୁଛନ୍ତି ସେ ବିଷୟରେ କୌଣସି ଧାରଣା ନଥାଇପାରେ। DEV Community ରେ ନିକଟରେ ନିଜ କାହାଣୀ ସେୟାର କରିଥିବା ଜଣେ ଡେଭଲପର୍ଙ୍କଠାରୁ ଏହା ହିଁ ଶିକ୍ଷା, ଏବଂ ଏହା ଏକ ସ୍ମାରକ ଯେ ସିଦ୍ଧାନ୍ତ ଏବଂ ଅଭ୍ୟାସ ଭିନ୍ନ ଦୁନିଆରେ ବାସ କରନ୍ତି। ଏହା ବର୍ତ୍ତମାନ ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ କାରଣ containerization ସବୁଠି ଅଛି—Docker, Kubernetes, ଏବଂ ହଜାର ହଜାର deployment system ଏପରି ଧାରଣା ଉପରେ ଆଧାରିତ ଯାହା ଆପଣ ରିଅଲ-ଟାଇମରେ ସେଗୁଡ଼ିକ ସହିତ ସାମ୍ନାସାମ୍ନି ନହେବା ପର୍ଯ୍ୟନ୍ତ ବିମୂର୍ତ୍ତ ମନେହୁଏ।
ପ୍ରଥମ Command: ଏକ ଶିକ୍ଷଣୀୟ ଆରମ୍ଭ
ଏହା ସରଳ ଭାବରେ ଆରମ୍ଭ ହୋଇଥିଲା: ଏକ ନୂତନ namespace ରେ process ଚଲାଇବା ପାଇଁ ଏହି unshare command ବ୍ୟବହାର କରିବା। ପ୍ରଥମ ଚେଷ୍ଟା ଥିଲା:
bash sudo unshare -p 1 test
Error: unshare: failed to execute 1: No such file or directory
Flags ଗୁଡ଼ିକ ଭୁଲ୍ ଥିଲା। Command ଟି ସିଷ୍ଟମକୁ "1" ନାମକ ଏକ ପ୍ରୋଗ୍ରାମ ଚଲାଇବାକୁ କହିଥିଲା, ଯାହା ଅସ୍ତିତ୍ୱରେ ନାହିଁ। କିଛି ନିର୍ମାଣ କରିବା ପୂର୍ବରୁ, ପ୍ରକୃତ ସମସ୍ୟାରେ ପହଞ୍ଚିବା ପୂର୍ବରୁ, କିବୋର୍ଡ୍ ଏବଂ ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ମଧ୍ୟରେ କ’ଣ ହେବାକୁ ଥିଲା ସେ ନେଇ ଭିନ୍ନ ଧାରଣା ଥିଲା।
ଭାଗ ୧: Namespaces ଏବଂ PID 1
ପ୍ରଥମ ପ୍ରକୃତ ଚେଷ୍ଟା ଥିଲା ଏକ ନୂତନ PID (process ID) namespace ରେ ଏକ process ଚଲାଇବା ଏବଂ ଏହା ନିଜକୁ PID 1—process tree ର root ଭାବରେ ଦେଖୁଛି ବୋଲି ପ୍ରମାଣ କରିବା। ତେଣୁ command ଟି ଚାଲିଲା:
bash sudo unshare --pid bash
ତା’ପରେ ସେହି shell ଭିତରେ:
bash echo $$
Expected output: 1. Actual output: 25184.
ଏହା କାମ କଲାନାହିଁ। ସେଇଟି PID 1 ନଥିଲା; ଏହା କେବଳ host ରୁ parent process ID ଥିଲା। ନିୟମଟି ସରଳ ଥିଲା କିନ୍ତୁ ଅନୁଭୂତିର ବିପରୀତ ଥିଲା: PID namespaces କେବଳ child processes ପାଇଁ ଲାଗୁହୁଏ, ଏହାକୁ କଲ୍ କରୁଥିବା process ପାଇଁ ନୁହେଁ unshare। ଆପଣଙ୍କୁ fork କରିବାକୁ ପଡ଼ିବ। ନୂତନ namespace ରେ ଜନ୍ମ ହୋଇଥିବା ପ୍ରଥମ child, PID 1 ହୋଇଥାଏ।
ତେଣୁ କାର୍ଯ୍ୟକ୍ଷମ ସଂସ୍କରଣଟି ଥିଲା:
bash sudo unshare --pid --fork bash echo $$
ବର୍ତ୍ତମାନ output 1 ଥିଲା। Shell ଭାବିଲା ଯେ ଏହା process tree ର root। ଭିତରୁ ସବୁକିଛି ଭିନ୍ନ ଅନୁଭୂତ ହେଲା।
ତା’ପରେ ପରବର୍ତ୍ତୀ ଆଶ୍ଚର୍ଯ୍ୟଜନକ କଥା ଆସିଲା। ps ଭିତରୁ ଚଲାଇବାରୁ ଦେଖାଗଲା:
PID PPID COMMAND 25310 25304 bash 25344 25310 ps
କିନ୍ତୁ shell କହିଲା ଯେ ଏହା PID 1। ତାହା କୌଣସି ଅର୍ଥ ପ୍ରକାଶ କରୁନଥିଲା। ସତ୍ୟତାଟି ହେଉଛି: ps kernel କୁ କେବଳ "କେଉଁ processes ଅଛନ୍ତି?" ପ୍ରଶ୍ନ ପଚାରେ ନାହିଁ। ଏହା files ପଢ଼ିଥାଏ। ଯଦି /proc ଏବେ ବି host ର process filesystem କୁ ସୂଚାଉଥାଏ, ତେବେ ଆପଣଙ୍କ tools ଆପଣଙ୍କୁ ଭୁଲ୍ ତଥ୍ୟ ଦେବେ। ସେଗୁଡ଼ିକ host ର ନମ୍ବରିଂ ସ୍କିମ୍ ଦେଖାଇବେ।
ଏହାର ସମାଧାନ ଥିଲା ପୁନର୍ବାର remount କରିବା /proc namespace ଭିତରୁ:
bash mount -t proc proc /proc ps -o pid,ppid,comm
ବର୍ତ୍ତମାନ ଏହା ଦେଖାଇଲା:
PID PPID COMMAND 1 0 bash 7 1 ps
ସେହି ମୁହୂର୍ତ୍ତରେ ହିଁ ସବୁକିଛି ସ୍ପଷ୍ଟ ହୋଇଗଲା। Namespace ପ୍ରକୃତ isolation ପ୍ରଦାନ କରିଥିଲା, କିନ୍ତୁ filesystem view ନବଦଳିବା ପର୍ଯ୍ୟନ୍ତ tools ଗୁଡ଼ିକ ତାହା ଦେଖିପାରୁନଥିଲେ। Isolation ଏବଂ visibility ଦୁଇଟି ଭିନ୍ନ ଜିନିଷ।
UTS namespace—ଯାହା hostname ନିୟନ୍ତ୍ରଣ କରେ—ବୁଝିବା ପାଇଁ ଅଧିକ ସହଜ ଥିଲା। Host ରେ hostname ଚଲାଇବାରୁ ଗୋଟିଏ ନାମ ଦେଖାଗଲା। ଏକ ନୂତନ UTS namespace ଭିତରେ ( sudo unshare --uts bashସହିତ ସୃଷ୍ଟି କରାଯାଇଥିବା), ଏହାକୁ ବଦଳାଇବାରୁ ଅନ୍ୟ କିଛି ଦେଖାଗଲା। Host କୁ ଫେରିବା ପରେ, ଏହା ପୁନର୍ବାର ମୂଳ ନାମକୁ ଫେରିଗଲା। ଗୋଟିଏ machine, ଗୋଟିଏ kernel, ତିନୋଟି ଭିନ୍ନ views।
ଭାଗ ୨: Filesystem Handoff
Namespaces ପରେ, ପରବର୍ତ୍ତୀ ସଂସ୍କରଣଟି process କୁ ତା’ର ନିଜସ୍ୱ filesystem ଦେବାର ଥିଲା: BusyBox ଏବଂ shell ସହିତ ଏକ rootfs (root filesystem)। ସମ୍ପୂର୍ଣ୍ଣ container ପରି।
ପ୍ରଥମ ତ୍ରୁଟିଟି ସରଳ ଥିଲା:
exec /bin/sh: no such file or directory
Script ରେ କୁହାଯାଇଥିବା ସ୍ଥାନରେ shell ନଥିଲା। ତାହା ସଂଶୋଧିତ ହେଲା। କିନ୍ତୁ ତା’ପରେ:
./rootfs/bin/busybox: cannot execute: required file not found
ଏହି error ଟି କଷ୍ଟଦାୟକ କାରଣ file ଟି ସେଠାରେ ହିଁ ଅଛି। ଆପଣ ଏହାକୁ list କରିପାରିବେ। ଆପଣ ଏହାକୁ ଦେଖିପାରିବେ। ତଥାପି kernel ଏହାକୁ ଚଲାଇବାକୁ ମନା କରେ। ଏହି file command ସତ୍ୟତା ପ୍ରକାଶ କଲା:
ELF 64-bit LSB pie executable, ARM aarch64, dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, stripped
Binary ଟି ସେଠାରେ ଥିଲା। ଏହା ପାଇଁ ଆବଶ୍ୟକ ଥିବା interpreter—dynamic linker—ପୁରୁଣା ଦୁନିଆରୁ ଉପଲବ୍ଧ ନଥିଲା। Linux ଏହା କହୁନଥିଲା ଯେ file ଟି ନାହିଁ। ଏହା କହୁଥିଲା "ଏଠାରୁ, ମୁଁ ଏହି ELF ଆବଶ୍ୟକ କରୁଥିବା interpreter କୁ load କରିପାରିବି ନାହିଁ।"
ସମାଧାନଟି BusyBox କୁ static କରିବା ନଥିଲା। ଏହା Alpine କୁ ନୂତନ root filesystem କରିବା ଥିଲା ଯାହାଦ୍ୱାରା interpreter ସଠିକ୍ path ରେ ରହିବ। କିନ୍ତୁ ପ୍ରଥମେ, ଏହି ପରିବର୍ତ୍ତନ ପାଇଁ ଏକ ସେତୁର ଆବଶ୍ୟକତା ଥିଲା—ଏକ tool ଯାହା filesystem switch ହେବା ପୂର୍ବରୁ ଏବଂ ସମୟରେ ଚାଲିପାରିବ। BusyBox ଦୁଇଟି ରୂପରେ ଆସିଥିଲା: Alpine ଭିତର ପାଇଁ ଏକ dynamic ଏବଂ handoff ପାଇଁ ଏକ static:
bash /bin/busybox pivot_root . put_old
Static BusyBox ଟି ସେହି ଚାବି ଥିଲା ଯାହା ଚଲାଇପାରୁଥିଲା pivot_root ସିଷ୍ଟମ୍ ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଦୁନିଆ ବଦଳାଇବା ପୂର୍ବରୁ।
Alpine ନୂତନ root ହେବା ପରେ, ଆହୁରି ଅନେକ ଆଶ୍ଚର୍ଯ୍ୟଜନକ କଥା ସାମ୍ନାକୁ ଆସିଲା। Bash ଏବେ ବି ପୁରୁଣା filesystem ରୁ command paths ମନେ ରଖିଥିଲା। ଯେତେବେଳେ ଏହା ଚଲାଇବାକୁ ଚେଷ୍ଟା କଲା mount, ଏହା ଖୋଜିଲା /usr/bin/mount ସେହି ଦୁନିଆରେ ଯାହାକୁ ସଦ୍ୟ ଅପସାରିତ କରାଯାଇଥିଲା:
bash: /usr/bin/mount: No such file or directory
ସମାଧାନଟି ଥିଲା hash -r, ଯାହା command cache କୁ ସଫା କରେ। Bash ପୁରୁଣା ଦୁନିଆରେ ଏକ ନିଷ୍ପତ୍ତି ନେଇସାରିଥିଲା ଏବଂ ତାହାକୁ ଛାଡ଼ିପାରୁନଥିଲା।
ଭାଗ ୩: Mac ଜଟିଳତା
Setup ଟି ଏକ ସାଧାରଣ Linux laptop ନଥିଲା। ଏହା ଥିଲା Apple Silicon Mac → privileged Ubuntu container → macOS ରୁ mounted ହୋଇଥିବା repo। ତା'ର ଅର୍ଥ virtiofs (virtualization ପାଇଁ ଏକ filesystem passthrough) ଜଡ଼ିତ ଥିଲା, କେହି ଚାହୁଁଥାନ୍ତୁ କି ନାହିଁ।
Alpine ଭିତରେ, ଯାହା ବର୍ତ୍ତମାନ root filesystem ଥିଲା, symlinks ମାଧ୍ୟମରେ execute କରିବା Mac-shared mount ରେ "Permission denied" ସହିତ ବିଫଳ ହୋଇପାରେ, ଯେତେବେଳେ କି BusyBox କୁ ସିଧାସଳଖ call କରିବା କାମ କରୁଥିଲା:
bash ls
sh: ls: Permission denied
/bin/busybox ls
(works)
Files ଗୁଡ଼ିକ ସେଠାରେ ଥିଲା। ସେହି symlinks ମାଧ୍ୟମରେ execute କରିବା ଏକ ଅଜବ କଥା ଥିଲା। ସମାଧାନଟି ସାଧାରଣ ଏବଂ ସଠିକ୍ ଥିଲା: rootfs କୁ ଏକ container-native path କୁ ଘୁଞ୍ଚାନ୍ତୁ ଏବଂ ସେଠାରୁ ଚେଷ୍ଟା କରନ୍ତୁ। ଏକ Mac-shared mount କୁ ସାଧାରଣ Linux ପରି ବ୍ୟବହାର କରିବାକୁ ବାଧ୍ୟ କରନ୍ତୁ ନାହିଁ।
ଭାଗ ୪: pivot_root ର ନିଜସ୍ୱ ନିୟମ ଅଛି
ସେସବୁ ପରେ ମଧ୍ୟ, pivot_root ନିଜେ ଶିଖାଇବା ଶେଷ କରିନଥିଲା। Error:
pivot_root: invalid argument
ନୂତନ root କୁ ଏକ mount point ହେବାକୁ ପଡ଼ୁଥିଲା। ପୁରୁଣା root କୁ ଯିବା ପାଇଁ ଏକ ସ୍ଥାନ ଆବଶ୍ୟକ ଥିଲା। ତେଣୁ କାର୍ଯ୍ୟପ୍ରଣାଳୀ ଥିଲା:
- ନୂତନ root କୁ ନିଜ ଉପରେ Bind-mount କରନ୍ତୁ
- ଗୋଟିଏ ସୃଷ୍ଟି କରନ୍ତୁ
oldrootdirectory - Call କରନ୍ତୁ
pivot_root(newroot, oldroot) - ନୂତନ root କୁ directory ପରିବର୍ତ୍ତନ କରନ୍ତୁ
- ପୁରୁଣା root କୁ Unmount କରନ୍ତୁ
ଯେତେବେଳେ ଏହା ଶେଷରେ କାମ କଲା, ପୁରସ୍କାରଟି ଛୋଟ ଏବଂ ସମ୍ପୂର୍ଣ୍ଣ ସଠିକ୍ ଥିଲା:
bash cat /etc/os-release NAME="Alpine Linux" ID=alpine VERSION_ID=3.24.1
କେବଳ ଏକ text file। କିନ୍ତୁ ବର୍ତ୍ତମାନ ଏହା ପ୍ରମାଣ ଥିଲା ଯେ container ଟି କାମ କଲା।
ନିଷ୍କର୍ଷ
ସ୍କ୍ରାଚ୍ରୁ ଏକ container ନିର୍ମାଣ କରିବା ଏପରି କିଛି ଶିଖାଏ ଯାହା କୌଣସି କୋର୍ସ ଶିଖାଇପାରିବ ନାହିଁ: ସିଦ୍ଧାନ୍ତ ଜାଣିବା ଏବଂ ରିଅଲ-ଟାଇମରେ ଏହା ବିଫଳ ହେବା ଦେଖିବା ମଧ୍ୟରେ ଥିବା ଦୂରତା। Namespaces, cgroups, ଏବଂ ଅନ୍ୟାନ୍ୟ ସବୁକିଛି ସତ୍ୟ। ସେଗୁଡ଼ିକ ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ଅନୁଯାୟୀ ହିଁ କାମ କରନ୍ତି। କିନ୍ତୁ "ମୁଁ ଏହା ବୁଝିପାରୁଛି" ରୁ "ମୁଁ ଏହାକୁ କାର୍ଯ୍ୟକ୍ଷମ କରିପାରିବି" ପର୍ଯ୍ୟନ୍ତ ରାସ୍ତା error messages, Bash caches, filesystem permissions, ଏବଂ ଏହି ଅନୁଭୂତି ଦେଇ ଗତିକରେ ଯେ ଯଦି filesystem ସଠିକ୍ ନଥାଏ ତେବେ ଆପଣଙ୍କ tools ଆପଣଙ୍କୁ ଭୁଲ୍ ତଥ୍ୟ ଦେବେ।
ସୁବିଧାଗୁଡ଼ିକ
- ପ୍ରାକ୍ଟିକାଲ୍ (Hands-on) ଶିକ୍ଷା ବୁଝିବାର ଶକ୍ତିକୁ ଏପରି ଭାବରେ ଗଭୀର କରେ ଯାହା କେବଳ ପଢ଼ିବା ଦ୍ୱାରା ହୋଇପାରିବ ନାହିଁ
- ପ୍ରକୃତ ତ୍ରୁଟିଗୁଡ଼ିକ (real errors) ଏପରି ସୀମାବଦ୍ଧତା ଶିଖାଏ ଯାହା ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ପ୍ରାୟତଃ ଛାଡ଼ିଦିଏ
- ସ୍କ୍ରାଚ୍ରୁ ନିର୍ମାଣ କରିବା ଦ୍ୱାରା ଆଧୁନିକ container tools ଗୁଡ଼ିକ କିପରି ଜଟିଳତାକୁ ଲୁଚାନ୍ତି ତାହା ପ୍ରକାଶ ପାଏ
- Namespaces, filesystems, ଏବଂ interpreters ବୁଝିବା ଦ୍ୱାରା Docker ଏବଂ Kubernetes କମ୍ ରହସ୍ୟମୟ ମନେହୁଏ
ଅସୁବିଧାଗୁଡ଼ିକ
- ଶିଖିବାର ପ୍ରକ୍ରିୟା କଠିନ ଏବଂ ଏଥିରେ ଅନେକ ଛୋଟ, ଦ୍ୱନ୍ଦ୍ୱପୂର୍ଣ୍ଣ errors ଜଡ଼ିତ
- ପରିବେଶଗତ କାରକଗୁଡ଼ିକ (ଯେପରିକି macOS ରେ virtiofs) ଅପ୍ରତ୍ୟାଶିତ ଜଟିଳତା ଯୋଗ କରେ
- ସିଧାସଳଖ Docker ବ୍ୟବହାର କରିବା ତୁଳନାରେ ଏହି ପ୍ରକ୍ରିୟା ଧୀର ଅଟେ
- ଅନେକ edge cases (Bash hash caching, symlink permissions) ଡକ୍ୟୁମେଣ୍ଟେସନ୍ରୁ ସ୍ପଷ୍ଟ ହୋଇନଥାଏ
ସାବଧାନତା
ଏହି ଲେଖାଟି ଶିକ୍ଷଣୀୟ ଏବଂ ମୌଳିକ ନୀତିରୁ containers ନିର୍ମାଣ କରିବାର ପ୍ରକୃତ ଶିକ୍ଷା ବର୍ଣ୍ଣନା କରେ। ଦେଖାଯାଇଥିବା commands ଏବଂ ଧାରଣାଗୁଡ଼ିକ ମୂଳ ତଥ୍ୟ ସହିତ ସଠିକ୍। ଏହା ଏକ production-grade container runtime ନୁହେଁ; କଣ୍ଟେନରଗୁଡ଼ିକ କିପରି କାମ କରେ ତାହା ବୁଝିବା ପାଇଁ ଏହା ଏକ ଶିକ୍ଷଣୀୟ ସାଧନ। Production ରେ କୌଣସି container system ଉପରେ ନିର୍ଭର କରିବା ପୂର୍ବରୁ, ଆନୁଷ୍ଠାନିକ ଡକ୍ୟୁମେଣ୍ଟେସନ୍ ଏବଂ ସର୍ବୋତ୍ତମ ଅଭ୍ୟାସଗୁଡ଼ିକର ପରାମର୍ଶ ନିଅନ୍ତୁ। ଆପଣଙ୍କ ପରିବେଶରେ କିଛି କାର୍ଯ୍ୟକାରୀ କରିବା ପୂର୍ବରୁ ମୂଳ ଉତ୍ସ ସହିତ ସମସ୍ତ ଦାବି ସତ୍ୟାପନ କରନ୍ତୁ।
ବାରମ୍ବାର ପଚରାଯାଉଥିବା ପ୍ରଶ୍ନଗୁଡ଼ିକ (FAQ)
- PID namespace କ’ଣ ଏବଂ containers ରେ ଏହା କାହିଁକି ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ?
- Unshare କଲ୍ କରୁଥିବା ଏକ process ସ୍ୱୟଂଚାଳିତ ଭାବରେ PID 1 କାହିଁକି ହୁଏ ନାହିଁ?
- /proc filesystem ର containers ସହିତ କ’ଣ ସମ୍ପର୍କ ଅଛି?
- Pivot_root, chroot ଠାରୁ କିପରି ଭିନ୍ନ?
- /proc କୁ ପୁନର୍ବାର remount କରିବା ଦ୍ୱାରା ps ଦେଖାଉଥିବା ତଥ୍ୟ କାହିଁକି ବଦଳିଗଲା?
- Container ନିର୍ମାଣରେ BusyBox ର ଭୂମିକା କ’ଣ?
- ଏକ ନୂତନ root filesystem କୁ switch କରିବା ସମୟରେ dynamic interpreters କାହିଁକି ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ?
- virtiofs, macOS ରେ container setup କୁ କିପରି ଜଟିଳ କରିଥାଏ?
Tags
#containers #linux #docker #devops #namespaces #cgroups #filesystem #learning
API Security Testing Checklist
A practical workflow for testing authentication, authorization, input handling, business logic, and evidence without losing track of scope.
Free. No spam — unsubscribe in one click.


Responses
Sign in to leave a response.