1. はじめに
最近、Ansibleを触る機会が増えてきました。
せっかくなので、Playbookを一から書いて、監視サーバを構築してみることにします。
実際に手を動かしながら、「ここで何してるんだっけ?」となった部分や、あとから自分が見返したくなりそうなポイントをそのまま整理していく記事です。
読むと得する人
- Ansibleを使い始めたい人
- サーバ構築や設定作業をもっと楽にしたい人
- IaCをこれから触ってみたい人
- インフラエンジニア1年目くらいで、手動作業から少しずつ抜け出したい人
この記事について
この記事は、あくまで自分の備忘録として書いているものです。
そのため、説明が少し長くなったり、細かいところで立ち止まったりする部分もあります。
ガッツリ読み込まなくても大丈夫なので、気になるところだけ拾うくらいの感覚で、気楽に読んでもらえればと思います。
2. 今回の構成とゴール
2.1 構成の全体像
まず前提として、この内容は二部構成で進める予定です。
前半となる今回は、Ansibleを使って監視基盤を立ち上げ、実際にメトリクスが取得できる状態までにします。
後半では、この構成をベースに、Promtail や Loki、Alertmanager などを追加し、ログ収集やアラート通知まで含めた、より実務を意識した監視基盤へ発展させていく予定です。
今回構築する監視基盤は、できるだけシンプルな構成にしています。
監視サーバ上でPrometheusとGrafanaを動かし、監視対象サーバにはnode_exporterを導入する形です。OSの初期設定からアプリケーションの起動まで含め、この一連の流れをすべてAnsibleで自動化することをテーマにしています。
2.2 今回のゴール
今回は、監視基盤のセットアップが一通り完了し、実際に監視が取得できている状態をゴールとします。
Ansible Playbookを実行することで、OSの共通設定が適用され、Dockerの実行環境が整い、PrometheusとGrafanaが起動します。あわせて監視対象サーバにnode_exporterを導入し、Prometheus上でターゲットがUPとなり、Grafana上でメトリクスを可視化できるところまでを進めます。
3. 検証環境
検証環境は、自宅のPC上に構築した完全ローカル環境です。
VMware Workstation Proを使用し、3台の Rocky Linux 9.6 を立てています。
今回使用するサーバは、以下の3台です。
すべて同一セグメント内に配置しており、Ansible から SSH 接続できる状態にしています。
| サーバ名 | CPU / メモリ | 役割 |
|---|---|---|
| lab-ctl-01 | 2core / 3GB | Ansible実行用 |
| lab-mon-01 | 2core / 8GB | 監視サーバ |
| lab-trg-01 | 2core / 3GB | 監視対象サーバ |
以降の章では、これらのサーバに対して Ansible Playbook を順に実行しながら、
構成がどのように作られていくのかを確認していきます。
4. Ansible構成の全体解説(Inventory / Playbook / Role)
この章では、今回作成した Ansible 構成について、
Inventory / Playbook / Role を軸にしながら全体像を整理していきます。
まずは今回のディレクトリ構成を確認します。
.
├── ansible.cfg # Ansible 全体の挙動を制御する設定ファイル
├── inventory
│ └── hosts.ini # 管理対象サーバーの定義(control / monitoring / target)
├── playbooks
│ ├── common.yml # 全サーバー共通の初期設定を適用
│ ├── docker.yml # 監視サーバーに Docker / Docker Compose をセットアップ
│ ├── monitoring-stack.yml # Prometheus / Grafana を起動する Playbook
│ └── target-agent.yml # 監視対象サーバーに node_exporter を導入
└── roles
├── common
│ └── tasks
│ └── main.yml # OS 共通設定(パッケージ、timezone、SELinux など)
├── docker
│ └── tasks
│ └── main.yml # Docker Engine / Docker Compose のインストールと起動
├── monitoring-stack
│ ├── defaults
│ │ └── main.yml # Prometheus / Grafana 用の変数定義
│ ├── tasks
│ │ └── main.yml # 設定ファイル配置と Docker Compose 起動処理
│ └── templates
│ ├── docker-compose.yml.j2 # Prometheus / Grafana 用 Docker Compose テンプレート
│ ├── grafana-datasources.yml.j2 # Grafana データソース定義テンプレート
│ └── prometheus.yml.j2 # Prometheus スクレイプ設定テンプレート
└── target-agent
├── defaults
│ └── main.yml # node_exporter 用の変数定義
└── tasks
└── main.yml # node_exporter 配置と systemd サービス設定
検証では、構成を分かりやすくするため、役割ごとに Playbook を分割して実行しています。
- OS 共通設定
- Docker の基盤構築
- 監視スタックのセットアップ
- 監視対象サーバへのエージェント導入
実務的な目線であれば、ある程度 Playbook をまとめて管理する選択肢もあると思います。ただ今回は、検証中に問題が起きた際の切り分けを優先し、あえて Playbook を分割する構成を採っています。
そのため本章では、各セクションでRole の中身を中心に見ながら、それを呼び出している Playbook についても簡単に触れていきます。
4.1 インベントリの定義
まずは inventory/hosts.ini です。
ここでは、IPアドレスや接続に使用するユーザー情報を定義します。
Inventory は、Ansibleを利用するうえで必要不可欠な存在であり、最初に作成する設定ファイルです。
[control]
lab-ctl-01 ansible_host=192.168.1.30 ansible_user=user
[monitoring]
lab-mon-01 ansible_host=192.168.1.31 ansible_user=user
[target]
lab-trg-01 ansible_host=192.168.1.40 ansible_user=user
ansible_host には、各VMに割り当てている固定IPアドレスを指定してます。
いずれのホストも、ローカル検証環境内の同一セグメントに配置されたサーバです。
ansible_user は全ホスト共通で user を指定してます。
本構成では、Ansible は一般ユーザーで実行し、必要な操作のみ Playbook 側で sudo による権限昇格 を行います。
補足:Inventoryにおける.iniと.ymlの使い分け
Ansibleでは、Playbookや変数ファイル、ロール内の設定ファイルなど、多くの設定を .yml形式 で記述します。
一方で、Inventoryについては .ini形式 で書かれているケースをよく見かけます。
これは、Inventoryがもともと INI形式を前提として設計されている という背景があり、ホストやグループをシンプルかつ直感的に記述できるという利点があるためです。
特に構成が小規模な場合は、.ini形式 の方が可読性が高く、Inventory全体の見通しを掴みやすいと感じています。
ただ、Inventoryは .yml形式 で記述することも可能です。
.yml形式 は 階層構造の表現 に向いているため、グループ構成が複雑な場合や、Inventory側で多くの情報を管理したい場合に適してます。
実務では次のような基準で分けると思います。
-
構成がシンプルで、Inventoryを「対象ホストの一覧」として扱いたい場合
→ .ini形式が適している -
構成が複雑で、階層的な管理が必要な場合
→ .yml形式が適している
本構成では小規模構成であるため、.ini形式 を採用してます。
4.2 OS共通設定
ここでは全サーバ共通のOS初期設定を行います。
4.2.1 OS共通設定用Playbook
# playbooks/common.yml
# OS共通設定プレイブック:全サーバにOS初期設定を適用する
- name: Apply common configuration to all hosts
hosts: all
become: true
roles:
- common
このPlaybookでは、すべてのサーバに対してOSの初期設定や最低限の運用に必要な設定を一括で適用します。
対象ホストをhosts: allとしているのは、 監視サーバ・監視対象サーバを問わず、 全サーバで共通となる前提条件を揃えるためです。
Playbook自体は非常にシンプルで、実際の処理内容は呼び出しているcommonロール側に集約しています。
4.2.2 OS共通設定ロールの実装内容
# roles/common/tasks/main.yml
# ➀dnfのパッケージキャッシュを最新化
- name: Update dnf package cache
ansible.builtin.dnf:
update_cache: true
# ➁基本的な運用・検証に必要なパッケージをインストール
- name: Install essential packages
ansible.builtin.dnf:
name:
- net-tools
- wget
- curl
- tar
- htop
- chrony
- unzip
- tree
- jq
- rsync
state: present
# ➂タイムゾーンを日本時間に設定
- name: Set timezone
ansible.builtin.timezone:
name: Asia/Tokyo
# ➃Chronyによる時刻同期を有効化
- name: Enable and start chronyd
ansible.builtin.systemd:
name: chronyd
state: started
enabled: true
# ➄SELinuxをPermissiveに設定
- name: Set SELinux permissive mode
ansible.posix.selinux:
policy: targeted
state: permissive
➀パッケージキャッシュ更新
初回構築時に古いメタデータを参照しないよう、最初に必ず実行してます。
➁基本パッケージの導入
net-tools や htop など、検証・トラブルシュート時に最低限必要となるツールを選定してます。
また、tar や unzip、curl、wget といったツールは、Ansible によるファイル展開や外部リソース取得を行う際に必要不可欠なため、あらかじめインストールしてます。
➂,➃時刻設定・同期
監視やログの時系列整合性を保つため、タイムゾーン設定と Chrony による時刻同期をセットで実施してます。
また、時刻がずれるとSSH接続もうまくできず、Ansible を実行できないこともあります。
➄SELinux設定
検証環境では SELinux を Permissive に設定してます。
Promtail などのログ収集系コンポーネントは、Enforcing 状態だと意図せずアクセスがブロックされるケースがあるため、Permissiveとしてます。
4.3 Dockerセットアップ
ここでは、Promethes/Grafana をDocker Compose で動かすためのセットアップを行います。
4.3.1 Dockerセットアップ用Playbook
# playbooks/docker.yml
# 監視サーバにDockerをセットアップ
- name: Setup Docker on monitoring servers
hosts: monitoring
become: true
roles:
- docker
この Playbook では、監視サーバとして使用するホストに対して、
Docker Engine および Docker Compose の実行環境をセットアップします。
対象ホストを hosts: monitoring に限定しているのは、 Docker を使用するのが監視スタック(Prometheus / Grafana)を動かすサーバのみであるためです。
Playbook 側では処理内容を最小限に留め、 実際のインストール手順や設定内容は docker ロールに集約しています。
4.3.2 Docker基盤ロールの実装内容
本ブログの主役はあくまで Ansible による構成管理です。
Prometheus / Grafana 自体の構築コストを下げるため、アプリケーション実行基盤としてDocker Compose を採用してます。
# roles/docker/tasks/main.yml
# ➀Docker公式リポジトリ追加に必要なプラグインを導入
- name: Install dnf-plugin-core
ansible.builtin.dnf:
name: dnf-plugins-core
state: present
# ➁Docker公式リポジトリを追加
- name: Add Docker repository
ansible.builtin.get_url:
url: https://download.docker.com/linux/centos/docker-ce.repo
dest: /etc/yum.repos.d/docker-ce.repo
mode: '0644'
# ➂Docker Engine / CLI / Compose Plugin をインストール
- name: Install Docker packages
ansible.builtin.dnf:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
# ➃Dockerサービスを起動し、自動起動を有効化
- name: Start and enable Docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true
# ➄Ansible実行ユーザーをdockerグループに追加
- name: Add ansible_user to docker group
ansible.builtin.user:
name: "{{ ansible_user }}"
groups: docker
append: true
➀dnf-plugins-core の導入
Docker公式リポジトリを追加するために必要なプラグインを、ansible.builtin.dnf モジュールで導入してます。
state: present を指定することで、既にインストール済みの場合でも冪等性が保たれます。
➁Docker公式リポジトリの追加
ansible.builtin.get_url モジュールを使用し、Dockerが提供するリポジトリ定義ファイルを直接配置してます。
dest を /etc/yum.repos.d/ 配下に指定することで、dnf からDocker関連パッケージを取得できるようにしてます。
➂Docker関連パッケージのインストール
ansible.builtin.dnf モジュールで、Docker Engine・CLI・containerd・Compose Plugin をまとめてインストールしてます。
Composeは従来のdocker-composeではなく、docker-compose-plugin を指定し、docker compose コマンドを使用する構成としてます。
➃Dockerサービスの起動と自動起動設定
ansible.builtin.systemd モジュールを用いて、Dockerサービスを起動し、あわせて自動起動を有効化してます。
state: started と enabled: true を明示することで、サービス状態と起動設定の両方を管理してます。
➄dockerグループへのユーザー追加
ansible.builtin.user モジュールを使用し、Ansible実行ユーザーを docker グループに追加してます。
append: true を指定することで、既存のグループ設定を保持したまま docker グループを追加してます。
4.4 監視スタックのデプロイ
ここでは、監視スタック(Prometheus/Grafana)をデプロイ&実行するための処理を行います。
4.4.1 監視スタックデプロイ用Playbook
# playbooks/monitoring-stack.yml
# 監視スタックデプロイプレイブック:監視サーバに監視基盤を展開する
- name: Deploy monitoring stack on monitoring servers
hosts: monitoring
become: true
roles:
- monitoring-stack
対象ホストを hosts: monitoring に限定しているのは、監視スタック自体を稼働させるサーバが監視サーバのみであるためです。
4.4.2 monitoring-stack ロールの実装内容
# roles/monitoring-stack/tasks/main.yml
# ➀Prometheus / Grafana 共通のベースディレクトリを作成
- name: Create Directories for monitoring-stack
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
loop:
- /opt/monitoring
- /opt/monitoring/prometheus
- /opt/monitoring/grafana
# ➁Prometheus データ保存用ディレクトリを作成
- name: Create Data Directories for prometheus
ansible.builtin.file:
path: /opt/monitoring/prometheus/data
state: directory
owner: "65534"
group: "65534"
mode: '0755'
# ➂Grafana データおよび Provisioning 用ディレクトリを作成
- name: Create Data Directories for grafana
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "472"
group: "472"
mode: '0755'
loop:
- /opt/monitoring/grafana/data
- /opt/monitoring/grafana/config/provisioning/datasources
# ➃各コンポーネントの設定ファイル配置用ディレクトリを作成
- name: Create Config Directories for monitoring-stack
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
loop:
- /opt/monitoring/prometheus/config
- /opt/monitoring/grafana/config
# ➄docker-compose.yml を配置
- name: Copy docker-compose.yml
ansible.builtin.template:
src: docker-compose.yml.j2
dest: /opt/monitoring/docker-compose.yml
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
# ➅Prometheus 設定ファイルを配置
- name: Copy prometheus.yml
ansible.builtin.template:
src: prometheus.yml.j2
dest: /opt/monitoring/prometheus/config/prometheus.yml
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
# ➆docker-compose 起動
- name: Start docker-compose
ansible.builtin.command:
cmd: docker compose up -d
chdir: /opt/monitoring
➀共通ディレクトリ作成
Ansible の file モジュールでディレクトリの存在を保証してます。
state: directory により、既に存在する場合でもエラーにならず冪等性が保たれます。
➁Prometheus データディレクトリ
Prometheus コンテナは UID/GID 65534 で動作するため、ホスト側のディレクトリ所有者も同じ数値に設定してます。
➂Grafana データ/Provisioning ディレクトリ
Grafana の provisioning ディレクトリは、起動時に自動で読み込まれる初期設定(主にデータソース定義)を配置するための場所です。
ここに設定ファイルを置くことで、Grafana 起動後に GUI から手動設定を行わずにデータソースを作成できます。
➃設定ファイル用ディレクトリ
設定ファイルは Ansible から配置・更新するため、Ansible 実行ユーザーを所有者としてます。
➄docker-compose.yml 配置
template モジュールを使用し、Jinja2 テンプレートからファイルを生成します。
➅prometheus.yml 配置
Prometheus は起動時にこの設定ファイルを読み込みます。
Ansible で配置することで、設定変更と再起動を自動化できます。
➆Docker Composeの起動
ansible.builtin.command モジュールを使って、Docker Compose の起動コマンドを実行しています。
このモジュールは、指定したコマンドをそのまま実行するシンプルな挙動のため、
docker compose up -d のように 実行内容を明示したい場合に向いています。
chdir について
ここで chdir を指定しているのは、 Docker Compose が 実行時のカレントディレクトリに存在する docker-compose.yml を参照する仕様だからです。
そのため、docker-compose.yml を配置している /opt/monitoring を作業ディレクトリとして指定しています。
なお chdir は、シェルでいう「cd」に相当する独立した処理ではなく、 command モジュールに対する実行条件の一つとして扱われます。 Ansible では「どのモジュールを、どの条件で実行するか」という考え方で記述するため、 chdir は command の配下にまとめて記載しています。
補足:Jinja2テンプレートについて
ここで初めて登場する .j2 は、Jinja2(ジンジャツー)というテンプレートエンジンのファイル形式です。
Jinja2 を使うことで、IPアドレス/ポート番号/パスなどの環境ごとの差分を可変要素を 変数 として埋め込んだ設定ファイル を生成できます。
例えば、docker-compose.yml.j2 の中では次のように書きます。
# roles/monitoring-stack/templates/docker-compose.yml.j2
ports:
- "{{ prometheus_port }}:9090"
volumes:
- {{ monitoring_base_dir }}/prometheus/data:/prometheus
そして、defaults/main.ymlという変数格納ファイルには以下のような変数宣言をしておきます。
# roles/monitoring-stack/defaults/main.yml
prometheus_port: "9090"
monitoring_base_dir: /opt/monitoring
Ansible を実行すると、.j2 テンプレート内の変数が展開され、
最終的には通常の docker-compose.yml が生成されます。
# /opt/monitoring/docker-compose.yml
ports:
- "9090:9090"
volumes:
- /opt/monitoring/prometheus/data:/prometheus
このように、Jinja2 テンプレートを使うことで環境差分を変数として切り出しつつ、設定ファイルそのものは常に Ansible の管理下に置くことができます。
今回はAnsibleがメインのため、設定ファイルについての詳細な解説は割愛します。
4.5 監視対象サーバへのエージェント導入
ここまでで、監視サーバ側(Prometheus / Grafana)の基盤は一通り整いました。
ただ、この状態では監視サーバ側しか準備できておらず、実際に監視したいサーバからは何の情報も取得できません。そこで次に行うのが、監視対象サーバ側へのエージェント導入です。
Prometheus はプル型の監視方式であるため、監視対象側でメトリクスを公開する必要があります。
4.4 では、Prometheusの監視に必須である node_exporter の導入を行います。
ログ収集を担う Promtail や、ログの保存先となる Loki については、次回、Ansible を使って段階的に追加し、監視基盤をより実務に近い形へ拡張していく予定です。
4.5.1 エージェント導入用Playbook
# playbooks/target-agent.yml
# 監視対象サーバへのエージェント導入プレイブック
- name: Deploy target agent on target servers
hosts: target
become: true
roles:
- target-agent
対象ホストを hosts: target に限定しているのは、 エージェント導入が必要なのが監視対象サーバのみであるためです。
4.5.2 target-agent ロールの実装内容
target-agent ロールでは、node_exporter を 手動インストールと同等の手順で導入し、 systemd 管理の常駐サービスとして起動します。
以下が roles/target-agent/tasks/main.yml の主要な処理です。
# roles/target-agent/tasks/main.yml
# ➀作業用ディレクトリを作成
- name: Create working directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0755'
loop:
- /opt/monitoring
- /opt/monitoring/bin
# ➁node_exporter アーカイブをダウンロード
- name: Download node_exporter archive
ansible.builtin.get_url:
url: "https://github.com/prometheus/node_exporter/releases/download/v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-amd64.tar.gz"
dest: "/opt/monitoring/node_exporter.tar.gz"
mode: '0644'
# ➂node_exporter を展開
- name: Extract node_exporter
ansible.builtin.unarchive:
src: "/opt/monitoring/node_exporter.tar.gz"
dest: "/opt/monitoring"
remote_src: true
# ➃node_exporter バイナリを配置
- name: Install node_exporter binary
ansible.builtin.copy:
src: "/opt/monitoring/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter"
dest: "/usr/local/bin/node_exporter"
owner: root
group: root
mode: '0755'
remote_src: true
# ➄node_exporter の systemd unit を作成
- name: Create node_exporter systemd unit
ansible.builtin.copy:
dest: /etc/systemd/system/node_exporter.service
owner: root
group: root
mode: '0644'
content: |
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
ExecStart=/usr/local/bin/node_exporter
Restart=always
[Install]
WantedBy=multi-user.target
# ➅systemd を再読み込み
- name: Reload systemd daemon
ansible.builtin.systemd:
daemon_reload: true
# ➆node_exporter を起動・自動起動設定
- name: Enable and start node_exporter
ansible.builtin.systemd:
name: node_exporter
state: started
enabled: true
➀作業用ディレクトリ作成
node_exporter のアーカイブ配置や展開作業に使用するディレクトリを事前に作成してます。
file モジュールを使っているため、既に存在している場合でもエラーにならず、
Ansible を何度実行しても同じ状態を維持できます。
➁node_exporter アーカイブのダウンロード
GitHub 上で公開されている公式リリースから、node_exporter をダウンロードしてます。
バージョンは node_exporter_version という変数で管理しており、アップデート時は変数を変更するだけで差し替えられるようにしてます。
➂アーカイブの展開
unarchive モジュールを使い、ダウンロードした tar.gz を監視対象サーバ上で直接展開してます。
remote_src: true を指定することで、Ansible 実行ノードを経由せず、リモートホスト上のファイルをそのまま展開します。
➃実行バイナリの配置
展開されたディレクトリの中から、node_exporter の実行バイナリのみを /usr/local/bin に配置してます。
systemd から直接実行するため、PATH 配下に置き、実行権限を付与してます。
➄systemd unit ファイルの作成
node_exporter を常駐プロセスとして動かすため、systemdのunit ファイルを作成してます。
監視エージェントは「起動していること」自体が重要なため、
systemd 管理にしておくことで、プロセス管理を OS 側に任せる形にしてます。
➅systemd の再読み込み
新しく配置した unit ファイルを systemd に認識させるため、daemon_reload を実行してます。
この処理を入れておかないと、次のサービス起動時に unit が見つからず失敗します。
➆サービスの起動と自動起動設定
node_exporter を起動し、あわせて OS 起動時に自動で立ち上がるよう設定してます。
ここまで完了すれば、監視対象サーバは Prometheus からのスクレイプ要求を受け付けられる状態になります。
5. Ansible 実行と動作確認
ここまでで、監視基盤を構成する各要素の準備は一通り整いました。
本章では、実際に Ansible Playbook を実行した後、各サーバで実際に設定が反映されているかを確認していきます。
5.1 OS共通設定プレイブックの実行と確認
まずは、全サーバに対して OS の共通設定を適用するcommon.yml を実行します。
5.1.1 OS共通設定プレイブックの実行
Ansible実行ノードから、以下のコマンドで Playbook を実行します。
ansible-playbook -i inventory/hosts.ini playbooks/common.yml
-
-i inventory/hosts.ini
実行対象となるホスト情報を定義した Inventory を指定 -
playbooks/common.yml
実行させる Playbook を指定
実行が完了すると、実行サマリとしてPLAY RECAP が表示されます。
PLAY RECAP **************************************************************************************************************************************************
lab-ctl-01 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lab-mon-01 : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
lab-trg-01 : ok=6 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[user@lab-ctl-01 ansible]$
failed=0 かつ unreachable=0 となっており、Playbook はすべてのサーバで問題なく実行完了しています。
補足:PLAY RECAP 各項目の意味
-
ok
そのタスクが実行されたものの、 すでに期待した状態になっており、変更が発生しなかったことを示します。 -
changed
タスクの実行によって、 実際にサーバの状態が変更されたことを示します。 パッケージの新規インストール、設定変更、サービスの起動などが該当します。 -
unreachable
Ansible が対象ホストに 接続できなかった場合にカウントされます。
原因として以下のようなものがあります。- SSH 接続不可
- IP アドレス誤り
- ネットワーク疎通不可
-
failed
タスクの実行中に エラーが発生し、処理が失敗した場合にカウントされます。
構文ミス、依存関係不足、権限不足などが典型例です。 -
skipped
when条件などにより、 条件不一致のため実行されなかったタスクがある場合にカウントされます。
今回の構成では使用していないため、0で問題ありません。 -
rescued
block / rescue構文を使用している場合に、 エラー後に rescue 側の処理が実行された回数を示します。 今回の構成では使用していないため、0で問題ありません。 -
ignored
ignore_errors: trueが指定されたタスクで、 エラーが発生したが処理を継続した場合にカウントされます。 こちらも今回の構成では使用していません。
5.1.2 OS共通設定が反映されているかの確認
Playbook の実行結果だけでなく、実際にサーバへログインして状態を確認してみます。
追加パッケージの動作確認
Playbook 実行後、各サーバにログインし、 OS 共通設定で追加したパッケージが正しく導入されているかを確認します。
[user@lab-mon-01 ~]$ jq --version
jq-1.6
[user@lab-trg-01 ~]$ rsync --version
rsync version 3.2.5 protocol version 31
いずれも標準ではインストールされていないツールですが、それぞれ(監視サーバと監視対象サーバ)で正常に実行できることから、パッケージ導入が Playbook により反映されていることが確認できます。
これらのツールは、後続の設定確認や検証作業、トラブルシュート時の情報取得などで使用する想定です。
5.2 Dockerセットアップの実行と確認
続いて、監視サーバに対して Docker 実行環境を構築します。 ここでは docker.yml Playbook を実行し、Docker Engine と Docker Compose が正しく利用できる状態になっているかを確認します。
以下のコマンドを実行します。
ansible-playbook -i inventory/hosts.ini playbooks/docker.yml
実行後↓
PLAY RECAP **************************************************************************************************************************************************
lab-mon-01 : ok=7 changed=4 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[user@lab-ctl-01 ~]$
実行後、PLAY RECAP にて failed=0、unreachable=0 となっていることを確認します。
次に、監視サーバへログインし、Docker サービスの状態を確認します。
[user@lab-mon-01 ~]$ systemctl status docker
docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: disabled)
Active: active (running)
Active: active となっていることから、Docker Engine が起動しており、常駐サービスとして正しく動作していることが確認できます。この状態にであれば、以降の章で行う Docker Compose を使った監視スタックの起動準備は整っています。
5.3 監視スタックの起動と動作確認
続いて、監視サーバ上でPrometheus / Grafana を含む 監視スタック自体を起動します。
ここでは monitoring-stack.yml を実行し、Webでアクセスできる状態になっているかを確認します。
5.3.1 監視スタックのデプロイと、コンテナの起動確認
いつも通り、以下のコマンドを実行します。
ansible-playbook -i inventory/hosts.ini playbooks/monitoring-stack.yml
実行後↓
PLAY RECAP **************************************************************************************************************************************************
lab-mon-01 : ok=9 changed=8 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[user@lab-ctl-01 ~]$
failed=0、unreachable=0 であることを確認できたため、Playbook は問題なく完了しています。
次に監視サーバにログインし、docker ps でコンテナの起動状況を確認します。
[user@lab-mon-01 ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
129ca60db500 prom/prometheus:latest "/bin/prometheus --c " 2 minutes ago Up 2 minutes 0.0.0.0:9090->9090/tcp, [::]:9090->9090/tcp prometheus
2495792c07e4 grafana/grafana:latest "/run.sh" 2 minutes ago Up 2 minutes 0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp grafana
Prometheus と Grafana のコンテナが、指定したポートで正常に起動していることが分かります。
5.3.2 Prometheus / Grafana 起動確認
http://192.168.1.31:9090/ にアクセスします。
lab-mon-01 の IP アドレスと、Prometheus に割り当てたポートを指定しています。

Prometheus が正常に動作していることを確認できました。すでに設定ファイルには node_exporter 側の情報を記述しているため、ターゲット自体は表示されています。
ただし、この時点では監視対象サーバ側に node_exporter はまだ導入していないため、メトリクスは取得できておらず、State が Down となっている状態です。node_exporter の導入は、この後行います。
続いて Grafana にアクセスします。Prometheus と同一サーバ上で動作しているため、IP アドレスは同じで、ポートのみ 3000 に変更します。
http://192.168.1.31:3000/

Grafana の UI も表示され、こちらも問題なく起動していることを確認できました。
ちなみに、Prometheus はデフォルトでは認証なしでアクセスできますが、Grafana は初回アクセス時に認証が求められます。初期のユーザー名とパスワードは admin / admin でログインでき、その後に任意のパスワードを設定します。
5.4 監視対象サーバへのエージェント導入と確認
ここまでで、監視サーバ側(Prometheus / Grafana)の基盤は整いました。ただし現時点では、監視対象サーバ側にはまだ何も導入していない状態です。ここでは、監視対象サーバに node_exporter を導入し、Prometheus からメトリクスを取得できる状態を作っていきます。
5.4.1 target-agent Playbook の実行
まずは、監視対象サーバにエージェントを導入するための Playbook を実行します。
ansible-playbook -i inventory/hosts.ini playbooks/target-agent.yml
この Playbook は hosts: target を対象としており、監視対象サーバのみに node_exporter を導入します。 他サーバへは影響しません。実行後、以下のように PLAY RECAP が表示されます。
PLAY RECAP **********************************************************************************************************************************************************************
lab-trg-01 : ok=15 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[user@lab-ctl-01 ~]$
こちらも問題なく完了しています。
5.4.2 実行後の確認
まずは監視対象サーバで、systemd管理のサービスとして起動しているかを確認します。
[user@lab-trg-01 ~]$ systemctl status node_exporter
node_exporter.service - Prometheus Node Exporter
Loaded: loaded (/etc/systemd/system/node_exporter.service; enabled; preset: disabled)
Active: active (running) since Sun 2025-12-28 18:23:53 JST; 3min 38s ago
active (running) となっていることから、 node_exporter 正常に動作していることが分かります。
次に、Prometheus 上で監視が取得できているかを確認します。

先ほどまで State が Down だったターゲットが Up に変わり、メトリクスが正常に取得できるようになりました。
続いて、Grafana 側でも確認します。Grafana では新規ダッシュボードを作成し、node_exporter から取得した CPU メトリクスを簡単なグラフとして表示しました。
以下のように、CPU 使用率が取得できていることを確認できます。

6. まとめ
今回は、Ansible を使って以下の構成を自動化、構築しました。
- OS の共通設定
- Docker 実行環境の構築
- 監視基盤のセットアップ
- 監視対象サーバへのセットアップ
Playbook を役割ごとに分割し、段階的に実行することで、 「どこで何が変わったのか」 を追いながら構築できたと思います。
次回は、この構成をベースに、Ansible を軸としたまま、Loki / Promtail によるログ収集や Alertmanager によるアラート通知を追加していく予定です。
最後までお読みいただきありがとうございました。