LoginSignup
9
9

More than 5 years have passed since last update.

Pacemaker + Heartbeat でアクティブ・スタンバイを構成するレシピ

Last updated at Posted at 2015-10-12

SoftLayerクッキングLABO

このレシピで出来ること

Debian や Ubuntu で、Pacemaker + Heartbeatを利用して、アクティブ・スタンバイの2重化構成を作ります。 Debianのリポジトリでは、Heartbeat のパッケージの依存パッケージに Pacemaker が含まれています。 ところが、現在推奨となっている Pacemaker + Corosync でインストールする事ができませんでした。 頑張って自力でコンパイルするのも、なかなか面倒なので Debianで、Pacemaker + Heartbeatを使って2重化すレシピです。次の図では、右側の主と待機サーバーの2台の設定を実施するものです。
それから、CentOS/RedHat では Heartbeat が既にリポジトリに登録されていないため、Pacemaker + Corosync の記事を書きましたので、そちらを参照頂ければ幸いです。

スクリーンショット 2015-10-12 21.39.12.png

レシピの要約

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

  • heartbeat のパッケージ導入
  • アクティブとスタンバイのIPアドレス、ホスト名の設定
  • ホスト名の再設定 (Heartbeat用)
  • 認証キー設定
  • hostsファイルに追加登録
  • ha.cf 設定
  • haresources 設定

レシピの説明

代表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  :
:.........:....................:...................:............:.........:.....:..........:....:

レシピのファイル

クックブックの中で設定するのは6本のファイルです。

chef@ChefWs:~/chef-repo/site-cookbooks$ tree pm_heartbeat01/
pm_heartbeat01/
├── CHANGELOG.md
├── README.md
├── attributes
│   └── default.rb (1) アクティブとスタンバイのIPアドレス、ホスト名を設定
├── definitions
├── files
├── libraries
├── metadata.rb  (2) hostsファイル操作の共通レシピを追加
├── providers
├── recipes
│   └── default.rb (3) レシピ本体
├── resources
└── templates
    └── default
        ├── authkeys.erb  (4) HeartBeat 認証キー
        ├── ha.cf.erb     (5) HeartBeat 設定ファイル
        └── haresources.erb  (6) リソースファイル

上記のディレクトリのスグ上の Berksfileに cookbook 'hostsfile' を追加しておきます。

chef@ChefWs:~/chef-repo$ cat Berksfile
site :opscode
source "https://api.berkshelf.com"
cookbook 'hostsfile'

サーバーの準備

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

#!/bin/bash
#
slcli vs create \
--hostname server1 --domain softlayer.com \
--datacenter tok02 \
--cpu 1 --memory 1 \
--os DEBIAN_8_64 \
--billing hourly \
--public \
--postinstall https://raw.githubusercontent.com/takara9/ProvisioningScript/master/debian_basic_config \
--key 370981 \
--network 100
#
slcli vs create \
--hostname server2 --domain softlayer.com \
--datacenter tok02 \
--cpu 1 --memory 1 \
--os DEBIAN_8_64 \
--billing hourly \
--public \
--postinstall https://raw.githubusercontent.com/takara9/ProvisioningScript/master/debian_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    :   -    :
:..........:..........:.................:...............:............:........:

(1) 両サーバーのIPアドレスなどパラメータ

VIPだけを設定する場合
サーバーのIPアドレスなどの毎回設定が必要な部分は、attributes のディレクトリ下のファイルに集めてあります。 注釈を参考に環境に合わせて値をセットします。

attributes/default.rb
default["mystate"] = 'MASTER'    <--- 自ノードが主系の場合、待機系にする時はBACKUPとする
default["master"]["hostname"] = 'node1'       <--- 主系のホスト名、IPアドレスをセット 
default["master"]["ipaddr"] = '10.132.253.7'   
default["backup"]["hostname"] = 'node2'       <--- 待機系のホスト名、IPアドレスをセット
default["backup"]["ipaddr"] = '10.132.253.17'

default["vip"]["addr"] = "10.132.5.132/26/eth0"   <--- 仮想IPアドレス、ネットマスク、インタフェース
default["vip"]["storage"] = ""   <--- 以下の例を参考に必要に応じて設定
default["vip"]["service"] = ""

サービスを共用ディスクを指定する場合の変更部分
以下の例は、VIPを持つサーバー側に、iSCSIストレージを /data1 にマウントする場合の設定例です。

attributes/default.rb
default["vip"]["addr"] = "10.132.5.132/26/eth0"   
default["vip"]["storage"] = "Filesystem::/dev/mapper/iscsimp1::/data1::ext4"
default["vip"]["service"] = "mysql"

(2) hostsファイル操作の共通レシピを追加

hostsファイルに、IPアドレス、ホスト名を追加するレシピは、自分で書くと、結構なコード量になるので、CHEF SUPERMARKET https://supermarket.chef.io/ の中から利用できるものを選んできます。
ここでは、hostsfile https://supermarket.chef.io/cookbooks/hostsfile/versions/0.1.1 を利用する設定をおこないます。

metadata.rb
name             'pm_heartbeat01'
maintainer       'YOUR_COMPANY_NAME'
maintainer_email 'YOUR_EMAIL'
license          'All rights reserved'
description      'Installs/Configures pm_heartbeat01'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version          '0.1.0'

depends          'hostsfile'  <-- ここを追加

(3) レシピ本体

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

recipes/default.rb

# -*- coding: utf-8 -*-
#
# Cookbook Name:: pm_heartbeat01
# Recipe:: default

# 
# パッケージのインストール 
#
execute 'apt-get update' do
  command 'apt-get update'
  ignore_failure true
end

%w{
  heartbeat   <-- これを指定すれば、pacemakerも一緒に入るが、pacemakerを指定してインストールできない点注意
}.each do |pkgname|
  package "#{pkgname}" do
    action :install
  end
end

#
# アクティブとスタンバイのIPアドレス設定
#
mystate = node["mystate"]   <-- アトリビュートに指定した文字列で切換え MASTER <-> BACKUP
if mystate == 'MASTER' then
  peer_ip = node["backup"]["ipaddr"]
  myname = node["master"]["hostname"]
else
  peer_ip = node["master"]["ipaddr"]
  myname = node["backup"]["hostname"]
end

#
# ホスト名の変更    <-- クラスタのノード名をホスト名となる様に上書きします。
#
file "/etc/hostname" do
  owner "root"
  group "root"
  mode 0644
  hostname = "#{myname}\n"
  content hostname
  action :create
end
execute 'change_hostname' do
  command 'hostname -F /etc/hostname'
  action :run
end

#
# ハートビートの認証キー設定
#
template "/etc/heartbeat/authkeys" do
  source "authkeys.erb"
  owner "root"
  group "root"
  mode 0600
end

#
# パラメータの取り込み
#
vip_master = node["master"]["hostname"]
vip_backup = node["backup"]["hostname"]
vip_addr = node["vip"]["addr"]
vip_storage = node["vip"]["storage"]
vip_service = node["vip"]["service"]

#
# HOSTSファイルへノード名の追加
# 
master_hostname = node["master"]["hostname"]
master_ipaddr = node["master"]["ipaddr"]
hostsfile_entry "#{master_ipaddr}" do
  hostname master_hostname
  action :create
end
backup_hostname = node["backup"]["hostname"]
backup_ipaddr = node["backup"]["ipaddr"]
hostsfile_entry "#{backup_ipaddr}" do
  hostname backup_hostname
  action :create
end

#
# ハートビートの設定
#
template "/etc/heartbeat/ha.cf" do
  source "ha.cf.erb"
  owner "root"
  group "root"
  mode 0644
  variables({
    :master => vip_master,
    :backup => vip_backup,
    :peer => peer_ip,
  })
end

#
# リソースの設定
#
template "/etc/heartbeat/haresources" do
  source "haresources.erb"
  owner "root"
  group "root"
  mode 0644
  variables({
    :master => vip_master,
    :addr   => vip_addr,
    :storage => vip_storage,
    :service => vip_service,
  })
end

#
# ペースメーカー&ハートビートの開始
#
service 'heartbeat' do
  action [ :enable, :start ]
end

(4) heartbeat 認証キー

クラスタを構成するサーバー同士で同じ内容のファイルがあれば良い

auth 1
1 sha1 5692c19f3beb20008a590d05d52f59aed1f1b4fd

(5) heartbeat 設定ファイル

コメントを除いて設定だけを抜く出したものです。プラベートVLAN側の eth0 をクラスタ間の相互監視用に設定します。ソフトレイヤーでは、マルチキャストが通るので利用します。 ノード名はレシピからセットします。

debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility     local0
keepalive 2
deadtime 20
warntime 10
initdead 60
bcast   eth0    <-- eth0 プライベート側でハートビートを取ります
mcast eth0 225.0.0.1 694 1 0  <-- マルチキャスト も同じ
auto_failback off <-- 自動フェイルバック無し
node    <%= @master %>  <-- ノード名指定
node    <%= @backup %>  

(6) heartbeat リソースファイル

VIP、共有ストレージのマウントポインt、サービス名の項目ですが、すべれレシピからセットします。

<%= @master %> IPaddr::<%= @addr %> <%= @storage %> <%= @service %>

レシピの適用手順

このレシピは、物理サーバーと仮想サーバーのどちらでも対応しますが、簡単に試せる様に最小仮想サーバーでの適用例をご紹介します。次のシェルを利用して、仮想サーバーを注文します。 slcli コマンドの説明は "slcli vs create -h " で見る事ができます。

$ slcli vs list
:..........:..........:.................:...............:............:........:
:    id    : hostname :    primary_ip   :   backend_ip  : datacenter : action :
:..........:..........:.................:...............:............:........:
: 13040349 :  webap1  : 161.202.142.196 :  10.132.253.7 :   tok02    :   -    :
:..........:..........:.................:...............:............:........:

Chef Solo のリポジトリのあるサーバーから、ssh コマンドで ssh鍵を使ってログインしています。 ログインできれば、Chefでセットアップする準備の完了です。 ここでは何もしないでログアウトします。

$ ssh root@10.132.253.7 -i ~/key/chefkey
Welcome to Ubuntu 14.04.2 LTS (GNU/Linux 3.13.0-55-generic x86_64)

 * Documentation:  https://help.ubuntu.com/

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

root@webap1:~# logout

次のコマンドで、マスターとバックアップと両方に対して、chef のインスール と レシピの適用を実施します。

最初にマスター(主側)の設定をおこないます。このコマンドを実行する前に、アトリビュートのdefault[mystate]が、「MASTER」に設定されていることを確認してから実行します。

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

以下の部分に注意です。

attributes/default.rb
default["mystate"] = 'MASTER'    <--- 自ノードが主系の場合、待機系にする時はBACKUPとする

次にバックアップ(待機側)の設定をおこないます。 前述のアトリビュートのdefault[mystate]が、「BACKUP」になっていなければなりません。それからIPアドレスを間違えない様に注意が必要ですね。

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

設定完了時のメッセージでは、設定作業が16秒で完了していることがわかります。

  * service[heartbeat] action enable (up to date)
  * service[heartbeat] action start
    - start service service[heartbeat]

Running handlers:
Running handlers complete
Chef Client finished, 12/13 resources updated in 16.00316382 seconds

ifconfig コマンドで、VIPが確保している事を確認します。 以下の実行例では、eth0:0 にVIPが設定されていることが判ります。

root@node1:~# ifconfig eth0:0
eth0:0    Link encap:Ethernet  HWaddr 06:a9:3d:0e:8a:7c  
          inet addr:10.132.5.132  Bcast:10.132.5.191  Mask:255.255.255.192
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

root@node1:~# ifconfig eth0  
eth0      Link encap:Ethernet  HWaddr 06:a9:3d:0e:8a:7c  
          inet addr:10.132.253.7  Bcast:10.132.253.63  Mask:255.255.255.192
          inet6 addr: fe80::4a9:3dff:fe0e:8a7c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:84054 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15339 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:113952626 (108.6 MiB)  TX bytes:2299736 (2.1 MiB)

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

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

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

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

  • Ubuntu 14.04 64bit minimal install
  • Debian 8.1 64bit minimal install

レシピの置き場所

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

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)

参考資料

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9