pacemaker モジュールを知らない？ボーッと生きてんじゃねーよ!!

冒頭からタイトルで失礼しました。ただの釣りです。

#　はじめに

[Pacemaker](https://clusterlabs.org/pacemaker/) はご存知ですよね？ HA クラスタ基盤 OSS の１つで、デファクトスタンダードと言って良いでしょう。[Qiita でも pacemaker タグが付いた記事が多数投稿されています](https://qiita.com/search?q=tag%3Apacemaker)。Pacemaker を知らない SE の皆様、ボーッと生きている可能性があります。ご注意下さい。
コンテナ時代になって Kubernetes がアプリケーションシステム向け HA クラスタ基盤の役割を担い始めていますが、世の中のソフトウェアが全てコンテナ化されている訳ではありません。相変わらず Pacemaker は様々なシステムの HA クラスタ基盤として活躍しています。

しかし、上記の割には、Pacemaker 設定用の Ansible モジュールがありません。[pacemaker_cluster](https://docs.ansible.com/ansible/latest/modules/pacemaker_cluster_module.html#pacemaker-cluster-module) というモジュールがあるにはあるのですが、これはクラスタ設定用ではなく、設定済みクラスタを online, offline, restart, cleanup する事しか出来ません。
そのため、従来 Ansible を用いたPacemaker 上のクラスタ設定は皆苦労してきました。ある者はリソース設定専用の Ansible ロールを作り、またある者は Pacemaker 設定コマンドを使った Ansible モジュールを作りました。しかし、これらの方法では べき等性の担保が難しかったり、制約があったりと色々難しい点がありました。

私も[同様の Ansible モジュールを自作していた](https://github.com/yosshy/ansible-pacemaker)のですが、crm コマンドが旧式化した事から、[新たな Pacemaker 設定用の Ansible モジュール](https://github.com/yosshy/ansible-pacemaker2)を作りました。 https://github.com/yosshy/ansible-pacemaker2 で公開しています。

# モジュール構成

現在、以下の８種類の Ansible モジュールが整備されています。

* pacemaker_resource：リソース設定用
* pacemaker_resource_default：リソースのデフォルト設定用
* pacemaker_resource_group：リソースグループ設定用
* pacemaker_colocation：Colocation 制約設定用
* pacemaker_location：Location 制約設定用
* pacemaker_order：Order 制約設定用
* pacemaker_order_set：Order Set 制約設定用
* pacemaker_property：クラスタプロパティ設定用

これらのモジュールは cibadmin を用いて現在の Pacemaker クラスタ設定取得＋設定を行いますので、Ansible が SSH 接続するホスト上に cibadmin を予めインストールしておく必要があります。とはいえ、通常は Pacemaker クラスタが構成された環境には cibadmin がインストールされています。

処理としてはどのモジュールも同じ事をやっています。

1. cibadmin コマンドで既存の Pacemaker 設定を XML で取得する。
2. モジュールのパラメータに合わせて XML の一部を改変する。
3. 改変前後で XML に違いがあれば、cibadmin コマンドで Pacemaker に XML を適用する。

これにより、Ansible モジュールに求められる「必要なら設定する、不要なら何もしない」という べき等性を担保しています。

# インストール方法

Ansible モジュール置き場を用意します。

```shell-session
$ mkdir -p ~/.ansible/plugins/modules
```

リポジトリを git clone します。

```shell-session
$ git clone https://github.com/yosshy/ansible-pacemaker2
```

library 配下のファイルを Ansible モジュール置き場にコピーします。

```shell-session
$ cp ansible-pacemaker2/library/* ~/.ansible/plugins/modules
```

Ansible モジュールの置き場所はデフォルトで幾つかあり、ansible.cfg や環境変数、ansible/ansible-playbook 実行時のオプションで変更可能です。詳しくは以下のページを参照して下さい。

* [DEFAULT_MODULE_PATH](https://docs.ansible.com/ansible/latest/reference_appendices/config.html?highlight=library#default-module-path)
* [Embedding Modules and Plugins In Roles](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html?highlight=library#embedding-modules-and-plugins-in-roles)

# 使用例

[README](https://github.com/yosshy/ansible-pacemaker2/blob/master/README.md)に書かれたサンプル（２ノード MariaDB Master-Slave クラスタ設定用 Ansible Playbook）を引用します。ノード名は仮に server1, server2 とします。

```yaml

# ①Pacemaker クラスタの設定
- pacemaker_property:
    params: stonith-enabled=false start-failure-is-fatal="false"

# ②MariaDB 実行リソースの設定
- pacemaker_resource:
    name: mariadb-service
    type: ocf:heartbeat:mysql
    params: |
      binary=/usr/bin/mysqld_safe
      datadir=/var/lib/mysql
      log=/var/log/mariadb/mariadb.log
      pid=/run/mariadb/mariadb.pid
      replication_user=repl
      replication_passwd=slavepass
    op:
      - start interval=0 timeout=120s
      - stop interval=0 timeout=120s
      - monitor interval=20s timeout=30s
      - monitor interval=10s role=Master timeout=30s
      - monitor interval=30s role=Slave timeout=30s
      - promote interval=0 timeout=120s
      - demote interval=0 timeout=120s
      - notify interval=0 timeout=90s
    master: |
      master-max=1
      master-node-max=1
      clone-max=2
      clone-node-max=1
      notify=true

#③MariaDB 用フローティング IP リソースの設定
- pacemaker_resource:
    name: mariadb-vip
    type: ocf:heartbeat:IPaddr2
    params: ip=192.168.0.100
    op:
      - monitor interval=30s

#④２，３の各リソースによるリソースグループの設定
- pacemaker_resource_group:
    resource:
      - mariadb-service
      - mariadb-vip

#⑤２，３の各リソースの同居設定
- pacemaker_colocation:
    resource1: mariadb-service=master
    resource2: mariadb-vip
    score: INFINITY

#⑥３のリソース起動サーバで server1 を優先するよう設定
- pacemaker_locaiton:
    resource: mariadb-vip
    node: server1
    score: 100
```
紙面の都合上、ここで細々とした解説はしませんが、pcs コマンドを使った事のある人であればそれほど難しい内容ではないでしょう。
各種属性は params パラメータの値として key=value の形で列挙します。辞書型にしようかとも思ったのですが、pacemaker_resource モジュールの op パラメータのリストエントリとの書式と一致しない（あるいは複雑化する）のを避けるためにこの形になりました。"|" を使えばそれなりに見やすく記述できると思います。

各モジュールの説明は、モジュールインストール後に以下のコマンドを実行して下さい。

```
$ ansible-doc <モジュール名>
```

# 注意点

通常、Pacemaker クラスタが正常にセットアップされた環境では、クラスタ内の１ノード上で pcs コマンドを実行する事で Pacemaker の設定や制御を行います。これは pacemaker モジュール群でも同様です。
よって、pacemaker モジュール群を使用する Ansible Playbook では、Playbook 又は Task に

```yaml
run_once: yes
```

を指定し、モジュールが実行されるノードを１つに絞った方が良いでしょう。

それでは皆様、平成最後のクリスマスに pacemaker モジュール群をお楽しみ下さい。