RHEL 7 における systemd の概要

更新 -

systemd システムおよびサービスマネージャーは、サービスがどのように開始または停止したか、または Red Hat Enterprise Linux 7 でどのように管理されているかを制御します。オンデマンドのサービス起動を提供し、トランザクションの依存関係管理を改善することで、systemd は起動時間を大きく削減します。systemd では、重要なサービスの優先順位をあまり重要でないサービスのものよりも高くすることができます。

起動時にサービスを開始しランレベルを変更する init プロセスから systemd プロセスに変更になりました (/sbin/init は /usr/lib/systemd/systemd へのシンボリックリンクになります)。systemd は、既存の init スクリプトのサポートを続けながら、init プロセスより改善された制御を提供します。以下は、systemd 機能の一例となります。

  • ロギング:初期 RAM ディスクをマウントして Linux カーネルを起動してからシステムをシャットダウンするまでのログメッセージが、すべて新しい systemd ジャーナルに保存されます。systemd ジャーナルが導入される以前は、初期ブートメッセージが消えてしまうため、起動の問題をデバッグする際はメッセージをスクロールして確認する必要がありました。
    今後は、すべてメッセージが単一ストリームに記録され、/run ディレクトリに保存されます。メッセージは rsyslog 機能で使用され (/var/log ディレクトリに保存されている従来のログファイルまたはリモートのログサーバーにリダイレクトされ)、さまざまな属性で journalctl コマンドを使用し表示できます。

  • 依存関係:systemd を使用して、依存関係セットを各サービスに明確に定義できます。定義しない場合は起動順による暗黙的な定義が使用されます。依存関係を定義すると、その依存関係が一致した時にサービスを起動できます。これにより、多くのサービスを同時に開始できるため、起動にかかる時間が短くなります。また、複雑な依存関係セットを設定できるため、サービスが開始する前に満たす要件 (ストレージの可用性やファイルシステムチェックなどの) を正確に定義できます。

  • Cgroups:サービスは Cgroups によって特定されるため、サービスのすべてのコンポーネントを管理できます。たとえば、System V init スクリプトでは、その他の子プロセスを開始するプロセスを起動してサービスを開始していました。サービスを kill したら、親プロセスが適切に子プロセスを kill していました。Cgroups を使用すると、 サービスのすべてのコンポーネントに、すべてのコンポーネントが適切に開始または停止していることを確認するためのタグが含まれています。

  • サービスの有効化:サービスは、systemd が導入される以前はランレベルに基づいて実行の有無が決まっていましたが、パス、ソケット、バス、タイマー、またはハードウェアの起動に基づいてサービスを有効にすることができるようになりました。同様に、systemd でソケットを設定できるため、プロセス処理接続ができなくなると、そこで起動したプロセスはソケットから次のメッセージを受け取ることができます。サービスを使用するクライアントには、サービスが中断せずに続いているように見えます。

  • サービス以外の機能:systemd は、サービス管理の他に数種類のユニットを管理できます。これらのユニットには以下が含まれます。

    • デバイス:デバイスを作成して使用します。
    • マウントおよび自由マウント:要求に応じてファイルシステムをマウントしたり、ファイルシステム内のファイルまたはディレクトリに関する要求に基づいて自動マウントしたりします。
    • パス:ファイルやディレクトリが存在するかを確認したり、必要に応じて作成したりします。
    • サービス:サービスを開始します。多くの場合、サービスデーモンと関連コンポーネントを起動します。
    • スライス:(CPU やメモリなど) コンピューターリソースを分割して、選択したユニットに適用します。
    • スナップショット:システムの現在の状況についてスナップショットを取得します。
    • ソケット:プロセスへの接続パスを許可するソケットを設定します。これは、基本プロセスを再起動する必要があったとしても有効のままになります。
    • スワップ:スワップファイルまたはスワップパーティションを作成および使用します。
    • ターゲット:ランレベル数ではなくターゲットによって表示される 1 つのユニットに存在するサービスセットを管理します。
    • タイマー:タイマーに基づいた操作のトリガーとなります。
  • リソース管理

    • 実際は、各 systemd ユニットは常に自身の cgroup に関連付けられていて、各サービスが使用できるリソースの量を制御できます。たとえば、サービスが使用できる CPU の合計に上限を設けるサービスによって、CPU 使用量のパーセントを設定できます。つまり、プロセスをさらに分割させ、サービスが使用するリソースを増やしません。systemd 以前では、貴重な CPU 時間が独占されないように nice レベルがしばしば使用されました。cgroups を使用する systemd を使用すれば、正確な制限を CPU やメモリ使用量などに設定できます。
    • slices と呼ばれる機能を使用すると、様々な種類のシステムリソースの一部を取得して、ユーザー、サービス、仮想マシンなどのユニットに割り当てます。また、これらのリソースにアカウンティングが行われるため、そのリソースの利用料金をユーザーに請求することもできます。

systemd で RHEL 7 を起動する

RHEL 7 を実行している標準の X86 コンピューターを起動するには、選択したメディア (通常はローカルハードディスク) から BIOS を起動すると、ブートローダー (RHEL 7 の場合は GRUB2) が RHEL 7 カーネルと初期 RAM ディスクを起動します。その後、systemd プロセスによってシステムが初期化され、システムサービスがすべて開始します。

RHEL 7 (systemd) システムを起動したときにサービスを起動する順番は厳密に決まっているわけではありませんが、起動プロセスの構造は存在します。systemd プロセスは起動時に default.target ファイルの命令に従います。default.target ファイルは長いリストになっていて、システムの起動時にどのターゲットを開始するかを決定します。

# cd /etc/systemd/system
# ls -l default.target 
lrwxrwxrwx.1 root root 16 Aug 23 19:18 default.target -> /lib/systemd/system/graphical.target

ここでは、graphical.target (グラフィカルインターフェイスを使用したデスクトップシステムまたはサーバー) が (シンボリックリンク経由で) default.target として設定されています。どのターゲット、サービス、ユニットがグラフィカルターゲットで起動しているかを理解するには、依存関係ツリーを構築するために systemd がどのように動作しているかを確認してください。以下はその一例です。

  • graphical.target:****/lib/systemd/system/graphical.target ファイルには以下の行が含まれます。

    Requires=multi-user.target
    Wants=display-manager.service
    Conflicts=rescue.service rescue.target
    After=multi-user.target rescue.service rescue.target display-manager.service
    AllowIsolate=yes
    

    これにより、systemd はグラフィカルターゲットを起動する前に multi-user.target に含まれるものをすべて開始します。開始したら、systemd は "Wants" エントリーに従って display-manager.service サービス (/etc/systemd/system/display-manager.service) を開始します。これにより、GNOME ディスプレイマネージャー (/usr/sbin/gdm) が実行されます。

  • multi-user.target:****/usr/lib/systemd/system/multi-user.target は、RHEL マルチユーザーモードで使用されるサービスを開始します。このファイルには、以下の行が含まれます。

    Requires=basic.target

    これにより、その他のマルチユーザーサービスを開始する前に、systemd が /usr/lib/systemd/system/basic.target ターゲットに含まれるものをすべて開始します。その後、multi-user.target の場合は、/etc/systemd/system/multi-user.target.wants および /usr/lib/systemd/system/multi-user.target.wants 内のすべてのユニット (サービス、ターゲットなど) が開始します。サービスを有効にすると、/etc/systemd/system/multi-user.target.wants ディレクトリにシンボリックリンクが保存されます。ディレクトリには、マルチユーザーモードとして開始すると考えられる大部分のサービス (printing、cron、auditing、SSH など) へのリンクがあります。以下は、一般的な multi-user.target.wants ディレクトリに含まれる services、paths、および targets の例となります。

    # cd /etc/systemd/system/multi-user.target.wants
    abrt-ccpp.service      hypervkvpd.service        postfix.service
    abrtd.service          hypervvssd.service        remote-fs.target
    abrt-oops.service      irqbalance.service        rhsmcertd.service
    abrt-vmcore.service    ksm.service               rngd.service
    abrt-xorg.service      ksmtuned.service          rpcbind.service
    atd.service            libstoragemgmt.service    rsyslog.service
    auditd.service         libvirtd.service          smartd.service
    avahi-daemon.service   mdmonitor.service         sshd.service
    chronyd.service        ModemManager.service      sysstat.service
    crond.service          netcf-transaction.service tuned.service
    cups.path              nfs.target                vmtoolsd.service
    
  • basic.target:****/usr/lib/systemd/system/basic.target ファイルは、実行中のすべての RHEL 7 システムに関連する基本的なサービスを開始します。このファイルには、以下の行が含まれます。

    Requires=sysinit.target

    これは、systemd を /usr/lib/systemd/system/sysinit.target に指定し、basic.target を継続する前に起動する必要があります。basic.target ターゲットファイルは、firewalld および microcode サービスを /etc/systemd/system/basic.target.wants ディレクトリから開始します。SELinux、カーネルメッセージ、ロードするモジュールのサービスは /usr/lib/systemd/system/basic.target.wants ディレクトリから開始します。

  • sysinit.target:****/usr/lib/systemd/system/sysinit.target ファイルは、ファイルシステムのマウントや、スワップデバイスの有効化など、システムの初期化サービスを開始します。このファイルには、以下の行が含まれます。

    Wants=local-fs.target swap.target

    sysinit.target は。ファイルシステムのマウントとスワップデバイスを有効にする以外に、/usr/lib/systemd/system/sysinit.target.wants ディレクトリに含まれるユニットに基づいて、ターゲット、サービス、およびマウントを開始します。これらのユニットがロギングし、カーネルオプションの設定し、udevd デーモンを起動するハードウェアの検出、ファイルシステムの暗号解読の許可などを有効にします。/etc/systemd/system/sysinit.target.wants ディレクトリには、iSCSI、マルチパス、LVM 監視、および RAID サービスの開始が含まれます。

  • local-fs.target:local-fs.target は、以下の行で、local-fs-pre.target ターゲットの後に実行するように設定されています。

    After=local-fs-pre.target

    local-fs-pre.target ターゲットに関連するサービスはありません (必要に応じて "wants" ディレクトリに追加できます)。ただし、/usr/lib/systemd/system/local-fs.target.wants ディレクトリのユニットは initramfs からネットワーク設定をインポートし、必要に応じて root ファイルシステムで ファイルシステムチェック (fsck) を実行し、/etc/fstab ファイルのコンテンツに基づいて root ファイルシステム (および特殊なカーネルファイルシステム) を再マウントしています。

起動プロセスは上述した順番で systemd に構築されますが、実際は逆の順番で実行します。他のターゲットが依存しているターゲットは、通常、最初のターゲットのユニットが開始する前に実行している必要があります。起動プロセスの詳細については、bootup の man ページ (man 7 bootup) を参照してください。

systemctl コマンドを使用する

systemctl は、RHEL 7 (systemd) システムでサービスを管理する最も重要なコマンドです。このセクションでは、systemctl コマンドの一例 (nfs-server サービスを使用) と、その他の便利な一般的なコマンドを紹介します。

  • サービスのステータスを確認する:サービスのステータスを確認 (nfs-server.service など) するには以下のコマンドを実行します。

    # systemctl status nfs-server.service
    nfs-server.service - NFS Server
       Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; disabled)
       Active: active (exited) since Wed 2014-03-19 10:29:40 MDT; 57s ago
      Process:5206 ExecStartPost=/usr/libexec/nfs-utils/scripts/nfs-server.postconfig (code=exited, status=0/SUCCESS)
      Process:5191 ExecStart=/usr/sbin/rpc.nfsd $RPCNFSDARGS $RPCNFSDCOUNT (code=exited, status=0/SUCCESS)
      Process:5188 ExecStartPre=/usr/sbin/exportfs -r (code=exited, status=0/SUCCESS)
      Process:5187 ExecStartPre=/usr/libexec/nfs-utils/scripts/nfs-server.preconfig (code=exited, status=0/SUCCESS)
     Main PID:5191 (code=exited, status=0/SUCCESS)
       CGroup:/system.slice/nfs-server.service
    
    Mar 19 10:29:40 localhost.localdomain systemd[1]:Starting NFS Server...
    Mar 19 10:29:40 localhost.localdomain systemd[1]:Started NFS Server.
    
  • サービスを停止する:サービスを停止するには、以下のように stop オプションを使用します。

    # systemctl stop nfs-server.service
    
  • サービスを開始する:サービスを開始するには、以下のように start オプションを使用します。

    # systemctl start nfs-server.service
    
  • サービスを有効にする:サービスを有効にしてシステムの起動時に自動的に開始するようにするには、以下のコマンドを実行します。

    # systemctl enable nfs-server.service
    
  • サービスを無効にする:サービスを無効にしてシステムの起動時に自動的に開始しないようにするには、以下のコマンドを実行します。

    # systemctl disable nfs-server.service
    
  • 依存関係を一覧表示する:サービスの依存関係を表示するには、以下のように list-dependencies オプションを使用します。

    # systemctl list-dependencies nfs-server.service
    nfs-server.service
    ├─nfs-idmap.service
    ├─nfs-mountd.service
    ├─nfs-rquotad.service
    ├─proc-fs-nfsd.mount
    ├─rpcbind.service
    ├─system.slice
    ├─var-lib-nfs-rpc_pipefs.mount
    └─basic.target
      ├─alsa-restore.service
      ├─alsa-state.service
    ...
    
  • ターゲットでユニットを一覧表示する:どのサービスとユニット (service、mount、path、socket など) が特定のターゲットに関連しているかを表示するには、以下のコマンドを実行します。

    # systemctl list-dependencies multi-user.target
    multi-user.target
    ├─abrt-ccpp.service
    ├─abrt-oops.service
    ├─abrt-vmcore.service
    ├─abrt-xorg.service
    ├─abrtd.service
    ├─atd.service
    ├─auditd.service
    ├─avahi-daemon.service
    ├─brandbot.path
    ├─chronyd.service
    ├─crond.service
    ...
    
  • 特種なユニットを一覧表示する:以下のコマンドを使用すると特殊なユニットを一覧表示します (例では service および mount ユニットを使用)。

    # systemctl list-units --type service 
    UNIT                         LOAD   ACTIVE SUB     DESCRIPTION
    abrt-ccpp.service            loaded active exited  Install ABRT coredump hook
    abrt-oops.service            loaded active running ABRT kernel log watcher
    abrt-xorg.service            loaded active running ABRT Xorg log watcher
    abrtd.service                loaded active running ABRT Automated Bug Reporting 
    accounts-daemon.service      loaded active running Accounts Service
    ...
    
    # systemctl list-units --type mount 
    UNIT                         LOAD   ACTIVE SUB     DESCRIPTION
    -.mount                      loaded active mounted /
    boot.mount                   loaded active mounted /boot
    dev-hugepages.mount          loaded active mounted Huge Pages File System
    dev-mqueue.mount             loaded active mounted POSIX Message Queue File Syst
    mnt-repo.mount               loaded active mounted /mnt/repo
    proc-fs-nfsd.mount           loaded active mounted RPC Pipe File System
    run-user-1000-gvfs.mount     loaded active mounted /run/user/1000/gvfs
    ...
    
  • ユニットをすべて表示する:システムにインストールされているすべてのユニットをそのステータスとともに一覧表示するには、以下のコマンドを実行します。

    # systemctl list-unit-files
    UNIT FILE                            STATE
    proc-sys-fs-binfmt_misc.automount    static
    dev-hugepages.mount                  static
    dev-mqueue.mount                     static
    proc-sys-fs-binfmt_misc.mount        static
    ...
    arp-ethers.service                   disabled
    atd.service                          enabled
    auditd.service                       enabled
    ...
    
  • systemd-cgtop を使用してサービスプロセスを表示する:特定のサービス (cgroup) に関連付けられているプロセスを表示するには、systemd-cgtop コマンドを使用できます。systemd-cgtop は、(プロセスを CPU やメモリ使用量でソートする) top コマンドと同様、そのサービス (cgroup ラベル) で実行中のプロセスを一覧表示します。systemd-cgtop を実行したら、対応するキーを押すと、メモリ (m)、CPU (c)、タスク (t)、パス (p)、または I/O 負荷 (i) でプロセスをソートできます。たとえば以下のようになります。

    # systemd-cgtop
    
  • cgroup コンテンツを再帰的に表示する:cgroup コンテンツの再帰リストを出力するには、systemd-cgls コマンドを使用します。

    # systemd-cgls
    ├─user.slice
    │ ├─user-1000.slice
    │ │ ├─session-5.scope
    │ │ │ ├─2661 gdm-session-worker [pam/gdm-password]
    │ │ │ ├─2672 /usr/bin/gnome-keyring-daemon --daemonize --login
    │ │ │ ├─2674 gnome-session --session gnome-classic
    │ │ │ ├─2682 dbus-launch --sh-syntax --exit-with-session
    │ │ │ ├─2683 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
    │ │ │ ├─2748 /usr/libexec/gvfsd
    ...
    
  • ジャーナル (ログ) ファイルを表示する:****journalctl コマンドを使用すると、systemd ジャーナルのメッセージを表示できます。オプションを複数使用して、どのメッセージグループを表示するかを選択できます。また、journalctl コマンドを使用すると、検索するフィールドに書き込むタグ補完をサポートします。以下のその一例となります。

    # journalctl -h     View help for the command
    # journalctl -k     View kernel messages from current boot
    # journalctl -f     Follow journal messages (like tail -f)
    # journalctl -u NetworkManager     View messages for specific unit (can tab complete)    
    

systemd を従来の init と比較する

従来の System V init 機能と比較すると、systemd には以下の利点があります。

  • ログの初期メッセージを保存します。
  • 必要に応じてデーモンを生き返らせます。
  • ランタイムデータを記録します (プロセスの stdout/stderr を取得します)。
  • ランタイム時にデーモンコンテキストを失いません。
  • サービスのすべてのコンポーネントを適切に killします。

RHEL 7 以前の init および関連コマンドと systemd は、以下の点で異なります。

  • システムを起動する:systemd プロセスは、RHEL 7 システムで実行する最初のプロセス ID (PID 1) です。システムを起動し、従来の init プロセスが起動していたすべてのサービスを起動します。

  • システムサービスを管理する:RHEL 7 で、systemctl コマンドは service および chkconfig に変更になりました。RHEL 7 以前では、RHEL の起動後に service コマンドを使用してサービスを直ちに開始および停止していました。chkconfig コマンドを使用すれば、サービスがどのランレベルで自動的に開始または停止されているのを確認できました。
    service コマンドは、サービスを開始または停止したり、chkconfig コマンドを使用してサービスを有効または無効にしたりすることができますが、RHEL 7 systemctl コマンドと 100% 互換性があるわけではありません。たとえば、データベースの起動や設定ファイルの確認などの非標準サービスオプションは、RHEL 7 サービスと同じようにサポートされない可能性があります。

  • ランレベルを変更する:RHEL 7 以前では、必要に応じて、ランレベルを使用してサービスセットを開始または停止していました。systemd では、ランレベルの代わりにターゲットの概念を使用して、開始または停止するサービスセットをまとめています。ターゲットに他のターゲットも含めることができます (たとえば、マルチユーザーターゲットには nfs ターゲットが含まれます)。
    従来のランレベルと同じように機能する systemd ターゲットも存在しますが、ターゲットがアクティビティレベルを示しているとは限りません (たとえば、ランレベル 3 は、ランレベル 1 より多くのサービスがアクティブであることを示しています)。ターゲットではサービスをグループ化しているため、ランレベルよりもターゲットの方が数が多くなります。以下の一覧は、systemd ターゲットが従来のランレベルにどのように対応しているかを示しています。

    Traditional runlevel      New target name     Symbolically linked to...
    Runlevel 0           |    runlevel0.target -> poweroff.target
    Runlevel 1           |    runlevel1.target -> rescue.target
    Runlevel 2           |    runlevel2.target -> multi-user.target
    Runlevel 3           |    runlevel3.target -> multi-user.target
    Runlevel 4           |    runlevel4.target -> multi-user.target
    Runlevel 5           |    runlevel5.target -> graphical.target
    Runlevel 6           |    runlevel6.target -> reboot.target
    
  • デフォルトのランレベル:デフォルトのランレベル (従来は /etc/inittab ファイルに設定) はデフォルトのターゲットに変更になりました。デフォルトのターゲットは /etc/systemd/system/default.target に保存され、複数ユーザーのターゲットにリンクされます。

  • サービスの場所:systemd 以前では、サービスは/etc/init.d のスクリプトとして保存され、異なるランレベルディレクトリ (/etc/rc3.d/etc/rc5.d など) にリンクされていました。systemd サービスは、xx.service という名前 (firewalld.service など) で、/lib/systemd/system および /etc/systemd/system ディレクトリに保存されます。/lib のファイルは永続的なファイル、そして /etc のファイルは必要に応じて設定を変更できるファイルになります。
    RHEL 7 でサービスを有効にするには、/etc/systemd/system/multi-user.target.wants ディレクトリのファイルにサービスファイルをリンクします。たとえば、systemctl enable fcoe.service を実行すると、/lib/systemd/system/fcoe.service を指定する /etc/systemd/system/multi-user.target.wants/fcoe.service からシンボリックリンクが作成されます。これにより、システムの起動時に fcoe.service が起動します。
    また、従来の System V init スクリプトはシェルスクリプトでした。これと同じように動作する systemd ファイルは .ini ファイルに近い機能を持ち、サービスを起動するのに必要な情報が含まれます。

  • 設定ファイル:RHEL 6 以前の init プロセスで使用されていた /etc/inittab ファイルは、システムを起動するのに必要な初期化ファイル (/etc/rc.sysinit など) とランレベルサービスディレクトリ (/etc/rc5.d など) を指定していました。これらのサービスは、/etc/sysconfig ディレクトリのファイル (通常はそのサービスにちなんだ名前) から変更していました。RHEL 7 の systemd でサービスの動作を修正するには /etc/sysconfig ファイルが使用されます。ただし、サービスは /etc/systemd ディレクトリにファイルを追加し、/lib/systemd ディレクトリの永続サービスファイルを上書きすることで修正できます。

systemd への移行

RHEL 7 以前の init プロセスと System V init スクリプトを使い慣れている場合は、systemd に移行するのに注意すべき点がいくつかあります。

  • RHEL 6 コマンドを使用する:RHEL 6 で使用していたコマンド (servicechkconfigrunlevel、および init) は、しばらくの間は使用できます。これにより、完全に同一ではありませんが、同じような結果を取得できます。以下のその一例となります。

    # service cups restart
    Redirecting to /bin/systemctl restart cups.service
    # chkconfig cups on
    Note:Forwarding request to 'systemctl enable cups.service'.
    
  • System V init スクリプト:System V init スクリプトは、推奨はされていませんがサポート対象内です。RHEL 7 でサポートされているサービスで System V init スクリプトに実行されているものもいくつかあります。システムで利用可能な System V init スクリプトと、起動するランレベルを確認するには、以下のように chkconfig コマンドを使用します。

    # chkconfig --list
    ...
    iprdump       0:off   1:off   2:on   3:on   4:on   5:on   6:off
    iprinit       0:off   1:off   2:on   3:on   4:on   5:on   6:off
    iprupdate     0:off   1:off   2:on   3:on   4:on   5:on   6:off
    netconsole    0:off   1:off   2:off  3:off  4:off  5:on   6:off
    network       0:off   1:off   2:on   3:on   4:on   5:on   6:off
    rhnsd         0:off   1:off   2:on   3:on   4:on   5:on   6:off
    ...
    

ただし、chkconfig を使用しても、システムのすべてのサービスを一覧表示するわけではありません。systemd-specific サービスを表示する場合は、上述の systemctl list-unit-files コマンドを実行してください。

systemd の参考情報

systemd の詳細については、Red Hat Enterprise Linux 7 System Administrator's Guide を参照してください。