電脳世界のケーキ屋さん

考えの甘い甘党エンジニアがいろいろ書くブログ

PacemakerでPrometheusを冗長化する(Pacemaker編)

はじめに

せっかくLPIC304を取ったのに何もそれらしいことに活用できていないので, 監視ソフトのPrometheusの冗長化とかやってみようと思った次第である.

前提条件

  • 2台のLinuxマシンがIP疎通可能な状態で準備できていること
    今回は以下の2台を利用する.
    • [node-1(Active)] KVM上に準備した Fedora30
      • Prometheus: 2.10
      • Pacemaker: 2.0.1-2
      • corosync: 3.0.1-2
      • pcs: 0.10.1-4
    • [node-2(Standby)] 家のLANで適当にSSHアクセスできた Debian9.9(ARMv7)
      • Prometheus: 2.10
      • Pacemaker: 2.0.1-5
      • corosync: 3.0.1-2
      • pcs: 0.10.1-2

Prometheus の簡易インストール

ダウンロードするバイナリのプロセッサタイプを間違えないよう注意.

# curl -O https://github.com/prometheus/prometheus/releases/download/v2.10.0/prometheus-2.10.0.linux-amd64.tar.gz -L
# mkdir /opt/prometheus
# tar xvf prometheus-2.10.0.linux-amd64.tar.gz -C /opt/prometheus/ 

それぞれのホストで, systemd 用のサービスファイルを以下の具合に作成

# /etc/systemd/system/prometheus.service #
[Unit]
Description=Prometheus server daemon
After=network.target

[Service]
ExecStart=/opt/prometheus/prometheus-2.10.0.linux-amd64/prometheus --config.file=/opt/prometheus/prometheus-2.10.0.linux-amd64/prometheus.yml

[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl start prometheus
# systemctl status prometheus

http://<ノードアドレス>:9090 にアクセスしてそれっぽい画面が出力されたらインストールは完了である.
これを2台分実施する. クラスタに外れてる状態で勝手に起動すると困るので, enable にはしない方が良い.

Pacemaker によるクラスタの構築

基本は Linux-HA プロジェクトのクイックスタートガイド通りに実行する.
clusterlabs.org

パッケージのインストール

# apt-get install pacemaker pcs
または
# yum install pacemakr pcs

クラスタサービスの有効化

本環境では pacemaker, corosync, pcsdクラスタの動作に必要なデーモンであるので, これらの enable と start を実施する.
/etc/corosync/corosync.conf が存在しない場合は空ファイルを touch しておく.
(ファイルが無いと pcs デーモンの起動の際に怒られて失敗する(場合がある))

# touch /etc/corosync/corosync.conf
# systemctl start pcsd
# systemctl enable pcsd
# systemctl enable corosync
# systemctl enable pacemaker

pcsd用ユーザの設定

pcs がクラスタ管理に利用するユーザ hacluster について, ログインパスワードを設定する. 必ず両ノードで実施すること.

# passwd hacluster

設定後, どちらかのノード以下のコマンドを実行し, pcs にノード認証を行わせる.
Authorized と出力されれば問題なく認証が行なわれている.

# pcs host auth node1 addr=<ノード#1のアドレス> node2 addr=<ノード#2のアドレス> -u hacluster -p "<ユーザパスワード>"
node1: Authorized
node2: Authorized

クラスタ初期化

pcs cluster setup で指定ノードでクラスタを構築する.
ここで動作している各デーモンのバージョンに差分があると死ぬ.
Error: node2: Old version of pcsd is running on the node, therefore it is unable to perform the action なんて親切に出力してくれる.
ちなみに, マイナーバージョンまで合ってれば誤魔化せた.

# pcs cluster setup Prometheus-Cluster node1 node2 --force
...
Cluster has been successfully set up.

空ファイルだった /etc/corosync/corosync.conf に色々書き込まれていることが確認できる.
クラスタの初期セットアップが完了したので, クラスタを開始させる.

# pcs cluster start --all
# pcs cluster status

クラスタ開始後にクラスタに関するプロパティの変更が行えるようになる.

  • STONITH の無効化
# pcs property set stonith-enabled=false
  • 2ノードで自動フェイルオーバが実行されるようにする(クォーラムを無視する)
# pcs property set no-quorum-policy=ignore

クラスタへのリソース登録

VIP

クライアントが Prometheus にアクセスする際のIPアドレスを登録する.

# pcs resource create VIP ocf:heartbeat:IPaddr2 \
 > ip=192.168.16.35 cidr_netmask=24 \
 > op monitor interval=15s

Prometheus

Prometheus もデフォルトで RA の定義があるので, これをクラスタに登録する.

# pcs resource create Prometheus service:prometheus

リソースのコロケーション制約の設定

VIPが設定されているノードでPrometheusが動作するように colocation 制約を設定する.

# pcs constraint colocation add Prometheus with VIP

この辺りまで実施すれば, 他問題がなければクラスタが稼動を初める.
他の問題とは, prometheus を片ノードでサービス登録していなかったり, ルート領域が pacemaker のログで溢れていたりである.

正常に動作していればどちらのノードから pcs status を発行しても以下のような出力が得られる.

# pcs status 抜粋
Online: [ node1 node2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       Started node1
 Prometheus     (service:prometheus):   Started node1

おまけ

確認系コマンド

# pcs cluster status
Cluster Status:
 Stack: corosync
 Current DC: NONE
 Last updated: Sun Jun 30 15:03:11 2019
 Last change: Sun Jun 30 15:02:04 2019 by root via cibadmin on node1
 2 nodes configured
 2 resources configured

PCSD Status:
  node1: Online
  node2: Online
# pcs status
Cluster name: Prometheus-Cluster
Stack: corosync
Current DC: NONE
Last updated: Sun Jun 30 15:03:43 2019
Last change: Sun Jun 30 15:02:04 2019 by root via cibadmin on node1

2 nodes configured
2 resources configured

OFFLINE: [ node1 node2 ]

Full list of resources:

 VIP    (ocf::heartbeat:IPaddr2):       Stopped
 Prometheus     (service:prometheus):   Stopped

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled
# pcs property
Cluster Properties:
 cluster-infrastructure: corosync
 cluster-name: Prometheus-Cluster
 dc-version: 2.0.1-9e909a5bdd
 have-watchdog: false
 no-quorum-policy: ignore
 stonith-enabled: false
  • 利用可能なリソースエージェントの一覧
    出力に時間がかかる
# pcs resource list
ocf:heartbeat:aliyun-vpc-move-ip - Move IP within a VPC of the Aliyun ECS
ocf:heartbeat:anything - Manages an arbitrary service
ocf:heartbeat:AoEtarget - Manages ATA-over-Ethernet (AoE) target exports
ocf:heartbeat:apache - Manages an Apache Web server instance
ocf:heartbeat:asterisk - Manages an Asterisk PBX
ocf:heartbeat:AudibleAlarm - Emits audible beeps at a configurable interval
...

トラブル

Debian側のpcsコマンドが pycurl 云々のエラーで動作しない

libcurl 系がエラー出力に記載のバージョンと合うように調整する(libcurl3-gnutlsかな).

crm_mon コマンドがないって言われる

yum なら pacemaker-cli , apt なら pacemaker-cli-util がパッケージとして入っている必要がある.
crm_mon コマンドがインストールされていない場合 pcs status コマンドなどを打った際に以下のエラーが出る.

Error: unable to run command crm_mon --one-shot --inactive: No such file or directory: 'crm_mon'

ノード再起動後に既存クラスタに再認識されない.

pacemaker サービスを再起動させようとするとハングする

CIBがノード間で正常に同期されない

上の3つの事象は結論として CIB の設定がノード間で異なっていたことに起因するものであった.

pcs cluster stop を行おうとすると以下のようなログを出力し続けて pacemaker の停止が終わらない.
これのせいでログが膨れ上がってルート領域が溢れた.
こうなるとシステムの再起動も正常に実施できない状態になって大惨事である.

  • ノード1
pacemaker-based     [732] (cib_file_backup)         info: Archived previous version as /var/lib/pacemaker/cib/cib-71.raw
pacemaker-controld  [737] (election_count_vote)     info: election-DC round 170944 (owner node ID 2) lost: vote from node2 (Uptime)
pacemaker-controld  [737] (update_dc)       info: Unset DC. Was node2
pacemaker-controld  [737] (do_log)  info: Input I_PENDING received in state S_PENDING from do_election_count_vote
pacemaker-controld  [737] (update_dc)       info: Set DC to node2 (3.1.0)
pacemaker-based     [732] (cib_process_replace)     info: Digest matched on replace from node1: ac2adcc396bcf584915ad51e4ef426ad
pacemaker-based     [732] (cib_process_replace)     info: Replaced 0.34.4 with 0.34.4 from node1
pacemaker-based     [732] (cib_file_write_with_digest)      info: Wrote version 0.34.0 of the CIB to disk (digest: 621d39f18d6f54be5f4c900d543c5c00)
pacemaker-based     [732] (cib_process_request)     info: Completed cib_replace operation for section 'all': OK (rc=0, origin=node1/crmd/341932, version=0.34.4)
  • ノード2
pacemaker-based[14088]:  error: Completed cib_replace operation for section 'all': Update does not conform to the configured schema ...
pacemaker-controld[14093]:  error: Sync from node1 failed: Update does not conform to the configured schema

pcs cluster cib で両ノードの CIB を diff ってみると, 1行目にそれらしい差分があることが分かる.
どう見ても validate-with プロパティのpacemakerのバージョンに差異が発生している.
恐らく pacemaker のバージョンが違う状態でクラスタを組もうとしたのが原因と考えられる.

# node1 CIB
<cib crm_feature_set="3.1.0" 
  validate-with="pacemaker-3.2" epoch="46"  //*
  num_updates="2" admin_epoch="0"
  cib-last-written="Sat Jul  6 20:24:51 2019"
  update-origin="node2"
  update-client="crmd"
  update-user="hacluster"
  have-quorum="1" dc-uuid="1">   
# node2 CIB
<cib crm_feature_set="3.1.0"
  validate-with="pacemaker-2.6" epoch="19"  //*
  num_updates="29" admin_epoch="0"
  have-quorum="1"
  cib-last-written="Tue Jul  2 14:30:52 2019"
  update-origin="node1"
  update-client="cibadmin"
  update-user="root" dc-uuid="2">

一旦この値をノード間で合わせて, クラスタが正常化するかを試してみる.

# cibadmin --modify --xml-text '<cib validate-with="pacemaker-2.0"/>' 

直すと, クラスタが正常化したのでこれでヨシとする.
pacemaker を再起動したり, pcs cluster stop --all も正常に動作するようになった.

さいごに

見れば分かるが, Prometheus のデータ共有などは全く行っていないため, クラスタとしては不完全な状態である.
Pacemaker でどはまりして体力を使ったので, Prometheusについては別記事を書くこととする.