Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

インフラエンジニアのお仕事 ~ daemontools から systemdに乗り換えた話 ~

486 views

Published on

KLab TECH Meetup #3
インフラエンジニアのお仕事
~ daemontools から systemdに乗り換えた話 ~

Published in: Technology
  • Be the first to comment

インフラエンジニアのお仕事 ~ daemontools から systemdに乗り換えた話 ~

  1. 1. インフラエンジニアのお仕事 ~ daemontools から systemdに乗り換えた話 ~ Kansei CHIBA @KLab
  2. 2. $ whoami 千葉 幹正 (CHIBA Kansei) ● 仕事 ○ KLab 株式会社 2011 年新卒入社 ○ インフラマネジメント部 所属 ○ AWS・GCP を使ったクラウド環境でのインフラ設計・構築・運用がメイン ● 趣味 ○ ここ数年は、ロードバイク一本 ● AWS, GCP, Golang, Systemd...
  3. 3. $ groups KLab 株式会社 ● くらぶ かぶしきがいしゃ ● 2000 年発足 ● サイバード社の研究開発部署から独立した会社 ● 元々は、(株) ケイ・ラボラトリー で、今もたまに ケイラボ と呼ばれる ● 技術大好きな人にとって、居心地の良い会社(だと思います) ○ インフラエンジニア絶賛募集中 (公には募集してないので声かけてください)
  4. 4. $ login どんな人がこの会社のインフラエンジニアに向いているか? ● 入社初日 ● しーてぃーおー 「一般ユーザあげるからさ、root をどうにかして奪っといてよ(^^)」 ● あなた 「....この会社超絶ブラックだわorz」 => 向いていません 「....ヤベェ、おらワクワクしてきた」=> 向いています!
  5. 5. $ su - 一応説明しておくと・・・ ● root 取れなくてもしーてぃーおーに食べられたりはしません ● root 取るために何を考えて行動を起こしたか、起こせそうか、そんなことを 考えることに少しでもテンション上がる方を募集中 ● あくまで一例です。 この分野なら俺に語らせろ、これで仕事させろ というあなたからのお声がけをお待ちしています
  6. 6. 要約: 人足りてません。声かけてください(TT)
  7. 7. 宣伝終わり
  8. 8. プロセスの管理手段 考え直してみました
  9. 9. プロセスの管理どうしてますか (Linux) 制御方法 ● プロセスの起動・停止・再起動は何を使って管理している? 関連して... ● プロセスの起動判定基準 ● プロセスが終了した際の挙動 ● プロセスの標準出力・エラー出力の取り扱い など
  10. 10. これまではどうしてきた? 環境 ● Debian 7 (Wheezy) ● sysvinit + daemontools プロセスの管理 ● 原則、独自に導入したアプリケーションの管理は、daemontools にお任せ ● daemontools から、各種アプリケーション向けに用意したシェルを実行
  11. 11. daemontools ● 任意のプログラムをデーモン化 ● 起動・停止・再起動用コマンドの提供 ● 自動再起動 ● プログラムの標準出力,エラー出力を、ログファイルへ ● KLab では、長い間使い続けている OSS ○ http://cr.yp.to/daemontools.html
  12. 12. sysvinit ● 説明不要の大御所 init (ですよね? ● 多くのデストリで systemd への置き換えが進められている状況 ● daemontools 同様に KLab では長い間使い続けている ○ というか、構築当初はこれ以外選択肢がなかったはず
  13. 13. sysvinit + daemontools ● 以前 ○ Apache + modphp の組み合わせで API を提供する構成が多数 ○ インフラの構成は、各案件共通で、一つのシステムで相乗り ● 現在 ○ Apache, PHP 以外の OSS も採用されるように ■ nginx, uwsgi ■ python, golang で作成された自社プログラム ● 扱うものは変わったが、大抵の案件はこの構成で運用できた
  14. 14. プロセス管理を再考するきっかけ 以下要件でデーモンを立ち上げる必要が出た 1. プロセス終了時に自動再起動したくない 2. プロセス終了時に通知を出して欲しい 3. プロセスの標準出力/エラーはログに出力したい
  15. 15. プロセス管理を再考するきっかけ 以下要件でデーモンを立ち上げる必要が出た 1. プロセス終了時に自動再起動したくない -> daemontools では運用不可と判断 (頑張ればできそうだけど、容易でない) 2. プロセス終了時に通知を出して欲しい -> 従来のやり方で対応可能(デーモン監視ツールの運用) 3. プロセスの標準出力/エラーはログに出力したい -> 従来のやり方で対応可能(daemontools + multilog)
  16. 16. 作ってみた execmon ● 任意のプログラムをデーモン化・監視(通知)・標準(エラー)出力をログに落と し込んでくれる便利なやつ ● fork(), execve(),dup2(),pipe() あたりを利用して、バックグラウンド実行 & ロ グ出力 ● $ execmon -n ${notifycmd} -p ${pathtopid} -- cmd ● 正直、daemonize のお作法一度実装しておきたかった面がでかい\(^o^)/
  17. 17. execmon
  18. 18. 運用上の懸念 ● インフラ担当者として、C を触れる人をアサインする必要がある ○ そうコストが高いものではないが、新しいメンバーが、execmon のために、C を触るの? ● プロセス管理手段が複数あるの少し気になる(できたらまとめたい) ○ sysvinit (daemontools の 始動, その他システム関連) ○ daemontools (自動再起動が必要なデーモンの管理) ○ execmon(自動再起動したくないデーモンの管理)
  19. 19. プロセス管理手段を改めて考え直す 1. execmon を部内の共通言語で書き直す? a. 最近の部内の共通言語は、Go・Python あたり i. 可能なら、コード見なくても済むようにしたい 2. やっぱり、sysvinit + daemontools だけで頑張ってみる? a. sysvinit で管理するとしても、標準(エラー)出力はどうログに書き出そう? b. daemontools だと、起動スクリプトの実装が若干煩雑に i. あまりシンプルな方法を思いつかない 3. それ以外の選択肢を模索? a. sysvinit, daemontools, execmon を綺麗にまとめられる奴がいたら... i. せめて、daemontools と、execmon だけでも ● 直近、別案件で、触る機会のあった Debian 8 の systemd を第一候補に
  20. 20. systemd の採用検討 ● プロセスの起動/停止/再起動/自動再起動 ● プロセスの起動完了判定 ● プロセス終了判定時の通知 ● プロセスの標準出力の扱い ● https://www.freedesktop.org/software/systemd/man/ ● http://0pointer.de/blog/projects/systemd.html ● Debian, Arch, RedHat の systemd に関わるドキュメントは、 日本語での情報提供もちらほらあるので、割とすんなり情報採集できた
  21. 21. s/sysvinit/systemd/ ● execmon は、systemd ユニット で簡単に置き換え可と判断 ○ 自動再起動しない (Restart=no (default)) ○ 落ちたら通知を出す (OnFailure=alert.service) ○ プロセスの標準出力/エラーはログに出力 (Journald) ● sysvinit + daemontools の置き換え ○ こちらも同様に置き換えできそうな温度感 ○ 独自に作ってきた起動処理の置き換えをどう systemd で対応するか
  22. 22. 独自の起動フロー @ AWS EC2 一つのサーバイメージから様々な役割のサーバを立ち上げる仕組み AWS EC2 インスタンス起動時に、タグに役割を登録することで、役割ごとに設定 されているプロセスが立ち上がる
  23. 23. 検討初期 ● 設定された役割に応じて、ステータスを変えるサービスユニットの配置 (役割判定ユニット) ● 役割ごとに、役割判定ユニットを配置して、各サービスユニットは適切な役 割ユニットを前提ユニットに指定
  24. 24. 検討初期 ● 役割判定ユニットの具体例 ○ WEB という役割が設定されていれば、Active になる WEB-role.service ○ DB という役割が設定されていれば、Active になる DB-role.service ■ いずれも、当該役割の設定がなければ、Fail になる ● 役割判定ユニットを前提ユニットとするサービスユニットの挙動 ○ 役割判定ユニットが、 ■ Active であれば、起動する ■ Fail であれば、前提ユニットとの依存関係解決に失敗して、起動しない (Fail ステータスへ落ちる)
  25. 25. OnFailure が使えない.. ● 設定外のサービスユニットのステータスは、Fail となる ● 担当役割外のサービスユニットに、OnFailure が設定されていると、サーバ 起動時に、発火してしまう。(そして、アラートで埋もれる...) ● OnFailure 使うのやめる? ○ これまで、自前で実装してきたプロセス監視ツールを systemd にお任せできるのは大きい ○ OnFailure はプロセスが不意に落ちた時の通知などに使いたい ※ OnFailure: プロセスが落ちた時に任意のサービスユニットを呼び出す機能
  26. 26. original-init.service 役割判定 & 当該役割のターゲットユニット を動的に実行するプログラムを配置
  27. 27. 実装にあたって KLab インフラ内でのちょっとした運用ポリシー ● シェルスクリプト運用をできるだけ回避する ● サクッとかけて便利だけど、書く人によって品質の差が出やすい ● サクッと修正できるので、環境ごとの差異が生まれやすい (あくまで、KLab インフラG 内での認識です)
  28. 28. systemd API の利用 ● golang (1.10) ○ 言語はなんでもいいけど、とりあえず使える人が多いものを ● go-systemd ○ https://github.com/coreos/go-systemd ● systemd v232 ○ version が古いと、使えない API がいくつかある ○ https://www.freedesktop.org/wiki/Software/systemd/dbus/
  29. 29. systemd API の利用 Sysvinit との大きな違い ● Systemd は、各種プロセスのステータスを握っている ● Systemd 経由で、プロセスの制御はもちろん、PID や、UID、GID などの情報 を取り出したりできる ● これらは、プロパティという形で Systemd から取得できる
  30. 30. サービスユニットの組み方
  31. 31. サービスユニット の組み方? 依存先のサービスユニットは、本当にアプリケーションレベルで機能しているか? ● 標準では、exec() した瞬間に起動完了とみなすため、アプリケーションが完 全に立ち上がっていなくても、起動完了と判断される (Type=simple) ● アプリケーションが本当に機能しているかを確認するサービスユニットの導 入 (テストユニット)
  32. 32. サービスユニット の組み方? 結局この組み方はやめた ● テストプログラムのメンテナンスコストが大きい ● サービスユニットと、テストユニットの挙動を同期させる必要がある ○ サービスユニットが停止しているのに、テストユニットは立ち上がったまま ○ サービスユニットの再起動に合わせて、テストユニットも再起動など ■ これらを満たすには、ユニットに一手間設定を加える必要があるが、複雑性が増す
  33. 33. サービスユニットの組み方? ではどうしたか? ● 説明がややこしいのと、時間がないので懇親会で(笑
  34. 34. インフラ利用者への対応
  35. 35. (再) daemontools の置き換え インフラ 管轄の sysvinit + daemontools な処理を systemd へ置き換えたが、実環 境では、インフラ利用者(アプリ開発者)向けに、専用の daemontools を立ち上げ ている ● インフラ利用者と協議し、daemontools -> systemd (user) への乗り換えに ● cron についても、systemd timer への乗り換え ● 勿論、systemd API も、systemd (system) 同様に利用可
  36. 36. systemd --user ● 一般ユーザ向けの systemd プロセス ○ ps で見ると、systemd --user で見えるハズ ● systemctl や、ライブラリ類から、systemd (user) に接続する際は、 systemd の一部環境変数を修正する必要あり ● Debian 9 だとデフォルトで利用可能だが、標準設定では、 ログイン中のみ有効となるため注意
  37. 37. systemd --user インフラとして、インフラ利用者へ協力したこと ● systemd (user) がユーザログアウト後も動作するように ○ Debian 9 なのですんなりだったけど、CentOS あたりだと... ● systemd の基本的な扱い方と概念の説明 ○ service, timer, target ... ○ ユニットのサンプル提供 ● systemd API 利用時のサンプル作成 ○ 本案件では、Golang のコードを提供
  38. 38. s/sysvinit with daemontools/systemd/ ● 一部案件では、sysvinit + daemontools + execmon 運用を、systemd 運用へ 乗り換え完了 ● 一部のパッケージが、LSB script を取り込んでくるので、一応 sysvinit 互換 は残してある
  39. 39. 最後に systemd で幸せになれたのか ● まだ、systemd 各所で把握できていないものがあるため、これからも様々な 調査が必要。そういった意味では、それなりの学習コストを覚悟 ● 取り扱うシェルスクリプト群が減った ● プログラマブルにプロセスを管理することができるようになった ● 通知が容易になった 等から、現時点では、幸せになりつつある(笑
  40. 40. systemd 管理者の方、ぜひお声がけください ● systemd の罠を踏んだ方 ● systemd なんてアンインストールしてやる と言う方 ● systemd よりこの init の方が断然いい!!1111 ● systemd のこの機能使ってる? ぜひお声がけください
  41. 41. 最後の最後に
  42. 42. 相談とか共有とか
  43. 43. (相談) configtest service hogefuga configtest 相当のことをやりたい ● サービスユニットで管理しているアプリケーションの設定ファイルの syntax check とか ● syntax check 専用のサービスユニットを作るぐらいしか方法を思いつかない ● どんな運用でカバーしている?
  44. 44. (相談) 認証ロジック d-bus API, systemd API の認証ロジック ● getsockopt() + SO_PEERCRED ? ● 多分それしかないと思うんだけど、違ってたら誰か教えて
  45. 45. (共有) systemd API の入り口 private socket & dbus socket の使い分けをどう考えるか ● systemctl や、各種ライブラリを見ていると、private socket, dbus socket に connect() しているのが見える。 自前のプログラムからつなぐ場合はどちらを使えばいい? ● 原則として、dbus socket を利用する ○ private socket は、dbus が使えないシーンで systemctl から利用される ○ 将来、破壊的な変更が入る可能性があるため、private socket の利用は非推奨 ○ systemd API 利用時は、不必要に private socket を利用しない
  46. 46. 詳しい話は、懇親会で!

×