Quadlet: รันคอนเทนเนอร์ Podman ด้วย systemd
(mo8it.com)- เนื่องจาก Podman ไม่มี daemon จึงต้องมีตัวดำเนินการที่จะยกคอนเทนเนอร์ขึ้นมาได้อย่างเสถียรหลังเซิร์ฟเวอร์บูต และ Quadlet แก้ปัญหานี้ด้วยแนวทางแบบไฟล์บริการของ systemd
- เดิมที
podman generate systemdต้องจัดการการสร้างคอนเทนเนอร์และการสร้างไฟล์บริการแยกกัน และทุกครั้งที่ต้องเปลี่ยนไฟล์ที่สร้างขึ้นก็มีภาระในการ แก้ไขด้วยมือ - Quadlet วางการตั้งค่า
[Container],[Service],[Install]ไว้ร่วมกันในไฟล์.containerภายใต้~/.config/containers/systemdทำให้จัดการตัวเลือกของ Podman และพฤติกรรมของ systemd ได้ในที่เดียว - สำหรับ rootless Podman การเริ่มอัตโนมัติตอนบูตต้องใช้
WantedBy=default.targetและต้อง เปิดใช้งาน linger ส่วนmulti-user.targetไม่ได้ถูกกำหนดไว้ในโหมดผู้ใช้ - เมื่อใช้
AutoUpdate=registry, dependency ของ systemd, การจัดกลุ่มไฟล์ตามไดเรกทอรี และเครื่องมือแปลงpodletร่วมกัน Quadlet จึงเหมาะกับการดำเนินงาน Podman แบบ rootless·daemonless
ทำไมจึงต้องมี Quadlet
- Quadlet คือวิธีที่ทำให้รันคอนเทนเนอร์ Podman ได้เหมือนบริการของ systemd
- สามารถรันคอนเทนเนอร์ในเบื้องหลังได้
- สามารถเริ่มคอนเทนเนอร์อัตโนมัติหลังเซิร์ฟเวอร์รีบูตได้
- แนวทางการรันคอนเทนเนอร์ Podman ภายใต้ systemd เองไม่ใช่เรื่องใหม่
- เดิมใช้คำสั่ง
podman generate systemd - ตอนนี้คำสั่งนี้แสดง คำเตือนว่าเลิกใช้แล้ว และแนะนำให้ย้ายไปใช้ Quadlet
- เดิมใช้คำสั่ง
- Podman มีโครงสร้างแบบ daemonless ดังนั้นจึงต้องมีตัวดำเนินการที่จะเริ่มคอนเทนเนอร์ให้โดยไม่ต้องมี daemon
ความไม่สะดวกของวิธีเดิม podman generate systemd
- วิธีเก่าต้องสร้างคอนเทนเนอร์ด้วย
podman createก่อน- คอนเทนเนอร์ตัวอย่างใช้ image
docker.io/library/postgres:16 - รวม
-p 5432:5432, การเมานต์ volume, ตัวแปรสภาพแวดล้อมPOSTGRES_PASSWORDและ labelio.containers.autoupdate=registry
- คอนเทนเนอร์ตัวอย่างใช้ image
- จากนั้นรัน
podman generate systemd test-db -fn --newเพื่อสร้างไฟล์container-test-db.service - ไฟล์บริการที่สร้างขึ้นถูกวางไว้ที่
~/.config/systemd/userแล้วเปิดใช้งานและเริ่มด้วยคำสั่งต่อไปนี้systemctl --user enable --now container-test-db
- flow นี้ทำให้ต้องทำซ้ำขั้นตอนการสร้างคอนเทนเนอร์ สร้างไฟล์บริการ ย้ายไฟล์เมื่อจำเป็น และเปิดใช้งานบริการ
- เมื่อคำสั่งสร้างคอนเทนเนอร์ยาวขึ้น ก็ต้องจัดการ shell script แยกต่างหากเพื่อให้รันซ้ำในภายหลังได้
- หากต้องการปรับแต่งไฟล์บริการ systemd ที่สร้างขึ้น ก็ต้อง แก้ไขด้วยมือ ใหม่ทุกครั้ง
โครงสร้างไฟล์ Quadlet
- ในแนวทาง Quadlet ให้สร้างไดเรกทอรี
~/.config/containers/systemdแล้ววางไฟล์.containerไว้ข้างใน - ไฟล์ตัวอย่าง
test-db.containerมีองค์ประกอบต่อไปนี้[Container]Image=docker.io/library/postgres:16AutoUpdate=registryPublishPort=5432:5432Volume=%h/volumes/test-db:/var/lib/postgresql/data:ZEnvironment=POSTGRES_PASSWORD=CHANGE_ME
[Service]Restart=always
[Install]WantedBy=default.target
- ไฟล์
.containerเป็นไฟล์บริการ systemd ทั่วไป แต่มีส่วนพิเศษ[Container]รวมอยู่ด้วย - หลายตัวเลือกใน
[Container]สอดคล้องกับตัวเลือกบรรทัดคำสั่งที่ใช้ในpodman createImage: image และ tag ที่จะใช้AutoUpdate=registry: สอดคล้องกับ--label "io.containers.autoupdate=registry"PublishPort: สอดคล้องกับ-pVolume: สอดคล้องกับ-vEnvironment: สอดคล้องกับ-e
- สำหรับไดเรกทอรี home ของผู้ใช้ ต้องใช้ตัวระบุของ systemd คือ
%hแทน~ Restart=alwaysใน[Service]ทำให้คอนเทนเนอร์รีสตาร์ตเสมอ เว้นแต่จะหยุดด้วยมือWantedBy=default.targetใน[Install]ทำให้คอนเทนเนอร์เริ่มอัตโนมัติเมื่อบูต
การตั้งค่า systemd ที่จำเป็นสำหรับ rootless Podman
- สำหรับคอนเทนเนอร์แบบ rootless ต้องใช้
default.targetไม่ใช่multi-user.targetmulti-user.targetไม่ได้ถูกกำหนดไว้ในโหมดผู้ใช้ของ systemd- ตรวจสอบได้ด้วย
systemctl --user status multi-user.target - ในโหมดระบบตรวจสอบได้ด้วย
systemctl status multi-user.target
- เนื่องจากรันคอนเทนเนอร์เป็นบริการผู้ใช้ของ systemd หากต้องการให้คอนเทนเนอร์เริ่มแม้ผู้ใช้ไม่ได้ login ต้องเปิดใช้งาน linger
loginctl enable-linger
- หากต้องการเริ่มอัตโนมัติหลังเซิร์ฟเวอร์รีบูต การเปิดใช้งาน linger เป็นสิ่งจำเป็น
- เพื่อให้ systemd พบไฟล์บริการใหม่ ให้รันคำสั่งต่อไปนี้
systemctl --user daemon-reload
- การเริ่มคอนเทนเนอร์และตรวจสอบสถานะทำได้ทั้งฝั่ง systemd และ Podman
systemctl --user start test-dbsystemctl --user status test-dbpodman ps
- ชื่อคอนเทนเนอร์เริ่มต้นคือรูปแบบที่เติม
systemd-หน้าชื่อไฟล์บริการ- ชื่อคอนเทนเนอร์เริ่มต้นของ
test-db.containerคือsystemd-test-db - เป็นกฎการตั้งชื่อเพื่อหลีกเลี่ยงการชนกัน
- สามารถกำหนดเองได้ด้วยตัวเลือก
ContainerNameในส่วน[Container]
- ชื่อคอนเทนเนอร์เริ่มต้นของ
ข้อดีด้านการดำเนินงานของ Quadlet
- Quadlet ทำให้จัดการการตั้งค่าบริการคอนเทนเนอร์ได้ด้วยไฟล์เดียว
- ไม่จำเป็นต้องจัดการสคริปต์ที่สร้างไฟล์บริการและไฟล์บริการที่ถูกสร้างขึ้นแยกกันเหมือนวิธีเดิม
- สามารถใช้ตัวเลือกที่มีในส่วน
[Unit]และ[Service]ของ systemd ได้- เช่น ระบุคำสั่งที่จะรันก่อนเริ่มคอนเทนเนอร์ด้วย
StartExecPre - ลดขั้นตอนการแก้ไฟล์ที่สร้างขึ้นด้วยมือในภายหลัง
- เช่น ระบุคำสั่งที่จะรันก่อนเริ่มคอนเทนเนอร์ด้วย
- แทนที่จะเขียนและ debug shell script ก็สามารถดำเนินงานคอนเทนเนอร์โดยยึด ไฟล์ configuration เป็นศูนย์กลางได้
- แสดง dependency ระหว่างคอนเทนเนอร์ตามแนวทางของ systemd ได้ง่าย
การแสดง dependency ระหว่างคอนเทนเนอร์
- หากคอนเทนเนอร์แอปพึ่งพาคอนเทนเนอร์ฐานข้อมูล สามารถกำหนดความสัมพันธ์ด้วยส่วน
[Unit]ของ systemd ได้ - คอนเทนเนอร์ OxiTraffic เป็นตัวอย่างที่พึ่งพาคอนเทนเนอร์
test-db- ตั้ง
Requires=test-db.serviceใน[Unit]เพื่อให้แอปเริ่มได้เฉพาะเมื่อฐานข้อมูลเริ่มแล้ว - ตั้ง
After=test-db.serviceเพื่อไม่ให้คอนเทนเนอร์ทั้งสองเริ่มแบบขนานกัน
- ตั้ง
- เวลาจะอ้างอิง ให้ใช้ ชื่อบริการ ไม่ใช่ชื่อไฟล์
.containertest-db.container: ชื่อไฟล์test-db.service: ชื่อบริการsystemd-test-db: ชื่อคอนเทนเนอร์เริ่มต้น
- หากแอปต้องสื่อสารกับฐานข้อมูล ทั้งสองคอนเทนเนอร์ต้องเพิ่มตัวเลือก
Networkในส่วน[Container]แต่จะไม่กล่าวถึง networking ในที่นี้
หลายไฟล์และการจัดกลุ่ม
- Quadlet สามารถจัดโครงสร้างโดยแยกไฟล์
.containerสำหรับแต่ละคอนเทนเนอร์ได้ - เมื่อเทียบกับการใส่แอปหลายคอนเทนเนอร์ทั้งหมดไว้ในไฟล์ Docker Compose ไฟล์เดียว ไฟล์แยกตามคอนเทนเนอร์สามารถลด ภาระทางการรับรู้ ได้
- หากไฟล์ Docker Compose มีหลายร้อยบรรทัดและคอนเทนเนอร์หลายสิบตัว การดูแลรักษาอาจยากขึ้น
- ไฟล์ Docker Compose ของ Mailcow เป็นตัวอย่างของไฟล์ Compose ขนาดใหญ่
- Docker Compose ก็รองรับความสามารถในการแยกเป็นหลายไฟล์เช่นกัน
- Quadlet สามารถวางไฟล์ unit ไว้ในไดเรกทอรีภายใต้
~/.config/containers/systemdได้- ในตัวอย่างสามารถสร้างไดเรกทอรี
oxitrafficแล้ววางไฟล์ของแอปและฐานข้อมูลไว้ด้วยกันได้
- ในตัวอย่างสามารถสร้างไดเรกทอรี
การอัปเดต image
- เมื่อตั้ง
AutoUpdate=registryสามารถตรวจสอบการอัปเดต image ด้วยpodman auto-updateได้ - หากมี image ใหม่ที่เข้ากันได้กับ tag ที่ใช้อยู่ใน registry Podman จะ pull image แล้วรีสตาร์ตคอนเทนเนอร์
- ใน Docker อาจต้องใช้เครื่องมืออย่าง Watchtower เพื่อวัตถุประสงค์นี้ แต่ Podman มีฟีเจอร์ดังกล่าวมาให้ในตัว
- tag อย่าง
latestอาจมีความเสี่ยง- ใน OxiTraffic
latestอาจรวม breaking change ของเวอร์ชันถัดไป - หากใช้
latestกับ PostgreSQL อาจขยับขึ้นเป็น major version ใหม่ และการอัปเกรด major ของ PostgreSQL จำเป็นต้องมีการ migrate ด้วยมือเสมอ
- ใน OxiTraffic
- ใน production ควรใช้ tag ที่ไม่นำไปสู่ breaking change
- อีกวิธีหนึ่งคือรัน
podman auto-updateด้วยมือทุก ๆ สองสามวันเพื่อดูว่ามีอะไรถูกอัปเดตบ้าง แล้วตรวจสอบภายหลังว่าคอนเทนเนอร์ทำงานปกติหรือไม่
podman-compose และเครื่องมือ migration
podman-composeเป็นสคริปต์ Python ที่รันไฟล์ Compose ด้วย Podman- เหตุผลที่มองว่าเป็นทางเลือกของ Docker Compose ในระยะยาวได้ยากมีดังนี้
- เป็นชั้นการแปลระหว่างสเปก Compose กับ Podman·systemd และไม่ได้ทำให้ใช้ฟีเจอร์ทั้งหมดของ systemd ได้
- โปรเจกต์ Podman ทางการเขียนด้วยภาษาคอมไพล์อย่าง Rust หรือ Go
- commit ล่าสุดเมื่อ 5 เดือนก่อน จึงไม่ได้ถูกดูแลอย่างคึกคัก
- Quadlet เข้ากับการออกแบบแบบ rootless·daemonless ของ Podman ได้ดีกว่า
- หากต้องการลอง Quadlet จากไฟล์ Compose สามารถใช้ podlet ได้
- เป็นเครื่องมือ Rust ที่สร้างไฟล์ Quadlet จากคำสั่ง Podman หรือไฟล์ Docker Compose ได้
อ่านเพิ่มเติม
- หากต้องการเข้าใจ Quadlet ให้ลึกขึ้น man page
podman-systemd.unitมีประโยชน์ - Quadlet จัดการได้ไม่เฉพาะคอนเทนเนอร์ แต่ยังรวมถึง pod, network และ volume ด้วย
- หากไม่คุ้นเคยกับการเขียนไฟล์ systemd unit สามารถดู man page
systemd.unitและsystemd.serviceได้ - มุมมองอื่นและตัวอย่างที่สองดูได้จาก บทความคล้ายกันของ blog.while-true-do
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
Quadlet แทบจะเป็นสิ่งที่ดีที่สุดที่ออกมาจาก Podman และแนะนำอย่างมากสำหรับคนที่สนใจ Podman หรือกำลังจะย้ายไปใช้เวิร์กโหลดแบบคอนเทนเนอร์
มันทำให้จัดการคอนเทนเนอร์ได้เหมือนเป็นบริการระบบทั่วไป โดยไม่ต้องไปเรียนรู้ออร์เคสเตรชันอีกชั้นเพื่อให้มันทำงานร่วมกัน หรือพึ่งพาทรัพยากรที่ไม่ใช่คอนเทนเนอร์
แค่เขียน systemd unit แบบที่เคยใช้อยู่ได้เลย และยังได้การอัปเดตอัตโนมัติหรือการรีสตาร์ต/แจ้งเตือนเมื่อบริการล้มเป็นของแถม
วิธีที่เคยพยายามทำอะไรคล้ายกันด้วย Docker มักจะลงเอยด้วยการเลี่ยง Docker daemon ผ่านคำสั่ง
runขนาดมหึมา จนเหลือบริการและคอนเทนเนอร์ผีไว้บ่อย ๆ แต่ Quadlet สะอาดกว่ามาก และคอนฟิกก็อยู่รวมกับตำแหน่งของ systemd unit อย่าง/etc/systemd/,.config/systemd,/usr/local/lib/systemdทำให้สำรองข้อมูลง่ายแต่ก็ไม่ใช่คำตอบของ docker-compose สำหรับงานพัฒนาในเครื่อง และทีม Podman เองก็ดูไม่ได้สนใจพื้นที่นี้มากนัก
คอนเทนเนอร์ฝั่งผู้ใช้เหมาะกับโครงสร้างพื้นฐานทดสอบในเครื่องที่รันยาว ๆ เช่นฐานข้อมูลเบื้องหลัง แต่สำหรับลูปทั่วไปแบบคอมไพล์ →
docker compose up→ ทดสอบ →docker compose downมันยุ่งยากเกินไปคำตอบที่ใช้งานได้จริงคือใช้
.kubeQuadlet (Kubernetes play) หรือใช้docker composeกับ Podman socketชอบมันมากจนถึงขั้นใช้เวลาว่างหลายเดือนทำเครื่องมือ GitOps สำหรับจัดการ Quadlet และรู้สึกว่านี่คือวิธีที่ถูกต้องในการดูแลเซิร์ฟเวอร์ที่ทำงานแบบคอนเทนเนอร์
สิ่งสำคัญคือ
[0]ไม่ใช่ podman-compose ด้วย ผู้เขียนก็ชี้ไว้ในบทความเหมือนกันว่า podman-compose ไม่ค่อยดีและพัฒนาไม่มากพอ Podman รองรับ compose spec เกือบทั้งหมด จึงใช้docker composeได้ในแทบทุกสถานการณ์มีความเป็นไปได้สูงว่าคนที่ลองใช้ตอน RH เริ่มผลักดัน Podman ใหม่ ๆ จะเลิกใช้ไปเพราะความก้ำกึ่งของ Podman 3 และประสบการณ์แย่ ๆ กับ podman-compose
ต้องคอยเปลี่ยนแฟลก อัปเกรดเวอร์ชัน และไล่ตามกระแสที่แม้แต่ podlet เองยังแนะนำให้เปลี่ยนไปใช้เครื่องมืออื่น จนกลายเป็นโพรงกระต่ายไม่รู้จบ
สุดท้าย systemd ของผมก็แค่รัน
podman compose upเลยสงสัยว่าข้อดีของ Quadlet เมื่อเทียบกับการปล่อยให้ compose ทำหน้าที่ของมันเองคืออะไร
สำหรับอ้างอิง Podman ของผมรันภายใต้ผู้ใช้ของผมเอง และไม่มี daemon เลย
docker-composeแบบสแตนด์อโลนpodman composeเพิ่งค้นพบ Quadlet ไม่นานนี้ และได้สร้างโฮมแล็บทั้งชุดบนพื้นฐาน atomic OS กับ rootless Quadlet ซึ่งขอแนะนำอย่างมาก
มันรองรับ systemd socket activation ได้ด้วย เช่นสามารถสร้าง systemd http/https socket แล้วให้ Traefik ถูกเปิดใช้งานอัตโนมัติได้ เหมือนกับที่
ssh.socketและpodman.socketเปิดใช้งานsshd.serviceกับpodman.serviceตามลำดับสำหรับคอนฟิกแบบ rootless นี่แทบเป็นวิธีเดียวที่ใช้งานได้จริงในการคงค่า IP ต้นทางไว้ จนแทบเรียกว่าเป็นผู้ช่วยชีวิตได้เลย เพราะ rootless Podman/Docker โดยทั่วไปไม่ได้เปิดทางให้คงค่า IP ต้นทางได้ง่าย ๆ โดยไม่มีข้อเสียใหญ่
https://github.com/savely-krasovsky/homelab
Quadlet เป็นทางเลือกที่ดีสำหรับการใช้งานแบบ docker compose ที่ว่า “รันคอนเทนเนอร์ที่พึ่งพากันทั้งหมดในสภาพแวดล้อมที่คล้ายโปรดักชัน”
แต่ถ้าเป็นอีกกรณีใช้งานหนึ่งของ docker compose คือฝั่งพัฒนา ก็น่าจะมีทางเลือกที่ดีกว่านี้
docker compose สามารถสตาร์ตฐานข้อมูล, Redis, OpenSearch, dependency อื่น ๆ, nginx proxy และคอนเทนเนอร์สำหรับพัฒนาที่เมานต์
.:/appเป็นโวลุ่มขึ้นมาพร้อมกันได้, ลบทั้งหมดพร้อมกันได้, และเก็บdocker-compose.ymlไว้ใน repository ได้แต่ Quadlet บอกให้วางไฟล์ทั้งหมดไว้ที่
~/.config/containers/systemdจึงไม่ถูกแยกอยู่ในโปรเจ็กต์อีกต่อไป และไม่สะดวกนักที่จะ commit แล้วแชร์กับนักพัฒนาคนอื่น ๆ อีกทั้งพวกเขาก็ต้องใช้ Podman ด้วยคนส่วนใหญ่ยังคงใช้ Docker และแม้แต่ในสภาพแวดล้อมพัฒนาแบบโฮสต์อย่าง Codespaces ก็มี Docker ให้
เลยใช้ docker compose กับไฟล์ YAML ที่ commit ไว้ ฉันใช้ Podman จึงต้องใส่
:Zให้ทุกโวลุ่มด้วยมือตลอด แต่ Docker ทั่วไปจัดการสิ่งนั้นไม่ได้ถ้ามีทางเลือกแทน docker compose สำหรับงานพัฒนาก็คงดี แต่ Quadlet ดูไม่ค่อยเหมาะ
podman-compose --in-pod=1 systemd -a create-unitก็สามารถสร้างบริการpodman-compose@ได้ และหลังจากนั้นใช้podman-compose systemd -a registerเพื่อลงทะเบียนไฟล์compose.ymlพร้อมกับ$nameจากนั้นก็จัดการ pod ที่อิงจากไฟล์ compose ได้ด้วย
podman-compose@$name.serviceและยังทำงานแบบ rootless ได้เต็มรูปแบบด้วยsystemd-runช่วยให้รัน บริการ systemd แบบชั่วคราว โดยอิงจากคำสั่งใดก็ได้ถ้าจำเป็น มันยังสร้าง unit ชั่วคราวที่เรียบร้อยและเป็นไปตามกฎของ systemd scope รวมถึง timer ให้ด้วย
[1] https://www.freedesktop.org/software/systemd/man/systemd-run...
มันใช้รูปแบบคล้าย Kubernetes และเพิ่มความสะดวกบางอย่างอย่างการ build container เข้ามาเล็กน้อย
วางไฟล์ kube play ไว้ที่ root ของโปรเจ็กต์ แล้วรัน
podman kube play project.yaml --buildก็จะสตาร์ตทั้ง pod, โวลุ่ม และอื่น ๆ ขึ้นมาด้วยกันส่วนไฟล์ Quadlet มีประโยชน์ในขั้น deploy ถ้าต้องการนำโปรเจ็กต์ขึ้น VPS ก็ใช้ Kube Quadlet[2] ร่วมกับ
project.yamlที่มีอยู่แล้วได้เลย[1] https://docs.podman.io/en/latest/markdown/podman-kube-play.1...
[2] https://docs.podman.io/en/latest/markdown/podman-systemd.uni...
docker-compose.ymlสำหรับงานพัฒนาเหมือนกัน เลยเข้าใจความลำบากนี้ดีโดยรวมมันทำงานได้ดีมาก แต่บน OSX บางครั้งก็มีอาการแปลก ๆ เพราะ VM ตัวกลางบ้านั่น
เป็นครั้งคราวก็ลองเช็กความเข้ากันได้กับ Podman อยู่เหมือนกัน แต่ตอนนี้ยอมรับแล้วว่าคงทำให้เข้ากันได้แบบสมบูรณ์ไม่ได้ เพราะแนวคิดแบบ rootless ต่างกันมากเกินไป
ถึงอย่างนั้น เครื่องมือนี้ก็ยอดเยี่ยมมากสำหรับโปรดักชัน ฉันมีโปรเจ็กต์งานอดิเรกอยู่ไม่กี่ตัวที่รันบน bare metal node ด้วยบริการ systemd ที่ทำขึ้นเอง ซึ่งตอนนี้ใช้ containerd โหมดผู้ใช้
ถ้ามีเวลาก็อาจจะลองย้ายดู
น่าขำดีที่บทความนี้บอกว่า Podman-Compose “ไม่ได้มีการบำรุงรักษาอย่างต่อเนื่อง” โดยชี้ว่าคอมมิตล่าสุดคือเมื่อ 5 เดือนก่อน แล้วก็แนะนำ Podlet เป็นทางเลือกทันที ทั้งที่คอมมิตล่าสุดของมันก็เมื่อ 5 เดือนก่อนเหมือนกัน
Podlet อาจมีประโยชน์ แต่ไม่รองรับฟีเจอร์จำนวนมากของ Docker Compose และก็ไม่ได้แปลงให้ออกมาสะอาดเรียบร้อยเสมอไป
โดยเฉพาะอย่างยิ่งมันไม่รองรับการซ้อนหลายไฟล์ YAML แบบ
-f docker-compose.yml -f docker-compose.override.ymlดูเหมือนว่า compose CLI จะควบคุมเอนจินผ่าน socket และ Podman กับ Docker engine ก็มี API ที่แทบจะเหมือนกัน
ผมใช้วิธีนี้อยู่เพราะ podman-compose ทำงานไม่ได้ตามที่คาดหวัง
โดยปกติ Docker-compose จะติดตั้งเป็นปลั๊กอินของไคลเอนต์ docker แต่ผมใช้แบบแอปพลิเคชันสแตนด์อโลนเพื่อใช้กับ Podman
และสำหรับการตั้งค่าการเชื่อมต่อ ผมชอบใช้ docker
contextsมากกว่าตัวแปรสภาพแวดล้อมDOCKER_HOSTถ้า Quadlet อย่างเดียวไม่ทรงพลังพอ ทั้ง Quadlet[3] และ Podman ปกติ[4] ก็รองรับการรัน Kubernetes manifest แบบจำกัดได้เช่นกัน
ผมยังไม่ได้หาคำตอบว่า Podman จัดการตัวเลือก
restartในไฟล์ compose อย่างไร เพราะ Podman ไม่มี supervisor daemonแต่ผมรู้ว่าตัวเลือก
healthcheckนั้นพึ่งพา systemd timerตอนใช้ Podman บน Gentoo ซึ่งไม่ใช่ดิสโทรที่ใช้ systemd การตรวจสุขภาพอัตโนมัติใช้งานไม่ได้ แต่เมื่อรัน healthcheck แบบแมนนวลแล้ว การตั้งค่าที่เหลือก็ทำงานต่อจนจบ
[1] https://github.com/docker/compose
[2] https://docs.podman.io/en/latest/markdown/podman-system-serv...
[3] https://docs.podman.io/en/latest/markdown/podman-systemd.uni...
[4] https://docs.podman.io/en/latest/markdown/podman-kube-play.1...
Podlet เป็นเครื่องมือเสริม และในระยะยาวการทำงานกับ Quadlet โดยตรงน่าจะดีกว่า
5 เดือนไม่ได้แปลว่าไม่มีการบำรุงรักษา ต้องระดับประมาณ 2 ปีถึงจะใช่
ถึงอย่างนั้นมันก็ทำให้กังวลมากขึ้นได้ เพียงแต่ 5 เดือนไม่ใช่หลักฐานว่าโครงการยังได้รับการบำรุงรักษาแน่นอน
แม้แต่รีโพซิทอรีที่ไม่ได้รับการบำรุงรักษาก็ยังมีเหตุผลมากมายที่อาจถูกอัปเดตได้ มีแค่ฟีเจอร์ archive ของ GitHub ที่ช่วงหลังแย่ลงเท่านั้นที่ช่วยกันเรื่องนี้ได้
เมื่อหลายปีก่อน ตอนรีเซ็ตระบบ self-hosting ผมอยากลองอย่างอื่นจึงเลือก openSUSE MicroOS และสุดท้ายก็ได้มารันคอนเทนเนอร์ Podman ภายใต้ systemd/Quadlet ซึ่งตอนนี้ผมพอใจกับชุดตั้งค่านี้มาก
คอนเทนเนอร์อัปเดตอัตโนมัติด้วยเครื่องมือที่มีมาใน Podman และการดูล็อกกับมอนิเตอร์ก็ทำผ่านเครื่องมือ systemd ตามปกติ
เวลาอยากเปลี่ยนอะไร ก็หาตำแหน่งไฟล์คอนฟิกได้ง่ายแม้จะลืมไปแล้ว และยังอ่านกับแก้ไขได้ง่ายด้วย
แบบ rootless และ daemonless ก็ดีมาก
ผมลองหลายอย่างระหว่างทาง แต่ podman compose ให้ความรู้สึกเทอะทะ รู้สึกดีที่มันถูก deprecated แล้ว และชัดเจนว่า Quadlet คือทิศทางที่ควรไป
ต้องยอมรับว่ามี learning curve และมีข้อมูลน้อยกว่า Docker
แต่ถ้าเป็นงาน local development ที่ต้องยกและปิดหลาย service stack อยู่เรื่อย ๆ ผมก็คงยังเลือก Docker และ docker compose
ใช้เวลาพอสมควรกว่าจะตั้งค่าลงตัว แต่ผมประทับใจมากที่มันแทบไม่ต้องบำรุงรักษาเลย จนถึงตอนนี้ยังไม่ต้องทำอะไรเลย
ถ้าใครอยากลองทำแบบคล้ายกัน ก็อ้างอิงการตั้งค่าของผมได้
https://github.com/jeppester/coreos-nextcloud
ผมกำลังทยอยย้ายทุกโหนดไปเป็น MicroOS และที่บริษัทก็กำลังผลักดัน MicroOS หรือสิ่งที่คล้ายกันอยู่
มันให้ความรู้สึกว่าการ rollback อัตโนมัติของ OS พื้นฐาน รวมกับการตั้งค่าคอนเทนเนอร์แบบ declarative และการอัปเดตอัตโนมัติ เข้ากันได้อย่างลงตัว
รูปแบบนี้ชัดเจนกว่า
podman generate systemdหรือ Kubernetes YAML และ การผสานกับ systemd ก็ยอดเยี่ยมสิ่งที่น่าหงุดหงิดคือ Podman upstream ไม่ได้มีรีโพซิทอรีสำหรับ Debian/Ubuntu
บน Debian stable มันถูกตรึงไว้ที่ 4.3.1 ทำให้พลาดฟีเจอร์ใหม่ไปมาก และสุดท้ายผมก็ตัดสินใจกลับไปใช้ Docker compose
วิธีแก้ชั่วคราวที่มีคนเสนอคือคอมไพล์ Podman เองหรือใช้
debian/testingหวังอย่างจริงใจว่าแนวทางใหม่นี้จะช่วยให้ผู้คนย้ายจาก Docker ไปใช้ Podman ได้
Docker-Compose เป็นเหตุผลที่ทำให้หลายคนลังเลที่จะย้าย และผมก็เป็นแบบนั้นเหมือนกัน
พูดกันตามตรง ก่อนมี Quadlet นั้น Podman ไม่มีคำตอบที่ดีพอจริง ๆ
ถ้าคุณลังเลที่จะย้ายออกจาก Docker เพราะ Docker-Compose, Podman ที่ใช้คู่กับ Quadlet ก็เป็นทางเลือกที่สมน้ำสมเนื้อกว่ามาก
คุณอาจไม่ได้คิดถึง Docker อย่างที่คิดไว้ และยังได้ความปลอดภัยที่ดีขึ้นจากการรันคอนเทนเนอร์แบบ rootless ด้วย
วิธีที่ให้ใส่ทุกอย่างไว้ใน
~/.config/quadlet/systemdใช้ไม่ได้เรื่องนี้จำเป็นมากสำหรับงานพัฒนาและการทดสอบ และตอนนี้ Quadlet ยังเป็นโซลูชันสำหรับการดีพลอยอย่างเคร่งครัด
ผมชอบ Quadlet มากเพราะมันทำให้ใช้คอนเทนเนอร์ได้เหมือนบริการระบบทั่วไป
แต่ประสบการณ์ใช้งานของ คอนเทนเนอร์แบบ rootless กลับไม่ค่อยเข้ากับแนวคิดนี้นัก
โดยปกติบริการระบบจะรันใน systemd session ของระบบในฐานะ system user แต่บริการของคอนเทนเนอร์แบบ rootless จะอยู่ใน user systemd session ของ system user นั้น
น่าจะดีถ้าสามารถรัน rootless Quadlet ภายใน system session ได้
user-lingerแล้วรันแบบ rootless ผ่าน user systemdผมทำแบบนั้นมาตลอด
และอยากให้สามารถรัน rootless Quadlet ด้วยตัวเลือก
DynamicUser=ได้ด้วยDynamicUser=เป็นวิธีที่ยอดเยี่ยมในการจำกัดสิทธิ์ของ system service แต่ตอนนี้มันยังเข้ากับ Podman ได้ไม่ดีน่าสนใจที่ได้เห็น Quadlet บนหน้าแรกของ Hacker News คิดว่ามันยังไม่ได้รับความสนใจมากพอ
Ygal และ Valentin จากโปรเจกต์นี้เคยส่งบทความรับเชิญเกี่ยวกับวิธีรันไคลเอนต์ inlets tunnel มาให้ เป็นอะไรคล้าย Ngrok/Cloudflared แต่โฮสต์เองได้โดยไม่มีข้อจำกัดแบบ SaaS
https://inlets.dev/blog/2023/10/03/client-quadlet.html
พวกเขาใช้
[kube]แทน[container]จึงสามารถนำ Kubernetes YAML มาตรฐานมาใช้ได้ และทำให้พกพาได้ดีพอสมควรสำหรับคนที่สนใจ ผมได้ทำ Ansible template ไว้เพื่อแสดงให้เห็นว่าช่วงนี้การดีพลอย Quadlet นั้นง่ายแค่ไหน
GH: https://github.com/Mati365/hetzner-podman-bunjs-deploy
example.site.orgแทนsite.example.orghttps://en.wikipedia.org/wiki/Example.com