VPS లో Podman vs Docker: ఏది ఎంచుకోవాలి?
Podman లో daemon ఉండదు మరియు ఇది rootless గా పనిచేస్తుంది. VPS లో కంటైనర్లను రన్ చేసేటప్పుడు compose ఫైల్స్, పోర్ట్స్ మరియు వాల్యూమ్ ఓనర్షిప్ విషయంలో వచ్చే మార్పులను తెలుసుకోండి.
Podman మరియు Docker మధ్య ఉన్న అసలు తేడాలు ఏమిటి
Podman మరియు Docker రెండూ ఒకే రకమైన OCI (open container initiative) ఇమేజ్లను VPS పై రన్ చేస్తాయి, కాబట్టి ఏ సాఫ్ట్వేర్ను రన్ చేయగలమనేది ఇక్కడ ప్రశ్న కాదు. వీటి మధ్య ప్రధాన తేడా ప్రాసెస్ మోడల్లో ఉంది. Docker ఒక root daemon ను రన్ చేస్తుంది, ఇది ప్రతి కంటైనర్ను నియంత్రిస్తుంది; docker కమాండ్ అనేది కేవలం ఆ daemon ను పని చేయమని కోరే ఒక చిన్న క్లయింట్ మాత్రమే. Podman కు ఎటువంటి daemon ఉండదు: podman run కంటైనర్ను పిలిచిన ప్రాసెస్ యొక్క child process గా, మీ unprivileged యూజర్ పరిధిలోనే ప్రారంభిస్తుంది.
మిగిలినవన్నీ ఈ ఒక్క అంశంపైనే ఆధారపడి ఉంటాయి. ఆటో-స్టార్ట్ అనేది daemon బాధ్యత కాకుండా systemd బాధ్యత అవుతుంది. వాల్యూమ్ ఓనర్షిప్ (volume ownership) ఒక user namespace ద్వారా జరుగుతుంది, కాబట్టి హోస్ట్ మెషీన్లో ls -l తో మీరు చూసే ఓనర్, కంటైనర్ లోపల కనిపించే ఓనర్ ఒకటే కాదు. మీరు kernel సెట్టింగ్ను మార్చే వరకు 1024 కంటే తక్కువ ఉన్న పోర్ట్లు bind అవ్వడానికి నిరాకరిస్తాయి. docker CLI (command line interface) ఒక wrapper ద్వారా పనిచేస్తూనే ఉంటుంది, కానీ ఏదైనా అప్లికేషన్కు Docker socket అవసరమైనప్పుడు మాత్రం ఇబ్బంది ఎదురవుతుంది.
Daemon లేకపోవడం: మీరు కంటైనర్ను ప్రారంభించినప్పుడు వాస్తవానికి ఏమి రన్ అవుతుంది
Docker హోస్ట్లో, pstree -a కమాండ్ dockerd ను root గా, దాని పక్కన containerd ను, మరియు రన్ అవుతున్న ప్రతి కంటైనర్కు ఒక containerd-shim-runc-v2 ను చూపిస్తుంది. మీ అప్లికేషన్ ఆ shim యొక్క చైల్డ్ ప్రాసెస్, మరియు ఆ shim అనేది PID 1 యొక్క చైల్డ్ ప్రాసెస్. కంటైనర్ను ప్రారంభించిన షెల్కు, కంటైనర్కు మధ్య ఎటువంటి సంబంధం ఉండదు. మీరు daemon ను ఆపివేస్తే, ఆ బాక్స్లోని ప్రతి కంటైనర్ యొక్క కంట్రోల్ ప్లేన్ కోల్పోతారు, మరియు డిఫాల్ట్ live-restore సెట్టింగ్ ఆఫ్ అయి ఉంటే, systemctl restart docker మీ కంటైనర్లను కూడా రీస్టార్ట్ చేస్తుంది.
Podman కు ఇటువంటి ప్రాసెస్ ఏదీ ఉండదు. మీరు ఒక కంటైనర్ను ప్రారంభించినప్పుడు, కంటైనర్ యొక్క ప్రధాన ప్రాసెస్ను కలిగి ఉండే ఒక conmon (కంటైనర్ మానిటర్) ప్రాసెస్ వస్తుంది, ఇది ఆ కమాండ్ను రన్ చేసిన యూజర్ ఆధీనంలో ఉంటుంది.
podman run -d --name web -p 8080:80 docker.io/library/caddy:2
ps -o user,pid,ppid,args -C conmon
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080ps కమాండ్ మీ లాగిన్ యూజర్తో రన్ అవుతున్న conmon ను చూపాలి, root గా కాదు, మరియు curl కమాండ్ 200 ను ప్రింట్ చేయాలి. కంటైనర్ను ఏ కేంద్ర సేవ (central service) నియంత్రించదు కాబట్టి, sudo apt upgrade podman ఇప్పటికే రన్ అవుతున్న వాటిని ఏవీ ఆపదు, మరియు ఒక కంటైనర్ మానిటర్ క్రాష్ అయితే అది మిగిలిన వాటిని ప్రభావితం చేయదు.
Daemon లేకపోవడం వల్ల కొన్ని పరిమితులు కూడా ఉన్నాయి. రీబూట్ తర్వాత మీ కంటైనర్లను ప్రారంభించడానికి ఏదీ ఉండదు. Docker యొక్క --restart=always అనేది బూట్ సమయంలో daemon ఇచ్చే హామీ, Podman దీనిని systemd తో భర్తీ చేస్తుంది, దీని కోసమే కింద ఉన్న quadlet విభాగం.
Socket అనేది ఈ కథలో మరో ముఖ్యమైన భాగం. /var/run/docker.sock అనేది root ఆధీనంలో ఉండే ఒక API (application programming interface) ఎండ్పాయింట్, దీనికి రాయగల ఏ ప్రాసెస్ అయినా హోస్ట్ ఫైల్సిస్టమ్ను మౌంట్ చేసే ప్రివిలేజ్డ్ కంటైనర్ను ప్రారంభించగలదు. ఒక యూజర్ను docker గ్రూప్లో చేర్చడం అంటే, ఆ యూజర్కు పరోక్షంగా root యాక్సెస్ ఇవ్వడమే, దీని గురించి ప్రతి సర్వీస్ అకౌంట్కు అవసరమైన యాక్సెస్ మాత్రమే ఇవ్వడం విభాగంలో చదవడం మంచిది. మీరు కోరితే తప్ప Podman ఎటువంటి socket ను ఎక్స్పోజ్ చేయదు, మరియు మీకు లభించే socket ఒకే యూజర్కు చెందినదిగా /run/user/<uid>/podman/podman.sock వద్ద ఉంటుంది.
Ubuntu 24.04లో Podman ఇన్స్టాల్ చేయడం మరియు rootless మోడ్ పనితీరును నిర్ధారించడం
sudo apt update
sudo apt install -y podman uidmap
podman --version
podman info | grep -i rootlessuidmap ప్యాకేజీ newuidmap మరియు newgidmap లను అందిస్తుంది. ఇవి setuid సహాయక ప్రోగ్రామ్లు; సాధారణ వినియోగదారుడు సబ్-ఆర్డినేట్ IDల పరిధిని పొందేందుకు ఇవి అవసరం. ఇవి లేకపోతే rootless కంటైనర్లు ప్రారంభం కావు. podman info కమాండ్ rootless: true ను అవుట్పుట్గా చూపాలి.
ఆగస్టు 2026 నాటికి, Ubuntu 24.04 లో Podman 4.9 మరియు Debian 13 లో Podman 5.x వెర్షన్లు అందుబాటులో ఉన్నాయి. ఈ వెర్షన్ల మధ్య వ్యత్యాసం ముఖ్యమైనది, ఎందుకంటే quadlet ఫైళ్లకు 4.4 లేదా అంతకంటే కొత్త వెర్షన్ అవసరం, మరియు .pod quadlet ఫైళ్లకు 5.0 వెర్షన్ తప్పనిసరి. అప్స్ట్రీమ్ డాక్యుమెంటేషన్ నుండి ఏదైనా ఉదాహరణను కాపీ చేసే ముందు podman --version కమాండ్ను రన్ చేయండి.
ప్రతి rootless వినియోగదారునికి ఒక సబ్-ఆర్డినేట్ ID పరిధి అవసరం:
grep "$USER" /etc/subuid /etc/subgidUbuntuలో adduser ద్వారా సృష్టించబడిన వినియోగదారునికి ఈ పరిధి స్వయంచాలకంగా లభిస్తుంది. useradd -M ద్వారా లేదా ఇతర కాన్ఫిగరేషన్ టూల్స్ ద్వారా సృష్టించిన వినియోగదారులకు ఇది తరచుగా లభించదు, అప్పుడు ఈ క్రింది విధంగా లోపం వస్తుంది:
Error: cannot find UID/GID for user deploy: no subuid ranges found for user "deploy" in /etc/subuid - check rootless mode in man pages.ఒక పరిధిని కేటాయించి, ఆపై ఆ వినియోగదారుని స్టోరేజ్ను రీసెట్ చేయండి, తద్వారా కొత్త మ్యాపింగ్ ఉపయోగించబడుతుంది:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 deploy
podman system migrateమొదటిసారి రన్ చేసినప్పుడు ఎదురయ్యే మరో ఆశ్చర్యం: Podman డిఫాల్ట్గా Docker Hubను పరిగణనలోకి తీసుకోదు. చిన్న ఇమేజ్ పేరును /etc/containers/registries.conf లోని unqualified-search-registries ద్వారా రిజాల్వ్ చేస్తుంది. టెర్మినల్ లేని స్క్రిప్ట్లో ఇమేజ్ పుల్ చేసినప్పుడు short-name resolution enforced but cannot prompt without a TTY లోపం కారణంగా అది విఫలమవుతుంది. కాబట్టి ప్రతిసారీ పూర్తి పేరును రాయండి. nginx కి బదులుగా docker.io/library/nginx:1.27 ను ఉపయోగించండి.
అద్దె సర్వర్లో rootless containers మీకు నిజంగా ఏమి అందిస్తాయి
Rootless container అనేది user namespace లోపల నడుస్తుంది. ఇది ఒక kernel ఫీచర్, ఇది ఒక ప్రాసెస్కు దాని స్వంత user IDల మ్యాప్ను ఇస్తుంది. ఈ namespace లోపల, కంటైనర్ యొక్క superuser అనేది UID (user ID) 0. కానీ బయట, మీ VPS పైన, అదే ప్రాసెస్ మీ సాధారణ లాగిన్ యూజర్గా ఉంటుంది. కంటైనర్లోని root, హోస్ట్ మెషీన్పై root కాదు.
ఇదే దీని వల్ల కలిగే అసలైన ప్రయోజనం. root గానే రన్ అవ్వాలని పట్టుబట్టే ఇమేజ్, remote code execution బగ్ ఉన్న వెబ్ అప్లికేషన్, లేదా బయట UID 0 గా ఉండటంపై ఆధారపడే escape - ఇవన్నీ మెషీన్ యొక్క పూర్తి అనుమతులను కాకుండా, మీ unprivileged యూజర్ యొక్క అనుమతులను మాత్రమే పొందుతాయి. Rootless వల్ల kernel బగ్స్ నుండి రక్షణ లభించదు, అలాగే మీ స్వంత ఫైళ్లకు కూడా రక్షణ ఉండదు, ఎందుకంటే బయటపడిన ప్రాసెస్ మీ యూజర్ ఐడితోనే నడుస్తుంది కాబట్టి, మీరు చదవగలిగే దేనినైనా అది చదవగలదు. UID మ్యాపింగ్ కంటే యూనిట్ ఐసోలేషన్ ముఖ్యం. ఇది ఒక FreeBSD jail, ఇది మీరు చిన్న మెషీన్లా నిర్వహించే పూర్తి userland ను కలిగి ఉంటుంది అనే దానిలో స్పష్టంగా కనిపిస్తుంది, ఇది రిజిస్ట్రీ నుండి డౌన్లోడ్ చేసిన లేయర్డ్ ఇమేజ్ కంటే భిన్నమైనది.
Docker కూడా rootless గా రన్ అవ్వగలదు. dockerd-rootless-setuptool.sh install ప్రతి యూజర్కు ఒక daemon ను సెటప్ చేస్తుంది మరియు ఇది బాగా పనిచేస్తుంది. తేడా ఏమిటంటే డిఫాల్ట్ సెట్టింగ్ దేనిని సూచిస్తుంది అనేది. Podman లో మీరు అడగకుండానే rootless లభిస్తుంది, కాబట్టి మీ మొదటి వైఫల్యం పోర్ట్ 80ని bind చేయలేని కంటైనర్ అవుతుంది, అంతే కానీ రెండేళ్లుగా నిశ్శబ్దంగా root గా నడుస్తున్న సర్వీస్ కాదు.
నా వాల్యూమ్ ఫైళ్లు UID 100999 కి ఎందుకు చెందుతున్నాయి?
అదే user namespace కారణం. కంటైనర్ లోని UID 0 మీ హోస్ట్ UID కి మ్యాప్ అవుతుంది. కంటైనర్ లోని UID 1 మీ subuid పరిధిలోని మొదటి ID కి మ్యాప్ అవుతుంది, అక్కడి నుండి సంఖ్యలు పెరుగుతూ వెళ్తాయి. 100000 తో మొదలయ్యే పరిధిలో, కంటైనర్ లోని UID 1000 హోస్ట్ పై 100999 గా మారుతుంది.
mkdir -p "$PWD/data"
podman run --rm --user 1000 -v "$PWD/data:/data" docker.io/library/alpine:3 sh -c 'id -u; touch /data/f'
ls -ln "$PWD/data"కంటైనర్ 1000 అని ప్రింట్ చేస్తుంది. హోస్ట్ లిస్టింగ్ 100999 అని యజమానిని చూపిస్తుంది, ఎందుకంటే 100000 ప్లస్ 1000 మైనస్ 1 అంటే 100999. ఏదీ పాడవలేదు, మరియు సాధారణ chown కమాండ్ దీనిని సరిచేయదు, ఎందుకంటే మీ unprivileged యూజర్ namespace వెలుపల ఫైల్ యాజమాన్యాన్ని మార్చలేరు.
దీని నుండి బయటపడటానికి నాలుగు మార్గాలు ఉన్నాయి:
podman unshare chown 1000:1000 "$PWD/data"కమాండ్ ను అదే user namespace లోపల రన్ చేయండి, అక్కడ ఆ సంఖ్యలు కంటైనర్ కు అర్థమయ్యే విధంగా ఉంటాయి.-v "$PWD/data:/data:U"కమాండ్ Podman ను ఉపయోగించి సోర్స్ డైరెక్టరీ యాజమాన్యాన్ని మీ కోసం సరిచేయమని అడుగుతుంది. దీనిని కొత్త డైరెక్టరీలపై మాత్రమే వాడండి, మీకు ముఖ్యమైన డేటాపై కాదు.--userns=keep-idమీ హోస్ట్ UID ని కంటైనర్ లోని అదే UID కి మ్యాప్ చేస్తుంది, తద్వారా కొత్త ఫైళ్లు మీకు చెందినవిగా ఉంటాయి.-v appdata:/dataవంటి named volume ఈ సమస్యను నివారిస్తుంది, ఎందుకంటే Podman దానిని మీ స్వంత స్టోరేజ్ లోనే సరైన యాజమాన్యంతో సృష్టిస్తుంది.
మీరు Docker లో ఈ సమస్యను ఎదుర్కొని ఉంటే, ఇది అదే సమస్యకు ఒక మెట్టు పైన ఉన్న వెర్షన్. అనేక ఇమేజ్లు అందించే PUID మరియు PGID వేరియబుల్స్ కంటైనర్ లోపల ప్రాసెస్ ఉపయోగించే UID ని సెట్ చేస్తాయి, మరియు rootless Podman లో ఆ UID రెండవసారి మ్యాప్ చేయబడుతుంది. rootless కంటైనర్ లోపల PUID=1000 ఇప్పటికీ 100999 యాజమాన్యంతోనే హోస్ట్ ఫైళ్లను రాస్తుంది. ఆ రెండవ మ్యాపింగ్ ను దృష్టిలో ఉంచుకుని సంఖ్యలను ఎంచుకోండి, లేదా డేటాను named volume లోకి తరలించి ఈ సమస్య గురించి ఆలోచించడం మానేయండి.
మౌంట్ల గురించి మరో రెండు గమనికలు. Fedora మరియు RHEL ఉదాహరణలలో మీరు చూసే :z మరియు :Z ఫ్లాగ్లు SELinux relabel ఆప్షన్లు, కాబట్టి అవి Ubuntu లో ఏమీ చేయవు. Rootless Podman మీ యూజర్ చదవలేని హోస్ట్ డైరెక్టరీని మౌంట్ చేయలేదు, ఇది లోపం కాదు, భద్రతా పరమైన ఉద్దేశ్యం.
rootless Podman ఎందుకు 80 పోర్టును పబ్లిష్ చేయడానికి నిరాకరిస్తుంది?
1024 కంటే తక్కువ ఉన్న పోర్టును బైండ్ చేయడానికి మీ యూజర్కు లేని ప్రత్యేక అధికారాలు అవసరం. ఈ ఎర్రర్ మెసేజ్ పరిష్కారాన్ని సూచిస్తుంది:
Error: rootlessport cannot expose privileged port 80, you can add 'net.ipv4.ip_unprivileged_port_start=80' to /etc/sysctl.conf (currently 1024), or choose a larger port number (>= 1024): listen tcp 0.0.0.0:80: bind: permission deniedదీనికి రెండు పరిష్కారాలు ఉన్నాయి. హోస్ట్ మొత్తానికి ఈ పరిమితిని తగ్గించడం మొదటిది:
echo 'net.ipv4.ip_unprivileged_port_start=80' | sudo tee /etc/sysctl.d/99-podman.conf
sudo sysctl --system
sysctl net.ipv4.ip_unprivileged_port_startచివరి కమాండ్ అవుట్పుట్గా 80 అని చూపాలి. ఈ సెట్టింగ్ ఏమి చేస్తుందో స్పష్టంగా తెలుసుకోండి: ఇప్పుడు మెషీన్లోని ప్రతి యూజర్ 80 మరియు 443 పోర్టులను బైండ్ చేయగలరు, కేవలం కంటైనర్లను రన్ చేసే యూజర్ మాత్రమే కాదు. ఒకే అడ్మిన్ ఉన్న VPSలో ఇది ఆమోదయోగ్యమైన మార్పు. కానీ ఇతరుల అకౌంట్లు కూడా ఉన్న సర్వర్లో ఇది సరైనది కాదు. మరొక పరిష్కారం ఏమిటంటే, 8080 పోర్టుపై పబ్లిష్ చేసి, ముందు ఒక రివర్స్ ప్రాక్సీని ఉంచడం. ఇక్కడే మీరు certbot ద్వారా nginxలో సర్టిఫికేట్లను జారీ చేయడం మరియు రెన్యూ చేయడం వంటివి చేయవచ్చు.
Rootless పబ్లిషింగ్ మీ అప్లికేషన్ చూసే విధానాన్ని కూడా మారుస్తుంది. Podman 4.x డిఫాల్ట్గా rootlesskit పోర్ట్ హ్యాండ్లర్తో slirp4netnsని ఉపయోగిస్తుంది. దీనివల్ల ఫార్వర్డ్ చేయబడిన కనెక్షన్లు రీరైట్ చేయబడిన సోర్స్ అడ్రస్తో వస్తాయి, కాబట్టి యాక్సెస్ లాగ్లో ప్రతి విజిటర్ 10.0.2.100గా కనిపిస్తారు. Podman 5.0 డిఫాల్ట్ను pastaకి మార్చింది, ఇది అసలైన క్లయింట్ అడ్రస్ను అలాగే ఉంచుతుంది. 4.x వెర్షన్లో, --network slirp4netns:port_handler=slirp4netnsని ఉపయోగించడం ద్వారా కొంత throughput తగ్గినప్పటికీ, అసలైన సోర్స్ అడ్రస్ను తిరిగి పొందవచ్చు.
ఇక్కడ ఒక మంచి విషయం ఉంది. Rootless పబ్లిష్ చేసిన పోర్ట్ అనేది ఒక సాధారణ ప్రాసెస్ యాజమాన్యంలోని listening socket, కాబట్టి మీ ఫైర్వాల్ ఇన్పుట్ రూల్స్ దీనికి వర్తిస్తాయి. Docker పోర్టులను పబ్లిష్ చేసేటప్పుడు NAT (network address translation) రూల్స్ను మరియు దాని స్వంత ఫార్వర్డింగ్ యాక్సెప్ట్లను రాస్తుంది. అందుకే పబ్లిష్ చేసిన Docker పోర్ట్, మీరు బ్లాక్ చేయాలనుకున్న ufw రూల్ను పట్టించుకోదు. Rootful Podman కూడా ఇలాంటి పద్ధతినే ఉపయోగిస్తుంది మరియు అదే సమస్యను కలిగి ఉంటుంది. కానీ Rootless అలా కాదు.
నా Docker Compose ఫైళ్లు Podman కింద పనిచేస్తాయా?
చాలా వరకు పనిచేస్తాయి, దీనికి రెండు మార్గాలు ఉన్నాయి. మొదటిది podman-compose, ఇది అదే ఫైల్ను చదివి Podman CLIని నడిపించే ఒక ప్రత్యేక అమలు:
sudo apt install -y podman-compose
podman-compose up -d
podman psరెండవది, అసలైన Docker Compose, ఇది ప్రతి-వినియోగదారు (per-user) సాకెట్ ద్వారా Podman యొక్క Docker-అనుకూల APIతో మాట్లాడుతుంది:
systemctl --user enable --now podman.socket
export DOCKER_HOST="unix:///run/user/$(id -u)/podman/podman.sock"
docker compose up -d
podman psdocker compose ps మరియు podman ps రెండూ ఒకే కంటైనర్ల జాబితాను చూపాలి, ఎందుకంటే అక్కడ ఉండేది ఒకే సెట్ కంటైనర్లు. పేరు రిజల్యూషన్ కూడా పనిచేస్తుంది: Podman యొక్క డిఫాల్ట్ నెట్వర్క్ బ్యాకెండ్, netavark, aardvark-dnsని నడుపుతుంది, కాబట్టి వినియోగదారు నిర్వచించిన నెట్వర్క్లోని కంటైనర్లు ఒకదానికొకటి పేరు ద్వారా కనుగొనగలవు.
కొన్ని పరిమితులు ఉన్నాయి. /var/run/docker.sockని మౌంట్ చేసే ఏదైనా సరే Podman సాకెట్కు పాయింట్ చేయాలి లేదా తొలగించాలి. network_mode: host వినియోగదారు నేమ్స్పేస్ (user namespace) కింద భిన్నంగా ప్రవర్తిస్తుంది. condition: service_healthyతో కూడిన depends_onకి podman-compose వెర్షన్లలో పూర్తి మద్దతు లేదు. restart: always రీబూట్ తర్వాత స్వయంచాలకంగా ఉండదు, దీనిని తదుపరి విభాగంలో పరిష్కరిస్తాము. ఒకే ఫైల్లో మల్టీ-కంటైనర్ స్టాక్ను వివరించడానికి Compose ఇప్పటికీ మంచి మార్గం, మరియు Podman కింద ఇది ఒక అనువాద పొర (translation layer) వలె పనిచేస్తుంది. మీరు సంవత్సరాల తరబడి ఉంచాలనుకునే స్టాక్ కోసం, దానిని quadlets కి మార్చుకుని, రెండు అబ్స్ట్రాక్షన్లకు బదులుగా ఒకదానినే నిర్వహించండి.
Pods: Docker వద్ద సమాధానం లేని భావన
Pod అనేది ఒకే network namespace ను పంచుకునే container ల సమూహం. ఆ namespace ను తెరిచి ఉంచడానికి Podman ఒక చిన్న infra container ను ప్రారంభిస్తుంది. ఆ తర్వాత, సభ్యులు ఎటువంటి user-defined network లేదా service discovery అవసరం లేకుండానే 127.0.0.1 ద్వారా ఒకదానికొకటి కనెక్ట్ అవుతాయి.
podman pod create --name app -p 8080:80
podman run -d --pod app --name app-cache docker.io/library/redis:7
podman run -d --pod app --name app-web docker.io/library/nginx:1.27
podman pod ps
podman ps --podpodman pod ps కమాండ్, infra container తో కలిపి మొత్తం మూడు container లు ఉన్న pod Running ను చూపాలి. ఇప్పుడు web container, Redis ను app-cache:6379 వద్ద కాకుండా 127.0.0.1:6379 వద్ద చేరుకుంటుంది. భాగస్వామ్య namespace వల్ల రెండు నియమాలు వర్తిస్తాయి: ports ను pod స్థాయిలోనే publish చేయాలి, సభ్యుల స్థాయిలో కాదు; మరియు ఏ ఇద్దరు సభ్యులు ఒకే port పై వినకూడదు (listen).
ఇది Kubernetes మోడల్, Podman దీనినే అనుసరిస్తుంది. podman kube generate app > app.yaml ప్రస్తుతం నడుస్తున్న వాటి నుండి Kubernetes manifest ను రాస్తుంది (పాత ప్యాకేజీలలో దీనిని podman generate kube అని పిలుస్తారు), మరియు podman kube play app.yaml దానిని మరొక host పై తిరిగి సృష్టిస్తుంది. Quadlet లో .kube అనే unit రకం ఉంది, ఇది అటువంటి ఫైల్ను systemd service గా నడుపుతుంది. ఇది సేవలను సమూహపరచడానికి ఒక విభిన్నమైన మార్గం. మీ భవిష్యత్తులో ఎక్కడైనా Kubernetes వాడాల్సి వస్తే, Podman ను ఎంచుకోవడానికి ఇదే అత్యంత బలమైన కారణం.
Daemon లేకుండా ఆటో-స్టార్ట్: quadlet యూనిట్లు
Quadlet అనేది ఒక systemd జనరేటర్. ఇది కంటైనర్ను వివరించే చిన్న ఫైల్ను బూట్ సమయంలో నిజమైన systemd సర్వీస్గా మారుస్తుంది. రూట్లెస్ (rootless) యూజర్ కోసం ఫైల్లను ~/.config/containers/systemd/ లో, లేదా రూట్ కోసం /etc/containers/systemd/ లో ఉంచాలి.
~/.config/containers/systemd/caddy.container:
[Unit]
Description=Caddy web server
After=network-online.target
[Container]
Image=docker.io/library/caddy:2
ContainerName=caddy
PublishPort=8080:80
Volume=caddy-data.volume:/data
Environment=TZ=UTC
AutoUpdate=registry
[Service]
Restart=always
MemoryMax=512M
[Install]
WantedBy=default.target~/.config/containers/systemd/caddy-data.volume దాదాపు ఖాళీగా ఉండవచ్చు, ఎందుకంటే సెక్షన్ హెడర్ వాల్యూమ్ను సృష్టిస్తుంది:
[Volume]systemctl --user daemon-reload
systemctl --user start caddy
systemctl --user status caddy
journalctl --user -u caddy -n 50సర్వీస్ పేరు ఫైల్నేమ్ నుండి వస్తుంది: caddy.container అనేది caddy.service గా మారుతుంది. systemctl --user enable caddy ని రన్ చేయవద్దు. జనరేట్ అయిన యూనిట్లను ఎనేబుల్ చేయలేము, మరియు systemd Failed to enable unit: Unit /run/user/1000/systemd/generator/caddy.service is transient or generated. అని సమాధానం ఇస్తుంది. [Install] సెక్షన్ బూట్ సమయంలో కంటైనర్ను ప్రారంభిస్తుంది, మరియు మీరు ఫైల్ను ఎడిట్ చేసిన తర్వాత యూనిట్ను మళ్లీ జనరేట్ చేయడానికి daemon-reload ఉపయోగపడుతుంది.
ఇప్పుడు అందరినీ ఇబ్బంది పెట్టే సెట్టింగ్ ఇక్కడ ఉంది:
sudo loginctl enable-linger deploy
loginctl show-user deploy --property=LingerLinger=yes ని ఆశించండి. Linger లేకపోతే, మీ చివరి SSH కనెక్షన్ క్లోజ్ అయినప్పుడు systemd మొత్తం యూజర్ సెషన్ను తొలగిస్తుంది, కాబట్టి ప్రతి రూట్లెస్ కంటైనర్ దానితో పాటు ఆగిపోతుంది మరియు బూట్ సమయంలో ఏవీ తిరిగి రావు. మీరు లాగ్ అవుట్ అయినప్పుడు మాయమయ్యే కంటైనర్లు ఎప్పుడూ దీని వల్లే జరుగుతాయి.
కంటైనర్ అనేది సాధారణ సర్వీస్ యూనిట్ యొక్క ప్రధాన ప్రాసెస్ కాబట్టి, systemd యొక్క సొంత కంట్రోల్స్ నేరుగా వర్తిస్తాయి. [Service] సెక్షన్లోని MemoryMax= మరియు CPUQuota=, systemd తో మీరు నియంత్రించే ఇతర సర్వీసుల మాదిరిగానే పనిచేస్తాయి. దీనికి cgroup v2 (కంట్రోల్ గ్రూప్ వెర్షన్ 2) అవసరం, ఇది Ubuntu లో 22.04 నుండి డిఫాల్ట్గా ఉంది. podman info | grep -i cgroup తో దీన్ని నిర్ధారించుకోండి.
అప్డేట్ల కోసం ఒక సరిపోలే మెకానిజం ఉంది. AutoUpdate=registry మరియు systemctl --user enable --now podman-auto-update.timer కలిపి, అదే ట్యాగ్పై కొత్త ఇమేజ్ కోసం రిజిస్ట్రీని తనిఖీ చేస్తాయి, యూనిట్ను రీస్టార్ట్ చేస్తాయి, మరియు కొత్త కంటైనర్ ప్రారంభం కాకపోతే మునుపటి ఇమేజ్కు రోల్ బ్యాక్ చేస్తాయి. ఇది ఏమి మారుస్తుందో చూడటానికి ముందుగా podman auto-update --dry-run ని రన్ చేయండి. పాత podman generate systemd కమాండ్ ఇప్పటికీ ఉంది కానీ అది నిలిపివేయబడింది (deprecated), కాబట్టి కొత్తగా దేనినైనా చేసేటప్పుడు quadlets నే రాయండి.
Docker alias ఎక్కడ పనిచేస్తుంది, ఎక్కడ పనిచేయదు
sudo apt install -y podman-docker
sudo touch /etc/containers/nodocker
docker pspodman-docker ఒక /usr/bin/docker wrapper ను ఇన్స్టాల్ చేస్తుంది, ఇది Podman ను పిలుస్తుంది. nodocker ఫైల్ లేకపోతే, ప్రతి కాల్ మొదట Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg. అని ప్రింట్ చేస్తుంది. ఈ wrapper మీరు రోజూ వాడే కమాండ్లను కవర్ చేస్తుంది: run, ps, logs, exec, build, pull, push, inspect, cp, volume, network.
ఏవి పనిచేయవో వాటి జాబితా చిన్నది, కానీ ముఖ్యమైనది. Swarm mode కు సమానమైన ఫీచర్ లేదు, కాబట్టి Swarm stack ఎక్కడా అమలు కాదు. Docker socket తో మాట్లాడే టూల్స్ కోసం Podman socket ను ఎగుమతి (export) చేయాలి, కొన్ని టూల్స్ ఇప్పటికీ తేడాను గుర్తిస్తాయి; Traefik యొక్క Docker provider ను /run/user/<uid>/podman/podman.sock కి పాయింట్ చేసినప్పుడు పనిచేస్తుంది, కానీ Watchtower కు ఇక్కడ స్థానం లేదు, ఎందుకంటే podman auto-update ఆ పనిని చేస్తుంది. స్టోరేజ్ వేరుగా ఉంటుంది, కాబట్టి Docker తో మీరు ఇప్పటికే డౌన్లోడ్ చేసిన images ను Podman చూడలేదు, మరియు బిజీగా ఉన్న Docker host పై podman images ఖాళీగా మొదలవుతుంది.
నడుస్తున్న stackను దశలవారీగా తరలించడం
- కంటైనర్లను నిర్వహించే unprivileged userను సృష్టించండి లేదా ఎంచుకోండి, మరియు దానికి
/etc/subuidలో పరిధి (range) ఉందని నిర్ధారించుకోండి. - Registry నుంచి వచ్చిన వాటిని పూర్తిగా అర్హత కలిగిన పేర్లతో (fully qualified names) మళ్ళీ pull చేయండి. Podmanకు సొంత image store ఉంటుంది, అది Docker యొక్క storeను చదవదు.
- స్థానికంగా build చేసిన imagesను
docker save app:1.4 | podman loadఉపయోగించి తరలించండి. - Docker కంటైనర్ను ఆపి,
/var/lib/docker/volumes/<name>/_dataనుంచి ప్రతి volume యొక్క కంటెంట్ను కాపీ చేయండి, ఆపైpodman unshare chown -R 1000:1000 <path>ఉపయోగించి ownershipను సరిచేయండి. - Port సమస్యను పరిష్కరించండి: reverse proxy వెనుక 1024 పైన portను publish చేయండి, లేదా
net.ipv4.ip_unprivileged_port_startను సెట్ చేయండి. - ప్రతి కంటైనర్కు ఒక quadlet ఫైల్ను రాయండి,
systemctl --user daemon-reloadను రన్ చేయండి, మరియు ప్రతి సేవను ప్రారంభించండి. sudo loginctl enable-linger <user>ను రన్ చేయండి, VPSను రీబూట్ చేయండి, తిరిగి లాగిన్ అయ్యిpodman psప్రతి సేవను మళ్ళీ జాబితా చేస్తుందో లేదో తనిఖీ చేయండి.
ఈ రెండు ఇంజిన్లు దేనినీ పంచుకోవు: వేర్వేరు image storage మరియు వేర్వేరు నెట్వర్క్లు ఉంటాయి. కాబట్టి మీరు మైగ్రేషన్ చేస్తున్నప్పుడు రెండింటినీ ఒకేసారి నడపవచ్చు, కేవలం host port నంబర్ విషయంలో మాత్రమే ఘర్షణ వచ్చే అవకాశం ఉంటుంది. ఒక సేవను తరలించి, ఒక రోజు దానిని గమనించండి, ఆపై తదుపరి దానిని తరలించండి.
Podman vs Docker: మీ VPSలో దేనిని ఉపయోగించాలి?
మీ stack ఇతర వ్యక్తులు కూడా నిర్వహించే compose files పై ఆధారపడి ఉంటే, లేదా Docker socket తో అనుసంధానమయ్యే సాధనాలపై మీరు ఆధారపడితే Docker నే కొనసాగించండి. ఇతరులు రాసే కోడ్తో అనుకూలత అనేది ఒక ముఖ్యమైన ఫీచర్, మరియు Docker లో ఇది ఎక్కువగా ఉంటుంది. టీమ్లోని అందరి ల్యాప్టాప్లలో Docker ఉన్నప్పుడు, ప్రొడక్షన్లో కూడా అదే ఇంజిన్ను వాడటం వల్ల స్పష్టమైన ప్రయోజనం ఉంటుంది.
మీరు పూర్తిగా నియంత్రించే కొన్ని సేవలు మాత్రమే VPSలో ఉంటే, లేదా ప్రతి అప్లికేషన్ను ఎటువంటి docker గ్రూప్ లేకుండా, ప్రత్యేకమైన unprivileged యూజర్ కింద నడపాలనుకుంటే Podman కి మారండి. డిస్ట్రిబ్యూషన్ అనుకూలత కూడా ముఖ్యమే: RHEL మరియు దాని ఆధారిత సిస్టమ్స్లో Podman అధికారికంగా మద్దతు ఇచ్చే ఇంజిన్గా వస్తుంది, కాబట్టి ఆ సిస్టమ్స్లో Podman వాడటం వల్ల సమస్యలు తక్కువగా ఉంటాయి. ఒకవేళ మీరు ఆ హోస్ట్లలో Docker నే వాడాలనుకుంటే, Rocky Linux మరియు AlmaLinux లో dnf ద్వారా ఇన్స్టాలేషన్ ప్రక్రియ, ఇప్పటికే docker కమాండ్ను కలిగి ఉన్న podman-docker wrapper ను తొలగించడంతో మొదలవుతుంది. మీరు ఇప్పటికే మిగిలిన వాటన్నింటినీ systemd units తో పర్యవేక్షిస్తుంటే, quadlets మీకు కొత్త సాధనంలా కాకుండా, లోపించిన ఒక భాగం దొరికినట్లు అనిపిస్తుంది.
మధ్యస్థమైన ఒక మార్గం గురించి కూడా తెలుసుకోవాలి. Rootful Podman దాదాపు Docker లాగే పనిచేస్తుంది, wrapper ద్వారా docker కమాండ్ను అలాగే ఉంచుతుంది, మరియు నిరంతరం నడిచే daemon ను తొలగిస్తుంది. అయితే ఇది rootless ఫీచర్ను వదులుకుంటుంది, ఇది మీ భద్రతా స్థితిని మార్చే ప్రధాన అంశం, కాబట్టి దీన్ని ఒక తాత్కాలిక మార్గంగా మాత్రమే చూడండి.
మీరు ఇంకా మీ మొదటి కంటైనర్ హోస్ట్ను నిర్మిస్తుంటే, కొత్త VPSలో Docker సెటప్ మరియు హార్డెనింగ్ మార్గం సులభమైనది, మరియు ఆ పరిజ్ఞానం ఎప్పటికీ వృథా కాదు. రెండు ఇంజిన్లలో images మరియు volumes ఒకేలా ఉంటాయి, కాబట్టి భవిష్యత్తులో మారినా మీ సేవల పర్యవేక్షణ విధానం మారుతుందే తప్ప, మిగిలినవి పెద్దగా మారవు.
FAQ
Podman అనేది Docker కు పూర్తి ప్రత్యామ్నాయమా?
మీరు టైప్ చేసే కమాండ్ల పరంగా చూస్తే, ఇది దాదాపు సమానంగా ఉంటుంది. podman-docker ని ఇన్స్టాల్ చేయడం ద్వారా మీకు /usr/bin/docker అనే wrapper లభిస్తుంది, మరియు run, ps, build, logs, exec అన్నీ ఒకే విధంగా పనిచేస్తాయి. అయితే ఇది daemon కు పూర్తి ప్రత్యామ్నాయం కాదు. Swarm కు దీనిలో సమానమైన ఫీచర్ లేదు, /var/run/docker.sock కి కనెక్ట్ అయ్యే టూల్స్ అన్నీ ప్రతి యూజర్కు ఉండే Podman socket కి మళ్లించబడాలి, మరియు Docker ద్వారా డౌన్లోడ్ చేసిన images Podman కు కనిపించవు ఎందుకంటే ఈ రెండూ వేర్వేరు స్టోరేజ్ను ఉపయోగిస్తాయి.
నేను SSH నుంచి లాగ్ అవుట్ అయినప్పుడు నా rootless Podman కంటైనర్లు ఎందుకు ఆగిపోతున్నాయి?
మీరు లాగ్ అవుట్ అయినప్పుడు, మీ చివరి సెషన్ ముగియడంతో పాటు systemd ఆ యూజర్ సెషన్ను మరియు దానికి సంబంధించిన అన్ని సర్వీసులను ఆపివేస్తుంది. sudo loginctl enable-linger <user> ని రన్ చేయండి, ఆపై loginctl show-user <user> --property=Linger కమాండ్ Linger=yes అని చూపిస్తుందో లేదో తనిఖీ చేయండి. Linger ఆప్షన్ వల్ల యాక్టివ్ సెషన్ లేకపోయినా యూజర్ యొక్క systemd ఇన్స్టాన్స్ రన్ అవుతూనే ఉంటుంది, దీనివల్ల రీబూట్ తర్వాత కూడా కంటైనర్లు ఆటోమేటిక్గా ప్రారంభమవుతాయి.
నా వాల్యూమ్లోని ఫైల్స్ UID 100999 కి ఎందుకు చెందుతున్నాయి?
Rootless Podman కంటైనర్లోని UID 0 ని మీ హోస్ట్ యూజర్కు మ్యాప్ చేస్తుంది, ఆపై కంటైనర్లోని UID 1 మరియు అంతకంటే ఎక్కువ ఉన్నవాటిని మీ subuid పరిధిలోకి మ్యాప్ చేస్తుంది. ఈ పరిధి 100000 తో మొదలైతే, కంటైనర్లోని UID 1000 అనేది హోస్ట్ మీద 100999 గా మారుతుంది. దీన్ని సరిచేయడానికి నేమ్స్పేస్ లోపల నుంచి podman unshare chown 1000:1000 /path/to/data ఉపయోగించండి, మొదటిసారి రన్ చేసేటప్పుడు :U ఫ్లాగ్తో మౌంట్ చేయండి, లేదా కంటైనర్ UIDలు మీ సొంత UIDతో సరిపోలడానికి --userns=keep-id ని ఉపయోగించండి.
నేను Podman తో docker-compose.yml ని ఉపయోగించవచ్చా?
అవును, రెండు పద్ధతుల్లో చేయవచ్చు. podman-compose ఆ ఫైల్ను చదివి నేరుగా Podman CLI ని నడుపుతుంది. లేదా systemctl --user enable --now podman.socket తో compatibility socket ని ఎనేబుల్ చేసి, DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock ని సెట్ చేసి, దానిపై నేరుగా docker compose ని రన్ చేయవచ్చు. అయితే network_mode: host విషయంలో, Docker socket ని మౌంట్ చేసే సర్వీసుల విషయంలో, మరియు రీబూట్ తర్వాత కూడా రన్ అవ్వడానికి quadlet unit మరియు linger అవసరమయ్యే restart: always విషయంలో కొన్ని ఇబ్బందులు ఎదురుకావచ్చు.
Rootless వాడటం వల్ల కంటైనర్లు నిజంగా సురక్షితంగా ఉంటాయా?
ఇది ఒక నిర్దిష్ట ప్రమాదాన్ని తొలగిస్తుంది: ఒకవేళ కంటైనర్ నుంచి ప్రాసెస్ బయటపడినా, అది root పర్మిషన్లకు బదులుగా మీ unprivileged యూజర్ పర్మిషన్లను మాత్రమే కలిగి ఉంటుంది. ఇది చాలా ముఖ్యమైనది, అందుకే rootless Podman లో root-equivalent అయిన docker గ్రూపుకు సమానమైనది ఏదీ లేదు. ఇది kernel లోని లోపాలను ఆపలేదు, మరియు మీ యూజర్ చదవగలిగే ఫైళ్లను రక్షించలేదు, కాబట్టి సాధారణ సర్వర్లో చేసే ఇతర భద్రతా చర్యలను దీనికి కూడా పాటించాలి.