it

Podman Rootless Container — คู่มือ Container

Podman Rootless Container — คู่มือ Container

Podman คืออะไรต่างจาก Docker ยังไง

Podman Rootless Container — คู่มือ Container

ผมเริ่มใช้ Podman ตั้งแต่ version 2.0 ในปี 2020 และค่อยๆย้าย workloads จาก Docker มาใช้ Podman มากขึ้นเรื่อยๆในปี 2026 ผมใช้ Podman เป็นหลักสำหรับ production servers ทั้งหมดเหตุผลหลักคือ security และ architecture ที่ดีกว่า

Podman (Pod Manager) เป็น container engine ที่พัฒนาโดย Red Hat มี 3 ข้อแตกต่างหลักจาก Docker Daemonless — Docker ต้องรัน dockerd daemon ด้วย root privileges ตลอดเวลาถ้า daemon ล่ม containers ทั้งหมดล่มตามไปด้วย Podman ไม่มี daemon แต่ละ container เป็น child process ของ user ถ้า container ตายไม่กระทบ container อื่น Rootless — Podman รัน containers ด้วย user ธรรมดาได้เลยไม่ต้อง root ไม่ต้อง sudo ปลอดภัยกว่ามาก Pod support — Podman รองรับ Pod concept เดียวกับ Kubernetes ทำให้ transition ไป Kubernetes ง่ายขึ้น

Docker Compatibility

Podman ออกแบบมาให้ compatible กับ Docker CLI 100% คุณสามารถ alias docker=podman แล้วใช้ commands เดิมได้เลย Dockerfiles ใช้ได้ Docker images ใช้ได้ docker-compose (ผ่าน podman-compose) ใช้ได้การ migrate จาก Docker มา Podman แทบไม่ต้องเปลี่ยนอะไร

ติดตั้งบน Ubuntu 24.04

Ubuntu 24.04+ มี Podman ใน official repo

apt install podman

ตรวจสอบ version

podman --version

podman version 4.9.3

ตรวจสอบ info

podman info

ทดสอบ rootless container

podman run --rm docker.io/library/hello-world

ตั้งค่า registries

/etc/containers/registries.conf

เนื้อหาเกี่ยวข้อง — External Secrets Operator Open Source Contribution

unqualified-search-registries = ["docker.io", "quay.io", "ghcr.io"]

ติดตั้งบน RHEL/Rocky/Alma

# RHEL 9 / Rocky 9 มี Podman ติดตั้งมาแล้ว

dnf install podman podman-compose buildah skopeo



# ตรวจสอบ

podman --version

buildah --version

skopeo --version

ตั้งค่า Rootless

# ตรวจสอบ subuid/subgid mapping

grep $USER /etc/subuid

grep $USER /etc/subgid

# output: bom:100000:65536



# ถ้าไม่มี ให้เพิ่ม

usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER



# ตั้งค่า storage สำหรับ rootless

# ~/.config/containers/storage.conf

[storage]

driver = "overlay"

graphroot = "/home/bom/.local/share/containers/storage"



[storage.options.overlay]

mount_program = "/usr/bin/fuse-overlayfs"



# Enable lingering (ให้ containers รันต่อหลัง logout)

loginctl enable-linger $USER

Rootless Container — ทำไมถึงปลอดภัยกว่า

ปัญหาใหญ่ของ Docker คือ Docker daemon รันด้วย root ถ้า attacker exploit ช่องโหว่ใน container และ escape ออกมาได้จะได้ root access บน host ทันที Podman rootless แก้ปัญหานี้เพราะ container รันด้วย user namespace ที่ map UID 0 (root) ใน container ไปยัง UID ของ user ธรรมดาบน host

ตัวอย่าง Rootless vs Rootful

Rootless — ปลอดภัย ไม่ต้อง sudo

podman run -d --name web -p 8080:80 docker.io/library/nginx:alpine

ดู user ที่รัน container

แนะนำเพิ่มเติม — บทวิเคราะห์จาก XM Signal

podman top web user

UID USER

0 root ← root ใน container

แต่ใน host จริงๆ รันด้วย UID 100000+ (user ธรรมดา)

ps aux | grep nginx

bom 12345 ... nginx: master process ← รันด้วย user "bom" บน host

Rootful — ต้องใช้ sudo (เหมือน Docker)

sudo podman run -d --name web-root -p 80:80 docker.io/library/nginx:alpine

ใน host จะรันด้วย root จริงๆ — อันตรายกว่า

เนื้อหาเกี่ยวข้อง — ดูเพิ่มเติมเรื่อง AWS App Runner Learning Path Roadmap

Security Differences

# Podman rootless + SELinux

podman run --security-opt label=type:container_t \

 -v /data:/data:Z \

 docker.io/library/nginx:alpine



# --security-opt label=type:container_t → SELinux context

# :Z → relabel volume สำหรับ SELinux



# ดู security options ที่ใช้ได้

podman run --security-opt help



# No new privileges

podman run --security-opt no-new-privileges:true \

 docker.io/library/nginx:alpine



# Read-only root filesystem

podman run --read-only \

 --tmpfs /tmp \

 --tmpfs /run \

 docker.io/library/nginx:alpine

Pods — แนวคิดเดียวกับ Kubernetes

Pod คือกลุ่มของ containers ที่แชร์ network namespace เดียวกันเหมือน Pod ใน Kubernetes containers ใน Pod เดียวกันเข้าถึงกันผ่าน localhost ได้เลย

สร้างและจัดการ Pods

# สร้าง Pod ชื่อ web-stack

podman pod create --name web-stack -p 8080:80 -p 3306:3306



# เพิ่ม containers เข้า Pod

podman run -d --pod web-stack --name nginx \

 docker.io/library/nginx:alpine



podman run -d --pod web-stack --name php-fpm \

 docker.io/library/php:8.3-fpm-alpine



podman run -d --pod web-stack --name mariadb \

 -e MYSQL_ROOT_PASSWORD=SecurePass123 \

 -e MYSQL_DATABASE=webapp \

 docker.io/library/mariadb:11.3



# nginx เข้า php-fpm ผ่าน localhost:9000

# php-fpm เข้า mariadb ผ่าน localhost:3306



# ดู Pod status

podman pod ps

podman pod inspect web-stack



# หยุด/ลบ Pod ทั้งหมด

podman pod stop web-stack

podman pod rm web-stack

Generate Kubernetes YAML จาก Pod

Export Pod เป็น Kubernetes YAML

podman generate kube web-stack > web-stack.yaml

ดู YAML ที่ generate ได้

cat web-stack.yaml

apiVersion: v1

kind: Pod

metadata:

name: web-stack

แนะนำเพิ่มเติม — แหล่งความรู้ Forex iCafeForex

spec:

Podman Rootless Container — คู่มือ Container

containers:

  • name: nginx

image: docker.io/library/nginx:alpine

  • name: php-fpm

image: docker.io/library/php:8.3-fpm-alpine

...

Import Kubernetes YAML กลับมาเป็น Podman Pod

podman play kube web-stack.yaml

เนื้อหาเกี่ยวข้อง — Libvirt KVM Cloud Migration Strategy

ลบ Pod จาก YAML

podman play kube --down web-stack.yaml

Buildah — Build Images โดยไม่ต้อง Dockerfile

# Build จาก Dockerfile (เหมือน docker build)

buildah bud -t myapp:latest .



# Build แบบ interactive (ไม่ต้อง Dockerfile)

container=$(buildah from docker.io/library/ubuntu:24.04)

buildah run $container -- apt update

buildah run $container -- apt install -y nginx php-fpm

buildah copy $container ./app/ /var/www/html/

buildah config --port 80 $container

buildah config --cmd "nginx -g 'daemon off;'" $container

buildah commit $container myapp:latest



# Multi-stage build

buildah bud --layers --target production -t myapp:prod .



# Push to registry

buildah push myapp:latest docker://registry.example.com/myapp:latest

Skopeo — จัดการ Images ระหว่าง Registries

# Copy image ระหว่าง registries (ไม่ต้อง pull แล้ว push)

skopeo copy docker://docker.io/library/nginx:alpine \

 docker://registry.example.com/nginx:alpine



# ดู image info โดยไม่ต้อง pull

skopeo inspect docker://docker.io/library/nginx:alpine



# ดู tags ทั้งหมด

skopeo list-tags docker://docker.io/library/nginx



# Sync images (mirror registry)

skopeo sync --src docker --dest dir docker.io/library/nginx /backup/images/



# Copy image เป็น OCI archive

skopeo copy docker://docker.io/library/nginx:alpine \

 oci-archive:/backup/nginx-alpine.tar

Podman Compose

# ติดตั้ง podman-compose

pip install podman-compose



# ใช้ docker-compose.yml ได้เลย

# docker-compose.yml (ไม่ต้องแก้อะไร)

services:

 web:

 image: docker.io/library/nginx:alpine

 ports:

 - "8080:80"

 volumes:

 - ./html:/usr/share/nginx/html:ro

 app:

 image: docker.io/library/php:8.3-fpm-alpine

 volumes:

 - ./app:/var/www/html



# รัน

podman-compose up -d

podman-compose ps

podman-compose logs -f

podman-compose down

Systemd Integration — Auto-start Containers

# Generate systemd unit จาก container ที่รันอยู่

podman generate systemd --new --name web-stack > ~/.config/systemd/user/web-stack.service



# หรือ generate สำหรับ Pod ทั้ง pod

mkdir -p ~/.config/systemd/user/

podman generate systemd --new --files --name web-stack

mv *.service ~/.config/systemd/user/



# Enable auto-start

systemctl --user daemon-reload

systemctl --user enable --now pod-web-stack.service



# ดู status

systemctl --user status pod-web-stack.service



# ดู logs

journalctl --user -u pod-web-stack.service

Quadlet — Podman + Systemd Native (Podman 4.4+)

# Quadlet เป็นวิธีใหม่ที่ดีกว่า generate systemd

# สร้างไฟล์ .container ใน ~/.config/containers/systemd/



# ~/.config/containers/systemd/nginx.container

[Container]

Image=docker.io/library/nginx:alpine

PublishPort=8080:80

Volume=./html:/usr/share/nginx/html:ro



[Service]

Restart=always



[Install]

WantedBy=default.target



# Reload และ start

systemctl --user daemon-reload

systemctl --user start nginx.service

Step-by-Step Migration

# 1. ติดตั้ง Podman

apt install podman podman-compose



# 2. สร้าง alias (optional)

echo 'alias docker=podman' >> ~/.bashrc

echo 'alias docker-compose=podman-compose' >> ~/.bashrc

source ~/.bashrc



# 3. Import Docker images

# วิธี A: Pull จาก registry ใหม่

podman pull docker.io/library/nginx:alpine



# วิธี B: Export จาก Docker แล้ว Import เข้า Podman

docker save myapp:latest | podman load



# 4. แก้ docker-compose.yml (ถ้าจำเป็น)

# เพิ่ม full image path: docker.io/library/nginx:alpine

# แทน: nginx:alpine



# 5. รัน

podman-compose up -d



# 6. ตรวจสอบ

podman ps

podman logs container-name

สิ่งที่ต้องระวังเมื่อ Migrate

1. Rootless ไม่สามารถ bind port < 1024 ได้

แก้: ใช้ port สูง (8080 แทน 80)

หรือ: sysctl net.ipv4.ip_unprivileged_port_start=80

2. Volume ownership อาจต่างกัน

Docker: files owned by root

Podman rootless: files owned by user (UID mapping)

podman unshare chown 33:33 /data/html # set ownership inside user namespace

3. Docker socket ไม่มี

ถ้า app ต้องการ /var/run/docker.sock

ใช้ Podman socket แทน

systemctl --user enable --now podman.socket

Socket อยู่ที่: /run/user/$(id -u)/podman/podman.sock

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน gRPC Protobuf Blue Green Canary Deploy

4. Network mode ต่างกัน

Docker: bridge network เป็น default

Podman rootless: slirp4netns เป็น default (ช้ากว่า bridge)

แก้: ใช้ pasta network (เร็วกว่า)

podman run --network pasta -d nginx:alpine

Podman ช้ากว่า Docker ไหม?

สำหรับ container runtime performance แทบไม่ต่างกันเพราะทั้งคู่ใช้ runc เป็น OCI runtime เหมือนกันแต่ rootless networking (slirp4netns) อาจช้ากว่า Docker bridge เล็กน้อยใน Podman 5.x มี pasta network mode ที่เร็วเทียบเท่า bridge แล้วสำหรับ build images Buildah อาจช้ากว่า Docker buildkit เล็กน้อยแต่ไม่มีนัยสำคัญ

Podman รองรับ Docker Compose ไหม?

รองรับครับมี 2 ทางเลือก podman-compose เป็น Python tool ที่อ่าน docker-compose.yml แล้วสร้าง Podman containers แทน docker-compose with Podman socket ใช้ docker-compose ตัวจริงกับ Podman socket ได้เลยผมใช้ podman-compose เป็นหลักทำงานได้ดีกับ Docker Compose files ที่มีอยู่

ใช้ Podman กับ Kubernetes ได้ดีแค่ไหน?

Podman ออกแบบมาให้ work กับ Kubernetes ได้ดี Pod concept เหมือนกัน podman generate kube สร้าง YAML ที่ใช้กับ Kubernetes ได้เลย podman play kube รัน Kubernetes YAML บน Podman ได้ทำให้ develop บน Podman แล้ว deploy บน Kubernetes ได้ smooth RHEL OpenShift ก็ใช้ CRI-O (พื้นฐานเดียวกับ Podman) เป็น container runtime

Docker Desktop มี GUI แต่ Podman มีไหม?

มีครับ Podman Desktop เป็น GUI application สำหรับ Windows, macOS, Linux มี features ครบจัดการ containers, images, pods, volumes ได้ทั้งหมดฟรีและ open-source ไม่มีปัญหา licensing เหมือน Docker Desktop ที่ต้องจ่ายเงินสำหรับ commercial use

สรุป

Podman เป็น container engine ที่ปลอดภัยกว่า Docker ด้วย rootless architecture และ daemonless design Compatible กับ Docker CLI, Dockerfiles และ docker-compose.yml ทำให้ migrate ได้ง่าย Pod support ทำให้ transition ไป Kubernetes สะดวกและ Quadlet integration ทำให้จัดการ containers ด้วย systemd ได้อย่างเป็นระเบียบ

สำหรับปี 2026 ผมแนะนำให้ทุกคนลองใช้ Podman โดยเฉพาะสำหรับ production servers ที่ security เป็นสิ่งสำคัญร่วมกับ Buildah สำหรับ build images และ Skopeo สำหรับจัดการ images ข้าม registries ก็ได้ container toolchain ที่สมบูรณ์แบบโดยไม่ต้องพึ่ง Docker เลยครับ

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง