それなりに適当にやってます

なんとなくそれっぽいメモとか備忘録とか適当に。 2018年5月にブログ移転しました。 古い記事は未整理です。

CentOS7.x+Pacemaker/Corosync+DRBD8によるHA構成

CentOS7.xでPacemakerを使ってHAを構成する場合、下記2通りの方法があった。

  • RHEL/CentOS7.x で提供されている High Availability オプションを利用(RHELのはオプションで有償)
  • Linux-HA Japan 提供のPacemakerパッケージを利用
  • あとCLUSTEPROとかの商用製品

以下では情報量の多い&便利なプラグインが用意されている "Linux-HA Japan" のパッケージを利用した手順を示す。

参考URL

Linux-HA Japan コミュニティの方々がオープンソースカンファレンス等で提供・公開して下さっている資料を参考にする。

備忘メモ

  • crm と pcs の両コマンドが用意されているが、Linux-HA Japan パッケージでは crm が推奨らしい(pcsはcorosyncがいぢれないとか)
  • STONITH(ストニス)プラグインとして fence-agents と、cluster-glue のパッケージがあるが、cluster-glue に含まれるプラグインの利用が推奨らしい
  • DRBD9 + drbd-utils で試したらうまくいかなかった(´・ω・`)

検証環境

  • AWS/EC2, t2.micro インスタンス
  • CentOS7.x (2016/04/18時点)
  • /dev/sda 8GB, /dev/sdb 8GB
  • SELinux を無効化
  • その他、インスタンス作成時の状態を維持
  • セキュリティグループでノード間の通信は全て通すように設定
  • server1 : 10.0.0.10
  • server2 : 10.0.0.11

2016/12追記
今はAWS/EC2上で作ってもうまく動かないかも。

Linux-HA Japan製 Pacemaker のインストール

Linux-HA Japan で公開されていリポジトリ設定用のRPMをインストールし、yumを用いてPacemaker関連パッケージのインストールを行う。"mailx" はメール通知で使うので一緒に入れる。

# mkdir /usr/local/src/pacemaker ; cd $_# curl -L "https://osdn.jp/frs/redir.php?m=iij&f=%2Flinux-ha%2F63918%2Fpacemaker-repo-1.1.13-1.1.el7.x86_64.rpm" -o pacemaker-repo-1.1.13-1.1.el7.x86_64.rpm# yum -y install ./pacemaker-repo-1.1.13-1.1.el7.x86_64.rpm# yum -y install pacemaker-all mailx

yum アップデートの除外設定

そのままだと CentOS7.x デフォルトで提供されている Pacemaker/Corosync でアップデートが適用されてしまう恐れがあるので、念のため更新から除外しておく。

# vi /etc/yum.conf
exclude=pacemaker* corosync*  

Corosync の設定

Corosync共通暗号鍵の作成

Corosyncが用いる暗号鍵を作成する。

# corosync-keygen -k /etc/corosync/authkey -l

Corosync共通暗号鍵の展開

HAを構成する各ノードに、作成した暗号鍵を適当に転送する。

# scp -p /etc/corosync/authkey root@10.0.0.11:/etc/corosync/authkey

Pacemaker/Corosyncの設定

Corosyncの設定

続いて Corosync の動作に必要な設定を行う。テンプレートとしてUDPマルチキャストのものと、UDPユニキャストの設定が用意されている。下記ではUDPユニキャストのテンプレートをベースに設定を行う。

# cd /etc/corosync# cp corosync.conf.example.udpu corosync.conf

コメントアウトしている xxx.xxx.xxx.xxx は2つ目のNICを用いたい場合に設定する。

# Please read the corosync.conf.5 manual pagetotem {          version: 2        rrp_mode: active        crypto_cipher: none        crypto_hash: none        interface {                ringnumber: 0                bindnetaddr: 10.0.0.0                mcastport: 5405                ttl: 1        }        #interface {        #        ringnumber: 1        #        bindnetaddr: xxx.xxx.xxx.xxx        #        mcastport: 5405        #        ttl: 1        #}        transport: udpu}logging {          fileline: off        to_logfile: yes        to_syslog: yes        logfile: /var/log/cluster/corosync.log                debug: off                timestamp: on        logger_subsys {                subsys: QUORUM                debug: off        }}nodelist {          node {                ring0_addr: 10.0.0.10                #ring1_addr: xxx.xxx.xxx.xxx                nodeid: 1        }        node {                ring0_addr: 10.0.0.11                #ring1_addr: xxx.xxx.xxx.xxx                nodeid: 2        }        # 3台目以降の設定        #node {        #       ring0_addr: xxx.xxx.xxx.xxx        #       ring1_addr: xxx.xxx.xxx.xxx        #}}quorum {          # Enable and configure quorum subsystem (default: off)        # see also corosync.conf.5 and votequorum.5        provider: corosync_votequorum        expected_votes: 2}

プロセスの挙動について設定

Pacemakerのプロセスが故障した際、halt状態になるよう設定する。

# cp /etc/sysconfig/pacemaker{,.orig}# vi /etc/sysconfig/pacemaker
...68 # PCMK_fail_fast=no  69 PCMK_fail_fast=yes  

Corosyncのプロセスが故障した際、CorosyncのWatchdogが動作するように設定(Restartを有効にする)

# systemctl edit --full corosync
...Restart=on-failure  ...RestartSec=70  ...ExecStartPre=/sbin/modprobe softdog soft_margin=60  ...

Pacemaker停止時にCorosyncも停止する設定を有効にする。

# systemctl edit --full pacemaker
...46 # ExecStopPost=/bin/sh -c 'pidof crmd || killall -TERM corosync'  47 ExecStopPost=/bin/sh -c 'pidof crmd || killall -TERM corosync'  

HA構成の起動確認

Pacemakerを起動し、HAを構成する各ノードの通信が正常に行われている事を確認

# systemctl start pacemaker# crm_mon -rfA -1...2 Nodes configured  ...※両ノードが認識されており、Online で認識されている事を確認# systemctl stop pacemaker

DRBDのインストール

DRBDによる共有ディスクを作成する。ここではコマンドだけ列挙し細かい説明は省く。とりあえずDRBDインスコ

# yum -y install @development wget bash-completion# mkdir /usr/local/src/drbd ; cd $_# wget http://www.drbd.org/download/drbd/8.4/drbd-8.4.7-1.tar.gz# tar zxvf drbd-8.4.7-1.tar.gz# cd drbd-8.4.7-1# make && make install ; echo $?# cd ..# modinfo drbd | egrep -i version

drbd-utils のインスコ

# mkdir /usr/local/src/drbd-utils ; cd $_# wget https://www.drbd.org/download/drbd/utils/drbd-utils-8.9.6.tar.gz# tar zxvf drbd-utils-8.9.6.tar.gz# cd drbd-utils-8.9.6# ./configure --sysconfdir=/etc --localstatedir=/var --without-manual --with-pacemaker --with-udev --with-bashcompletion# make && make install ; echo $?

各設定ファイルの作成

# cd /etc/drbd.d/# mv global_common.conf global_common.conf.orig# vi global_common.conf
global {    usage-count no;}common {  startup {    wfc-timeout 60;         # 1 minutes.    degr-wfc-timeout 60;    # 1 minutes.  }  disk {    on-io-error pass_on;  }  net {    protocol C;    max-buffers    8000;    max-epoch-size 8000;    sndbuf-size 0;  }  syncer {    c-plan-ahead 0;    c-max-rate 120M;    c-min-rate 50M;    rate 120M;    al-extents 3389;  }}
# vi drbd0.res
resource drbd0 {    device      /dev/drbd0;  disk        /dev/xvdb1;  meta-disk   internal;  on ip-10-0-0-10.ap-northeast-1.compute.internal {    address   10.0.0.10:7789;  }  on ip-10-0-0-11.ap-northeast-1.compute.internal {    address   10.0.0.11:7789;  }}
# vi /etc/hosts...10.0.0.10    server1 ip-10-0-0-10 ip-10-0-0-10.ap-northeast-1.compute.internal  10.0.0.11    server2 ip-10-0-0-11 ip-10-0-0-11.ap-northeast-1.compute.internal  # parted /dev/xvdb> mklabel> mkpart> quit# drbdadm create-md drbd0# mkdir /data

DRBDのここまでの手順を両系で実行後、DRBDのサービスを両方で起動し、初期同期を開始する。

# systemctl start drbd# cat /proc/drbd# drbdadm primary drbd0 --force# cat /proc/drbd# mkfs.xfs /dev/drbd0# mount /dev/drbd0 /data

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

ついでに PostgreSQL もリソースに含めるため、インストールしておく。

# yum -y install postgresql-server# systemctl edit --full postgresql...# Location of database directory#Environment=PGDATA=/var/lib/pgsql/dataEnvironment=PGDATA=/data/pgsql/data  

下記はDRBDをマウントしている側(Primary)で実行

# drbdadm status  =>Primaryである事を確認# mount  =>/dev/drbd0 を /data にマウントしている事を確認# mkdir /data/pgsql# chown postgres:postgres /data/pgsql# su - postgres$ initdb --no-locale -E UTF8 /data/pgsql/data$ exit# systemctl start postgresql# ps -efww | grep postgres  =>/data/pgsql/data でサービスが起動している事を確認# systemctl stop postgresql# umount /data# drbdadm secondary drbd0

CRMリソースの設定

CRMリソースの設定は、基本的にリソースの定義 -> グループ/クローンの作成 -> 起動・依存関係の設定みたいな感じ。crm ファイルを作成後、読み込ませるだけ。

# cd ~# vi /tmp/hoge  =>下記の"設定ファイル"の内容を編集してコピペ

設定ファイル

### Cluster Option ------------------------------------------------------- ##### クラスター全体の設定、STONITH(ストニス)は false にしている。## no-quorum-policy      ... 2台構成なので "ignore" を選択(クォーラムを無視する)# stonith-enabled       ... 強制的なノード停止を無効(false)にする# startup-fencing       ... 起動時のフェンシングを無効(false)にする# resource-stickiness   ... 切り戻しが起こらないようにする(INFINITY)# migration-threshold   ... リソース管理エラー -> 切り替えまでの閾値(1回)#property \      no-quorum-policy="ignore" \    stonith-enabled="false" \    startup-fencing="false"### Resource Defaults ###rsc_defaults \      resource-stickiness="INFINITY" \    migration-threshold="1"### Fencing Topology ----------------------------------------------------- ##### フェンシング動作時の挙動設定## stonith           ... ipmi/libvirt を利用した、相方にトドメを刺す仕組み# stonith-helper    ... stonith による相打ちを防ぐ仕組み##fencing_topology \#    server01: prmHelper1-1 prmLibvirt1-2 \#    server02: prmHelper2-1 prmLibvirt2-2###### Group Configuration ####group grpStonith1 \#    prmHelper1-1 \#    prmLibvirt1-2##group grpStonith2 \#    prmHelper2-1 \#    prmLibvirt2-2##primitive prmHelper1-1 stonith:external/stonith-helper \#    params \#        pcmk_reboot_retries=1 \#        hostlist="server01" \#        dead_check_target="192.168.1.10 192.168.11.10 192.168.12.10 192.168.122.40" \#        standby_check_command="/usr/sbin/crm_resource -r prmDB -W | grep -qi `hostname`" \#        run_online_check="yes" \#    op start interval="0s" timeout="20s" on-fail="restart" \#    op monitor interval="3600s" timeout="20s" on-fail="restart" \#    op stop interval="0s" timeout="15" on-fail="ignore"##primitive prmLibvirt1-2 stonith:external/libvirt \#    params \#        hostlist="server01" \#        hypervisor_uri="qemu+ssh://192.168.122.1/system" \#    op start interval="0s" timeout="60s" on-fail="restart" \#    op monitor interval="3600s" timeout="60s" on-fail="restart" \#    op stop interval="0s" timeout="60s" on-fail="ignore"##primitive prmHelper2-1 stonith:external/stonith-helper \#    params \#        pcmk_reboot_retries=1 \#        hostlist="server02" \#        standby_check_command="/usr/sbin/crm_resource -r prmDB -W | grep -qi `hostname`" \#        run_online_check="yes" \#    op start interval="0s" timeout="20s" on-fail="restart" \#    op monitor interval="3600s" timeout="20s" on-fail="restart" \#    op stop interval="0s" timeout="15" on-fail="ignore"##primitive prmLibvirt2-2 stonith:external/libvirt \#    params \#        hostlist="server02" \#        hypervisor_uri="qemu+ssh://192.168.122.1/system" \#    op start interval="0s" timeout="60s" on-fail="restart" \#    op monitor interval="3600s" timeout="60s" on-fail="restart" \#    op stop interval="0s" timeout="60s" on-fail="ignore"##### Reousce Settings ----------------------------------------------------- ##### primitive ... リソースエージェントに準じたリソースの設定# group     ... リソースのグループ化 (=orderも含めて考慮)# clone     ... クラスタノードで共通するリソースの設定# ms        ... master/slave系リソースの設定(DB,DRBDなど)#### Group Configuration ##### Master/Slaveリソース(ms)は location で紐付けるのでグループには含めないgroup grpTrac \      prmVIP \    prmFS \    prmDB \    prmMail### Clone Configuration ###clone clnPing \      prmPingclone clnDiskd1 \      prmDiskd1clone clnDiskd2 \      prmDiskd2ms msDrbd \      drbd \    meta \        resource-stickiness="1" \        master-max="1" \        master-node-max="1" \        clone-max="2" \        clone-node-max="1" \        notify="true"## VIPprimitive prmVIP ocf:heartbeat:IPaddr2 \      params \        ip="10.0.0.9" \        nic="eth0" \        cidr_netmask="24" \    op start interval="0s" timeout="20s" on-fail="restart" \    op monitor interval="10s" timeout="20s" on-fail="restart" \    op stop interval="0s" timeout="20s" on-fail="ignore"## DRBD/drbd0    primitive drbd ocf:linbit:drbd \      params \        drbdconf="/etc/drbd.conf" \        drbd_resource="drbd0" \    op start interval="0s" timeout="240s" on-fail="restart" \    op monitor role="Master" interval="10s" timeout="20s" on-fail="restart" \    op monitor role="Slave" interval="20s" timeout="20s" on-fail="restart" \    op promote interval="0s" timeout="90s" on-fail="stop" \    op demote interval="0s" timeout="90s" on-fail="ignore" \    op stop interval="0s" timeout="100s" on-fail="ignore"### Primitive Configuration ##### DRBD/mountprimitive prmFS ocf:heartbeat:Filesystem \      params \        fstype="xfs" \        run_fsck="force" \        device="/dev/drbd0" \        directory="/data" \    op start interval="0s" timeout="60s" on-fail="restart" \    op monitor interval="20s" timeout="40s" on-fail="restart" \    op stop interval="0s" timeout="60s" on-fail="ignore"## PostgreSQLprimitive prmDB ocf:heartbeat:pgsql \      params \        pgctl="/bin/pg_ctl" \        psql="/bin/psql" \        pgdata="/data/pgsql/data" \        start_opt="-p 5432" \        pgdba="postgres" \        pgport="5432" \        pgdb="template1" \    op start interval="0s" timeout="120s" on-fail="restart" \    op monitor interval="10s" timeout="10s" on-fail="restart" \    op stop interval="0s" timeout="20s" on-fail="ignore"## Mailprimitive prmMail ocf:heartbeat:MailTo \      params \        email="underboob@example.com,oppaoppai@example.com" \        subject="Pacemaker Alert - futomomo.example.com (xxx.xxx.xx.xxx)" \    op monitor depth="0" timeout="10s" interval="10s"## GATEWAY PINGprimitive prmPing ocf:pacemaker:ping \      params \        name="default_ping_set" \        host_list="10.0.0.1" \        multiplier="100" \        attempts="2" \        timeout="2" \        debug="true" \    op start interval="0s" timeout="60s" on-fail="restart" \    op monitor interval="10s" timeout="60s" on-fail="restart" \    op stop interval="0s" timeout="60s" on-fail="ignore"## Local Disk Check - /dev/xvdbprimitive prmDiskd1 ocf:pacemaker:diskd \      params \        name="diskcheck_status" \        device="/dev/xvdb" \        options="-e -t 70" \        interval="10" \        dampen="2" \    op start interval="0s" timeout="60s" on-fail="restart" \    op monitor interval="10s" timeout="60s" on-fail="restart" \    op stop interval="0s" timeout="60s" on-fail="ignore"## Local Disk Check - /dev/xvdaprimitive prmDiskd2 ocf:pacemaker:diskd \      params \        name="diskcheck_status_internal" \        device="/dev/xvda" \        options="-e" \        interval="10" \        dampen="2" \op start interval="0s" timeout="60s" on-fail="restart" \  op monitor interval="10s" timeout="60s" on-fail="restart" \  op stop interval="0s" timeout="60s" on-fail="ignore"### Persistence Settings ------------------------------------------------- ##### ノードの重み付けと、リソースの場所・同居・順序の明示# location      ... 場所、どのノードで起動するか?# colocation    ... 同居、どのリソースと一緒に起動するか?# order         ... 順序、どのリソースの前/後に起動するか?#### Resource Location ##### DRBD/grpTracリソースの起動は、ping/disk check が正常なノードで行う。# 重み付けで1台目のノードを優先するように設定#location rsc_location-msDrbd-1 msDrbd \      rule 200: #uname eq ip-10-0-0-10.ap-northeast-1.compute.internal \    rule 100: #uname eq ip-10-0-0-11.ap-northeast-1.compute.internal \    rule -INFINITY: not_defined default_ping_set or default_ping_set lt 100 \    rule -INFINITY: not_defined diskcheck_status or diskcheck_status eq ERROR \    rule -INFINITY: not_defined diskcheck_status_internal or diskcheck_status_internal eq ERRORlocation rsc_location-grpTrac-2 grpTrac \      rule 200: #uname eq ip-10-0-0-10.ap-northeast-1.compute.internal \    rule 100: #uname eq ip-10-0-0-11.ap-northeast-1.compute.internal \    rule -INFINITY: not_defined default_ping_set or default_ping_set lt 100 \    rule -INFINITY: not_defined diskcheck_status or diskcheck_status eq ERROR \    rule -INFINITY: not_defined diskcheck_status_internal or diskcheck_status_internal eq ERROR#location rsc_location-grpStonith1-3 grpStonith1 \#    rule -INFINITY: #uname eq pm01#location rsc_location-grpStonith2-4 grpStonith2 \#    rule -INFINITY: #uname eq pm02### Resource Colocation ##### ping/dick check が有効なノードで DRBD を起動する# DRBD/Masterノードでのみ grpTrac のリソースを起動する。#colocation rsc_colocation-msDrbd-clnPing-1            INFINITY: msDrbd        clnPing  colocation rsc_colocation-msDrbd-clnDiskd1-2          INFINITY: msDrbd        clnDiskd1  colocation rsc_colocation-msDrbd-clnDiskd2-3          INFINITY: msDrbd        clnDiskd2  colocation rsc_colocation-grpTrac-msDrbd-4            INFINITY: grpTrac       msDrbd:Master### Resource Order ##### ping/disk check が有効になってから DRBD を開始する。# DRBDが開始された後、grpTrac のリソースが開始するように設定# 末尾の設定で grpTrac のリソースが停止してから、DRBDが secondary になるように指定している(symmetrical=true)、他は順不同#order rsc_order-clnPing-msDrbd-1         0:        clnPing              msDrbd        symmetrical=false  order rsc_order-clnDiskd1-msDrbd-2       0:        clnDiskd1            msDrbd        symmetrical=false  order rsc_order-clnDiskd2-msDrbd-3       0:        clnDiskd2            msDrbd        symmetrical=false  order rsc_order-msDrbd-grpTrac-4         INFINITY: msDrbd:promote       grpTrac:start  

コメント行で怒られるので、コメント行を除外した crm ファイルを作成し反映する。

# egrep -v "^#" /tmp/hoge > ~/resource.crm# crm configure load update resource.crm

ちゃんと動く事を祈る。 ダメな場合は /etc/sysconfig/pacemaker や corosync.conf でデバッグを有効にして調査してなんとかする。

# crm_mon -rfA -1

とりあえず動いたのは動いた。実際にはもっと設定詰めて色々試験しないとダメだけども。

以上、なにごとも適当に。