Podman คืออะไร? ต่างจาก docker ยังไง?
podman ย่อมาจาก Pod Manager คือเครื่องมือที่ใช้สร้างและจัดการ container เหมือนกับ docker แต่มีความปลอดภัยมากกว่า ซึ่งทั้ง doker และ podman จะต่างกันตรงที่
-
podman จะไม่มี daemon ที่ run เป็น background process เหมือน docker ซึ่ง docker จะมี dockerd(docker daemon) คอยฟังคำสั่งตลอดเวลา ซึ่งข้อเสียของการมี dockerd คือถ้า dockerd ตายไปเราจะไม่สามารถคุยกับ container ได้อีกเลย
จากรูปจะเห็นว่าการทำงานของ docker จะมีขั้นตอนต่างๆ ดังนี้
- developer ส่งคำสั่งเข้ามาทาง docker cli
- docker cli ส่งคำสั่งต่อให้ docker daemon(background process)
- docker daemon ส่งคำสั่งต่อให้ containerd(เป็น container runtime ตัวจริง)
- containerd สร้าง container จาก image ที่เรากำหนด
แต่ podman นั้นจะเป็น command line เมื่อได้รับคำสั่งมา ก็ทำการสร้าง container ตาม image ที่เราระบุไว้ หลังจากนั้นก็จะจบการทำงานไป
-
podman จะเป็น Rootless คือไม่ต้องใช้สิทธิของ root ในการทำงานกับ container ซึ่งจะต่างจาก docker เพราะ docker-cli ต้องคุยกับ dockerd(daemon) ดังนั้นทุกครั้งที่เราสั่ง docker ps จึงต้องนำหน้าด้วย sudo เสมอ
- คำสั่ง list รายการของ container ทั้งหมดที่มีอยู่ในเครื่องด้วย docker
$ sudo docker ps
- คำสั่ง list รายการของ container ทั้งหมดที่มีอยู่ในเครื่องด้วย podman
$ podman ps
แล้วการเป็น rootless มันดียังไงก็แค่ไม่ต้องพิมพิ์ sudo เท่านั้นเองเหรอ คำตอบคือ มันจะต่างกันเมื่อ container มีช่องโหว่ถ้าเป็น root จะมีสิทธิที่สูงสามารถเข้าไปโจมตีต่อได้ง่าบ ความรุนแรงของช่องโหว่นั้นจะมีมากกว่า
- คำสั่ง list รายการของ container ทั้งหมดที่มีอยู่ในเครื่องด้วย docker
ด้วยเหตุผลทั้ง 2 ข้อนี้ทำให้บน Server เราควรจะใช้ podman เพราะ podman ปลอดภัยกว่า docker
Podman basic command
เนื่องจาก podman นั้นทำตามมาตรฐาน Open Container Initiative(OCI) เลยทำให้คำสั่งต่างๆที่เราใช้ใน podman จะเหมือนกับ docker ทุกอย่างแค่เปลี่ยนคำว่า docker ไปเป็น podman เท่านั้น ลองดูตัวอย่างคำสั่งที่เราต้องใช้ในชีวิตประจำวันมีดังนี้
-
คำสั่งในการ pull image ลงมาจาก container registry(เราสามารถใช้ image จาก docker hub ได้เลย)
$ podman pull nginx
-
คำสั่งในการ run container
$ podman run nginx
-
เมื่อเกิดปัญหาขึ้นเราจะเข้าไปดู logs ใน container ได้ด้วยคำสั่ง
$ podman logs --tail 5 [container ID]
ในตัวอย่างนี้เราจะดึงเอา logs(จาก stdout) 5 บรรทัดหลังสุดออกมาดู
-
ถ้าเราอยาก run คำสั่งใน shell ของ container ให้ใช้คำสั่ง
$ podman exec -it [container ID] ls
ในตัวอย่างนี้เป็นการ run command ls ใน shell ของ container ที่มี ID ตามที่เราใส่ตรง [container ID]
-
หยุดการทำงานของ container ได้ด้วยคำสั่ง
$ podman stop [container Id]
-
คำสั่ง build container image
$ podman build -t myapp .
ที่สำคัญที่สุดคือเราสามารถ build container โดยใช้ Dockerfile ได้เลย ไม่ต้องเรียนรู้ syntax ใหม่เลย
-
พิเศษสำหรับการใช้งานบน MacOS ที่ต้องมีการจำลอง VM ขึ้นมาเนื่องจาก OS ไม่ support การสร้าง container เราจึงต้องใช้คำสั่ง podman machine เพื่อจำลอง VM ขึ้นมา
$ podman machine init $ podman machine start
ส่วนบน Windows podman จะติดต้ังอยุ่ใน Window Sub Linux(WSLv2) เราสามารถใช้คำสั่ง podman ตรงๆ ผ่านทาง Powershell หรือ Command Prompt ได้เลย
จะเห็นว่า podman นั้นแทบไม่มี learning curve เลยเพราะถ้าเราใช้ docker อยู่แล้วเราก็เปลี่ยนมาใช้ podman ได้เลย
Podman Desktop
Redhat ได้สร้าง podman desktop ออกมาทำให้เราทำงานกับ podman ได้ง่ายขึ้น เพราะปกติตอนติดตั้ง podman เราจะได้มาเฉพาะ command-line เท่านั้น ถ้าเราอยากได้ GUI เราต้อง install podman desktop เพิ่ม
สามารถเข้าไปดูวิธีการติดตั้งและใช้งานเพิ่มเติมได้ที่ https://github.com/containers/podman-desktop
Podman Compose
นอกจาก podman จะเลียนแบบ docker ได้อย่างแนบเนียนแล้ว podman ยังจะไปล้อเลียน docker-compose ได้แบบแนบเนียนอีกด้วย
อันดับแรกเราต้องติดตั้ง podman compose ลงในเครื่องก่อน ซึ่ง podman compose พัฒนาด้วย python ดังนั้นเราต้องติดตั้งด้วยคำสั่ง
$ pip install podman-compose
# หรือ
$ pip3 install podman-compose
ในตัวอย่างนี้เราจะสร้างไฟล์ docker-compose.yml ขึ้นมาและใส่ content เข้าไปแบบนี้
version: '3'
services:
web:
image: k8s.gcr.io/echoserver:1.4
ports:
- "${HOST_PORT:-8080}:8080"
หลังจากนั้นเราจะสร้าง network ของ podman container ด้วยคำสั่ง
$ podman-compose up -d
เหมือนกับการใช้งาน docker compose อีกแล้ว ลองดูตัวอย่างอื่นเพิ่มเติมได้ที่นี่
Podman Pods
การทำงานของ Pod ใน Podman จะเหมือนกับ Pod ใน kubernetes cluster เพราะใน Pod จะเป็นการ group รวม container เข้ามาไว้ด้วยกัน(ใช้ network และ volume ร่วมกัน) ถ้าอยู่ใน Pod เดียวกันจะใช้ localhost ในการเช้าถึง service ต่างๆได้เลย แต่ถ้าข้าม Pod เราจะใช้ IP address ในการเข้าถึง
สร้าง Pod
เริ่มต้นจากการสร้าง pod ขึ้นมาใหม่ด้วยคำสั่ง (pod ที่สร้างขึ้นจะ random container ขึ้นมาให้)
$ podman pod create
ถ้าเราไม่ได้กำหนดขื่อ podman จะ random ชื่อ pod ให้เราโดยอัตโนมัติ แต่ถ้าเราต้องการกำหนดชื่ีอ pod ให้ใส่ –name
$ podman pod create --name my_pod
List รายการของ Pod และ container
เมื่อเราต้องการ list รายชื่อ pods ใน kubernetes ออกมาเราจะใช้คำสั่ง
$ podman pod list
# หรือ
$ podman pod ls
ถ้าเราต้องการ list รายชื่อของ container เราจะใช้คำสั่ง
$ podman ps -a --pod
บรรจุ Container เข้าไปใน Pod
ถ้าเราต้องการใส่ container เข้าไป เราต้องรู้ชื่อ pod และใช้ –pod ในการกำหนดว่าจะใหh container ที่สร้างขึ้นไปอยู่ใน pod ไหน
$ podman run -dt --pod my_pod docker.io/library/alpine:latest top
- -dt คือการกำหนดใส้ container run เป็น backgroud(detached mode)
- –pod my_pod เป็นการระบุชื่อ pod ที่ต้องการใส่ container ลงไป
- docker.io/library/alpine:latest ระบุ container image ที่ต้องการ pull ลงมาจาก container registry ในตัวอย่างนี้ดึง container ลงมาจาก docker.io(docker hub)
- top เป็นคำสั่งที่เราสั่งให้ run ใน container เพื่อให้ container ยังคงค้างอยู่ใน running state ถ้า run container โดยไม่ใช้คำสั่งอะไรเลย container จะหยุดทำงานและกลับไปอยุ่ใน successed state
ข้อแนะนำ ในชีวิตจริงเราจะไม่ได้สร้าง pod จาก podman แต่จะใช้ kubernetes manifest file แทน