Slide 1

Slide 1 text

半年前の自分に教えたい systemd のハマりどころ 1 @shora_kujira16 dbus / systemd を話すお茶会

Slide 2

Slide 2 text

自己紹介 2 • 所属:サイボウズ株式会社 クラウド運用チーム • 2019年1月よりオンコールに参加中 • 最近取り組んでいること • MySQL の IO 周りのチューニング • CPU やメモリのリソース割り当ての改善 • 古いサービスの systemd への移植

Slide 3

Slide 3 text

発表内容 3 古いサービスを systemd に移植したときにいろいろな間違いをしてきました。 「昔の自分に教えたいハマりどころ」を共有させてください。 1. Wants = network.target はだいたい間違っている 2. WantedBy = default.target? 3. drop-in の意外な仕様 4. Requires= は「このサービスの起動に必要」ではない 5. Assert と Condition の微妙な違い 6. After= が使えるのは正しく作られたサービスに限る 資料作成間に合わず

Slide 4

Slide 4 text

Wants = network.target はだいたい間違っている 4 ネットワーク接続が必要なサービスを作るとき ↓ は だいたい間違っている 書くべきだったのは多くの場合これ もしくはこっち [Unit] Wants = network.target [Unit] After = network.target [Unit] Wants = network-online.target After = network-online.target

Slide 5

Slide 5 text

Wants = network.target はだいたい間違っている 5 どうしてこういうことが起こるのか? • network.target と network-online.target の違いが知られていない • special passive system unit について知られていない

Slide 6

Slide 6 text

Wants = network.target はだいたい間違っている 6 network.target と network-online.target の違い • network.target … ネットワーク管理スタックが起動した • network-online.target … ネットワークが使えるようになった (「使える」の定義はネットワーク管理スタックに依存する) ※ ネットワーク管理スタック … Ubuntu 18.04 では systemd-networkd 以下に記載がある https://www.freedesktop.org/wiki/Software/systemd/NetworkTarget/

Slide 7

Slide 7 text

Wants = network.target はだいたい間違っている 7 • (別のサーバーに接続するために) ネットワークが利用可能になるのを待つ必要があるサービスの場合 • ネットワークが利用可能になるのを待たなくても 起動してよいサービスの場合(例:apache, sshd) [Unit] Wants = network-online.target After = network-online.target [Unit] After = network.target シャットダウン時に graceful stop するために このサービスを止めた後にネットワークを止める (stop 時は ordering dependency が逆になることに注意)

Slide 8

Slide 8 text

Wants = network.target はだいたい間違っている 8 special passive system unit とは • man 7 systemd.special の Special Passive System Units を参照 • 起動順序の制御のために用意されている特殊な target • サービスの利用側 (consumer) が Wants= を設定するのではなく サービスの提供側 (provider) が Wants= を設定する consumer provider [Unit] Wants = network.target Before = network.target [Unit] After = network.target

Slide 9

Slide 9 text

Wants = network.target はだいたい間違っている 9 multi-user.target foo.service network.target systemd- networkd.service Wants= Wants=, After= Wants=, After= まちがい

Slide 10

Slide 10 text

Wants = network.target はだいたい間違っている 10 multi-user.target foo.service network.target systemd- networkd.service Wants= After= Wants=, Before= せいかい Wants=

Slide 11

Slide 11 text

Wants = network.target はだいたい間違っている 11 結論 • network.target は Wants= や Requires= に設定してはいけない (※ あなたがネットワーク管理スタックの開発者である場合を除く) • 多くの場合、書くべきだったのはこれ • ほかに気を付けたほうが良さそうなのは time-sync.target と nss-lookup.target [Unit] Wants = network-online.target After = network-online.target

Slide 12

Slide 12 text

WantedBy = default.target? 12 OS 起動時に自動起動させたいサービスは次のように書くことが多い 仕組み • systemd は OS 起動時に default.target を activate する • default.target は multi-user.target (≒ runlevel 3) や graphical.target (≒ runlevel 5) の symlink になっている • systemctl enable すると multi-user.target.wants 以下に symlink が生成される • multi-user.target が activate されるときに一緒に起動する [Install] WantedBy = multi-user.target

Slide 13

Slide 13 text

WantedBy = default.target? 13 とある Web サイトの記載

Slide 14

Slide 14 text

WantedBy = default.target? 14 • レスキューモードで起動すると default.target = rescue.target になる • WantedBy = default.target と指定すると当然起動する • そのサービス、レスキューモードでも必要???

Slide 15

Slide 15 text

WantedBy = default.target? 15 • この書き方は Red Hat Customer Portal で見つけた • 間違っているのは私のほうではないかと疑心暗鬼になっています https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files

Slide 16

Slide 16 text

drop-in の意外な仕様 16 drop-in とは • /etc/systemd/system/foo.service.d に .conf ファイルを置くと オリジナルのファイルを override できる • sudo systemctl edit foo.service を使うとエディタが起動して いい感じにしてくれる

Slide 17

Slide 17 text

drop-in の意外な仕様 17 • 例:ExecStopPost= を追加してサービス停止時に クリーンアップ処理を追加したい • 例:デフォルトのクリーンアップ処理を別の処理に置き換えたい # /etc/systemd/system/foo.service.d/override.conf [Service] ExecStopPost=/usr/local/bin/foo-cleanup # /etc/systemd/system/foo.service.d/override.conf [Service] ExecStopPost= ExecStopPost=/usr/local/bin/foo-cleanup

Slide 18

Slide 18 text

drop-in の意外な仕様 18 man 5 systemd.unit の最後

Slide 19

Slide 19 text

drop-in の意外な仕様 19 man 5 systemd.unit の最後

Slide 20

Slide 20 text

drop-in の意外な仕様 20 • Before=, After=, Wants=, Requires= などは空行でリセットできない • systemd-sysv-generator で自動生成されたファイルは 無駄な dependency が設定されていることがある(特に Ubuntu 16.04) • drop-in を使って直したくなるが、残念ながら使えない • 自作するか、Ubuntu 18.04 から backport してくるとよい (Ubuntu 18.04 は自動生成ではなく、ちゃんと作られていることが多い) # /etc/systemd/system/foo.service.d/override.conf [Unit] After= After=bar.service ← これはダメ