నేను కంటైనర్లను అర్థం చేసుకున్నానని భావించాను. ఆ తర్వాత ఒకదాన్ని నిర్మించడానికి ప్రయత్నించాను.

నేను కంటైనర్లను అర్థం చేసుకున్నానని భావించాను. ఆ తర్వాత ఒకదాన్ని నిర్మించడానికి ప్రయత్నించాను.

మొదటి నుండి నిర్మించడం అనేది పాఠ్యపుస్తకాలు వదిలివేసే విషయాలను ఎలా వెల్లడిస్తుంది

తెలుసుకోవడం మరియు నిర్మించడం మధ్య ఉన్న వ్యత్యాసం

మీరు Docker పరీక్షలో టాప్ మార్కులు సాధించవచ్చు, సరియైన పదాలను గుక్కతిప్పుకోకుండా చెప్పవచ్చు—namespaces, cgroups, images, layers, PID 1, Kubernetes Pods—అయినప్పటికీ మీరు వాస్తవంగా కంటైనర్‌ను నిర్మించడానికి ప్రయత్నించినప్పుడు మీరు ఏమి చేస్తున్నారో తెలియకపోవచ్చు. ఇటీవల DEV Community లో తమ కథనాన్ని పంచుకున్న ఒక డెవలపర్ నుండి లభించిన పాఠం ఇది, మరియు సిద్ధాంతం, ఆచరణ వేర్వేరు ప్రపంచాలలో ఉంటాయని ఇది గుర్తుచేస్తుంది. ప్రస్తుతం ఇది చాలా ముఖ్యం, ఎందుకంటే కంటైనరైజేషన్ ప్రతిచోటా ఉంది—Docker, Kubernetes మరియు వేలాది డిప్లాయ్‌మెంట్ సిస్టమ్‌లు మీరు రియల్ టైమ్‌లో వాటిని ఎదుర్కొనే వరకు అమూర్తంగా అనిపించే భావనలపై ఆధారపడి ఉన్నాయి.

మొదటి కమాండ్: వినయాన్ని నేర్పిన ప్రారంభం

ఇది సరళంగా ప్రారంభమైంది: వీటిని ఉపయోగిస్తూ కొత్త నేమ్‌స్పేస్‌లో ఒక ప్రాసెస్‌ను రన్ చేయడానికి ప్రయత్నించడం unshare కమాండ్. మొదటి ప్రయత్నం:

bash sudo unshare -p 1 test

Error: unshare: failed to execute 1: No such file or directory

ఫ్లాగ్‌లు తప్పుగా ఉన్నాయి. "1" అనే పేరుగల ప్రోగ్రామ్‌ను అమలు చేయమని ఆ కమాండ్ సిస్టమ్‌ను అడిగింది, కానీ అది లేదు. దేనినైనా నిర్మించే ముందు, అసలు సమస్యలను చేరుకోవడానికి ముందే, ఏం జరగాలనే దానిపై కీబోర్డ్ మరియు డాక్యుమెంటేషన్ వేర్వేరు ఆలోచనలను కలిగి ఉన్నాయి.

పార్ట్ 1: నేమ్‌స్పేసెస్ మరియు PID 1

మొదటి నిజమైన ప్రయత్నం ఏమిటంటే కొత్త PID (ప్రాసెస్ ID) నేమ్‌స్పేస్‌లో ప్రాసెస్‌ను రన్ చేయడం మరియు అది తన్ను తాను PID 1—ప్రాసెస్ ట్రీ యొక్క రూట్—గా చూసుకుంటుందని నిరూపించడం. కాబట్టి కమాండ్ రన్ చేయబడింది:

bash sudo unshare --pid bash

ఆపై ఆ షెల్ లోపల:

bash echo $$

ఆశించిన అవుట్‌పుట్: 1. వాస్తవ అవుట్‌పుట్: 25184.

ఇది పనిచేయలేదు. అది PID 1 కాదు; అది హోస్ట్ నుండి వచ్చిన పేరెంట్ ప్రాసెస్ ID మాత్రమే. ఆ నియమం సరళమైనది కానీ విరుద్ధమైనది: PID నేమ్‌స్పేసెస్ చైల్డ్ ప్రాసెస్‌లకు వర్తిస్తాయి, దీనిని కాల్ చేసే ప్రాసెస్‌కు కాదు unshare. మీరు fork చేయాలి. కొత్త నేమ్‌స్పేస్‌లో పుట్టిన మొదటి చైల్డ్ PID 1 అవుతుంది.

కాబట్టి పనిచేసే వర్షన్ ఇలా ఉంది:

bash sudo unshare --pid --fork bash echo $$

ఇప్పుడు అవుట్‌పుట్ 1 అని వచ్చింది. షెల్ తాను ప్రాసెస్ ట్రీ యొక్క రూట్ అని భావించింది. లోపలి నుండి అన్నీ భిన్నంగా అనిపించాయి.

ఆ తర్వాత తదుపరి ఆశ్చర్యం ఎదురైంది. దీనిని రన్ చేయగా ps లోపలి నుండి ఇలా చూపించింది:

PID PPID COMMAND 25310 25304 bash 25344 25310 ps

కానీ షెల్ అది PID 1 అని చెప్పింది. అది అర్థరహితంగా ఉంది. అసలు నిజం: ps కర్నెల్‌ను కేవలం "ఏ ప్రాసెస్‌లు ఉన్నాయి?" అనే ప్రశ్న అడగదు. ఇది ఫైళ్లను చదువుతుంది. ఒకవేళ /proc ఇప్పటికీ హోస్ట్ యొక్క ప్రాసెస్ ఫైల్‌సిస్టమ్‌ను నిర్దేశిస్తుంటే, మీ టూల్స్ మీతో అబద్ధం చెబుతాయి. అవి హోస్ట్ యొక్క సంఖ్యల విధానాన్ని చూపిస్తాయి.

పరిష్కారం ఏమిటంటే దీనిని రీమౌంట్ చేయడం /proc నేమ్‌స్పేస్ లోపల నుండి:

bash mount -t proc proc /proc ps -o pid,ppid,comm

ఇప్పుడు అది ఇలా చూపించింది:

PID PPID COMMAND 1 0 bash 7 1 ps

అప్పుడే విషయం అర్థమైంది. నేమ్‌స్పేస్ నిజమైన ఐసోలేషన్ అందించింది, కానీ ఫైల్‌సిస్టమ్ వ్యూ మారే వరకు టూల్స్ దానిని చూడలేకపోయాయి. ఐసోలేషన్ మరియు విజబిలిటీ వేర్వేరు విషయాలు.

హోస్ట్‌నేమ్‌ను నియంత్రించే UTS నేమ్‌స్పేస్ అర్థం చేసుకోవడానికి మరింత స్పష్టంగా ఉంది. దీనిని రన్ చేయగా hostname హోస్ట్‌పై ఒక పేరును చూపించింది. కొత్త UTS నేమ్‌స్పేస్ లోపల (దీనితో సృష్టించబడింది sudo unshare --uts bash), దానిని మార్చినప్పుడు వేరే రకంగా కనిపించింది. తిరిగి హోస్ట్‌పై, అది అసలు స్థానానికి చేరుకుంది. ఒకే మిషన్, ఒకే కర్నెల్, మూడు విభిన్న వీక్షణలు.

పార్ట్ 2: ఫైల్‌సిస్టమ్ హ్యాండ్‌ఆఫ్

నేమ్‌స్పేసెస్ తర్వాత, తదుపరి వర్షన్ ప్రాసెస్‌కు దానికి సొంత ఫైల్‌సిస్టమ్‌ను ఇవ్వాల్సి ఉంది: BusyBox మరియు ఒక షెల్‌తో కూడిన rootfs (రూట్ ఫైల్‌సిస్టమ్). చాలా కంటైనర్ తరహాలో.

మొదటి లోపం స్పష్టంగా ఉంది:

exec /bin/sh: no such file or directory

స్క్రిప్ట్ చెప్పిన ప్రదేశంలో షెల్ లేదు. అది సరిచేయబడింది. కానీ ఆ తర్వాత:

./rootfs/bin/busybox: cannot execute: required file not found

ఈ లోపం చాలా దారుణమైనది ఎందుకంటే ఫైల్ సరిగ్గా అక్కడే ఉంది. మీరు దానిని లిస్ట్ చేయవచ్చు. మీరు దానిని చూడవచ్చు. అయినప్పటికీ కర్నెల్ దానిని రన్ చేయడానికి నిరాకరిస్తుంది. దీనిని ఉపయోగించడం వల్ల file కమాండ్ ద్వారా అసలు నిజం బయటపడింది:

ELF 64-bit LSB pie executable, ARM aarch64, dynamically linked, interpreter /lib/ld-musl-aarch64.so.1, stripped

బైనరీ అక్కడే ఉంది. దానికి కావలసిన ఇంటర్‌ప్రిటర్—డైనమిక్ లింకర్—పాత ప్రపంచం నుండి అందుబాటులో లేదు. ఫైల్ లేదు అని Linux చెప్పడం లేదు. "ఇక్కడ నుండి, ఈ ELF కి కావలసిన ఇంటర్‌ప్రిటర్‌ను నేను లోడ్ చేయలేను" అని అది చెబుతోంది.

పరిష్కారం BusyBox ను స్టాటిక్‌గా మార్చడం కాదు. ఇంటర్‌ప్రిటర్ సరైన పాత్‌లో ఉండేలా Alpine ను కొత్త రూట్ ఫైల్‌సిస్టమ్‌గా మార్చడం. కానీ మొదట, ఈ మార్పుకు ఒక వారధి అవసరం—ఫైల్‌సిస్టమ్ స్విచ్‌కు ముందు మరియు స్విచ్ సమయంలో రన్ కాగల ఒక సాధనం. BusyBox రెండు రూపాల్లో వచ్చింది: Alpine లోపలి కోసం డైనమిక్, మరియు హ్యాండ్‌ఆఫ్ కోసం స్టాటిక్:

bash /bin/busybox pivot_root . put_old

సిస్టమ్ పూర్తిగా ప్రపంచాలను మార్చడానికి ముందు దీనిని ఎగ్జిక్యూట్ చేయగల ఏకైక మార్గం స్టాటిక్ BusyBox: pivot_root మునుపు.

Alpine కొత్త రూట్‌గా మారిన తర్వాత, మరిన్ని ఆశ్చర్యాలు ఎదురయ్యాయి. Bash ఇప్పటికీ పాత ఫైల్‌సిస్టమ్ నుండి కమాండ్ పాత్‌లను గుర్తుంచుకుంది. ఇది రన్ చేయడానికి ప్రయత్నించినప్పుడు mount, అది ఈ ప్రదేశంలో వెతికింది /usr/bin/mount ఇప్పుడే తొలగించబడిన ప్రపంచంలో:

bash: /usr/bin/mount: No such file or directory

పరిష్కారం ఏమిటంటే hash -r, ఇది కమాండ్ క్యాచేని క్లియర్ చేస్తుంది. Bash పాత ప్రపంచంలో ఒక నిర్ణయం తీసుకుంది మరియు దానిని వదులుకోలేకపోయింది.

పార్ట్ 3: Mac వల్ల ఎదురైన చిక్కులు

ఈ సెటప్ ఒక సాధారణ Linux ల్యాప్‌టాప్ కాదు. ఇది Apple Silicon Mac → ప్రివిలేజ్డ్ Ubuntu container → macOS నుండి మౌంట్ చేయబడిన repo. దానిర్థం ఎవరికి ఇష్టం ఉన్నా లేకపోయినా virtiofs (వర్చువలైజేషన్ కోసం ఒక ఫైల్‌సిస్టమ్ పాస్‌త్రూ) తో సంబంధం ఉంది.

ఇప్పుడు రూట్ ఫైల్‌సిస్టమ్‌గా ఉన్న Alpine లోపల, సిమ్‌లింక్స్ ద్వారా ఎగ్జిక్యూట్ చేయడం Mac-shared మౌంట్‌పై "Permission denied" తో విఫలం కావచ్చు, అయితే BusyBox ను నేరుగా కాల్ చేయడం పనిచేసింది:

bash ls

sh: ls: Permission denied

/bin/busybox ls

(works)

ఫైళ్లు అక్కడే ఉన్నాయి. ఆ సిమ్‌లింక్స్ ద్వారా ఎగ్జిక్యూట్ చేయడమే విచిత్రమైన భాగం. పరిష్కారం సరళమైనది మరియు సరైనది: rootfs ను కంటైనర్-నేటివ్ పాత్‌కి తరలించి, అక్కడ నుండి ప్రయత్నించండి. Mac-shared మౌంట్‌ను సాధారణ Linux లాగా ప్రవర్తించేలా బలవంతం చేయవద్దు.

పార్ట్ 4: pivot_root స్వంత నిబంధనలను కలిగి ఉంటుంది

అదంతా జరిగిన తర్వాత కూడా, pivot_root స్వయంగా పాఠాలు నేర్పడం పూర్తి చేయలేదు. లోపం:

pivot_root: invalid argument

కొత్త రూట్ ఒక మౌంట్ పాయింట్ అయి ఉండాలి. పాత రూట్ వెళ్లడానికి ఒక ప్రదేశం అవసరం. కాబట్టి విధానం ఇలా ఉంది:

  1. కొత్త రూట్‌ను దానికి దాన్నే బైండ్-మౌంట్ చేయండి
  2. ఒకటి సృష్టించండి oldroot డైరెక్టరీ
  3. కాల్ చేయండి pivot_root(newroot, oldroot)
  4. డైరెక్టరీని కొత్త రూట్‌కి మార్చండి
  5. పాత రూట్‌ను అన్‌మౌంట్ చేయండి

చివరకు అది పనిచేసినప్పుడు, లభించిన ప్రతిఫలం చిన్నదిగా మరియు పరిపూర్ణంగా ఉంది:

bash cat /etc/os-release NAME="Alpine Linux" ID=alpine VERSION_ID=3.24.1

కేవలం ఒక టెక్స్ట్ ఫైల్. కానీ ఇప్పుడు అది కంటైనర్ పనిచేసిందనడానికి నిరూపణ.

ముగింపు

మొదటి నుండి కంటైనర్‌ను నిర్మించడం అనేది ఏ కోర్సూ నేర్పలేనిదాన్ని నేర్పుతుంది: సిద్ధాంతాన్ని తెలుసుకోవడానికి మరియు అది రియల్ టైమ్‌లో విఫలమవ్వడాన్ని చూడటానికి మధ్య ఉన్న వ్యత్యాసం. Namespaces, cgroups మరియు మిగిలినవి నిజమైనవి. అవి డాక్యుమెంట్ చేసినట్లే ఖచ్చితంగా పనిచేస్తాయి. కానీ "నాకు ఇది అర్థమైంది" నుండి "నేను దీనిని పనిచేసేలా చేయగలను" అనే మార్గం ఎర్రర్ మెసేజ్‌లు, Bash క్యాచేలు, ఫైల్‌సిస్టమ్ పర్మిషన్‌లు మరియు ఫైల్‌సిస్టమ్ సరిగ్గా లేకపోతే మీ టూల్స్ మీతో అబద్ధం చెబుతాయనే గ్రహింపు ద్వారా సాగుతుంది.

ప్రయోజనాలు

  • ప్రాక్టికల్‌గా నేర్చుకోవడం అనేది కేవలం చదవడం ఇవ్వలేని అవగాహనను కలిగిస్తుంది
  • నిజమైన లోపాలు డాక్యుమెంటేషన్ తరచుగా వదిలివేసే పరిమితులను నేర్పుతాయి
  • మొదటి నుండి నిర్మించడం అనేది ఆధునిక కంటైనర్ టూల్స్ సంక్లిష్టతను ఎలా దాచిపెడతాయో వెల్లడిస్తుంది
  • Namespaces, ఫైల్‌సిస్టమ్‌లు మరియు ఇంటర్‌ప్రిటర్లను అర్థం చేసుకోవడం Docker మరియు Kubernetes ను తక్కువ రహస్యంగా చేస్తుంది

పరిమితులు

  • నేర్చుకునే క్రమం కష్టతరమైనది మరియు అనేక చిన్న, అయోమయపరిచే లోపాలను కలిగి ఉంటుంది
  • పర్యావరణ కారకాలు (macOS లో virtiofs వంటివి) అంచనా వేయలేని చిక్కులను జోడిస్తాయి
  • Docker ను నేరుగా ఉపయోగించడంతో పోలిస్తే ఈ ప్రక్రియ నెమ్మదిగా ఉంటుంది
  • అనేక ప్రత్యేక సందర్భాలు (Bash hash caching, symlink permissions) డాక్యుమెంటేషన్ నుండి స్పష్టంగా తెలియవు

హెచ్చరిక

ఈ వ్యాసం విద్యాసంబంధమైనది మరియు ప్రాథమిక సూత్రాల నుండి కంటైనర్లను నిర్మించడం ద్వారా నేర్చుకున్న నిజమైన జ్ఞానాన్ని వివరిస్తుంది. చూపబడిన కమాండ్‌లు మరియు భావనలు మూల విషయోత్పత్తికి ఖచ్చితమైనవి. ఇది ప్రొడక్షన్-గ్రేడ్ కంటైనర్ రన్‌టైమ్ కాదు; కంటైనర్లు ఎలా పనిచేస్తాయో అర్థం చేసుకోవడానికి ఇదొక బోధనా సాధనం. ప్రొడక్షన్‌లో ఏదైనా కంటైనర్ సిస్టమ్‌పై ఆధారపడే ముందు, అధికారిక డాక్యుమెంటేషన్ మరియు ఉత్తమ పద్ధతులను సంప్రదించండి. మీ వాతావరణంలో దేనినైనా అమలు చేయడానికి ముందు అసలు మూలానికి వ్యతిరేకంగా అన్ని దావాలను సరిచూసుకోండి.

తరచుగా అడిగే ప్రశ్నలు

  • PID namespace అంటే ఏమిటి మరియు కంటైనర్లలో ఇది ఎందుకు ముఖ్యం?
  • unshare ను కాల్ చేసే ప్రాసెస్ స్వయంచాలకంగా PID 1 ఎందుకు కాదు?
  • /proc ఫైల్‌సిస్టమ్‌కు కంటైనర్లతో సంబంధం ఏమిటి?
  • pivot_root అనేది chroot నుండి ఎలా భిన్నంగా ఉంటుంది?
  • /proc ను రీమౌంట్ చేయడం ps చూపించిన దాన్ని ఎందుకు మార్చింది?
  • కంటైనర్ నిర్మాణంలో BusyBox పాత్ర ఏమిటి?
  • క్రొత్త root ఫైల్‌సిస్టమ్‌కు మారేటప్పుడు dynamic interpreters ఎందుకు ముఖ్యం?
  • macOS లో virtiofs కంటైనర్ సెటప్‌ను ఎలా క్లిష్టతరం చేస్తుంది?

ట్యాగ్‌లు

#containers #linux #docker #devops #namespaces #cgroups #filesystem #learning

Free field guide

API Security Testing Checklist

A practical workflow for testing authentication, authorization, input handling, business logic, and evidence without losing track of scope.