Skip to content

필사 모드: systemd v261 — PID 1に来た段階的ロールアウト、クラウドIMDSの取り込み、そしてdlopen移行の完成

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに — 3か月に一度、今回はfleetの番

systemdは最近ほぼ四半期ごとにメジャーリリースを出しています。raw NEWSファイルのリリースフッターをそのまま拾うと、v258が2025-09-17、v259が2025-12-17、v260が2026-03-17、そしてv261が2026-06-19です。本稿執筆時点で、Arch Linuxのcoreリポジトリはすでに261.1を配布しており、Ubuntuは26.10開発ブランチ(stonking)に261.1が入り、26.04 LTSは259.5に留まっています。つまりローリングリリース系のユーザーは今出会い、LTSユーザーはおそらく来年出会います。

バージョン番号だけ見ればまた一つの四半期リリースですが、NEWSを最初から最後まで読むと、今回のリリースには一つのはっきりした方向性が見えます。PID 1が単一マシンのinitを超えてfleet運用のプリミティブを吸収し始めたということです。ユニットをfleetの一定割合でしか有効にしないConditionFraction=、マシンをリングにまとめるタグシステム、クラウドのインスタンスメタデータ(IMDS)を起動プロセスに統合する新しいサブシステムが、すべてこの一つのリリースに入りました。その傍らでは、2024年から続く依存関係の隔離作業 — 外部ライブラリのdlopen()移行 — がついに完結し、v258のcgroup v1廃止から始まった「削除の弧」も続いています。

本稿はセールスポイントの順ではなく、運用者の視点での重要度順に進みます。各項目が何であり、どこで使えて、そして — 同じくらい重要な — 何ではないかを見分けることに重点を置きます。systemdのユニットや条件式自体が初めてなら、systemdサービス管理・ユニットファイル設定・トラブルシューティングを先に読むほうがいいでしょう。

ConditionFraction= — ユニットファイルに来た段階的ロールアウト

v261で最も興味深い新機能です。v261タグのsystemd.unit manソースを基準に整理するとこうなります。

ConditionFraction=は、ユニットを「fleetの安定した疑似ランダム部分集合」でのみ有効化します。同じユニット(またはドロップイン)をfleet全体に配布しつつ、設定した割合のマシンでのみ条件が真になるようにするものです。判定は完全にローカルで行われます — マシンIDをタグ文字列と一緒にハッシュして32ビット整数を作り、その値が2^32の指定パーセントより小さければ真になります(NEWSの説明による)。中央の調整役はなく、ネットワーク呼び出しもなく、同じマシンは常に同じ判定を受けます。

文法はパーセント一つ、またはタグとパーセントの組み合わせです。パーセントは小数点第2位まで許容されます。

# /etc/systemd/system/telemetry-v2.service.d/rollout.conf
# fleetの約10%でのみこのユニットが有効になる
[Unit]
ConditionFraction=telemetry-v2 10%

感嘆符を前に付けると補集合になります — manページの例をそのまま持ってくると、!myrollout 30%は残りの約70%のマシンで真になります。新旧バージョンを排他的に分けて運用するのにそのまま使えます。

# 旧バージョン側のユニット: 同じタグの補集合でのみ有効になる
[Unit]
ConditionFraction=!telemetry-v2 10%

ここでタグが果たす役割が重要です。タグはハッシュの導出に混ぜ込まれる任意の文字列(空白不可)であり、タグが異なれば互いに独立な部分集合が選ばれます。逆に言えば、タグなしのConditionFraction=条件はすべて同じマシン集合を選びます — タグなしで10%ロールアウトを2つ走らせると、2つの実験はまったく同じマシンに重なります。無関係なロールアウトには必ず異なるタグを使い、複数のユニットを同じマシン集合に結びつけたいときだけタグを共有せよ、というのがmanページの指針です。マシンIDが読めない場合、条件は失敗(偽)になります。

デプロイ前に特定のマシンで判定を事前確認することもできます。systemd-analyze conditionコマンドは条件文字列をその場で評価してくれます。

systemd-analyze condition 'ConditionFraction=telemetry-v2 10%'

これはカナリアデプロイシステムではない

ここで正直になっておく部分です。「PID 1にカナリアロールアウトが来た」という文は半分だけ正しいです。ConditionFraction=が提供するのは母集団選択だけであり、カナリアデプロイをカナリアデプロイたらしめる残りの部分 — 観測、判定、中断 — はまったく提供しません。

  • ヘルスゲートがありません。 10%でエラー率が急騰してもsystemdは何も知りません。指標を見てロールアウトを止める判断は依然として外部の仕事です。
  • 自動ロールバックがありません。 条件はユニットの有効化時点で評価される静的な述語です。誤ったデプロイを元に戻すのはドロップインを修正して再デプロイすることであり、それは結局構成管理ツールの仕事です。
  • 割合の変更はそのまま再デプロイです。 10%から50%に上げるには、ドロップインファイルを変えてfleetに再度配布する必要があります。中央でダイヤルを回す体験を求めているなら、この機能はその答えではありません。
  • パーセンテージは近似値です。 manページ自体も「おおよそ(approximately)設定された割合」と書いています。ハッシュベースなので、fleetが小さいと偏差が大きくなります。マシン20台での10%は0台のこともあれば4台のこともあります。

では、どこで使うために作られたのでしょうか。manページが明示する用途そのまま、同じアーティファクトをfleet全体に配布するイメージベースシステムの段階的な露出です。OSTreeやUKIイメージのように、マシンごとに異なるファイルを配布できない(したくない)環境では、「全員に配布しつつ一部でだけ有効にする」が事実上唯一のロールアウト手段です。中央の調整なしに決定論的に動くという性質は、この環境では欠点ではなく要件です。逆にKubernetesや構成管理ツールでマシンごとのデプロイ制御がすでにできている環境なら、この機能が新しく開く扉はほとんどありません。

意図的なリング分けが必要なら、ランダムな割合の代わりに新しく入ったタグシステムを使います。v261からマシンは/etc/machine-infoTAGS=フィールドにタグの一覧を持てるようになり、hostnamectl manソース基準でhostnamectl tagsで照会・置換します(タグは1〜255文字のASCII英数字、ハイフン、ドット)。ユニット側ではConditionMachineTag=がシェルのglobパターンでタグを検査します。

# ring0タグが付いたマシン(社内dogfoodリング)でのみ有効になる
[Unit]
ConditionMachineTag=ring0

AssertMachineTag=も一緒に追加され、NEWSによればsystemd-firstbootがコマンドライン引数やcredentialでプロビジョニング時にタグを埋め込めます。まとめるとこうなります — 明示的なリングはタグで、リング内のランダムな割合はfractionで。観測と判定はあなたのモニタリングで。この分業が設計意図に最も近い読み方です。

IMDSサブシステム — systemdがcloud-initの庭に入ってきた

v261はクラウドインスタンスメタデータサービス(IMDS)を扱うサブシステム一式を新しく搭載しました。構成要素はかなり多くあります。

  • hwdb.d/40-imds.hwdb — SMBIOS情報でクラウドを識別し、そのクラウドのIMDSエンドポイントアドレス・トークンURL・ヘッダー形式を記述するハードウェアDBです。NEWS基準でAmazon EC2、Microsoft Azure、Google Compute Engine、Hetzner、Oracle Cloud、Scaleway、Tencent Cloud、Alibaba ECS、Vultrの9つを認識します。hostname、region、zone、パブリックIPv4/IPv6、SSH公開鍵、user-dataといった「よく知られたキー」のクラウドごとのマッピングもここに入っています。
  • systemd-imdsd@.servicemanページ基準、/run/systemd/io.systemd.InstanceMetadataでVarlink IPC経由のIMDSフィールド照会を受け付けるローカルデーモンです。
  • systemd-imdsd-early-network.service — IMDSエンドポイントに到達するためのearly-bootネットワーク設定(.networkファイル)を生成します。
  • systemd-imds — クライアントツール。NEWSによれば、IMDSが提供するフィールドをシステムcredentialとして取り込み、以降のサービスがそのcredentialを消費します。取り込み前にデータがTPMに測定(measure)される点も明記されています。
  • systemd-imds-generator — 対応するクラウドが検出されると、これらのサービスを起動トランザクションに自動的に取り込みます。NEWSが言う目標は「本当に汎用なイメージ」 — IMDSがあれば使い、なければ静かに素通りする単一イメージです。

運用者が注意すべき部分はネットワークロックです。カーネルコマンドラインsystemd.imds.network=はoff、locked、unlockedの3つの値を取り、lockedモードではIMDSエンドポイントへのprohibitルートが敷かれ、非特権プロセスによる直接アクセスが遮断され、すべてのアクセスがsystemd-imdsdを経由する必要があります。IMDS credential窃取がクラウド侵害の常套手段だったことを考えれば、方向性自体は妥当です。問題はNEWS自身が書き残している一文です — このロックはセキュリティ上推奨されるものの、IMDSへの直接アクセスを前提とするcloud-initのような従来型クライアントと「typically conflicts」、つまり大抵は衝突します。

デフォルトが何かという問いには、文書が食い違った答えをします。meson_options.txtimds-networkオプションは明示的なデフォルトなしにchoicesがunlocked、lockedの順であり、アップストリームのソース基準ではデフォルトはunlockedになります(mesonのcomboオプションは最初の項目がデフォルト)が、manページのカーネルスイッチの説明にはlockedがデフォルトだと書かれています。実際のあなたのシステムでのデフォルトはディストリビューションがビルド時に何を選んだかに依存するので、cloud-initと一緒に使うイメージなら、ディストリビューションのパッケージのビルドオプションを確認するのが安全です。

一つはっきりさせておく必要があります。これはcloud-initの代替物ではありません — 少なくとも今のところは。systemd-imdsがすることはメタデータフィールドをcredentialとして取り込むところまでで、cloud-configの解釈、パッケージのインストール、ユーザー作成といったプロビジョニングロジックは範囲外です(NEWSもmanページもそういう主張はしていません)。ただ、hostname、SSH鍵、user-dataがcredential体系に入り始めたということは、単純なプロビジョニング要求ならsystemdの純正部品だけで処理される未来への第一手として読むのが自然です。cloud-init側がこのロックモードとどう共存するかは、今後見守るべき問題です。

dlopen移行の完成 — そしてrsyslogが壊れた経緯

2024年3月のxz-utilsバックドア(CVE-2024-3094)は、ディストリビューションがsshdにlibsystemdをリンクしていたことを通り道にしました — liblzmaがlibsystemdの推移的依存としてsshdプロセスに乗り込んだのです。3か月後の2024年6月に出たv256から、systemdはまさにそのliblzmaを含む5つのライブラリ(liblz4、libzstd、liblzma、libkmod、libgcrypt)を通常のリンクからdlopen()ベースに変え始め、リリースのたびに対象を広げてきました。

v261がこの作業の終着点です。今回libgnutls、libmicrohttpd、libcurl、libcrypto、libssl、libfdisk、libcryptsetupまで変換され、NEWSは枠で囲んで宣言しています — 外部ライブラリへの直接リンクはこれで全部dlopen()に置き換わり、唯一の例外はlibcだと("with the sole exception of libc")。どのdlopen依存があるかは各バイナリに埋め込まれるELF dlopen metadataノートで宣言されるので、パッケージングツールがオプション依存を機械的に把握できます。

この方向の利点は明らかです — プロセスに乗るコードが減り、最小イメージから外せるライブラリが増え、xz事件のような推移的依存の攻撃面が狭まります。ところがこの移行は逆方向の落とし穴も作ります。libsystemdがこれまで他者の代わりに引き込んでくれていたライブラリが消えるということです。

v261のNEWSに載った実際の事例が正確にこれです。libsystemdがlibm(数学ライブラリ)にリンクされるという保証が消えると、libmのシンボルを使っていながらlibm自体をリンクしていなかったlibfastjsonの問題が露呈し、その結果rsyslogが起動時にクラッシュします。これまではlibsystemdがlibmを引き込んでくれていたおかげで隠れていたバグです。NEWSは根本修正(libfastjsonがlibmを直接リンクする)がされるまでの暫定的な回避策としてリンカーフラグを提示しています。

-Wl,--push-state,--no-as-needed,-lm,--pop-state

教訓はrsyslogに限りません。libsystemdにリンクするソフトウェアをビルドまたはパッケージングしているなら、これまで「たまたまリンクされていた」推移的依存に頼っていなかったか確認する時です。使うシンボルは直接リンクせよという原則が、いま文字どおり強制され始めています。

アップグレード前チェックリスト — 静かに嚙みつくもの

NEWSの非互換な変更のリストから、実際の運用に触れるものだけを拾いました。

  • udev DB v0サポートの廃止。 v247未満のバージョンからv261以上へのライブアップグレード(再起動なしのデーモン差し替え)はもうサポートされません。かなり古いシステムを運用してきたなら、中間バージョンを経由するか、再起動の計画が必要です。
  • nspawnの--user=--uid=に改名。 短いオプション-uと従来の表記はまだ動作しますが警告が出るようになり、引数なしの--userは今やuserサービスマネージャのスコープを選ぶスイッチとして再利用されます。--userを使うスクリプトは意味が変わっていないか点検が必要です。
  • TPM・CC測定値の変更。 systemd-stubがdevicetree、initrd、ucodeアドオン、UKIプロファイルをTPMにのみ測定し、ハードウェアCCレジスタ(例: Intel TDX RTMR)には測定を落としていた不具合が修正されました。方向としては正しい修正ですが、レジスタの期待値が変わります — RTMRベースのattestationを運用しているなら、ポリシーの更新なしには検証が壊れます。新しく追加されたsystemd-pcrosseparator.serviceもPCR 0-7、9、12-14にセパレータ測定を追加するため、該当PCRを参照するTPMポリシーに影響があります。
  • Varlink io.systemd.Unitのenum表記変更。 文字列として公開されていたフィールドがenum型に変わり、ワイヤーフォーマットの値表記が変わりました(例: tty-forceがtty_forceに、kmsg+consoleがkmsg_consoleに)。このインターフェースをパースするツールがあるなら修正対象です。
  • MinimumUptimeSec=のデフォルトが15秒に。 起動直後に自動シャットダウンを繰り返すブートループを防ぐため、稼働時間が15秒未満の状態でシャットダウンが要求されると、shutdownの最後の段階(reboot()システムコール直前)にその分の遅延が入ります。systemd-system.conf manソース基準で、コンテナには適用されず0で無効化できます。起動-終了を素早く繰り返すテストパイプラインなら、このデフォルト値が壁時計時間を伸ばす可能性があります。
  • musl最小バージョン1.2.6。 muslベースのビルドを維持しているディストリビューションに関係します。
  • v262の予告。 /run/boot-loader-entries/のサポートと、実験的だったsystemd-sysupdated D-Bus APIが次のリリースで削除される予定です(後者はVarlink直結に置き換え)。今依存しているなら、1四半期以内に移行する必要があります。

文脈を一つ補うと、このリストはv258から始まった削除の流れの続きです。v258(2025-09)がcgroup v1とSystem Vの状態制御(runlevel、telinit、init 3)を廃止し、v260(2026-03)がSystem Vサービススクリプトのサポート(systemd-sysv-generator、rc-local.service)をさらに廃止しました。まだSysVスクリプトで配布されている社内デーモンがあるなら、すでにv260系のディストリビューションでは起動時に上がってきません。

その他注目すべき点

紙幅の都合で短くまとめますが、環境によっては上記より重要になりうる項目です。

  • kexecを越えて生き残るFDストア。 カーネルのLive Update Orchestration(LUO)/ Kexec Handover(KHO)があるシステムで、FileDescriptorStorePreserve=yesのユニットのFDストアがkexec再起動を越えて保存されます。NEWSの表現どおり「本稿執筆時点ではmemfdのみ」対応ですが、カーネルを入れ替えながらユーザースペースの状態を維持する無停止カーネルアップデートの物語の、ユーザースペース側の半分がここから始まります。systemctl kexecがkexec-toolsなしでkexec_file_load()システムコールを直接使うようになったこと、--kernel-cmdline=オプションが追加されたことも同じ文脈です。
  • cgroup制御の拡張。 CPUSetPartition=でcpusetパーティションタイプ(root、isolated、member)をユニットから直接設定できます。CPU隔離をスクリプトで処理してきたなら、ユニット設定に移せます。PSI側ではCPUPressureWatch=/IOPressureWatch=系の設定でサービスがCPU・IO圧力の通知を受けられるようになりました(従来はメモリ圧力のみ)。
  • systemd-oomdルールセット。 /etc/systemd/oomd/rules.d/にOOMポリシールールを定義し、ユニット側でOOMRule=で選んで使う構造ができました。
  • ユニットファイルなしのPID 1。 マネージャがbasic.target、multi-user.targetといった中核ユニットセットをバイナリに内蔵し、ユニットファイルを一つもインストールしていないコンテナでもsystemdをPID 1として起動できるようになりました。
  • networkd DHCPリレーの刷新。 新しいsd-dhcp-relayバックエンドの導入により、従来[DHCPServer]セクションにあったリレー関連設定4種がdeprecatedになり[DHCPRelay]セクションに移動しました。該当設定を使っているなら移行対象です。
  • resolvedの静的レコードドロップイン。 /etc/systemd/resolve/static.d/などのJSONドロップインでローカル解決用のDNSレコードを定義できます。/etc/hostsの一般化と考えればいいでしょう。
  • ソフトウェアTPMフォールバック。 物理TPMがないシステムでIBMのswtpmを自動フォールバックとして動かすsystemd-tpm2-swtpm.serviceが追加されました(カーネルコマンドラインでのオプトイン)。NEWS自身がハードウェアTPMと同等のセキュリティ態勢ではないと明記しているので、「TPMなし」よりましなものが必要な状況向けです。
  • coredumpにカーネル7.1の理由コード。 systemd-coredumpがカーネル7.1が提供するCOREDUMP_CODEフィールドを収集し、coredumpctlが解読します。カーネル7.1についてはsched_extサブスケジューラ — カーネル7.1に半分だけ届いたcgroup別スケジューラ編で扱いました。
  • ちょっとした事実を一つ — v261のコントリビューター一覧には、人々に混ざって「Claude Opus 4.6」が載っています。AIが出したパッチがマージされ、コントリビューターとして記録されることが、systemdのようなコアインフラでもリリースノートの日常になりました。

それで誰がいつ気にすべきか

まとめると対象別にこうなります。

今すぐ — confidential computingでRTMR/PCRベースのattestationを検証している側(測定値が変わります)、libsystemdにリンクするソフトウェアのパッケージャー(推移的依存の整理)、rsyslogを自前ビルドしている側。ローリングリリース系ならすでにv261が届いています。

設計に反映すべき時点 — イメージベースのfleetを運用しているチーム。ConditionFraction=とマシンタグは、これまで外部ツールで模倣していた段階的な露出をユニットファイルの文法に落とし込みます。ただし前述のとおり、観測・判定・ロールバックは依然としてあなたの仕事だという前提で設計してください。IMDSサブシステムは、cloud-init依存を減らしたかったミニマルイメージ陣営にとって、実質的な選択肢になり始めています。

まだ余裕がある — LTSディストリビューションに留まる大半のサーバー運用者。Ubuntu 26.04はv259で、大半のエンタープライズディストリビューションはそれよりさらに後ろにいます。ただしv258以降の削除の流れ(cgroup v1、SysVスクリプト、udev DB v0)は次のメジャーアップグレードでまとめて届くので、レガシー依存があるなら、リストだけでも先に作っておくといいでしょう。

おわりに

v261を一文に縮めるとこうなります — systemdはもはや一台のマシンを起動するソフトウェアではなく、fleetの最小単位を自任するソフトウェアになりました。ConditionFraction=はロールアウトの母集団選択を、タグはリング区分を、IMDSサブシステムはクラウドコンテキストの取り込みを、それぞれPID 1の文法にしました。どれも既存のオーケストレーションを置き換えるわけではありませんが、3つとも「これまで必ず外部ツールが必要だったこと」のリストを少しずつ減らします。

同時にこのリリースは、systemdが自分自身にも同じ原則を適用していることを示しています。dlopen移行の完成は、xz事件が露わにした推移的依存の問題への2年がかりの答えであり、rsyslogの事例はその答えがエコシステムに請求するコストです。アップグレード自体はいつもの四半期リリースのように無難でしょうが、attestationの期待値と推移的依存 — この2つだけは、リリースノートを読まなかったチームを正確に嚙む種類の変更です。この記事がそのリストの代わりになっていれば幸いです。

参考資料

현재 단락 (1/76)

systemdは最近ほぼ四半期ごとにメジャーリリースを出しています。[raw NEWSファイル](https://raw.githubusercontent.com/systemd/systemd/m...

작성 글자: 0원문 글자: 12,887작성 단락: 0/76