Red Hat Certified Engineer (RHCE) #15 RHCSA 自動化 2: サービス、chronyd、log
#14 RHCSA 自動化 1 でユーザー・グループとパッケージ・repository を playbook で押さえました。今回の #15 では、RHCSA の手作業の 2 つ目の塊である サービス管理、時刻同期、ログ設定 を自動化します。いずれも RHCSA #9 サービスとブート で systemctl や chronyc、journalctl で手作業で扱った作業であり、今回は同じ結果を冪等なモジュールで宣言します。
この領域の採点ポイントはいつも変わりません。サービスは起動する (start) だけで終わらず、ブート時にも起動する (enable) 必要があります。 時刻同期は設定ファイルを変えた後にデーモンを上げ直す必要があり、ログは再起動後にも残るように永続設定する必要があります。つまり「今動く」と「再起動後にも動く」を同時に保証することが自動化の核心です。
サービス管理: service と systemd モジュール #
デーモンを起動・停止・ブート登録する作業は ansible.builtin.service または ansible.builtin.systemd_service モジュールで行います。手で打っていた systemctl start と systemctl enable を 1 つの task にまとめて宣言します。
service モジュールの 3 つの核心キー #
| キー | 意味 | 値の例 |
|---|---|---|
| name | 対象サービス名 | httpd、chronyd |
| state | 現在の動作状態 | started、stopped、restarted、reloaded |
| enabled | ブート時の自動起動可否 | true、false |
ここで最もよく見落とすのが state と enabled を一緒に指定する ことです。state: started だけ書くと今は起動しますが再起動後は止まっていることがあり、enabled: true だけ書くとブート登録はされますが今は停止しています。試験では両方を要求する場合がほとんどなので、2 つのキーを一緒に書く習慣をつけます。
- name: 웹 서버를 지금도 켜고 부팅에도 등록한다
hosts: webservers
become: true
tasks:
- name: httpd 패키지 설치
ansible.builtin.dnf:
name: httpd
state: present
- name: httpd 서비스 enable + start
ansible.builtin.service:
name: httpd
state: started
enabled: trueservice と systemd_service の違い #
service モジュールは init システムを自動検出する汎用モジュールで、systemd_service モジュールは systemd 専用で daemon_reload や masked のような systemd 固有の機能を追加で提供します。RHEL 9 は systemd を使うので両方とも動作しますが、unit ファイルを直接配置した後に読み直す必要があるときは systemd モジュールが有利です。
- name: 사용자 정의 unit 배치 후 데몬 리로드
ansible.builtin.systemd_service:
name: myapp
state: started
enabled: true
daemon_reload: truedaemon_reload: true は systemctl daemon-reload に対応し、/etc/systemd/system に unit ファイルを新しく置いたり直したりした直後に systemd が変更を認識するようにします。
時刻同期: timesync system role と chrony テンプレート #
時刻同期は RHCE の定番テーマです。RHEL 9 の NTP 実装は chrony であり、デーモン名は chronyd です。自動化の方法は 2 通りあります。timesync system role を使う道 と chrony.conf を直接テンプレートで配布する道 です。
方法 1: timesync system role #
#13 system roles で扱った rhel-system-roles を使うと、NTP サーバーの一覧だけを変数で渡し、残りは role に任せます。最も短く安全な道です。
- name: timesync system role로 NTP 구성
hosts: all
become: true
vars:
timesync_ntp_servers:
- hostname: 0.kr.pool.ntp.org
iburst: true
- hostname: 1.kr.pool.ntp.org
iburst: true
roles:
- redhat.rhel_system_roles.timesyncrole が chrony のインストールと設定ファイルの作成、サービスの enable と start まで一度に処理するので、試験で「この NTP サーバーを使うように時刻同期を構成せよ」という問題に最も速く対応できます。
方法 2: chrony.conf テンプレート + handler #
system role を使わずに設定ファイルを直接扱うこともできます。template モジュールで chrony.conf を配布し、ファイルが変わったときだけ handler で chronyd を再起動する構造です。このパターンはすべての「設定ファイル変更後にサービス再起動」問題の標準形なので、必ず身につけます。
templates/chrony.conf.j2:
# Ansible managed
{% for server in chrony_servers %}
server {{ server }} iburst
{% endfor %}
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
logdir /var/log/chronyplaybook:
- name: chrony.conf 템플릿으로 시간 동기화 구성
hosts: all
become: true
vars:
chrony_servers:
- 0.kr.pool.ntp.org
- 1.kr.pool.ntp.org
tasks:
- name: chrony 패키지 설치
ansible.builtin.dnf:
name: chrony
state: present
- name: chrony.conf 배포
ansible.builtin.template:
src: chrony.conf.j2
dest: /etc/chrony.conf
owner: root
group: root
mode: '0644'
notify: restart chronyd
- name: chronyd enable + start
ansible.builtin.service:
name: chronyd
state: started
enabled: true
handlers:
- name: restart chronyd
ansible.builtin.service:
name: chronyd
state: restartedここで流れが重要です。template task がファイルを変えると notify で handler が予約され、playbook のすべての task が終わった後に handler が一度実行されて chronyd を再起動します。ファイルが変わらなければ handler は呼ばれないので、2 回目の実行では再起動が起きず冪等性が保たれます。
ジョブ予約: cron と at モジュール #
定期ジョブは ansible.builtin.cron モジュールで管理します。crontab の項目を直接編集する代わりに、モジュールが項目を冪等に入れたり外したりしてくれます。
cron モジュールの主なキー #
| キー | 意味 |
|---|---|
| name | 項目を識別する名前。冪等性の基準 |
| job | 実行するコマンド |
| minute / hour / day / month / weekday | 実行時刻。デフォルトは * |
| user | どのユーザーの crontab か |
| state | present または absent |
name が冪等性の基準である点が核心です。cron モジュールは crontab に #Ansible: <name> のコメントを一緒に記録し、次の実行で同じ name に出会うと新しく追加せず既存の項目を更新します。したがって name を毎回変えると重複項目が積み上がるので、一定の name を維持します。
- name: 정기 백업 cron 작업 등록
hosts: dbservers
become: true
tasks:
- name: 매일 02:30 백업 스크립트 실행
ansible.builtin.cron:
name: nightly-backup
user: root
minute: "30"
hour: "2"
job: "/usr/local/bin/backup.sh"
state: present上の作業は root の crontab に 30 2 * * * /usr/local/bin/backup.sh の項目を冪等に登録します。指定しない day、month、weekday は自動的に * になります。
特定のディレクトリに落とす方式が必要なら、cron_file で /etc/cron.d の下にファイルを作ることもできます。このときはシステム全体の crontab 形式なので user を一緒に指定します。
- name: /etc/cron.d 파일로 등록
ansible.builtin.cron:
name: log-rotate-check
user: root
minute: "0"
hour: "1"
job: "/usr/local/bin/check-logs.sh"
cron_file: custom-log-check一回きりのジョブは ansible.builtin.at モジュールで予約します。例えば ansible.builtin.at に command と count、units: minutes を与えると、指定時間後に一度だけ実行される at ジョブを登録します。
journald 永続保存の自動化 #
デフォルトの RHEL では journald のログは /run/log/journal のメモリ (揮発性) 領域に保存され、再起動すると消えます。ログを永続保存するには /etc/systemd/journald.conf で Storage=persistent に変えてデーモンを再起動する必要があります。この作業も template と handler パターンで自動化します。
templates/journald.conf.j2:
# Ansible managed
[Journal]
Storage=persistent
SystemMaxUse={{ journald_max_use | default('500M') }}playbook:
- name: journald 로그 영구 저장 설정
hosts: all
become: true
vars:
journald_max_use: 1G
tasks:
- name: 영구 저장 디렉터리 생성
ansible.builtin.file:
path: /var/log/journal
state: directory
owner: root
group: systemd-journal
mode: '2755'
- name: journald.conf 배포
ansible.builtin.template:
src: journald.conf.j2
dest: /etc/systemd/journald.conf
owner: root
group: root
mode: '0644'
notify: restart journald
handlers:
- name: restart journald
ansible.builtin.systemd_service:
name: systemd-journald
state: restarted/var/log/journal ディレクトリがあって初めて journald がそこに永続ログを記録するので、file モジュールで先に作っておきます。設定ファイルが変わると handler が systemctl restart systemd-journald に対応する再起動を実行します。
tuned プロファイルの適用 #
パフォーマンスプロファイルを管理する tuned も自動化の対象です。tuned-adm を手で打つ代わりに、tuned system role または command モジュールでプロファイルを適用します。system role が最もすっきりしています。
- name: tuned 프로파일 적용
hosts: dbservers
become: true
vars:
tuned_profile: throughput-performance
roles:
- redhat.rhel_system_roles.tunedsystem role を使わないなら、tuned サービスを enable と start で上げてから、tuned-adm profile <名前> を command で適用しつつ、すでに適用済みの場合に changed が出ないように changed_when 条件を整えます。
試験ポイント #
- enabled と state はペア。サービス問題はほぼ常に「今起動して (state: started) ブートにも登録 (enabled: true)」を同時に要求します。片方だけ書くと採点の半分しか満たしません。
- 設定変更は handler で再起動。chrony.conf や journald.conf のように設定ファイルを template で変えた後は、必ず
notifyと handler でデーモンを再起動します。task で毎回 restart を直接呼ぶと、ファイルが変わらなくても再起動されて冪等性が崩れます。 - NTP は system role が速い。時刻同期の問題は timesync system role でサーバー一覧だけを渡すのが最も安全です。role が使えない状況に備えて chrony.conf テンプレート方式も一緒に身につけておきます。
- cron は name で冪等性。cron モジュールの name が項目の識別子なので、同じ作業には同じ name を維持して重複登録を防ぎます。
- journald 永続化はディレクトリから。
/var/log/journalの作成とStorage=persistentの設定、そして systemd-journald の再起動が 1 つの塊です。 - 2 回回して changed 0 を確認。すべての playbook は 2 回目の実行で changed が 0 になる必要があります。handler が毎回回るか、command/shell が冪等性を崩していないかを点検します。
まとめ #
この記事で押さえたこと:
- service / systemd_service モジュール。name・state・enabled で enable と start まで一度にデーモンを宣言。unit 変更時は daemon_reload
- 時刻同期。timesync system role (サーバー一覧だけを変数で) または chrony.conf テンプレート + handler 再起動
- cron / at モジュール。cron の name で冪等性、minute・hour・user・job・state で定期ジョブを登録。at で一回きりの予約
- journald 永続保存。
/var/log/journalの作成 + journald.conf テンプレート + systemd-journald 再起動 handler - tuned。system role または command でパフォーマンスプロファイルを適用
- 共通原則。設定変更は handler で、サービスは enabled と state を一緒に、そして 2 回回して冪等性を検証
次: RHCSA 自動化 3 #
サービスと時刻、ログを自動化しました。次は RHCSA で最も手のかかった領域であるストレージです。
#16 RHCSA 自動化 3: ストレージ (LVM)、ファイルシステム (NFS) では、lvg と lvol モジュールでボリュームグループと論理ボリュームを作り、filesystem と mount モジュールでファイルシステムを作成して永続マウントし、storage system role で一度に宣言する方法、そして NFS クライアントマウントまで playbook で整理します。