View
328
Download
1
Category
Preview:
Citation preview
systemdって?● RHEL7で導入されたシステムとサービスの管理をおこなう
たくさんのユーティリティ、サービス、ライブラリ群● 「 initの置き換え」とよく言われますが単純な置き換えではな
い● 目標は?
– 高速化– ディストリビューション独自実装の統廃合
● RHEL, Fedora, OpenSUSE, Debian, Gentoo, ArchLinux, Ubuntu でsystemd採用(または採用予定)
– ベストプラクティスの統合● よくあるバグの回避● セキュリティ向上の工夫を簡単に利用
systemdでの互換性の維持
● SysV, LSBの init scriptsからunitファイルを自動生成● インタフェースの互換性維持
– dbus: ConsoleKit等– ソケット: /dev/initctl, /dev/log互換ソケット– 「ランレベル」への対応: runlevelX.target, カーネルコマンドラ
インオプション(1,2,3,4,5,6,S,emergency 等)
● 互換コマンドの提供– halt, init, poweroff, reboot, runlevel, shutdown, telinit の置き
換えを同梱– serviceコマンドを実行するとsystemctlを呼びだす
# service cups startRedirecting to /bin/systemctl start cups.service
どのあたりをカバーするのか?
● 起動・終了・再起動に必要な処理全般– デバイスの検出・命名・初期化– fsのmount, autmount, 暗号化block device対応– サービス起動・管理– ロギング– 起動失敗時のレスキュー処理– パスワード確認– システムのlocale, TimeZone, キーボード, 仮想コンソール– 電源管理
● サービス管理で典型的に必要な属性全般の管理– control groups, namespace, ulimit, 通知, /tmp の掃除– ユーザセッション管理
どのあたりをカバーするのか?
● 起動・終了・再起動に必要な処理全般– デバイスの検出・命名・初期化 ← udev
– fsのmount, autmount, 暗号化block device対応 ← systemd-fstab-generator, systemd-cryptsetup-generator
– サービス起動・管理 ← systemd本体– ロギング ← journald
– 起動失敗時のレスキュー処理 ← rescue.service
– パスワード確認 ← systemd-ask-password-*
– システムのlocale, TimeZone, キーボード, 仮想コンソール ← localectl, timedatectl, systemd-vconsole-setup
– 電源管理 ← systemd-sleep
● サービス管理で典型的に必要な属性全般の管理– control groups, namespace, ulimit, 通知, /tmp の掃除 ← systemd本体, systemd-
tmpfiles*
– ユーザセッション管理 ← systemd-logind
– shutdown inihibitor ← systemd-inihibit
サービス管理● serviceコマンドからsystemctlに● サービスの定義が宣言的
– 「unit」と呼ばれるオブジェクト群として管理する– /etc/init.d/* の微妙に異なる多数のシェルスクリプトは徐々になくして
行く。RHEL7ではほとんどのサービスが移行済み– 起動の高速化、メンテナンスの省力化、よくある問題の根絶– 設定変更時は systemctl daemon-reload で読み直させる
● 実行するタイミングでファイル内容を反映しないので注意
● systemdがunit間の依存関係や起動順序を計算して決定– 従来は人間が依存関係を考慮して起動・終了の順序を決定
● 起動・終了するだけでなくサービスの状態やログ、関係するプロセスを管理
/etc/init.d/* をどうする?
● (ほとんどの場合)そのままでOK:
– systemdは/etc/init.d以下のスクリプトを自動変換してserviceユニットを作成します
– service コマンドでのサブコマンドを独自拡張している場合は /usr/libexec/initscripts/legacy-actions/(ユニット名)/(サブコマンド名) に対応するスクリプトを配置する
● unitファイルへ移植– 基本的な起動・終了等ができるのは同じ– 起動エラー時の処理、タイムアウト処理、リソース制限(ulimit)、異常終
了時の自動再起動などを宣言的に記載するだけで利用– 他プロセスと共有しない/tmp, capabilityの制限, localのnetworkにの
み接続できる制限などによるセキュリティ強化も容易
initスクリプト移行例 - cupsd (1)cups.service [Service]ExecStart=/usr/sbin/cupsd -fPrivateTmp=true
[Install]Also=cups.socket cups.pathWantedBy=printer.target
● ExecStart= 起動時に実行するコマンド。ExecStop等の指定がなければ終了時はここで作成されたプロセスへ「SIGTERM送信→タイムアウト待ち→SIGKILL
送信」による終了処理を行う● PrivateTmp= namespaceを利用して自分のサービスからだけ見える /tmp を
作成して利用する。脆弱性回避に有効● Also= このunitを有効にする時に指定したunitも有効化する● WantedBy= 依存関係を挿入する。printer.tergetを有効化するとcups.service
を有効化するようになる
initスクリプト移行例 - cupsd (2)Socket Activation
cups.socket [Socket]ListenStream=/var/run/cups/cups.sock
● ListenStream= 指定したソケットをsystemdが待ちうけ● cups.socketだけをenable/startしている場合
– systemdがソケットのlistenを行い、はじめて接続がおこなわれた時点で対応するサービスを起動する(Socket Activation)
– この例ではcups.socketを待ちうけてcups.serviceを起動する● cups.socketとcups.serviceの両方をenable/startしている場
合– 起動完了待ち(printer.target)またはsocketが必要になるどちらか早いタイミングでサービスを起動する
initスクリプト移行例 - cupsd (3)Path based Activation
● ファイルやディレクトリの存在や変更を検知して対応するサービスを起動する(Path based activation)
● この例では/var/spool/cups/d*(未処理の印刷Jobに対応するファイル) が存在すればcups.serviceを起動する
cups.path
[Path]PathExistsGlob=/var/spool/cups/d*
[Install]WantedBy=multi-user.target
initスクリプト移行例 - iptables (1)
serviceコマンドの独自拡張● /etc/init.dスクリプトで独自拡張を行っている
– service iptables save
● 通常のserviceファイル以外に以下のファイルで saveコマンドを実装– /usr/libexec/initscripts/legacy-actions/iptables/save
● iptables.initスクリプトのsaveサブコマンドを呼ぶだけ– /usr/libexec/iptables/iptables.init
● 元の/etc/init.d/iptablesそのままで場所だけ変更
● これらを用意することで、service iptables saveを以前と同様に実行できる
initスクリプト移行例 - iptables (2)[Unit]Description=IPv4 firewall with iptablesAfter=syslog.targetConditionPathExists=/etc/sysconfig/iptables
[Service]Type=oneshotRemainAfterExit=yesExecStart=/usr/libexec/iptables/iptables.init startExecStop=/usr/libexec/iptables/iptables.init stopEnvironment=BOOTUP=serialEnvironment=CONSOLETYPE=serialStandardOutput=syslogStandardError=syslog
● ConditionalPathExists= でファイルが存在する場合のみ実行。同様のConditional* パラメータを多数提供
● Type=oneshotとRemainAfterExit=yesでiptables.initが実行終了してもサービスが実行中という状態が維持される
サービスを強制終了する
● あるサービスを今すぐ強制終了したい– サービスに関係するプロセスにkill -KILLする
● 「関係するプロセス」をどうやって発見するか?
– 伝統的手法: 起動したプロセスのPIDを/var/run以下に保存
– 直接の親子関係にあるプロセスは(ほぼ)みつけられる● double forkするプロセスはどうしよう?
– systemdではcontrol groupsで追跡● 関係するプロセスが明示的にcontrol groups を切り替えなけ
れば全て追跡可能
systemd-cgls, systemctl kill
● 各ユニット毎に所属するプロセス群を整理して表示● control groupによる追跡でdaemoniseされても問題ない● systemctl killでunit内全プロセスを対象としてシグナル送信systemctl kill -s 9 crond.service
– 代表プロセスのみ、シグナルの種類など選択可能
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 23├─system.slice│ ├─avahi-daemon.service│ │ ├─956 avahi-daemon: running [snake.local│ │ └─979 avahi-daemon: chroot helpe│ ├─dbus.service│ │ └─926 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation│ ├─firewalld.service│ │ └─923 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid│ ├─ModemManager.service│ │ └─958 /usr/sbin/ModemManager│ ├─lvm2-lvmetad.service│ │ └─13929 /usr/sbin/lvmetad -f(以下略)
journaldイメージ図
kernel dmesg
/dev/log(syslog)
サービスのstdout/stderr
journald nativeインタフェース
systemd-journald
journalfile
journalfile
journalfile
rsyslogimjournal
journalctll
syslogfile
バイナリログuid毎に分離
テキストログ設定により
優先度等で分離
クエリによりjournal file群から
ログを検索・整形・表示
journaldが解決する問題 (1)
起動直後のログ保存● syslogdが起動する以前のログを統一的に扱う
– syslogdはroot fsマウント後に起動する– 「起動しない」トラブルではこの時点のログが必須
● 従来の対応:
– カーネルについては? → rc.sysinitで dmesg に出力– ユーザランドのものは? → plymouthで boot.logに出力
● journaldでの対応:
– journaldはinitramfsに含まれ、起動直後のroot fs mount以前から起動– メモリ(tmpfsの/run/log/journal)上にログを保存– syslogdがjournaldに接続し、通常のsyslog出力として起動直後のログ
をディスクへ保存
journaldが解決する問題 (2)
● syslogの制限– 取得できるがログに残せないメタデータが多数ある– 多くのメタデータをクライアントが偽装できてしまう
● ログの圧縮● ログ改竄検知● logrotateにたよらないログファイルの切り替え● ログの検索、インデクシング● ログの権限管理
– ユーザが自分自身で出力したログは参照させたい
journaldによるロギング● メタデータ付加
– マイクロ秒64bitでのタイムスタンプ, 起動からの時間, ログの優先度, systemdのunit, cgroup,
SELinuxコンテキスト, boot ID, machine ID等– クライアントから送られる情報と照合できる
● 独自バイナリフォーマット– 圧縮・インデクシング・改竄検出対応– ユーザ毎に分離
● journaldによる自動的かつ透過的なrotate
– SIGUSR2送信による強制rotateも可● journalctlコマンドによるクエリ
– メタデータによる絞り込み● デフォルトではjournaldのログは揮発性。永続化はrsyslogで行う
– tmpfsの/run/log/journal 以下に収集する。サイズ上限になれば古いものから消す– rsyslogのimjournalモジュールでjournaldから読みだし、syslogとして保存
● mkdir /var/log/journal するとここへjournaldのログを保存
journaldで付加されるメタデータ例__CURSOR=s=70bed981e31a46e2a70c56776402e0eb;i=342;b=982826bc22454f079fd46ec94e2b__REALTIME_TIMESTAMP=1407830743019247__MONOTONIC_TIMESTAMP=1792842_BOOT_ID=982826bc22454f079fd46ec94e2b67fcPRIORITY=6_UID=0_GID=0_MACHINE_ID=025b7ff2c8af43f78513996f06584c4c_HOSTNAME=localhost.localdomainSYSLOG_IDENTIFIER=systemdSYSLOG_FACILITY=3CODE_FILE=src/core/unit.cCODE_LINE=1115CODE_FUNCTION=unit_status_log_starting_stopping_reloadingMESSAGE_ID=7d4958e842da4a758f6c1cdc7b36dcc5_TRANSPORT=journal_PID=1_COMM=systemd_EXE=/usr/lib/systemd/systemd_CAP_EFFECTIVE=1fffffffff_SYSTEMD_CGROUP=/_CMDLINE=/usr/lib/systemd/systemd --switched-root --system --deserialize 20_SELINUX_CONTEXT=system_u:system_r:init_t:s0UNIT=rsyslog.serviceMESSAGE=Starting System Logging Service..._SOURCE_REALTIME_TIMESTAMP=1407830743019153
カーソル位置時刻(usec)
起動からの経過時間BOOT IDログ優先度
UIDGID
マシンIDホスト名
syslogのIDと ファシリティソースコード 内の行番号 内の関数名
メッセージのID接続方法
PIDコマンド名実行ファイルCAPABILITY
CGROUPコマンドライン
SELinuxコンテキストsystemdのunit名メッセージ本文
出力時の時刻(usec)
systemdの各サービスのconfig
● /etc/systemd/bootchart.conf● /etc/systemd/journald.conf● /etc/systemd/logind.conf● /etc/systemd/system.conf● /etc/systemd/user.conf
各種config
● /etc/hostname
– ホスト名– インストール時に設定, hostnamectlコマンドで操作– /etc/sysconfig/network から移行
● /etc/locale.conf
– システムのlocale
– インストール時に設定, localectlコマンドで操作– systemdから起動されるunitは基本的にこのlocaleで実行される
● /etc/localtime
– システムのtimezone
– /etc/timezoneから移行– インストール時に設定, timedatectlコマンドで操作
各種config
● /etc/machine-id
– システムに固有な128bit ID
– インストール時に生成, 一旦ファイルを消してからsystemd-
machine-id-setupコマンドで再生成– journaldやdbusで利用– /var/lib/dbus/machine-idから移行
● /etc/machine-info
– ホスト名の別名やアイコン等(主にデスクトップ用途で利用)
– hostnamectlで操作● /etc/vconsole.conf
– 仮想コンソールのキーマップやフォント設定– インストール時に設定, localectlやsystem-config-keyboardで操作
各種config
● /etc/crypttab
– 暗号化ブロックデバイスの設定● /etc/os-release
– OS名やバージョン番号、バグレポート時の製品ID等– /etc/redhat-releaseを強化したもの。redhat-
releaseも引き続き提供
Recommended