最小構成UbuntuでQuadletを使った常駐サービス運用の実践メモ
Ubuntu 24.04 minimized を土台に、Quadlet と systemd で常駐サービスを管理するための実践的な構成メモ。ファイアウォール、監査、バックアップまでを最初から一貫した運用単位として扱う。
最小構成のUbuntuサーバーを常時稼働ノードとして使うとき、管理要素を後から足していく運用は崩れやすい。Ubuntu 24.04 minimized を土台にして、常駐サービスを systemd と Quadlet で管理する前提を先に固める方針で整理した。
狙いは単純だった。軽量さを保ちながらも、監視、ログ、防御、監査、バックアップまでを破綻なく回せる状態を最初から作ること。Quadlet でサービスを systemd に載せると、ログ確認・再起動制御・自動起動・障害切り分けを journalctl と systemctl に集約できる。
背景と設計の前提
コンテナを雑に起動したままにしないこと、Linux サーバーとして必要な保守運用を後回しにしないことが出発点だった。
rootless と rootful の責務も曖昧にしない。Loki、Prometheus、mktxp を rootless 側に、Exporter 群を rootful 側に分ける。公開ポートやホスト監視の扱いが単純になるためだ。関連する Podman Pods 設計でも rootful は GPU・ネットワーク・基盤系、rootless は UI・開発系という分離が基本になっていて、この方針と一致する。
ベース構成の方針
/opt/containers 配下の役割を最初から分ける。共通資産、ビルド資産、compose 系、実行時マウント、systemd 定義が混ざると、バックアップや権限整理のたびに判断がぶれる。
/opt/containers/
├─ _shared/ # 共通資産 (certs, secrets, config)
├─ build/ # 各appのDockerfile等
├─ compose/ # docker/podman-compose (rootful/rootless)
├─ runtime/ # 実行構成・マウント先
│ ├─ loki/
│ ├─ prometheus/
│ └─ ...
└─ systemd/
├─ rootless/
└─ rootful/
この構成にしておくと、どこが定義ファイルで、どこが永続データで、どこが共有設定なのかが明確になる。Quadlet は /home/ksh3/.config/containers/systemd に展開して、systemd のユーザーユニットとして動かす。
ベースの前提は次のとおり。
- OS: Ubuntu 24.04 (minimized)
- 管理:
systemd+ Quadlet (/opt/containers/systemd/{rootless,rootful}) - コンテナ: rootless(Loki, Prometheus, mktxp)+ rootful(Exporter 群)
- ストレージ:
/opt/containers/runtime配下に用途別で整理
必須パッケージ(minimized 補完セット)
minimized 構成は軽い反面、運用で当たり前に使う道具が足りない。用途別の補完セットを入れる前提で整理する。
| 分類 | 推奨パッケージ | 理由 |
|---|---|---|
| 基本運用 | sudo, less, vim, bash-completion, curl, wget | 操作・編集・確認用 |
| 監視・診断 | htop, iotop, iftop, ncdu, needrestart | 状況確認・再起動検出 |
| システム管理 | ufw, fail2ban, chrony | Firewall, SSH防御, 時刻同期 |
| ユーティリティ | jq, yq, git | 設定やJSON/YAMLの整形 |
| セキュリティ監査 | lynis, chkrootkit | 設定診断、rootkit検出 |
| ウイルススキャン | clamav, clamav-daemon | ファイル監査・定期スキャン |
この一覧は単なるおすすめではない。後続の各セクションで使う要素を先に揃える意味がある。ufw と fail2ban は外部公開面の防御に直結するし、lynis と chkrootkit は「導入した後に忘れやすい定期監査」を仕組みに乗せる入口になる。
Firewall と防御
外部公開面をまず ufw で絞る。rootful コンテナが公開するポートだけ通せばよい。rootless 側は slirp4netns を経由するため、基本的に外部から直接到達しない。
sudo apt install ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment "SSH"
sudo ufw allow 9090/tcp comment "Prometheus"
sudo ufw allow 3100/tcp comment "Loki"
sudo ufw allow 9633/tcp comment "smartctl exporter"
sudo ufw enable
sudo systemctl enable --now ufw
公開責務が rootful 側にまとまることで、ファイアウォールルールの理由が曖昧にならない。どのユニットが外部ポートを持つかを決めておけば、ルール管理が単純になる。
セキュリティ監査と整備
運用を続ける前提なら、初期構築の時点で監査を仕込んでおく。lynis を週次、chkrootkit を月次で回す前提にしている。
Lynis(システム全体の設定診断)
sudo apt install lynis
sudo lynis audit system
週次に実行するなら /etc/cron.weekly/lynis:
/usr/sbin/lynis audit system --quiet --no-colors \
--logfile /var/log/lynis-$(date +%F).log
Chkrootkit(月次で十分)
sudo apt install chkrootkit
sudo chkrootkit
重要なのは、監査を「必要なときだけ実行するコマンド」にしないことだ。最小構成サーバーほど、導入直後はきれいでも数週間で状態が見えにくくなる。ログファイルを残す形にしておけば、後から比較もしやすい。
ウイルス・マルウェア対策
常時稼働ノードでも、共有領域や取得ファイルを扱うならファイルスキャンの導線は必要になる。clamav と clamav-daemon を有効にし、chkrootkit を侵入検出側の補助に置く。
ClamAV(ファイルスキャン)
sudo apt install clamav clamav-daemon
sudo systemctl enable --now clamav-freshclam
定期スキャン例
/etc/cron.weekly/clamav-scan:
#!/bin/bash
LOG=/var/log/clamav/scan_$(date +%F).log
clamscan -r --bell -i /home /opt /srv > "$LOG"
Rootkit 検出の併用
sudo chkrootkit
/home、/opt、/srv をまとめて見ている点が実用的だった。前半で整理した /opt/containers 配下の資産や、バックアップ対象になる /srv と自然につながる。
journalctl / systemd 運用 Tips
Quadlet を使うなら、運用の観測点は podman logs より journalctl と systemctl に寄せたほうが揃う。障害時の切り分けを systemd ベースで完結させることを重視した。
| 操作 | コマンド例 |
|---|---|
| 追尾ログ | journalctl --user -u loki.service -f |
| エラーのみ | journalctl --user -u loki.service -p err..alert |
| このブート以降 | journalctl --user -u prometheus.service -b |
| Quadlet generator ログ確認 | journalctl --user -g 'generator|quadlet' |
| 一覧確認 | systemctl --user list-units --type=service --state=running |
| 監視モード | watch -n 2 'SYSTEMD_COLORS=1 systemctl --user list-units --type=service' |
Pod 単位でライフサイクルを揃える発想(Podman Pods 設計)と同様に、Quadlet では systemd のユニット管理で同じことを実現する。見るべき状態が分散しないことが重要だった。
Quadlet 運用の利点まとめ
従来の compose / run ベースと比べた差分を表にする。何が日々楽になるかを示している。
| 機能 | 旧来 (compose/run) | Quadlet 化後 |
|---|---|---|
| 自動起動 | cron or compose restart | WantedBy=default.target |
| 再起動ポリシー | 手動設定 | [Service] Restart=always |
| ログ統合 | podman logs | journalctl -u |
| セキュリティ | CLI引数管理 | systemd sandbox 設定可能 |
| 管理方法 | podman start/stop | systemctl start/stop |
特に効くのは、自動起動、再起動、ログ統合の三つだ。ここが揃うと、常駐サービス運用が「コンテナを知っている人だけが触れる環境」から「Linux サービスとして扱える環境」に変わる。
journald 設定チューニング
ログ管理を journald に寄せる前提なので、容量制御も最初に決めておく。
/etc/systemd/journald.conf 例:
SystemMaxUse=1G
SystemMaxFileSize=100M
RuntimeMaxUse=512M
Storage=persistent
Compress=yes
保存を永続化しつつ、肥大化を抑える。logrotate は不要で、journald にローテーションと圧縮を任せる。Quadlet や systemd user unit に運用を寄せるなら、この一元化は相性が良い。
バックアップ運用
定義ファイルとデータを分けてバックアップする。コンテナ実行系は再生成できても、永続データや共通資産は失うと戻しにくい。
Podman volume バックアップ
podman run --rm -v loki-data:/data -v /srv/backup:/backup alpine \
sh -lc 'tar czf /backup/loki-data_$(date +%F_%H%M).tar.gz -C /data .'
systemd 構成 + _shared 資産バックアップ
tar czf /srv/backup/containers_config_$(date +%F).tar.gz \
-C /opt/containers systemd runtime/_shared
前者は volume の中身を回収するためのもの、後者は systemd 定義と共有資産をまとめるためのものとして役割が分かれている。サービス再構築とデータ復旧を別々に扱えるようになる。
結論
この構成は、最小構成 Ubuntu に対して「軽量・静的・セキュアな常時稼働ノード」を作るための土台として有効だ。運用の核は次の4本柱にある。
journald— ログ管理の一元化ufw+fail2ban— 攻撃面防御clamav+chkrootkit— ファイルと侵入検知lynis— 設定監査(週次)
Quadlet でサービスを管理するにせよ、Pods で束ねるにせよ、rootful と rootless の境界、公開ポートの扱い、ログの一元化、バックアップ対象の明確化が揃っていれば、運用は崩れにくい。Ubuntu minimized を土台にしつつ、これらをひとまとまりの運用単位として扱うことで、後から付け足すより安定した構成になる。
今後の改善
- rootless / rootful の対象サービス一覧を明文化する。サービス名・公開ポート・バックアップ対象を表にしておくと、UFW ルールと復旧手順の整合が取りやすい。
cron.weeklyで書かれている監査・スキャンをsystemd timerに移す。Quadlet でサービス管理をsystemdに乗せている以上、定期ジョブ側も同じ管理面に寄せたほうが確認しやすい。- Quadlet ユニットの命名規則やディレクトリ構成に「どの責務に属するサービスか」が見えるようにしておく。規模が増えたときに効いてくる。
