สำรวจ ‘Podman’ ทางเลือกแทน Docker ที่เสริมความปลอดภัย
(betterstack.com)- Podman มอบประสบการณ์การรันคอนเทนเนอร์ที่คล้าย Docker แต่ทำงานโดยไม่มี daemon จึงแตกต่างในด้านความปลอดภัยและ audit trail
- Docker ใช้โครงสร้าง client-server ที่มี Docker daemon เป็นศูนย์กลาง แต่ Podman สร้างคอนเทนเนอร์โดยตรงจาก session ของผู้ใช้ ทำให้ การติดตามผู้ใช้ที่รัน ชัดเจนกว่า
- เนื่องจากทำตามมาตรฐาน OCI จึงรัน image อย่าง
hello-world,caddy,wordpress,mysql:5.7จาก Docker Hub ได้ และในหลายกรณีสามารถเปลี่ยนคำสั่งdockerเป็นpodmanได้เลย - ชื่อ image แบบสั้นจะไม่ตั้งค่าเริ่มต้นเป็น Docker Hub โดยอัตโนมัติเหมือน Docker ดังนั้นจึงต้องใช้หนึ่งในทางเลือกคือ ชื่อ image แบบเต็ม, alias หรือการตั้งค่า
unqualified-search-registries - การจัดการหลายคอนเทนเนอร์ทำได้ด้วย Podman Compose, pods และ Kubernetes manifest แต่ไม่มี orchestration สำหรับ production ในตัวแบบ Docker Swarm จึงต้องใช้ระบบภายนอกอย่าง Kubernetes
จุดที่ Podman กับ Docker แตกต่างกัน
- Podman เป็น container engine แบบโอเพนซอร์สที่มุ่งเป็นทางเลือกที่ปลอดภัยและเบากว่า Docker
- รันคอนเทนเนอร์โดยไม่มี daemon ที่ทำงานค้างอยู่ตลอด และมีโครงสร้างที่ผู้ใช้จัดการคอนเทนเนอร์โดยตรง
- แนวทางความปลอดภัยพื้นฐานเน้น rootless container, user namespace และการใช้ capability ของเคอร์เนลอย่างระมัดระวังมากขึ้น
- มีความเข้ากันได้สูงกับ image และระบบคำสั่งของ Docker จึงเป็นตัวเลือกที่ใช้งานได้จริงสำหรับนักพัฒนาและผู้ดูแลระบบที่มองหาทางเลือกแทน Docker
สถาปัตยกรรมและ audit trail
- Docker ใช้ โมเดล client-server โดยคำขอรันคอนเทนเนอร์จะถูกส่งจาก Docker client ไปยัง Docker daemon
- process ของคอนเทนเนอร์จะกลายเป็น child process ของ Docker daemon ไม่ใช่ของ session ผู้ใช้
- เมื่อ
auditdซึ่งเป็นระบบ Linux Audit ตรวจจับ event ของ process คอนเทนเนอร์ audit user ID อาจแสดงเป็นunsetแทนที่จะเป็น user ID จริง - โครงสร้างนี้ทำให้เชื่อมโยงกิจกรรมอันตรายกับผู้ใช้เฉพาะรายได้ยาก
- Podman ใช้ สถาปัตยกรรมแบบ daemonless
- แต่ละคอนเทนเนอร์ถูกสร้างโดยตรงผ่าน login session ของผู้ใช้
- ข้อมูล process ของคอนเทนเนอร์ยังคงข้อมูลผู้ใช้ไว้
auditdสามารถตรวจจับและบันทึก user ID ของผู้ที่เริ่ม process คอนเทนเนอร์นั้นได้อย่างถูกต้อง
- ความเร็วในการเริ่มคอนเทนเนอร์ของ Podman อาจเร็วกว่า Docker ได้สูงสุด 50% ขึ้นอยู่กับ image
การจัดการ lifecycle ของคอนเทนเนอร์
- เนื่องจาก Podman ไม่มี daemon วิธีจัดการ lifecycle ของคอนเทนเนอร์จึงต่างจาก Docker ด้วย
- บน Linux จะพึ่งพา Systemd เป็นหลัก
- ใช้ service ของ
systemdชื่อpodman-restartเพื่อใช้นโยบาย restart ของคอนเทนเนอร์ที่กำหนดด้วย flag--restart always - service นี้จะเริ่มคอนเทนเนอร์ที่กำหนดใหม่โดยอัตโนมัติหลังระบบ reboot
- ใช้ service ของ
- ยังมีคำสั่งสำหรับสร้าง ไฟล์ Systemd service จากคอนเทนเนอร์ที่กำลังรันอยู่ด้วย
- เมื่อนำคอนเทนเนอร์ไปอยู่ภายใต้การจัดการของ
systemdจะเริ่ม หยุด และตรวจสอบได้ง่ายขึ้น
- เมื่อนำคอนเทนเนอร์ไปอยู่ภายใต้การจัดการของ
- Docker จัดการงานเหล่านี้ภายใน daemon
ตัวเลือกด้าน orchestration
- ในการพัฒนาแบบ local ผู้ใช้ Docker มักนิยามและจัดการแอปพลิเคชันหลายคอนเทนเนอร์ด้วย Docker Compose
- Podman ไม่รองรับไฟล์ Compose เป็นค่าเริ่มต้น แต่มี Podman Compose เป็นทางเลือกที่เข้ากันได้
- โดยทั่วไปทำงานร่วมกับไฟล์
docker-compose.ymlเดิมได้ - ผู้ใช้ที่คุ้นเคยกับ Docker Compose สามารถใช้ไฟล์ Compose เดิมต่อไปได้
- โดยทั่วไปทำงานร่วมกับไฟล์
- วิธี native ของ Podman สามารถใช้ pods ได้
- เป็นแนวคิดที่นำมาจาก Kubernetes
- สามารถจัดการหลายคอนเทนเนอร์เสมือนเป็นหน่วยเดียวได้
- สำหรับการ deploy ใน production Podman ไม่มีเครื่องมือ orchestration ในตัวแบบ Docker Swarm
- ในกรณีนี้ ระบบ orchestration ภายนอกอย่าง Kubernetes จะเป็นทางเลือก
- Kubernetes สามารถผสานกับ Podman ได้ แต่อาจต้องมีการกำหนดค่าและตั้งค่าเพิ่มเติมเพื่อให้ทำงานได้ถูกต้อง
ค่าเริ่มต้นด้านความปลอดภัย
- ความเสี่ยงใหญ่ในการรักษาความปลอดภัยของคอนเทนเนอร์คือสถานการณ์ที่เกิด container escape จนระบบ host ถูกบุกรุก
- Podman ถูกออกแบบให้มี การตั้งค่าความปลอดภัยเริ่มต้น ที่แข็งแรงกว่า Docker
- rootless container
- user namespace
- seccomp profile
- Docker ก็สามารถใช้ rootless container, user namespace และ seccomp profile ได้เช่นกัน แต่ไม่ได้เปิดใช้เป็นค่าเริ่มต้น และมักต้องตั้งค่าเพิ่มเติม
- การตั้งค่าเริ่มต้นของ Podman จะรัน rootless container ภายใน user namespace ที่แยกออกมา เพื่อจำกัดผลกระทบของการ escape ที่อาจเกิดขึ้น
- ค่าเริ่มต้นของ Docker รัน process ของคอนเทนเนอร์เป็น
rootจึงมีความเสี่ยงสูงกว่าเมื่อเกิด escape - ค่าเริ่มต้นของ capability ก็ต่างกันด้วย
- Podman เริ่มคอนเทนเนอร์ด้วย capability 11 รายการเป็นค่าเริ่มต้น
- Docker ใช้ capability 14 รายการด้วยค่าเริ่มต้นที่เปิดกว้างกว่า
- เครื่องมือทั้งสองสามารถตั้งค่าให้มีความปลอดภัยสูงได้ แต่โดยทั่วไป Podman ใช้ความพยายามน้อยกว่าในการไปถึงสถานะนั้น
ความแตกต่างที่โดดเด่นในการเปรียบเทียบฟีเจอร์
- Podman รองรับ สถาปัตยกรรมแบบ daemonless และการผสานกับ Systemd
- สามารถรวมคอนเทนเนอร์เป็น pods และจัดการ Kubernetes YAML ได้
- Docker รองรับ Docker Swarm แต่ Podman ไม่รองรับ
- ฟีเจอร์อื่นส่วนใหญ่ถือว่าโดยรวมใกล้เคียงกันทั้งสองฝั่ง
การติดตั้งและสภาพแวดล้อมการรัน
- Podman รันได้บนระบบปฏิบัติการหลัก ๆ เช่นเดียวกับ Docker
- macOS
- Windows
- Linux distribution หลัก ๆ
- ความแตกต่างสำคัญคือบน Linux จะรันแบบ native แต่บน Windows และ macOS ต้องใช้ virtual machine
- ตัวอย่างนี้สมมติใช้ Linux distribution ตระกูล Debian ได้แก่ Ubuntu, Mint และ Debian
- หากต้องการติดตั้ง Podman รุ่นล่าสุด ต้องใช้ distribution ที่ค่อนข้างใหม่
- ณ เวลาที่เขียน บทความ Podman รุ่นหลักล่าสุดคือ
4.x - Ubuntu 22.04 LTS ถูกผูกไว้กับ Podman
3.x - ตัวอย่างอ้างอิง Ubuntu 23.10
- ณ เวลาที่เขียน บทความ Podman รุ่นหลักล่าสุดคือ
- หลังติดตั้ง output ตัวอย่างคือ
podman version 4.3.1และยืนยันได้ว่าสามารถรันคำสั่งpodmanในเครื่องได้
การรัน Docker image และความเข้ากันได้กับ OCI
- Podman สามารถรัน image
hello-worldที่สร้างด้วยเครื่องมือใน ecosystem ของ Docker ได้ - ความเข้ากันได้นี้เกิดจากทั้ง Docker และ Podman ต่างทำตามมาตรฐาน OCI(Open Container Initiative)
- OCI กำหนดข้อกำหนดรูปแบบ image และข้อกำหนด runtime
- ทำให้ container runtime ต่าง ๆ ทำงานร่วมกันได้
- Docker image และคอนเทนเนอร์ส่วนใหญ่บน Docker Hub สามารถใช้กับ Podman ได้
- สามารถย้าย workload เดิมไปยัง Podman โดยไม่ต้องแก้ไข หรือใช้คลัง image บน Docker Hub ได้
- แม้ output ของ
hello-worldจะแสดง “Hello from Docker!” แต่ตัวที่รันจริงคือ Podman- Docker client หรือ Docker daemon ไม่ได้เกี่ยวข้องกับกระบวนการรัน
วิธีจัดการชื่อ image แบบสั้น
- หากไม่ระบุชื่อ image แบบเต็ม Docker จะใช้ Docker Hub หรือ
docker.ioเป็น registry เริ่มต้น - Podman ไม่แนะนำให้ใช้ชื่อสั้น และไม่สมมติ registry เริ่มต้นโดยอัตโนมัติ
hello-worldมี alias อยู่ในshortnames.confจึงถูกตีความเป็นdocker.io/library/hello-world- หากรัน image ที่ไม่มี alias อย่าง
caddyด้วยชื่อสั้น จะเกิดข้อผิดพลาดดังนี้Error: short-name "caddy" did not resolve to an alias and no unqualified-search registries are defined in "/etc/containers/registries.conf"
- วิธีแก้มีสามแบบ
- ใช้ ชื่อ image แบบเต็ม โดยระบุชัดเจน เช่น
docker.io/library/caddy - เพิ่ม section
[aliases]ในregistries.confแล้วกำหนด alias เป็น"caddy"="docker.io/caddy" - ตั้งค่า
unqualified-search-registries=["docker.io"]เพื่อให้ค้นหาชื่อสั้นจาก Docker Hub
- ใช้ ชื่อ image แบบเต็ม โดยระบุชัดเจน เช่น
- การตั้งค่ารายผู้ใช้สามารถไว้ที่
$HOME/.config/containers/registries.conf- ไฟล์นี้มี priority สูงกว่า
/etc/containers/registries.conf - ตั้งค่าได้โดยไม่ต้องใช้สิทธิ์ root จึงเข้ากับแนวทาง rootless มากกว่า
- ไฟล์นี้มี priority สูงกว่า
- หากต้องการใช้ Podman เหมือนตัวแทน Docker การตั้งค่า
unqualified-search-registriesจะสะดวกกว่า alias ในระยะยาว
การใช้ private registry
- Podman สามารถใช้ private registry ได้เหมือน Docker
- ตัวอย่างการใช้บัญชี Docker Hub มีลำดับดังนี้
- สร้าง access token ใน Docker Hub
- ตั้งคำอธิบายเป็น
Podman tutorialและสิทธิ์เป็นRead & Write - สร้าง private repository
- login ด้วย
podman login docker.io
- หาก
docker.ioเป็นรายการแรกของunqualified-search-registriesในregistries.confสามารถละไว้ได้ แต่แนวปฏิบัติที่ดีคือระบุ registry ให้ชัดเจน - หากไม่ระบุ registry
podman loginจะล้มเหลวด้วยข้อผิดพลาดต่อไปนี้Error: no registries found in registries.conf, a registry must be provided
- หลัง login สามารถ push image
hello-worldไปยัง private repository ลบ public image ใน local แล้วรันคอนเทนเนอร์จาก image ใน private repository ได้ - หากไม่มี credential สำหรับ login ที่ถูกต้อง เมื่อ pull private image จะเกิดข้อผิดพลาดถูกปฏิเสธการเข้าถึงและต้องยืนยันตัวตน
- ความแตกต่างที่เห็นได้ชัดในการใช้ private registry คือเปลี่ยนจาก
dockerเป็นpodmanและ Podman ใช้ร่วมกับ private registry ที่นิยมใช้กันได้
รันหลายคอนเทนเนอร์ด้วย Podman Compose
- เมื่อต้องรันหลายคอนเทนเนอร์เป็นหน่วยเดียว Podman มีหลายตัวเลือก
- Podman Compose
- pods
- Kubernetes manifests
- ตัวอย่างใช้ Podman Compose เพื่อรัน WordPress และ MySQL
- Podman Compose เป็นเครื่องมือที่ขับเคลื่อนโดยชุมชน ซึ่ง implement Compose specification และผสานกับ Podman
- พึ่งพา Python 3 และในตัวอย่างติดตั้งด้วย pipx
- output การติดตั้งตัวอย่างคือ
podman-compose 1.0.6 - เวอร์ชัน Podman ที่ใช้คือ
4.3.1
- output การติดตั้งตัวอย่างคือ
- หาก
pipxติดตั้งไว้ที่$HOME/.local/binpath ดังกล่าวอาจไม่ได้อยู่ใน$PATH- สามารถเพิ่ม path ได้ด้วย
pipx ensurepath - ต้องเปิด terminal ใหม่หรืออ่านไฟล์ตั้งค่า shell ใหม่
- สามารถเพิ่ม path ได้ด้วย
ตัวอย่าง WordPress และ MySQL
- ตัวอย่างนิยามผู้ใช้ฐานข้อมูล รหัสผ่าน และชื่อฐานข้อมูลในไฟล์
.envและกำหนด service ของ WordPress กับ MySQL ในdocker-compose.yml - เมื่อรัน
podman-compose up -dPodman Compose จะวิเคราะห์docker-compose.yml - ขั้นตอนการจัดการ service
wordpress- ค้นหา external volume ที่จำเป็น และสร้างหากไม่มี
- ค้นหา network ที่เหมาะสม และสร้างหากไม่มี
- รันคอนเทนเนอร์
wordpress - หากไม่มี image ใน local จะดึง
wordpress:latestจาก registrydocker.ioที่ตั้งค่าไว้
- ขั้นตอนการจัดการ service
db- สร้าง volume
podman-tutorial_db - ตรวจสอบ network เดิม
- รันคอนเทนเนอร์
mysql:5.7 - หากไม่มี image ใน local จะดึงจาก Docker Hub
- สร้าง volume
- หลังรันแล้วจะเห็นหน้า install ของ WordPress ที่
localhost:8080 - output ของ
podman psจะแสดงว่าคอนเทนเนอร์wordpressและdbกำลังรันอยู่wordpressmap port เป็น0.0.0.0:8080->80/tcpdbรันด้วย imagemysql:5.7
- รายการ image จะแสดง
docker.io/library/wordpress:latestและdocker.io/library/mysql:5.7 - รายการ network จะแสดง network เริ่มต้น
podmanและ networkpodman-tutorial_defaultที่ Podman Compose สร้างขึ้นpodman-tutorial_defaultถูกสร้างเพื่อแยกคอนเทนเนอร์ที่นิยามในdocker-compose.ymlออกจากคอนเทนเนอร์อื่นในระบบเดียวกัน
- รายการ volume จะแสดง
podman-tutorial_dbและpodman-tutorial_wordpress podman-compose downจะหยุดและลบคอนเทนเนอร์ แต่ยังคง network และ volume ไว้- ใช้
podman volume rmเพื่อลบ volume - ใช้
podman network rmเพื่อลบ network
- ใช้
- คำสั่งแทบเหมือนกับ Docker และ Docker Compose ต่างกันเพียงพิมพ์
podmanและpodman-composeแทนdockerและdocker-compose
เกณฑ์ในการเลือก
- Podman เป็นทางเลือกที่ใช้งานได้จริงแทน Docker สำหรับการรัน container workload
- ทำงานส่วนใหญ่ที่ Docker ทำได้ และมีข้อดีคือไม่ต้องใช้ daemon เบื้องหลัง
- ยังมีฟีเจอร์ที่ Docker ไม่มีด้วย
- ทำงานกับไฟล์ Kubernetes manifest
- จัดคอนเทนเนอร์เดี่ยวเป็น pods
- หากต้องการโซลูชันจัดการคอนเทนเนอร์ที่เบากว่าและปลอดภัยกว่า Podman อาจเป็นตัวเลือกที่ดีกว่า
- หากให้ความสำคัญกับ ecosystem ที่แข็งแรงและการสนับสนุนจากชุมชนวงกว้าง Docker อาจเหมาะกว่า
- สำหรับข้อมูลเพิ่มเติม สามารถดู เว็บไซต์ทางการของ Podman, เอกสาร, ชุมชน
1 ความคิดเห็น
ความเห็นจาก Hacker News
ช่วงที่ Podman รองรับ ไฟล์ยูนิต systemd นั้นดีมาก เพราะสามารถตั้งให้ทั้งคอนเทนเนอร์และ pod ทั้งชุดเริ่มอัตโนมัติและอัปเดตอัตโนมัติผ่าน systemd ได้
แต่แล้วฟีเจอร์นั้นก็ถูกถอดออกและเริ่มผลักดัน Quadlet แทน สำหรับคอนเทนเนอร์เดี่ยวยังใช้ไฟล์ยูนิตได้ แต่ถ้าเป็น pod ต้องใช้คำจำกัดความของคลัสเตอร์ Kubernetes
แถมต่างจาก Docker ตรงที่คอนเทนเนอร์ปฏิบัติตาม ข้อกำหนดของ SELinux เลยทำให้เข้าถึงไดเรกทอรีที่แมปไว้ไม่ได้และเจอปัญหาหลายครั้ง
สุดท้ายก็ไม่เข้าใจว่า Podman ต้องการให้ทำอะไรกันแน่ จะให้ใช้ Kubernetes หรือ? จะให้เลิกแมปพาธเชิงตรรกะแล้วไปสร้างไดเรกทอรีเฉพาะทั้งหมดหรือ?
ฟีเจอร์นี้จะเขียนไฟล์ยูนิตเองโดยไม่ใช้ฟีเจอร์ Podman แบบเดิมที่ตอนนี้เลิกใช้แล้ว และสำหรับผมมันลื่นไหลกว่าวิธีเดิมของ Podman มาก
การเปิดใช้ฟีเจอร์ทำด้วย
$ podman-compose systemd -a create-unitและการลงทะเบียนยูนิต systemd ใช้$ podman-compose systemd -a register,$ systemctl --user enable --now "podman-compose@$PROJECT_NAME"การอัปเดตทำด้วย
$ podman-compose pullแล้วตามด้วย$ systemctl --user restart "podman-compose@$PROJECT_NAME"โดย$PROJECT_NAMEมักเป็นชื่อไดเรกทอรีถ้าอยากตรวจสอบ ซอร์สโค้ดของฟีเจอร์อยู่ที่นี่: https://github.com/containers/podman-compose/blob/f6dbce3618...
ตอนนี้ผมยังใช้ podman 4.3.1 อยู่ แต่ก็ดูไม่มีเหตุผลว่าทำไมวิธีนี้จะใช้ไม่ได้ในเวอร์ชันหลังจากนั้น
และไฟล์ systemd ที่ podman-generate-systemd เคยสร้างให้ สุดท้ายก็แค่รัน
"podman start containername"เลยเขียนเองได้ไม่ยาก เพียงแต่ไม่เหมือน docker-compose ที่จัดการได้สะดวก คอนเทนเนอร์ค่อนข้างเป็นกล่องดำข้อดีของ Quadlet คือการประกาศคำนิยามคอนเทนเนอร์ไว้ในไฟล์
.containerเมื่อก่อนต้องเขียนบรรทัดคำสั่ง podman run ลงในยูนิต systemd เอง ดังนั้นในแง่นี้ Quadlet ถือว่าพัฒนาขึ้นมาก และอาจเป็นทางเลือกแทน docker-compose ได้ แน่นอนว่าก็มีทั้งข้อดีและข้อเสียทุกครั้งที่พยายามรัน
podman generate systemd [...]ก็จะนึกขึ้นได้อีกครั้งว่ามีการเปลี่ยนผ่านนี้เกิดขึ้นที่ไม่ค่อยเจอบ่อยก็เพราะผมทำ Ansible role ของตัวเองไว้เพื่อจัดการเรื่องนี้แบบพอใช้ได้
ถึงอย่างนั้นก็ยังรู้สึกว่า Podman หลงทิศทางไปแล้ว ในเมื่อยอมรับภาระเรื่องการดูแลไฟล์ยูนิตและการออกแบบความสัมพันธ์มาแล้ว ก็อยากให้เปิดทางให้ใช้ตัวสร้างต่อไปได้ ไม่สนว่า Quadlet หรือคำอธิบายว่ามันดีกว่าจะเป็นอย่างไร
containers.confได้:[containers] label=falseถ้าไม่ชอบระดับความปลอดภัยตั้งต้นของ Podman โดยทั่วไปก็มักมีวิธีปิดได้
โมเดลนี้เข้าใจง่ายมาก แต่ถ้าจะนำไปใช้กับ Docker Compose ต้องย้ายด้วยมือลำบากพอสมควร
เลยทำเครื่องมือที่แปลงไฟล์ Compose เป็นคอนฟิก NixOS เพื่อให้ตีความและจัดการแบบเนทีฟได้: https://github.com/aksiksi/compose2nix
มีข้อดีอย่างหนึ่งของ Podman ที่แทบไม่ค่อยถูกพูดถึงในฐานะเหตุผลเด็ดขาดว่าทำไมควรเลือกมันแทน Docker นั่นคือ Docker ทำการตั้งค่าเครือข่ายพัง
ถ้าพยายามรัน Docker กับเครื่องเสมือน KVM พร้อมบริดจ์เครือข่ายไปด้วยพร้อมกัน มันเหมือนฝันร้าย แต่ Podman เข้ากันได้ดีกว่ามากแม้ใช้แค่ค่าตั้งต้น
ผมก็เคยมีทั้งกรณีที่ VPN พังเพราะ Docker หรือ Docker พังเพราะ VPN อยู่บ่อย ๆ ไม่รู้เหมือนกันว่าเครือข่ายของ Podman ภายในทำงานอย่างไร แต่ดูเหมือนออกแบบมาได้ดีอย่างน้อยก็ไม่ไปขัดขวางอย่างอื่น ซึ่งเป็นสิ่งที่พูดถึง Docker แบบนั้นไม่ได้เลย
ผมมองว่า Dockerfile เป็นขยะล้วน ๆ มีภาษาทั่วไปให้ใช้ได้อยู่แล้ว แต่ผมเกลียดเวลาที่ “นักพัฒนาที่ว่างเกินไป” ชอบสร้าง DSL หรือภาษาโปรแกรมใหม่ขึ้นมา โดยเฉพาะถ้าเป็น YAML ก็ยิ่งแย่ แม้กรณีนี้จะไม่ใช่ YAML แต่ Dockerfile ก็เป็นตัวอย่างชั้นดีว่าทำไมควรเลิกทำแบบนั้น
ถ้ามอง Buildah แบบไม่มี
budจะเห็นเหตุผลชัดเลยว่า คุณสามารถใช้ Bash, Fish หรืออะไรก็ได้ที่ต้องการ แทน DSL ครึ่ง ๆ กลาง ๆ ที่น่าหงุดหงิดทันทีที่กรณีใช้งานหลุดจากเส้นทางมาตรฐานไปนิดเดียวการตัดสินใจแย่ ๆ แบบนี้ส่งผลต่อทั้ง ecosystem ของ Docker ด้วย DCS และตัวแทนที่ดูไม่เคยเสร็จสมบูรณ์ก็เป็นตัวอย่าง แทนที่จะใช้โปรโตคอลการเซ็นชื่อที่เป็นมาตรฐานอย่าง Cosign กลับอยากสร้างระบบซับซ้อนที่ทำอัตโนมัติได้ยาก และโดยเฉพาะการหมุนเวียนคีย์ก็ยุ่งยาก
ดีใจที่ Podman ถูกใช้งานแพร่หลายขึ้น เครื่องมือจำนวนมากเกินไปถูกสร้างโดยตั้งสมมติฐานว่าผู้ใช้จะเพิ่มตัวเองเข้าไปในกลุ่ม
sudo dockerทำให้มันพังเมื่อเจอกับ การตั้งค่า Docker แบบคำนึงถึงความปลอดภัย ที่ไม่ได้ให้สิทธิ์ root แบบส่งเดชในฐานะ วิศวกร RHEL ที่ได้รับการรับรอง ผมใช้ Podman มาหลายปีแล้ว
พูดตามตรง สำหรับการใช้งานคอนเทนเนอร์ส่วนตัวผมค่อนข้างชอบมันมาก แต่ที่ทำงานก็ยังให้ Docker กับนักพัฒนาอยู่เหมือนเดิม จนถึงตอนนี้ยังไม่มีวิธีมอบสิ่งที่ทัดเทียมกับความเรียบง่ายของ docker compose ให้กับนักพัฒนาได้
ตอนสร้างอิมเมจคอนเทนเนอร์ ใน CI pipeline ก็ใช้ buildah ด้วยเหมือนกัน แต่ในมุมมองของผู้ใช้ปลายทางที่เป็นนักพัฒนา docker compose ก็ยังครองความนิยมอยู่
https://www.techrepublic.com/article/how-to-fix-the-docker-a...
ผมเกือบซวยเพราะปัญหานี้
ยังไม่ค่อยเข้าใจนักว่าทำไม Red Hat ถึงทุ่มลงทุนสร้างทางเลือกแทน Docker แต่ชอบผลลัพธ์ที่ออกมามาก
Podman ทำได้แทบทุกอย่างที่ Docker ทำได้ แถมยังมีฟีเจอร์เพิ่มอย่าง pod หรือในหลายกรณีก็มีแนวทางที่ดีกว่าโดยตัวมันเอง เช่น กระบวนการสร้างคอนเทนเนอร์แบบไม่ต้องมีเดมอน
สำหรับนักพัฒนาทั่วไป ปัญหาใหญ่สุดน่าจะเป็น Docker compose แต่ถ้าใช้ไฟล์ compose แบบไม่ซับซ้อน ก็มีสคริปต์ podman-compose ที่พยายามให้เข้ากันได้กับสเปกของ Docker compose
ยังมีวิธีใช้ Podman เป็นแบ็กเอนด์ของ docker-compose ด้วย [1] โดยรวมแล้วในปี 2024 มองไม่เห็นเหตุผลว่าทำไมบนเครื่อง Linux ยังต้องใช้ Docker ส่วนบน macOS หรือ Windows ไม่แน่ใจว่า Podman เป็นอย่างไร
[1] https://www.redhat.com/sysadmin/podman-docker-compose
เมื่อรวมกับข้อเท็จจริงที่ว่า Docker มีปัญหาด้านความปลอดภัยมากผิดปกติทั้งในอดีตและปัจจุบัน และคอนเทนเนอร์กับอิมเมจแบบ Docker ก็ถูกใช้อย่างแพร่หลายในหมู่นักพัฒนา สุดท้ายจึงเลี่ยงไม่ได้ที่จะต้องสร้าง implementation ของตัวเองที่เหมาะกับคุณค่าและแนวทางของ RHEL มากกว่า
ตัวอย่างเช่น Docker ทำ rootless ได้ แต่ก็ยังไม่ตั้งให้เป็นค่าปริยายอยู่ดี ในสภาพแวดล้อมที่เข้มงวดขึ้น ทั้ง docker user group และวิธีรันแบบไม่ใช้กลุ่ม ต่างก็ยอมรับได้ยากในเชิงความปลอดภัยสำหรับหลายกรณีการใช้งาน
Docker ในยุคแรกค่อนข้างไม่จริงจังกับการทำให้คอนเทนเนอร์ที่ไม่มีสิทธิพิเศษมีการแยกตัวอย่างน้อยที่สุด และแม้ปัญหาจะเป็นที่รับรู้แล้วก็ยังใช้เวลานานกว่าจะแก้ได้ นอกจากนี้ยังมีปัญหามากกับไฟร์วอลล์ กฎเครือข่าย และวิธีที่มันทำงานร่วมกับ SELinux นี่จึงเป็นเหตุผลว่าทำไมในบริษัทที่มีผู้ดูแลระบบ Linux โดยเฉพาะและให้ความสำคัญกับความปลอดภัย การแบน Docker จึงไม่ใช่เรื่องแปลก
ตั้งแต่เริ่มต้น เอกสารทั้งหมดก็พาไปทางการติดตั้งผ่าน GUI ที่ไม่เป็นมิตรกับผู้ใช้อย่างชัดเจน มันรันโปรเซสหนัก ๆ ตอนบูตเครื่อง บังคับให้สมัครบัญชีคลาวด์ด้วยเหตุผลบางอย่าง และยังคอยบ่นอีกว่าอย่าใช้ผลิตภัณฑ์โอเพนซอร์สตัวนี้ในงาน
ทางเลือกที่ไม่รองรับอย่างการติดตั้งแบบ “command-line Docker only” ก็ซับซ้อนเกินจำเป็น และตอนที่ลองครั้งล่าสุด WSL VM ส่วนใหญ่ก็ยังไม่รองรับในสภาพตั้งต้นด้วยซ้ำ
ตรงกันข้าม Podman แค่
winget install podmanก็จบและไม่รบกวนอะไร มันจะเริ่ม Podman VM เฉพาะตอนที่ต้องรันคอนเทนเนอร์ และเมื่อไม่ต้องใช้ ระบบก็กลับไปทำงานเหมือนเดิมถ้าต้องรันอะไรผ่านไฟล์ compose ก็มี podman-compose ให้ใช้ อาจจัดการการตั้งค่าแปลก ๆ ได้ไม่ครบ แต่สำหรับการใช้งานของฉันมันทำงานได้ดี
สิ่งที่ Podman ทำได้ไม่ค่อยดีจริง ๆ ก็คงเป็นการเชื่อมกับ VS Code แต่ความลำบากในการทำให้ Docker บน Windows ยอมทำงานเงียบ ๆ นั้นน่ารำคาญกว่าการเสียคีย์ลัดของ VS Code ไปไม่กี่ปุ่มมาก จึงไม่ใช่ปัญหา
บน Windows ขอแนะนำ Podman เป็นทางเลือกพื้นฐานสำหรับคอนเทนเนอร์ เหตุผลที่จะใช้ Docker มีประมาณว่าองค์กรออกค่าใช้จ่ายให้ หรือมี compose configuration ที่ซับซ้อน ซึ่งถ้าเป็นกรณีนั้น การย้ายไป Kubernetes อาจคุ้มค่าด้วยซ้ำ
มันทำเรื่องที่ทำให้ระบบพังได้ มีปัญหากับ rootless อยู่หลายปี และยังมีเรื่อง vendor lock-in ที่มองข้ามไม่ได้
Podman เปิดกว้าง เป็นไปตามมาตรฐาน และเข้ากับ Kubernetes ได้ดี เพียงเพราะเข้ามาในตลาดคอนเทนเนอร์แบบใช้งานง่ายก่อน นักพัฒนาจึงทุ่มแรงไปกับ Docker มากเกินสมควรอย่างไม่น่าเชื่อ
ถ้า Docker หายไป RedHat ก็จะมีอำนาจมากขึ้นในการผลักดันวาระองค์กรของตัวเอง
แม้ Podman จะมีข้อดี แต่ในกระบวนการที่ RedHat พยายามแทนที่ทุกอย่างของ Docker ก็มีส่วนที่ทำออกมาได้ไม่ดีเช่นกัน
ถ้ามองประวัติการเข้ามาในพื้นที่คอนเทนเนอร์ของ RedHat ก็มีแง่ที่พวกเขาสูญเสียเวลาและความพยายามไปกับโครงการจำนวนมาก ทั้งที่สามารถเข้าไปมีส่วนร่วมและช่วยปรับปรุงได้
RedHat ไม่ใช่บริษัทที่มีวาระเพื่อทำสิ่งที่ถูกต้องให้ลูกค้า ดังนั้นในภาพใหญ่ควรคิดด้วยว่าพวกเขาต้องการอะไรกันแน่
ข้อเสียใหญ่เพียงอย่างเดียวของ Podman บน macOS คือไม่สามารถใช้ host network จากในคอนเทนเนอร์ได้ แต่กรณีที่อยากใช้ host network จากคอนเทนเนอร์จริง ๆ ก็พบไม่บ่อย
อย่างไรก็ตาม ถ้ากำลังทดลองเรื่องเครือข่ายในคอนเทนเนอร์และอยากคงชื่อโฮสต์กับ IP address เดียวกับโฮสต์ไว้ ก็ควรคำนึงถึงเรื่องนี้ด้วย ถึงอย่างนั้นก็ยังมีวิธีหลบข้อจำกัดนี้และใช้งานต่อได้
ชอบแนวทางและการตัดสินใจที่ให้ความสำคัญกับความปลอดภัยก่อน ดูปลอดภัยตั้งแต่ค่าปริยาย และก็ชอบที่มันทำงานร่วมกับ docker compose ได้
แต่ก็สงสัยว่า ถ้า Podman ได้รับความนิยมมากพอ วันหนึ่งมันจะเลือกเดินคนละทางในเรื่องคำสั่งและรูปแบบ yml หรือไม่ ตอนนี้มันดูเหมือนเป็นเครื่องมือที่อาศัย Docker และรูปแบบไฟล์ Docker compose อยู่
อยากให้ Podman มีทางเลือกแทน Swarm ตอนนี้รู้สึกเหมือน Kubernetes ถูกใช้เป็นไม้ค้ำเพราะยังขาด orchestration
ถ้าเป็นทีมที่ใส่ใจความปลอดภัยดี ๆ ก็น่าจะสร้างวิธีรันคอนเทนเนอร์ในสเกลเล็กให้สมเหตุสมผลง่าย ๆ ได้ โดยไม่ต้องลงลึกกับ Kubernetes ซึ่งไม่ได้ปลอดภัยตั้งแต่ค่าปริยายเหมือนเรียนระดับปริญญาเอก และยังคงความเข้ากันได้กับรูปแบบ Docker compose ไว้ได้ด้วย
เห็นด้วยว่า ฟีเจอร์ด้านความปลอดภัย อย่างคอนเทนเนอร์แบบ rootless และ namespace ที่แยกออกจากกันเป็นเรื่องสำคัญ แต่ Docker ก็ทำแบบ rootless ได้เหมือนกันและไม่ได้ซับซ้อน แค่ตั้งค่าให้เป็นแบบนั้นก็พอ
ตอนนี้ผม/ฉันเคยเขียนบทความเกี่ยวกับการตั้งค่า Mastodon ด้วย Docker แบบ rootless โดยใช้แนวปฏิบัติที่ดีที่สุดทั้งหมดเท่าที่ทำได้ [1]
ข้อดีของการใช้ Docker ต่อไปคือเข้าถึงได้ง่ายกว่า มีทั้งชุมชนและบล็อกมากกว่า การตั้งค่า docker compose ก็แพร่หลายกว่า และคนรอบตัวที่ใช้งานเป็นก็มีมากกว่า
สุดท้ายแล้วทั้ง Podman และ Docker ต่างก็รันโปรเซสภายใน namespace ที่แยกออกจากโฮสต์
[1]: https://du.nkel.dev/blog/2023-12-12_mastodon-docker-rootless...
ไม่ได้อยากให้เข้าใจผิดนะ Podman ยอดเยี่ยมมาก และทุกวันนี้ผม/ฉันก็ใช้มันแทน Docker แต่ตอนแรกเริ่มใช้เพราะคิดว่าเป็นแค่ตัวแทน Docker แบบตรงไปตรงมา แล้วก็เจ็บตัวหนักกับเรื่อง การแมป UID/GID, นโยบาย SELinux และการตั้งค่า DNS ที่ขาดหายไป
เคยลองรัน
system migrateเพื่อแก้ปัญหา แล้วกลับทำให้การตั้งค่าทั้งหมดพังมาหลายครั้งเหมือนกัน มีระบบเฉพาะของมันเองเกี่ยวกับ security ACL, การแมป ID และ labelถ้าไปรัน
chmod -Rใต้โฟลเดอร์ home มีโอกาสที่คอนเทนเนอร์ทั้งหมดจะพังได้แม้จะพอใจกับผลลัพธ์ แต่ก็ยังห่างไกลจากโซลูชันแบบ “แค่ใช้แล้วมันก็ทำงาน” อย่าง Docker คิดว่าหลังจากที่ผม/ฉันเริ่มใช้มา มันน่าจะพัฒนาขึ้นมากแล้ว
สำหรับผม/ฉัน มันใช้ง่ายกว่า Docker และดูเหมือนว่าตอนนี้จะดีขึ้นกว่าสถานการณ์ที่เล่ามาข้างบนแล้ว
ถ้ามองในภาพใหญ่ Podman ให้ความรู้สึกเหมือน Linux ในอดีต คือเป็นสิ่งที่ขาดไม่ได้
ถึงจะมีคนใช้น้อยมาก แต่แค่การมีอยู่ของมันก็ช่วยยับยั้งไม่ให้พี่น้องสายซอฟต์แวร์กรรมสิทธิ์ที่ใหญ่กว่ามากทำเรื่องแย่ ๆ ได้
ที่พูดว่า “Linux ในอดีต” ไม่ได้หมายความว่า Linux สำคัญน้อยลง แต่ตรงกันข้าม ทุกวันนี้มันยิ่งจำเป็นและกลายเป็นศูนย์กลางมากขึ้น