Pacemaker + Corosync を利用してHAクラスタを構成するレシピ


SoftLayerクッキングLABO

このレシピで出来ること

このレシピは、CentOS/RedHat や Ubuntu で、Pacemaker + Corosync を利用して、アクティブ・スタンバイの2重化構成を作ります。このレシピの対象範囲は赤色破線の内側になります。iSCSIストレージとの接続は他のレシピと組み合わせにより対応します。

Pacemaker と Heartbeat / Corosync の関係について、次の図に整理しました。 HeartBeat と CoroSync は、共にクラスタ制御を担い、メッセージングによってクラスタ内のサーバーの状態を管理します。

Pacemakerは、Heartbeatから分離したプロジェクトでしたが、現在は CoroSync が推奨のクラスタ制御のサブシステムになっています。 参考資料 Pacemakerで簡単・手軽にクラスタリングしてみよう 2010年6月26日 Linux-HA Japanプロジェクト

レシピの要約

この pm_corosync01 レシピは、以下の設定を適用します。

  • pacemaker、corosync、pcs のパッケージ導入
  • corosync の設定
  • 設定ファイルの配置 (RedHat/CentOS は pcs、Ubuntu は crm コマンドファイル)
  • 設定の実施 (pcs または crm の実行)

レシピの説明

代表IPの準備

アクティブ・スタンバイのクラスタを代表して、サービスを提供するIPアドレスを 仮想IPアドレス (VIP) と呼ばれます。このVIPは、元々サーバーに付与されているIPアドレスではなく、クラスタ・ソフトウェアによって、サービス提供側のサーバーに付与されるIPアドレスです。 このアドレスをオーダーするには、ソフトレイヤー活用ガイド第2部「コンフィグレーション・ガイド」 4.2 サーバーを替えても同じIPアドレスを継続するには? をご参照ねがいます。

このレシピのために確保したサブネットのidは、758078 で、このサブネットの中からIPアドレスを選んで割当ます。このサブネットの管理は、ユーザーが自己管理しなければなりません。

$ slcli subnet list -d tok02 --sortby identifier
:.........:....................:...................:............:.........:.....:..........:....:
:    id   :     identifier     :        type       : datacenter : vlan_id : IPs : hardware : vs :
:.........:....................:...................:............:.........:.....:..........:....:
: 1038857 :  10.132.253.0/26   :      PRIMARY      :   tok02    :  978115 :  64 :    0     : 3  :
:  758078 :  10.132.5.128/26   : SECONDARY_ON_VLAN :   tok02    :  978115 :  64 :    0     : 0  :
: 1038909 : 161.202.142.192/28 :      PRIMARY      :   tok02    :  978113 :  16 :    0     : 3  :
:.........:....................:...................:............:.........:.....:..........:....:

サーバーの準備

ご参考までに、このレシピを実行するための最小スペックのサーバーをオーダーするシェルを以下に挙げておきます。

#!/bin/bash
#
slcli vs create \
--hostname server1 --domain softlayer.com \
--datacenter tok02 \
--cpu 1 --memory 1 \
--os CENTOS_7_64 \
--billing hourly \
--public \
--postinstall https://raw.githubusercontent.com/takara9/ProvisioningScript/master/centos_basic_config \
--key 370981 \
--network 100
#
slcli vs create \
--hostname server2 --domain softlayer.com \
--datacenter tok02 \
--cpu 1 --memory 1 \
--os CENTOS_7_64 \
--billing hourly \
--public \
--postinstall https://raw.githubusercontent.com/takara9/ProvisioningScript/master/centos_basic_config \
--key 370981 \
--network 100

上記のシェルでオーダーした結果は、以下の様になりました。このバックエンド側のIPアドレスを使って、レシピのアトリビュートファイルの設定します。

chef@ChefWs:~/shells$ slcli vs list
:..........:..........:.................:...............:............:........:
:    id    : hostname :    primary_ip   :   backend_ip  : datacenter : action :
:..........:..........:.................:...............:............:........:
: 13095065 : server1  : 161.202.142.196 :  10.132.253.7 :   tok02    :   -    :
: 13095069 : server2  : 161.202.142.203 : 10.132.253.17 :   tok02    :   -    :
:..........:..........:.................:...............:............:........:

レシピのファイル

クックブックの中で設定するのは4種類、7本のファイルです。 4種類は、[1]アトリビュート、[2]レシピ、[3]リソース管理コマンドファイル(crm用,pcs用)、[4]corosync設定ファイルです。

pm_corosync01/
├── CHANGELOG.md
├── README.md
├── attributes
│   └── default.rb  (1) VIPなどのパラメータ
├── definitions
├── files
├── libraries
├── metadata.rb
├── providers
├── recipes
│   └── default.rb  (2) レシピ本体
├── resources
└── templates
    ├── centos-6.7
    │   └── pcs_config.erb    (3) CentOS用 pcsコマンドファイル
    ├── centos-7.1.1503
    │   └── pcs_config.erb    (3) 上記と同じファイル
    ├── default
    │   ├── corosync.conf.erb (5) corosyncの設定ファイル
    │   └── pcmk.erb
    └── ubuntu14.04           (4) Ubuntu用 crmコマンドファイル
        └── crm_vip_1.erb

(1) VIPなどパラメータ

設定内容の説明は、項目の右側にコメントしました。

attributes/default.rb
default["network_addr"] = "10.132.253.0"    <-- eth0が繋がるネットワークアドレス 
default["multicast_addr"] = "226.94.1.1"    <-- マルチキャストのアドレス(クラスタ毎に一意)
default["multicast_port"] = "5405"  <-- マルチキャストのポート番号 
default["vip_ipaddr"] = "10.132.5.141" <-- VIP ポータブルサブネットからIPアドレスを割当
default["vip_netmask"] = "26" <-- ビット長を設定

(2) レシピ本体

このレシピの本物は、GitHubに登録してあります。 ポイントとなる部分は、このリストに注釈します。

recipes/default.rb
# -*- coding: utf-8 -*-
#
# Cookbook Name:: pm_corosync01
# Recipe:: default

# Pacemaker + Corosync  
# パッケージのインストール
#
case node['platform']
###
when 'ubuntu'
  execute 'apt-get update' do
    command 'apt-get update'
    action :run
  end

  %w{
    corosync
    pacemaker
    ntp
  }.each do |pkgname|
    package "#{pkgname}" do
      action :install
    end
  end

  execute 'ubuntu service' do
    command 'update-rc.d pacemaker defaults'
    action :run
  end

  execute 'default_corosync' do
    command 'echo "START=yes" > /etc/default/corosync'
    action :run
  end

###
when 'centos','redhat'
  execute 'yum update' do
    command 'yum update -y'
    ignore_failure true
    action :run
  end
  %w{
      corosync 
      pacemaker 
      pcs
      ntp
  }.each do |pkgname|
    package "#{pkgname}" do
      action :install
    end
  end
end # node['platform']

service 'corosync' do
  supports :start => true, :restart => true, :stop => true
  action [ :enable, :nothing ]
end

service 'pacemaker' do
  supports :start => true, :restart => true, :stop => true
  action [ :enable, :nothing ]
end

#
# サービスとして Pacemakerを指定
# CentOS 7 ではディレクトリなく不要
#
if node['platform_version'].to_i != 7 then
  template "/etc/corosync/service.d/pcmk" do
    owner "root"
    group "root"
    mode 0644
    source "pcmk.erb"
    action :create
  end
end

#
# corosync の設定ファイルを配置
# Ubuntu14.04 CentOS 6 共通
#
template "/etc/corosync/corosync.conf" do
  owner "root"
  group "root"
  mode 0644
  source "corosync.conf.erb"
  variables({
    :network_addr => node["network_addr"],
    :multicast_addr => node["multicast_addr"],
    :multicast_port => node["multicast_port"]
  })
  action :create
  notifies :start, 'service[corosync]', :immediately
  notifies :start, 'service[pacemaker]', :immediately
end


#
# RedHat/CentOS では、crmが無くなりpcsとなっている
# オプション等も異なるのでファイルを別ける
#
case node['platform']
when 'ubuntu'
  resource = "crm_config"
when 'centos','redhat'
  resource = "pcs_config"
end

template "/root/#{resource}" do
  owner "root"
  group "root"
  mode 0744
  source "#{resource}.erb"
  variables({
    :vip_ipaddr => node["vip_ipaddr"],
    :vip_netmask => node["vip_netmask"]
  })
  action :create
end

#
# クラスタのリソース管理コマンドを実行
#
case node['platform']
when 'ubuntu'
  execute "crm_execute" do
    command "/usr/sbin/crm -f /root/#{resource} configure"
    action :run
    ignore_failure true
  end
when 'centos','redhat'
  execute "pcs_execute" do
    command "/root/#{resource}"
    action :run
    ignore_failure true
  end
end

(3) CentOS用 pcs コマンドファイル

同じ様に Pacemaker を利用しているのですが、RedHat系には、crmコマンドが無くpcsコマンドに置き換えられています。このため、CentOS/RedHat と Ubuntu リソース管理のフロントエンドに合わせて、2種類のファイルを作成します。 ここではIPアドレスだけですが、共有ディスクのファイルシステムのマウント、サービスの起動などのリソースの追加はこのファイルに加えます。

#!/bin/bash
pcs property set stonith-enabled=false    <-- STONISHを無効化  IPMIで電源操作を行なわない
pcs property set no-quorum-policy=ignore  <-- クォーラムポリシーを無視する
pcs resource op defaults resource-stickiness=INFINITY migration-threshold=1  <-- 自動フェイルオーバー禁止
pcs resource create vip1 ocf:heartbeat:IPaddr2 ip=<%= @vip_ipaddr %> cidr_netmask=<%= @vip_netmask %> nic=eth0 op monitor interval=20s <--- 仮想IPアドレスを設定

(4) Ubuntu用 crmコマンドファイル

こちらも同じく、管理対象のリソースを増やす場合には、このファイルに追加します。

primitive vip-1 ocf:heartbeat:IPaddr \
params ip="<%= @vip_ipaddr %>" cidr_netmask="<%= @vip_netmask %>" \
op monitor interval="10s"
property stonith-enabled=false
commit

(5) corosyncの設定ファイル

変更箇所は、アトリビュートファイルの値をレシピを通じて変更します。

corosync.conf
totem {
      version: 2
      # How long before declaring a token lost (ms)
      token: 3000
      # How many token retransmits before forming a new configuration
      token_retransmits_before_loss_const: 10
      # How long to wait for join messages in the membership protocol (ms)
      join: 60
      # How long to wait for consensus to be achieved before starting a new round of membership configuration (ms)
      consensus: 3600
      # Turn off the virtual synchrony filter
      vsftype: none
      # Number of messages that may be sent by one processor on receipt of the token
      max_messages: 20
      # Limit generated nodeids to 31-bits (positive signed integers)
      clear_node_high_bit: yes
      # Disable encryption
      secauth: off
      # How many threads to use for encryption/decryption
      threads: 0
      # Optionally assign a fixed node id (integer)
      # nodeid: 1234
      # This specifies the mode of redundant ring, which may be none, active, or passive.
      rrp_mode: none
      interface {
        # The following values need to be set based on your environment 
        ringnumber: 0
    bindnetaddr: <%= @network_addr %>
    mcastaddr: <%= @multicast_addr %>
    mcastport: <%= @multicast_port %>
      }
}

amf {
    mode: disabled
}

quorum {
       # Quorum for the Pacemaker Cluster Resource Manager
       provider: corosync_votequorum
       expected_votes: 2
       two_node: 1
}

aisexec {
        user:   root
        group:  root
}

logging {
        fileline: off
        to_stderr: yes
        to_logfile: no
        to_syslog: yes
    syslog_facility: daemon
        debug: off
        timestamp: on
        logger_subsys {
                subsys: AMF
                debug: off
                tags: enter|leave|trace1|trace2|trace3|trace4|trace6
        }
}

リソース制御のサービスを指定します。

/etc/corosync/service.d/pcmk
service {
        # Load the Pacemaker Cluster Resource Manager
        name: pacemaker
        ver:  1
}

レシピの適用手順

本設定では、最初に立ち上がったサーバーが、サービスを提供するサーバーになります。 意図的にマスターやスタンバイを設定するには、pcsやcrmの設定で実施します。

chef@ChefWs:~/chef-repo$ knife solo bootstrap 10.132.253.7 -x root -r 'recipe[pc_corosync01]' -i ~/key/chefkey

それぞれ、IPアドレスを指定してレシピを適用します。

動作確認には、crm_monコマンドで行ないます。 このコマンドは、リアルタイムに画面が更新されるのでクラスタのノードに追加、離脱が発生した場合の動きを見ることができます。 以下の画面コピーでは、server1 と server 2が クラスタで オンラインとなっており、仮想IPアドレスは、server1から提供されていることが判ります。

server1が停止した場合、以下の様な表示に切り替わります。このスクリーンコピーはserver2でcrm_monを実行したものです。server1がオフラインとなり、VIPは、server2が保持していることが判ります。

対応するソフトレイヤー活用ガイド

このレシピを利用することで、以下の設計パターンや設定作業を自動化することができます。

テスト済みのLinuxディストリビューション

SoftLayerでサーバーオーダー時に選択できるOSの中から、確認できたもののリストです。

  • Ubuntu 14.04 64bit minimal install
  • CentOS 7.1 64bit minimal install
  • CentOS 6.7 64bit minimal install

レシピの置き場所

最新版のレシピはGitHubにあります。
- GitHub takara9/chef-repo/ iscsiStorage01 https://github.com/takara9/chef-repo/tree/master/site-cookbooks/pm_corosync01

Chef 関連マニュアル

このレシピを作るにあたって参照したCHEFマニュアルのリンクです。
- script (https://docs.chef.io/resource_script.html )
- execute (https://docs.chef.io/resource_execute.html )
- package (https://docs.chef.io/resource_package.html )
- template (https://docs.chef.io/resource_template.html)
- file (https://docs.chef.io/resource_file.html)

参考資料