iT邦幫忙

2026 iThome 鐵人賽

DAY 2
0

第二天,就用一張圖講Podman Quadlet如何將容器變成systemd的服務,之後幾天再講實務面操作。
在Linux,uid(User Identifier,使用者識別碼)在0到1000歸root權限使用,編號1001起,才是rootless的uid,沒特別指定的話,通常在Linux建立的第一個帳號的uid就是從1001開始編起。本專案所建立的rootless帳號名為appuser,uid正是1001。


以下這張圖就是如何把Podman的容器轉成systemd的服務的流程:
https://ithelp.ithome.com.tw/upload/images/20260809/20119865gWDtnZgfgT.png

上圖的a2a-xx的命名方式,是指a2a這個專案的xx模組,比如a2a-web、a2a-api等。

  1. 開發端通常是把容器匯出tar檔,便於版控會將tar檔名稱尾綴yyyyMMdd-NN,年月日加流水號,所以步驟一是podman load -i tar檔是將image匯入的動作。
  2. 步驟二是容器服務化的關鍵,主要是編寫.container檔,檔案位於HOME User目錄下的.config/containers/systemd子目錄,在podman 4.4之前沒有quadlet功能,是直接編輯步驟5的.service檔,比編寫步驟3的.contaienr更複雜。
  3. 以下先展示a2a-net.network與a2a-web.container的內容:
  • a2a-net.network
[Network]
# 內部隔離網路
# 用途:Backend APIs 之間的內部通訊
NetworkName=a2a-net
  • a2a-web.container
[Unit]
Description=React static site on SUSE NGINX
After=network-online.target
Wants=network-online.target

[Container]
Image=localhost/a2a-web:20260705-01
ContainerName=a2a-web
PublishPort=8080:80
Network=a2a-net.network
VolatileTmp=true

[Service]
Restart=no
TimeoutStartSec=900

[Install]
WantedBy=default.target

容器之間要能互相通訊,通常會建立一個.network檔,只有命名NetworkName,本例是a2a-network。而其它容器則需指定Network的值為a2a-network便能互相溝通。
而在.container檔裡,在[Container]標籤下指定什麼Image、ContainerName及PublishPort會對應到步驟五的.service內容。
4. 編輯完$HOME/.config/containers/systemd下的.container及.network檔後,需執行systemctl --user daemon-reload,它會更新步驟五下的所有.service檔,可以在執行後看步驟五的目錄最後修改日期。最後再用systemctl --user restart a2a-*.service重啟所有服務。加--user的參數是以appuser帳號下執行,若是root權限則可省略。
5. 以下就看執行systemctl --user daemon-reload過後的.service檔內容

  • a2a-net-network.service
# Automatically generated by /usr/lib/systemd/user-generators/podman-user-generator
# 
[X-Network]
# 內部隔離網路
# 用途:Backend APIs 之間的內部通訊
NetworkName=a2a-net

[Unit]
Wants=podman-user-wait-network-online.service
After=podman-user-wait-network-online.service
SourcePath=/home/appuser/.config/containers/systemd/a2a-net.network
RequiresMountsFor=%t/containers

[Service]
ExecStart=/usr/bin/podman network create --ignore a2a-net
SyslogIdentifier=%N
Type=oneshot
RemainAfterExit=yes
  • a2a-web.service
# Automatically generated by /usr/lib/systemd/user-generators/podman-user-generator
#
[Unit]
Wants=podman-user-wait-network-online.service
After=podman-user-wait-network-online.service
Description=React static site on SUSE NGINX
After=network-online.target
Wants=network-online.target
SourcePath=/home/appuser/.config/containers/systemd/a2a-web.container
RequiresMountsFor=%t/containers
Requires=a2a-net-network.service
After=a2a-net-network.service

[X-Container]
Image=localhost/a2a-web:20260705-01
ContainerName=a2a-web
PublishPort=8080:80
Network=a2a-net.network
VolatileTmp=true

[Service]
Restart=no
TimeoutStartSec=900
Environment=PODMAN_SYSTEMD_UNIT=%n
KillMode=mixed
ExecStop=/usr/bin/podman rm -v -f -i a2a-web
ExecStopPost=-/usr/bin/podman rm -v -f -i a2a-web
Delegate=yes
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
ExecStart=/usr/bin/podman run --name a2a-web --replace --rm --cgroups=split --network a2a-net --sdnotify=conmon -d --tmpfs /tmp:rw,size=512M,mode=1777 --publish 8080:80 localhost/a2a-web:20260705-01

[Install]
WantedBy=default.target

從上述.service內容看,就會看到直接編寫.service檔內容有多少,在執行systemctl --user daemon-reload後,.container沒寫到的值由quadlet代填入預設值。
6. 最後可以用systemctl --user [start|stop|status|restart|cat] a2a-xx.service來控制服務生命週期,活脫就是一日維運IT的工作內容。


上一篇
在單體系統到微服務之間,有個叫Podman Quadlet
下一篇
下載podman離線安裝包
系列文
Podman Quadlet-容器服務化(在單體系統到微服務之間)12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言