SSD Nodes Learn 🎉 VPS החל מ־$5.50/חודש
מדריכים Matt Connorמאת Matt Connor · עודכן 2026-08-13

Podman לעומת Docker ב-VPS: מה ההבדל בפועל?

ההבדל המרכזי בין Podman ל-Docker טמון בהיעדר daemon ובהרצת מכולות ללא root. גלו כיצד זה משפיע על ניהול volumes, הגדרות ports, שימוש ב-systemd וניהול הרשאות בשרת VPS.

מה ההבדל בפועל בין Podman לבין Docker

‏Podman ו־Docker מריצים את אותם images בתקן OCI (Open Container Initiative) על גבי VPS, לכן הבחירה אינה נוגעת לתוכנה שניתן להריץ. ההבדל טמון במודל התהליכים. Docker מריץ daemon עם הרשאות root שבבעלותו כל ה-containers, והפקודה docker היא לקוח קטן המבקש מאותו daemon לבצע את העבודה. ל־Podman אין daemon: הפקודה podman run מפעילה את ה-container כתהליך בן של מי שהפעיל אותה, תחת המשתמש חסר ההרשאות שלך.

כל השאר נובע מעובדה יחידה זו. הפעלה אוטומטית (auto-start) הופכת למשימה של systemd במקום של ה-daemon. הבעלות על volumes עוברת דרך user namespace, כך שהבעלים שאתה רואה באמצעות ls -l במערכת המארחת אינם הבעלים שה-container רואה. פורטים מתחת ל-1024 יסרבו להיקשר (bind) עד שתשנה הגדרת kernel. ממשק ה-CLI של docker ממשיך לעבוד דרך wrapper, עד לנקודה שבה רכיב כלשהו דורש גישה ל-Docker socket.

ללא daemon: מה באמת רץ כשמפעילים מכולה

במארח Docker, הפקודה pstree -a מציגה את dockerd כמשתמש root, את containerd לצידו, ואת containerd-shim-runc-v2 אחד עבור כל מכולה פעילה. היישום שלכם הוא תהליך בן של ה-shim הזה, וה-shim הוא תהליך בן של PID 1. שום דבר לא מחבר את המכולה ל-shell שהפעיל אותה. עצירת ה-daemon גורמת לאובדן מישור הבקרה (control plane) עבור כל מכולה במכונה, וכאשר הגדרת 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:8080

הפקודה ps אמורה להציג את conmon רץ כמשתמש המחובר שלכם ולא כ-root, ו-curl אמור להדפיס 200. מכיוון שאין שירות מרכזי שבבעלותו המכולה, sudo apt upgrade podman לא עוצר שום דבר שכבר רץ, וקריסה של מנטר של מכולה אחת לא יכולה להפיל את האחרות יחד איתו.

היעדר ה-daemon גובה מחיר. שום דבר לא מפעיל את המכולות שלכם לאחר אתחול (reboot). ה---restart=always של Docker הוא הבטחה שה-daemon מקיים בזמן העלייה, ו-Podman מחליף זאת ב-systemd, שזהו הייעוד של סעיף ה-quadlet להלן.

ה-socket הוא החצי השני של הסיפור. /var/run/docker.sock הוא נקודת קצה של API (ממשק תכנות יישומים) בבעלות root, וכל תהליך שיכול לכתוב אליו יכול להפעיל מכולה בעלת הרשאות גבוהות שמבצעת mount למערכת הקבצים של המארח. הוספת משתמש לקבוצת docker מעניקה לאותו משתמש הרשאות root בדרך עקיפה, נושא שראוי לקרוא עליו בהרחבה ב-מתן גישה מינימלית לכל חשבון שירות. Podman לא חושף socket אלא אם תבקשו זאת, וה-socket שתקבלו שייך למשתמש יחיד ב-/run/user/<uid>/podman/podman.sock.

התקנת Podman על Ubuntu 24.04 ואימות פעילות במצב rootless

sudo apt update
sudo apt install -y podman uidmap
podman --version
podman info | grep -i rootless

החבילה uidmap מספקת את newuidmap ואת newgidmap. אלו הם רכיבי עזר מסוג setuid המאפשרים למשתמש רגיל להקצות טווח של מזהים משניים (subordinate IDs); בלעדיהם, מכולות במצב rootless לא יפעלו. הפקודה podman info אמורה להדפיס rootless: true.

Ubuntu 24.04 מגיעה עם Podman 4.9, ו-Debian 13 מגיעה עם Podman 5.x (נכון לאוגוסט 2026). לפער הזה יש משמעות, כיוון שקובצי Quadlet דורשים גרסה 4.4 ומעלה, וקובצי Quadlet מסוג .pod דורשים גרסה 5.0. הריצו את podman --version לפני העתקת דוגמאות מתיעוד רשמי.

כל משתמש במצב rootless זקוק לטווח מזהים משניים:

grep "$USER" /etc/subuid /etc/subgid

משתמש שנוצר באמצעות adduser ב-Ubuntu מקבל טווח באופן אוטומטי. משתמש שנוצר באמצעות 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 הוא המקור. שם תמונה קצר מפורש מול unqualified-search-registries בתוך /etc/containers/registries.conf, ובסקריפט ללא מסוף (terminal) פעולת ה-pull תיכשל עם short-name resolution enforced but cannot prompt without a TTY. ציינו את השם המלא בכל פעם. השתמשו ב-docker.io/library/nginx:1.27 במקום ב-nginx.

מה באמת משיגים באמצעות מכולות (containers) במצב rootless על שרת מושכר

מכולה במצב rootless רצה בתוך user namespace, תכונה של הליבה (kernel) המעניקה לתהליך מיפוי פרטי של מזהי משתמשים (UID). בתוך ה-namespace, משתמש העל של המכולה הוא UID 0. מחוץ לו, על ה-VPS שלכם, אותו תהליך הוא משתמש ה-login הרגיל שלכם. משתמש root בתוך המכולה אינו root במערכת המארחת.

זהו היקף היתרון האמיתי. image שמתעקש לרוץ כ-root, יישום אינטרנט עם פגיעות של ביצוע קוד מרחוק (RCE), או פריצה (escape) התלויה בהיות התהליך UID 0 מחוץ למכולה: כל אלו מסתיימים בהרשאות של המשתמש הלא-מורשה שלכם במקום בהרשאות של המכונה כולה. מה ש-rootless לא עושה הוא להגן עליכם מפני באגים בליבה, והוא לא מגן על הקבצים שלכם, כיוון שהתהליך שפרץ רץ תחת המשתמש שלכם ויכול לקרוא כל מה שאתם יכולים לקרוא.

גם Docker יכול לרוץ במצב rootless. הפקודה dockerd-rootless-setuptool.sh install מגדירה daemon לכל משתמש והיא עובדת היטב. ההבדל טמון בברירת המחדל. עם Podman אתם מקבלים rootless ללא צורך בבקשה מיוחדת, כך שהכשל הראשון שלכם יהיה מכולה שלא מצליחה לבצע bind לפורט 80, במקום שירות שרץ בשקט כ-root במשך שנתיים.

מדוע קובצי ה-volume שלי שייכים ל-UID 100999?

הסיבה לכך היא אותו מרחב שמות של משתמשים (user namespace). ה-UID 0 בתוך המכולה ממופה ל-UID של המשתמש המארח שלכם. ה-UID 1 במכולה ממופה למזהה הראשון בטווח ה-subuid שלכם, והמספרים עולים משם. בטווח שמתחיל ב-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 רגילה לא תפתור זאת, כיוון שהמשתמש חסר ההרשאות שלכם אינו יכול לשנות בעלות על קבצים מחוץ למרחב השמות.

ארבע דרכים לפתרון:

  • podman unshare chown 1000:1000 "$PWD/data" מריצה את chown בתוך אותו מרחב שמות של משתמשים, שבו למספרים יש את המשמעות המוכרת למכולה.
  • -v "$PWD/data:/data:U" מבקשת מ-Podman לתקן עבורכם את הבעלות על תיקיית המקור. השתמשו בה על תיקייה חדשה, לא על נתונים שחשובים לכם.
  • --userns=keep-id ממפה את ה-UID שלכם במערכת המארחת לאותו UID בתוך המכולה, כך שקבצים חדשים ייווצרו עם הבעלות שלכם.
  • volume בעל שם כמו -v appdata:/data מונע את הבעיה, כיוון ש-Podman יוצר אותו בתוך האחסון שלכם עם בעלות תקינה מראש.

אם נתקלתם בבעיה זו ב-Docker, מדובר באותה בעיה ברמה אחת מעל. משתני PUID ו-PGID שדימויים רבים חושפים מגדירים את ה-UID שבו משתמש התהליך בתוך המכולה, ותחת Podman ללא הרשאות root, ה-UID הזה ממופה פעם שנייה. PUID=1000 בתוך מכולה ללא root עדיין כותב קבצים במערכת המארחת עם בעלות של 100999. בחרו את המספרים תוך התחשבות במיפוי השני הזה, או העבירו את הנתונים ל-volume בעל שם והפסיקו לעסוק בכך.

שתי הערות נוספות על mount: הדגלים :z ו-:Z שאתם רואים בדוגמאות של Fedora ו-RHEL הם אפשרויות לסימון מחדש של SELinux, ולכן הם אינם עושים דבר ב-Ubuntu, שמשתמשת ב-AppArmor. כמו כן, Podman ללא הרשאות root אינו יכול לבצע mount לתיקייה במערכת המארחת שהמשתמש שלכם אינו יכול לקרוא; זוהי מטרת המנגנון ולא תקלה.

מדוע Podman במצב rootless מסרב לפרסם את פורט 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 ולהציב לפניו reverse proxy, שזהו המקום שבו ממילא תרצו תעודות שיונפקו ויחודשו על ידי certbot ב-nginx.

פרסום במצב rootless משנה גם את מה שהיישום רואה. Podman בגרסה 4.x משתמש כברירת מחדל ב-slirp4netns עם ה-port handler של rootlesskit, וחיבורים מועברים מגיעים עם כתובת מקור שעברה שינוי, כך שלוג הגישה מתעד כל מבקר כ-10.0.2.100. ב-Podman 5.0 שונתה ברירת המחדל ל-pasta, ששומרת על כתובת הלקוח האמיתית. בגרסה 4.x, השימוש ב---network slirp4netns:port_handler=slirp4netns משחזר את כתובת המקור האמיתית, אך במחיר מסוים של ירידה בביצועי התעבורה.

יש כאן יתרון אחד מפתיע. פורט שמפורסם במצב rootless הוא socket האזנה רגיל בבעלות תהליך רגיל, ולכן חוקי ה-firewall שלכם חלים עליו. Docker מפרסם פורטים על ידי כתיבת חוקי NAT (תרגום כתובות רשת) בתוספת חוקי קבלה (accepts) משלו, וזו בדיוק הסיבה לכך ש-פורט של Docker שמפורסם מתעלם מחוק ה-ufw שחשבתם שחוסם אותו. Podman עם הרשאות root משתמש במנגנון דומה ויורש את אותה מלכודת. במצב rootless זה לא קורה.

האם קובצי ה-Docker Compose שלי עדיין עובדים תחת Podman?

ברוב המקרים כן, בשתי דרכים שונות. הראשונה היא podman-compose, מימוש נפרד שקורא את אותו הקובץ ומפעיל את ה-CLI של Podman:

sudo apt install -y podman-compose
podman-compose up -d
podman ps

הדרך השנייה היא שימוש ב-Docker Compose האמיתי, המתקשר עם ה-API התואם-Docker של Podman דרך socket השייך למשתמש:

systemctl --user enable --now podman.socket
export DOCKER_HOST="unix:///run/user/$(id -u)/podman/podman.sock"
docker compose up -d
podman ps

הפקודות docker compose ps ו-podman ps אמורות להציג את אותם המכולות, כיוון שקיימת קבוצה אחת בלבד של מכולות. גם פתרון שמות (Name resolution) עובד: מנגנון הרשת המובנה של Podman, הלא הוא netavark, מריץ את aardvark-dns, כך שמכולות ברשת המוגדרת על ידי המשתמש יכולות למצוא זו את זו לפי שם.

ישנם קצוות מחוספסים. כל מה שמבצע mount ל-/var/run/docker.sock חייב להיות מופנה ל-socket של Podman או להיות מוסר. הפקודה network_mode: host מתנהגת אחרת תחת user namespace. השימוש ב-depends_on עם condition: service_healthy נתמך בצורה לא אחידה בגרסאות השונות של podman-compose. הפקודה restart: always אינה שורדת אתחול באופן עצמאי, בעיה שהסעיף הבא פותר. Compose נותר דרך טובה לתאר מערך מרובה-מכולות בקובץ יחיד, ותחת Podman הוא משמש כשכבת תרגום. עבור מערך שאתם מתכננים להחזיק במשך שנים, מומלץ להמיר אותו ל-quadlets ולתחזק הפשטה אחת במקום שתיים.

Pods: הרעיון שאין לו מענה ב-Docker

Pod הוא קבוצת מכולות (containers) החולקות מרחב שמות (namespace) רשת יחיד. Podman מפעיל מכולת infra קטנה כדי להחזיק את מרחב השמות הזה פתוח, והחברים בקבוצה ניגשים זה לזה דרך 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 --pod

הפקודה podman pod ps אמורה להציג את ה-pod Running עם שלוש מכולות, כולל מכולת התשתית (infra container). כעת, מכולת ה-web ניגשת ל-Redis ב-127.0.0.1:6379 במקום ב-app-cache:6379. שני כללים נובעים ממרחב השמות המשותף: פרסום פורטים מתבצע ברמת ה-pod ולא ברמת חבר בודד, ואסור לשני חברים להאזין על אותו פורט.

זהו המודל של Kubernetes, ו-Podman מאמץ אותו. הפקודה podman kube generate app > app.yaml כותבת manifest של Kubernetes מתוך מה שרץ כרגע (בחבילות ישנות יותר הפקודה היא podman generate kube), והפקודה podman kube play app.yaml משחזרת אותו על מארח אחר. ל-Quadlet יש סוג יחידה .kube שמריץ קובץ כזה כשירות systemd. זוהי דרך שונה מהותית לקבץ שירותים, וזו הסיבה המשכנעת ביותר לבחור ב-Podman אם Kubernetes נמצא בתוכניות העתידיות שלכם.

הפעלה אוטומטית ללא daemon: יחידות Quadlet

Quadlet הוא מחולל עבור systemd. הוא הופך קובץ קצר המתאר מכולה לשירות systemd אמיתי בזמן האתחול. יש להציב את הקבצים ב-~/.config/containers/systemd/ עבור משתמש ללא הרשאות root, או ב-/etc/containers/systemd/ עבור root.

~/.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:

[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. לא ניתן להפעיל (enable) יחידות שנוצרו באופן זה, ו-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=Linger

צפו ל-Linger=yes. ללא linger,‏ systemd מפרק את כל סשן המשתמש כאשר חיבור ה-SSH האחרון שלכם נסגר, ולכן כל מכולה ללא הרשאות root נעצרת יחד איתו ואף אחת מהן לא חוזרת בזמן האתחול. מכולות שנעלמות כשאתם מתנתקים הן תמיד תוצאה של הגדרה זו.

מכיוון שהמכולה היא התהליך הראשי של יחידת שירות רגילה, בקרות ה-systemd הרגילות חלות ישירות. MemoryMax= ו-CPUQuota= במקטע [Service] מתנהגים בדיוק כפי שהם מתנהגים עבור כל שירות אחר שאתם מגבילים באמצעות systemd. זה דורש cgroup v2 (גרסה 2 של control group), שבה Ubuntu משתמשת כברירת מחדל מאז גרסה 22.04. אשרו זאת עם podman info | grep -i cgroup.

לעדכונים יש מנגנון תואם. AutoUpdate=registry בתוספת systemctl --user enable --now podman-auto-update.timer בודקים ב-registry אם קיימת תמונה חדשה יותר באותו tag, מבצעים הפעלה מחדש ליחידה, ומבצעים rollback לתמונה הקודמת אם המכולה החדשה נכשלת בהפעלה. הריצו את podman auto-update --dry-run תחילה כדי לראות מה ישתנה. הפקודה הישנה יותר podman generate systemd עדיין קיימת אך היא מיושנת (deprecated), לכן כתבו quadlets עבור כל דבר חדש.

היכן ה-alias של Docker תקף, והיכן לא

sudo apt install -y podman-docker
sudo touch /etc/containers/nodocker
docker ps

podman-docker מתקין מעטפת (wrapper) מסוג /usr/bin/docker הקוראת ל-Podman. ללא הקובץ nodocker, כל קריאה מדפיסה תחילה Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.. המעטפת מכסה את הפקודות שבהן אתם משתמשים לאורך כל היום: run, ps, logs, exec, build, pull, push, inspect, cp, volume, network.

מה שאינו עובר הוא רשימה קצרה וממוקדת יותר. למצב Swarm אין שקול, לכן ל-stack של Swarm אין מקום לנחות בו. כלים המדברים עם ה-socket של Docker צריכים לייצא את ה-socket של Podman, וחלקם עדיין מבחינים בהבדל; ה-provider של Docker ב-Traefik עובד כאשר מפנים אותו ל-/run/user/<uid>/podman/podman.sock, בעוד של-Watchtower אין מקום כלל, כיוון ש-podman auto-update מבצע את העבודה הזו. האחסון נפרד, לכן Podman אינו יכול לראות אימג'ים שכבר משכתם עם Docker, והפקודה podman images על מארח Docker עמוס מתחילה כשהיא ריקה.

העברת stack פעיל, צעד אחר צעד

  1. צרו או בחרו את המשתמש ללא הרשאות מיוחדות (unprivileged) שיחזיק במכולות, וודאו שיש לו טווח ב-/etc/subuid.
  2. בצעו משיכה מחדש (re-pull) לכל מה שהגיע מ-registry, תוך שימוש בשמות מלאים. ל-Podman יש מאגר תמונות משלו והוא לא יקרא את זה של Docker.
  3. העבירו תמונות שנבנו מקומית באמצעות docker save app:1.4 | podman load.
  4. עצרו את מכולת ה-Docker, העתיקו את תוכן כל volume מתוך /var/lib/docker/volumes/<name>/_data, ולאחר מכן תקנו את הבעלות על הקבצים באמצעות podman unshare chown -R 1000:1000 <path>.
  5. הכריעו בסוגיית הפורטים: בצעו פרסום (publish) מעל 1024 מאחורי reverse proxy, או הגדירו את net.ipv4.ip_unprivileged_port_start.
  6. כתבו קובץ Quadlet אחד לכל מכולה, הריצו את systemctl --user daemon-reload, והפעילו כל שירות.
  7. הריצו את sudo loginctl enable-linger <user>, בצעו reboot ל-VPS, התחברו מחדש וודאו ש-podman ps מציג את כל השירותים שוב.

שני המנועים אינם חולקים דבר: אחסון תמונות נפרד ורשתות נפרדות. לכן ניתן להריץ את שניהם במקביל בזמן ההגירה, והדבר היחיד שהם עלולים להתנגש עליו הוא מספר פורט במארח. העבירו שירות אחד, נטרו אותו במשך יום, ולאחר מכן עברו לשירות הבא.

Podman מול Docker: מה מתאים ל-VPS שלך?

הישארו עם Docker אם ה-stack שלכם מבוסס על קובצי compose שאנשים אחרים מתחזקים, או אם אתם תלויים בכלים שמתקשרים עם ה-socket של Docker. תאימות למה שכולם כותבים היא תכונה בעלת ערך, ול-Docker יש יתרון בתחום זה. צוות שכל המחשבים הניידים שלו מריצים Docker מרוויח יתרון מוחשי מהרצת אותו מנוע גם בסביבת ה-production.

עברו ל-Podman אם ה-VPS מריץ מספר מצומצם של שירותים שאתם שולטים בהם מקצה לקצה, או אם אתם רוצים שכל יישום ירוץ תחת משתמש ללא הרשאות (unprivileged) ללא קבוצת docker על השרת כלל. גם להתאמה להפצה יש משקל: RHEL והגרסאות המבוססות עליה מספקות את Podman כמנוע הנתמך, ולכן במערכות אלו Podman הוא המסלול עם פחות הפתעות. אם אתם כבר מנהלים את כל השאר באמצעות יחידות systemd, ה-quadlets ירגישו כמו חלק חסר שהגיע ולא כמו כלי חדש שצריך ללמוד.

כדאי לציין אפשרות ביניים אחת. Podman במצב rootful מתנהג בדומה ל-Docker, שומר על הפקודה docker דרך ה-wrapper, ועדיין מסיר את הצורך ב-daemon שרץ תמיד. עם זאת, הוא מוותר על היתרון של הרצה ללא root, שהוא החלק שמשנה את רמת האבטחה שלכם, לכן התייחסו אליו כתחנת מעבר בלבד.

אם אתם עדיין בונים את מארח ה-containers הראשון שלכם, הגדרת Docker ומסלול ההקשחה ב-VPS חדש הוא הדרך הקצרה יותר, ושום ידע שתצברו לא ירד לטמיון. Images ו-volumes הם אותם אובייקטים בשני המנועים, כך שמעבר מאוחר יותר ישנה רק את אופן הניהול של השירותים שלכם, ולא הרבה מעבר לכך.

FAQ

האם Podman הוא תחליף מלא ל-Docker?

עבור הפקודות שאתם מריצים, הוא קרוב לכך. התקנת podman-docker מספקת לכם מעטפת /usr/bin/docker, והפקודות run, ps, build, logs ו-exec מתנהגות באותו אופן. עם זאת, הוא אינו תחליף ל-daemon. ל-Swarm אין מקבילה, כלים שמתחברים ל-/var/run/docker.sock חייבים להיות מופנים ל-socket של Podman ברמת המשתמש, ותמונות (images) שנמשכו על ידי Docker נשארות בלתי נראות עבור Podman כיוון ששניהם מנהלים אחסון נפרד.

מדוע מכולות Podman ללא הרשאות root נעצרות כשאני מתנתק מ-SSH?

מכיוון ש-systemd עוצר את סשן המשתמש, ואיתו כל שירותי המשתמש, ברגע שהחיבור האחרון נסגר. הריצו את sudo loginctl enable-linger <user>, ולאחר מכן ודאו ש-loginctl show-user <user> --property=Linger מציג Linger=yes. הפקודה Linger שומרת על מופע ה-systemd של המשתמש פעיל גם ללא סשן פעיל, וזה גם מה שמאפשר למכולות לעלות מחדש לאחר reboot.

מדוע קבצים ב-volume שלי שייכים ל-UID 100999?

Podman ללא הרשאות root ממפה את UID 0 של המכולה למשתמש המארח שלכם, ולאחר מכן ממפה את UID 1 ומעלה לטווח ה-subuid שלכם. עם טווח שמתחיל ב-100000, ה-UID 1000 של המכולה הופך ל-100999 במערכת המארחת. תקנו זאת מתוך ה-namespace בעזרת podman unshare chown 1000:1000 /path/to/data, בצעו mount עם הדגל :U בהרצה הראשונה, או השתמשו ב---userns=keep-id כדי שה-UIDs של המכולה יתאימו לשלכם.

האם אני יכול להמשיך להשתמש ב-docker-compose.yml עם Podman?

כן, בשתי דרכים. podman-compose קורא את הקובץ ומפעיל את ה-CLI של Podman ישירות. לחלופין, הפעילו את ה-socket התואם בעזרת systemctl --user enable --now podman.socket, הגדירו את DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock, והריצו docker compose אמיתי מולו. צפו לקשיים ב-network_mode: host, בשירותים שמבצעים mount ל-socket של Docker, וב-restart: always, שדורש יחידת quadlet ו-linger כדי לשרוד reboot.

האם הרצה ללא root באמת הופכת מכולות למאובטחות יותר?

זה מסיר סיכון ספציפי אחד: תהליך שפורץ מתוך מכולה ללא הרשאות root מחזיק בהרשאות המשתמש הבלתי-מורשה שלכם במקום בהרשאות root. זהו יתרון משמעותי, וזו הסיבה שלקבוצת docker, המקבילה ל-root, אין מקבילה ב-Podman ללא הרשאות root. זה לא מונע פגיעויות ב-kernel, וזה לא מגן על קבצים שהמשתמש שלכם יכול לקרוא, לכן המשיכו ליישם את שאר אמצעי ההקשחה שהייתם מבצעים בכל שרת.

#podman#docker#rootless#containers#systemd