ハンドラーによるサービスの管理

AnsibleBeginner
オンラインで実践に進む

はじめに

ハンドラー(Handlers)は、変更があったタスクから通知を受けた場合にのみ実行される特別な Ansible タスクです。これらは主に、サービスのリロードや再起動によく使用されます。

この実験では、安全なデモ用の systemd ユニットをデプロイし、ユニットファイルが変更された際にハンドラーを通知し、サービスがアクティブかつ有効であることを確認します。

サービス自動化プロジェクトの作成

このステップでは、サービス自動化のためのプロジェクトを作成します。この実験では、サービスが RHEL 10 VM 上の実際のシステム状態であるため、ローカルホストのエイリアスを 1 つ使用します。

cd /home/labex/project
mkdir -p rhce-ansible/{inventory,files,playbooks,reports}
cd rhce-ansible
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
cat > inventory/hosts <<'EOF'
[service_hosts]
host ansible_connection=local
EOF

ローカル接続であっても、Playbook は VM 上の実際の systemd 状態を管理します。そのため、この実験では複数の独立したサービスホストがあるかのように装うのではなく、1 つのホストエイリアスを使用し、後で become: true を使用します。

デモ用 systemd ユニットファイルの作成

このステップでは、Ansible が /etc/systemd/system にコピーするソースユニットファイルを作成します。このサービスは /usr/bin/sleep infinity を実行するため、安全かつ簡単に検証できます。 このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。これにより、LabEx が各ステップを個別に実行する場合でもコマンドが安定します。

cd /home/labex/project/rhce-ansible
cat > files/rhce-handler-demo.service <<'EOF'
[Unit]
Description=RHCE handler demo service

[Service]
Type=simple
ExecStart=/usr/bin/sleep infinity
Restart=always
RestartSec=1

[Install]
WantedBy=multi-user.target
EOF

このユニットは意図的に無害なものにしています。長時間実行される sleep プロセスを開始し、終了した場合は再起動します。[Install] セクションにより、Ansible が multi-user.target に対してサービスを有効化できるようになります。

sed -n "1,12p" files/rhce-handler-demo.service

続行する前に、ExecStart 行と WantedBy 行を確認してください。ソースユニットファイルが間違っていると、Ansible は間違ったサービス定義をそのままデプロイしてしまいます。

ハンドラーを使用した Playbook の作成

このステップでは、ユニットファイルをコピーしてハンドラーに通知する Playbook を作成します。meta: flush_handlers タスクは、サービス関連のタスクの前に保留中のハンドラーを実行するため、systemd は新しいユニットを認識できます。 このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。

cd /home/labex/project/rhce-ansible
cat > playbooks/manage-service.yml <<'EOF'
---
- name: Deploy and manage the demo service
  hosts: service_hosts
  become: true
  gather_facts: false
  tasks:
    - name: Install demo systemd unit
      ansible.builtin.copy:
        src: ../files/rhce-handler-demo.service
        dest: /etc/systemd/system/rhce-handler-demo.service
        mode: '0644'
      notify:
        - Reload systemd
        - Restart demo service

    - name: Run handlers before enabling the service
      ansible.builtin.meta: flush_handlers

    - name: Ensure demo service is active and enabled
      ansible.builtin.systemd:
        name: rhce-handler-demo.service
        state: started
        enabled: true

  handlers:
    - name: Reload systemd
      ansible.builtin.systemd:
        daemon_reload: true

    - name: Restart demo service
      ansible.builtin.systemd:
        name: rhce-handler-demo.service
        state: restarted
EOF

copy タスクは、ユニットファイルが変更された場合にのみ 2 つのハンドラーに通知します。meta: flush_handlers は、systemd タスクが開始されサービスが有効化される前に保留中のハンドラーを実行します。これは、systemd が新しいサービスを認識する前にユニットファイルをリロードする必要があるため重要です。

ansible-playbook playbooks/manage-service.yml --syntax-check

Playbook が /etc/systemd/system に書き込む前に、構文チェックが通過することを確認してください。これにより、サービスの状態を変更することなく、タスクリストや handlers セクションのインデントミスを検出できます。

Playbook の実行とサービスの確認

このステップでは、サービス用の Playbook を実行します。初回実行時には、ユニットのインストール、systemd のリロード、サービスの開始、および起動時の有効化が行われるはずです。 このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。

cd /home/labex/project/rhce-ansible
ansible-playbook playbooks/manage-service.yml | tee reports/service-first-run.txt

初回実行では、ユニットファイルのコピー、systemd のリロード、ハンドラーを通じたデモサービスの再起動、そしてサービスの有効化が行われます。出力を保存することで、ハンドラーのパスが実行されたかどうかを確認できます。

systemctl is-active rhce-handler-demo.service
systemctl is-enabled rhce-handler-demo.service

is-active は現在の起動セッションにおける実行状態を確認し、is-enabled はサービスがブートターゲットにリンクされているかどうかを確認します。RHCE のサービス関連タスクでは、多くの場合その両方が求められます。

ユニットファイルの変更とハンドラーの再トリガー

このステップでは、ソースユニットファイルに対して制御された変更を加えます。copy タスクが変更を検出すると、再びハンドラーに通知が送られます。 このステップでコマンドを実行する前に、Ansible プロジェクトディレクトリに戻ってください。

cd /home/labex/project/rhce-ansible

lineinfile モジュールを使用して、アドホックコマンドでローカルファイルを編集することもできます。ここでは、ソースユニット内の 1 行のみを変更します。

ansible localhost -c local -m ansible.builtin.lineinfile -a 'path=files/rhce-handler-demo.service regexp=^RestartSec= line=RestartSec=3'

これはソースファイルを変更するものであり、/etc/systemd/system にインストールされたユニットを変更するものではありません。次の Playbook 実行時にソースの変更が検知され、更新されたユニットがコピーされ、ハンドラーが再度通知されます。

ansible-playbook playbooks/manage-service.yml | tee reports/service-second-run.txt
grep -F RestartSec /etc/systemd/system/rhce-handler-demo.service

インストールされたユニットには RestartSec=3 が反映されているはずです。ファイル変更後にハンドラーが systemd をリロードし、デモサービスを再起動したため、サービスはアクティブかつ有効な状態が維持されます。

まとめ

安全な systemd ユニットをデプロイし、systemd のリロードとサービスの再起動にハンドラーを使用し、サービスがアクティブかつ有効な状態であることを確認しました。また、ユニットファイルの制御された変更を通じてハンドラーをトリガーする方法を学びました。