2015年11月29日日曜日

[CentOS6][Ansible] EC2インスタンスで Webサーバを作成する


Ansible で EC2インスタンスのWebサーバ(CentOS6+Apache)を1台構築してみました。
自宅からAWSに接続することを前提にしています。

Ansible では以下のタスクを行います。
  • CentOS公式AMIからEC2インスタンスの作成
  • ルートパーティションの拡張(8GB ⇒ 10GB)
  • CentOS6の基本設定
    • SElinux無効化
    • ipv6無効化
    • ファイヤーウォール無効化
    • 日本語(ja_JP.UTF-8)設定
    • タイムゾーン(Asia/Tokyo)設定
  • Apache導入

AWS側は、事前に以下のリソースを用意します。
  • サブネット(パブリック)
  • セキュリティグループ(SSH、HTTPを許可)
  • キーペア


Ansibleのインストール


Ansible のインストールは以下のとおり。 
libselinux-python は、SELinuxの設定で使用します。
python-boto は EC2 の作成で使用します。
[root@node01 ~]# yum install ansible libselinux-python python-boto

Ansible のバージョンは以下のとおり
[root@node01 ~]# ansible --version
ansible 1.9.4
  configured module search path = None

Ansible プレイブックのディレクトリ構成


今回、ansible は 一般ユーザの infraユーザで実行することにしました。
Ansible のプレイブックは、ベストプラクティスを参考に以下のように配置しました。
[infra@node01 ansible]$ tree .
.
├── aws.yml
├── group_vars
├── host_vars
├── key.pem
├── production
├── roles
│   ├── apache
│   │   └── tasks
│   │       └── main.yml
│   ├── common
│   │   ├── defaults
│   │   ├── files
│   │   │   └── disable-ipv6.conf
│   │   ├── handlers
│   │   ├── meta
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   └── vars
│   │       └── main.yml
│   ├── ec2
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── vars
│   │       └── main.yml
│   └── growpart
│       ├── tasks
│       │   └── main.yml
│       └── vars
│           └── main.yml
├── site.yml
└── webservers.yml

19 directories, 13 files


Ansible プレイブックの内容


各ファイルの内容は以下のとおり。
key.pem はAWSで作成したキーペアの秘密鍵です。
CentOS6の公式AMで作成したEC2インスタンスには、この秘密鍵を使用して centos ユーザでログインします。
centosユーザはパスワードなしの sudo が使用できるようになっています。
[infra@node01 ansible]$ more * | cat -
::::::::::::::
aws.yml
::::::::::::::
- hosts: localhost
  connection: local
  gather_facts: False
  roles:
    - ec2
- hosts: webservers
  gather_facts: True
  sudo: yes
  roles:
    - growpart
::::::::::::::
key.pem
::::::::::::::
-----BEGIN RSA PRIVATE KEY-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END RSA PRIVATE KEY-----
::::::::::::::
production
::::::::::::::
[local]
localhost

[webservers:vars]
ansible_ssh_user=centos
ansible_ssh_private_key_file=/home/infra/ansible/key.pem

::::::::::::::
site.yml
::::::::::::::
- include: aws.yml
- include: webservers.yml
::::::::::::::
webservers.yml
::::::::::::::
- hosts: webservers
  gather_facts: True
  sudo: yes
  roles:
    - common
    - apache
[infra@node01 ansible]$ more */*/*/* | cat -
::::::::::::::
roles/apache/tasks/main.yml
::::::::::::::
- name: Apache のインストール
  yum: name=httpd state=latest
  tags:
    - apache

- name: Apache の自動起動ON
  service: name=httpd enabled=yes
  tags:
    - apache

- name: Apache の起動
  service: name=httpd state=started
  tags:
    - apache
::::::::::::::
roles/common/files/disable-ipv6.conf
::::::::::::::
options ipv6 disable=1
::::::::::::::
roles/common/tasks/main.yml
::::::::::::::
#-----------------------
# OS 基本設定
#-----------------------

# SElinux off
# yum install libselinux-python
- name: SELinux を無効にする
  selinux: state=disabled
  tags:
    - os_basic
    - selinux

# ipv6 off
- name: ipv6 を無効にする(/etc/sysconfig/network)
  lineinfile: >
    dest=/etc/sysconfig/network
    state=present
    backup=yes
    backrefs=no
    insertafter=EOF
    regexp='^NETWORKING_IPV6='
    line='NETWORKING_IPV6=no'
  tags:
    - os_basic
    - ipv6

- name: ipv6 を無効にする(/etc/modprobe.d/)
  copy: >
    src=disable-ipv6.conf
    dest=/etc/modprobe.d/disable-ipv6.conf
    group=root
    owner=root
    mode=0644
    backup=yes
  tags:
    - os_basic
    - ipv6

# Firewall off
- name: Firewall を無効にする
  service: name={{ item }} enabled=no
  with_items: firewall_srv
  tags:
    - os_basic
    - firewall

# LANG=ja_JP.UTF-8
- name: 日本語(ja_JP.UTF-8) にする
  lineinfile: >
    dest=/etc/sysconfig/i18n
    state=present
    backup=yes
    backrefs=no
    insertafter=EOF
    regexp='^LANG='
    line='LANG=ja_JP.UTF-8'
  tags:
    - os_basic
    - lang

# TIMEZONE=Asia/Tokyo
- name: タイムゾーンを Asia/Tokyo にする
  lineinfile: >
    dest=/etc/sysconfig/clock
    state=present
    backup=yes
    backrefs=no
    insertafter=EOF
    regexp='^ZONE='
    line='ZONE=Asia/Tokyo'
  tags:
    - os_basic
    - zone

- name: ローカルタイムを Asia/Tokyo にする
  file: >
    src=/usr/share/zoneinfo/Asia/Tokyo
    dest=/etc/localtime
    state=link
    force=yes
    owner=root
    group=root
  tags:
    - os_basic
    - zone

#-----------------------
# OS パッケージの最新化
#-----------------------

- name: yum アップデート
  yum: name=* enablerepo=epel state=latest
  tags:
    - yum_update

- name: reboot!
  command: shutdown -r now
  tags:
    - yum_update

- name: wait for SSH port down
  local_action: wait_for host={{ inventory_hostname }} port=22 state=stopped
  sudo: no
  tags:
    - yum_update

- name: wait for SSH port up
  local_action: wait_for host={{ inventory_hostname }} port=22 state=started timeout=300
  sudo: no
  tags:
    - yum_update

::::::::::::::
roles/common/vars/main.yml
::::::::::::::

firewall_srv:
 - iptables
 - ip6tables
::::::::::::::
roles/ec2/tasks/main.yml
::::::::::::::
# yum install python-boto

- name: EC2インスタンスを作成
  ec2:
    aws_access_key: "{{ aws_access_key }}"
    aws_secret_key: "{{ aws_secret_key }}"
    assign_public_ip: "{{ assign_public_ip }}"
    region: "{{region}}"
    zone: "{{zone}}"
    image: "{{ ami_image }}"
    instance_type: "{{ instance_type }}"
    key_name: "{{ key_name }}"
    group_id: "{{ sg_id }}"
    private_ip: "{{ ip }}"
    vpc_subnet_id: "{{ vpc_subnet_id }}"
    instance_tags:
      Name: "{{ hostname }}"
      System: "Test"
    wait: yes
    wait_timeout: 300
    volumes:
      - device_name: "{{ device_name }}"
        volume_size: "{{ volume_size }}"
        delete_on_termination: yes
  register: ec2
  tags:
    - ec2
#- debug: var=ec2

- name: SSHで接続できるようになるまで待機
  local_action: wait_for port=22 host={{ item.public_dns_name }} timeout=300 state=started
  with_items: ec2.instances
  when: ec2.changed == true
  tags:
    - ec2

- name: 作成したEC2インスタンスをインベントリに追加
  local_action: add_host hostname="{{ item.public_ip }}" groupname="webservers"
  with_items: ec2.instances
  when: ec2.changed == true
  tags:
    - ec2

::::::::::::::
roles/ec2/vars/main.yml
::::::::::::::

# EC2
region: us-east-1
zone: us-east-1a
aws_access_key: xxxxxxxxxxxxx
aws_secret_key: xxxxxxxxxxxxx
assign_public_ip: yes
ami_image: ami-57cd8732
key_name: keypaire
hostname: apache01
ip: 10.0.0.11
vpc_subnet_id: "subnet-xxxx"
sg_id: [ "sg-xxxx", "sg-xxxx" ]
instance_type: "t2.micro"
device_name: "/dev/sda1"
volume_size: 10

::::::::::::::
roles/growpart/tasks/main.yml
::::::::::::::
# ルートパーティション拡張
- name: epel レポジトリのインストール
  yum: name=epel-release state=latest
  tags:
    - growpart

- name: yum パッケージのインストール
  yum: name={{ item }} enablerepo=epel state=latest
  with_items: grow_part_pkg
  tags:
    - growpart

- name: パーティション拡張の指示
  shell: "dracut --force --add growroot /boot/initramfs-$(uname -r).img"
  register: dracut
  ignore_errors: true
  changed_when: false
  tags:
    - growpart

- name: reboot!
  command: shutdown -r now
  tags:
    - growpart

- name: wait for SSH port down
  local_action: wait_for host={{ inventory_hostname }} port=22 state=stopped
  sudo: no
  tags:
    - growpart

- name: wait for SSH port up
  local_action: wait_for host={{ inventory_hostname }} port=22 state=started timeout=300
  sudo: no
  tags:
    - growpart

::::::::::::::
roles/growpart/vars/main.yml
::::::::::::::
grow_part_pkg:
 - cloud-utils-growpart
 - dracut-modules-growroot
[infra@node01 ansible]$

イベントリ(puroduction)の webservers グループには、ホスト(IPアドレス)を指定していませんが、EC2作成時に自動的にIPアドレスが追加されるようにしています。
プレイブック実行時に、作成したEC2インスタンスのパブリックIPがwebsrversグループに追加され、後続の処理では、追加されたIPアドレスに対してタスクを実行します。

Ansibleプレイブックのタスク一覧


このプレイブックが実施するタスクは以下のとおり。
上から順番に実行されます。
[infra@node01 ansible]$ ansible-playbook site.yml -i production --list-tasks

playbook: site.yml

  play #1 (localhost):  TAGS: []
    EC2インスタンスを作成       TAGS: [ec2]
    SSHで接続できるようになるまで待機   TAGS: [ec2]
    作成したEC2インスタンスをインベントリに追加 TAGS: [ec2]

  play #2 (webservers): TAGS: []
    epel レポジトリのインストール       TAGS: [growpart]
    yum パッケージのインストール        TAGS: [growpart]
    パーティション拡張の指示    TAGS: [growpart]
    reboot!     TAGS: [growpart]
    wait for SSH port down      TAGS: [growpart]
    wait for SSH port up        TAGS: [growpart]

  play #3 (webservers): TAGS: []
    SELinux を無効にする        TAGS: [os_basic, selinux]
    ipv6 を無効にする(/etc/sysconfig/network)   TAGS: [ipv6, os_basic]
    ipv6 を無効にする(/etc/modprobe.d/) TAGS: [ipv6, os_basic]
    Firewall を無効にする       TAGS: [firewall, os_basic]
    日本語(ja_JP.UTF-8) にする  TAGS: [lang, os_basic]
    タイムゾーンを Asia/Tokyo にする    TAGS: [os_basic, zone]
    ローカルタイムを Asia/Tokyo にする  TAGS: [os_basic, zone]
    yum アップデート    TAGS: [yum_update]
    reboot!     TAGS: [yum_update]
    wait for SSH port down      TAGS: [yum_update]
    wait for SSH port up        TAGS: [yum_update]
    Apache のインストール       TAGS: [apache]
    Apache の自動起動ON TAGS: [apache]
    Apache の起動       TAGS: [apache]



Ansible実行(checkモード)


実際に変更は行わないようにして実行して、動きを確認してみます。
[infra@node01 ansible]$ ansible-playbook site.yml -i production --check

PLAY [localhost] **************************************************************

TASK: [ec2 | EC2インスタンスを作成] **********************************
skipping: [localhost]
ok: [localhost]

TASK: [ec2 | SSHで接続できるようになるまで待機] ****************
skipping: [localhost] => (item=ec2.instances)

TASK: [ec2 | 作成したEC2インスタンスをインベントリに追加] ***
skipping: [localhost] => (item=ec2.instances)

PLAY [webservers] *************************************************************
skipping: no hosts matched

PLAY [webservers] *************************************************************
skipping: no hosts matched

PLAY RECAP ********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0

[infra@node01 ansible]$

実際にEC2インスタンスを作成しないとイベントリにIPアドレスが追加されないので、webservers グループのタスクは実行されません。

Ansible実行


今度は、実際に変更を行います。
途中、EC2インスタンスに初めてSSHログインするタイミングで、接続確認入力を求められるので "yes" を入力します。
[infra@node01 ansible]$ ansible-playbook site.yml -i production

PLAY [localhost] **************************************************************

TASK: [ec2 | EC2インスタンスを作成] **********************************
changed: [localhost]

TASK: [ec2 | SSHで接続できるようになるまで待機] ****************
ok: [localhost -> 127.0.0.1] => (item={u'ramdisk': None, u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-10-0-0-11.ec2.internal', u'tags': {}, u'key_name': u'virginia_key', u'public_ip': u'52.23.158.7', u'image_id': u'ami-57cd8732', u'tenancy': u'default', u'private_ip': u'10.0.0.11', u'groups': {u'sg-bbf176df': u'default', u'sg-01237c67': u'webgroup'}, u'public_dns_name': u'ec2-52-23-158-7.compute-1.amazonaws.com', u'state_code': 16, u'id': u'i-a6f60810', u'placement': u'us-east-1a', u'ami_launch_index': u'0', u'dns_name': u'ec2-52-23-158-7.compute-1.amazonaws.com', u'region': u'us-east-1', u'ebs_optimized': False, u'launch_time': u'2015-11-29T04:24:40.000Z', u'instance_type': u't2.micro', u'state': u'running', u'root_device_name': u'/dev/sda1', u'hypervisor': u'xen', u'virtualization_type': u'hvm', u'architecture': u'x86_64'})

TASK: [ec2 | 作成したEC2インスタンスをインベントリに追加] ***
ok: [localhost -> 127.0.0.1] => (item={u'ramdisk': None, u'kernel': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-10-0-0-11.ec2.internal', u'tags': {}, u'key_name': u'virginia_key', u'public_ip': u'52.23.158.7', u'image_id': u'ami-57cd8732', u'tenancy': u'default', u'private_ip': u'10.0.0.11', u'groups': {u'sg-bbf176df': u'default', u'sg-01237c67': u'webgroup'}, u'public_dns_name': u'ec2-52-23-158-7.compute-1.amazonaws.com', u'state_code': 16, u'id': u'i-a6f60810', u'placement': u'us-east-1a', u'ami_launch_index': u'0', u'dns_name': u'ec2-52-23-158-7.compute-1.amazonaws.com', u'region': u'us-east-1', u'ebs_optimized': False, u'launch_time': u'2015-11-29T04:24:40.000Z', u'instance_type': u't2.micro', u'state': u'running', u'root_device_name': u'/dev/sda1', u'hypervisor': u'xen', u'virtualization_type': u'hvm', u'architecture': u'x86_64'})

PLAY [webservers] *************************************************************

GATHERING FACTS ***************************************************************
The authenticity of host '52.23.158.7 (52.23.158.7)' can't be established.
RSA key fingerprint is d8:8c:b2:3d:dd:d8:c3:7b:29:ec:41:72:29:ca:da:bf.
Are you sure you want to continue connecting (yes/no)? yes
ok: [52.23.158.7]

TASK: [growpart | epel レポジトリのインストール] ******************
changed: [52.23.158.7]

TASK: [growpart | yum パッケージのインストール] *******************
changed: [52.23.158.7] => (item=cloud-utils-growpart,dracut-modules-growroot)

TASK: [growpart | パーティション拡張の指示] ***********************
ok: [52.23.158.7]

TASK: [growpart | reboot!] ****************************************************
changed: [52.23.158.7]

TASK: [growpart | wait for SSH port down] *************************************
ok: [52.23.158.7 -> 127.0.0.1]

TASK: [growpart | wait for SSH port up] ***************************************
ok: [52.23.158.7 -> 127.0.0.1]

PLAY [webservers] *************************************************************

GATHERING FACTS ***************************************************************
ok: [52.23.158.7]

TASK: [common | SELinux を無効にする] ***********************************
changed: [52.23.158.7]

TASK: [common | ipv6 を無効にする(/etc/sysconfig/network)] **************
changed: [52.23.158.7]

TASK: [common | ipv6 を無効にする(/etc/modprobe.d/)] ********************
changed: [52.23.158.7]

TASK: [common | Firewall を無効にする] **********************************
changed: [52.23.158.7] => (item=iptables)
changed: [52.23.158.7] => (item=ip6tables)

TASK: [common | 日本語(ja_JP.UTF-8) にする] *****************************
changed: [52.23.158.7]

TASK: [common | タイムゾーンを Asia/Tokyo にする] *******************
changed: [52.23.158.7]

TASK: [common | ローカルタイムを Asia/Tokyo にする] ****************
changed: [52.23.158.7]

TASK: [common | yum アップデート] ***************************************
changed: [52.23.158.7]

TASK: [common | reboot!] ******************************************************
changed: [52.23.158.7]

TASK: [common | wait for SSH port down] ***************************************
ok: [52.23.158.7 -> 127.0.0.1]

TASK: [common | wait for SSH port up] *****************************************
ok: [52.23.158.7 -> 127.0.0.1]

TASK: [apache | Apache のインストール] *********************************
changed: [52.23.158.7]

TASK: [apache | Apache の自動起動ON] *************************************
changed: [52.23.158.7]

TASK: [apache | Apache の起動] *********************************************
changed: [52.23.158.7]

PLAY RECAP ********************************************************************
52.23.158.7                : ok=22   changed=15   unreachable=0    failed=0
localhost                  : ok=3    changed=1    unreachable=0    failed=0

[infra@node01 ansible]$

動作確認


EC2インスタンスにログインして、パーティションの拡張や、OS設定が成功しているか確認します。
[centos@ip-10-0-0-11 ~]$ getenforce
Disabled
[centos@ip-10-0-0-11 ~]$ lsblk
NAME    MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
xvda    202:0    0  10G  0 disk
└─xvda1 202:1    0  10G  0 part /
[centos@ip-10-0-0-11 ~]$ df -Th
Filesystem     Type   Size  Used Avail Use% Mounted on
/dev/xvda1     ext4   9.8G  867M  8.4G  10% /
tmpfs          tmpfs  498M     0  498M   0% /dev/shm
[centos@ip-10-0-0-11 ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc pfifo_fast state UP qlen 1000
    link/ether 0a:7f:41:05:7d:b5 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.11/24 brd 10.0.0.255 scope global eth0
[centos@ip-10-0-0-11 ~]$ date
2015年 11月 29日 日曜日 13:40:06 JST
[centos@ip-10-0-0-11 ~]$ chkconfig | grep iptables
iptables        0:off   1:off   2:off   3:off   4:off   5:off   6:off
[centos@ip-10-0-0-11 ~]$ chkconfig | grep ip6tables
ip6tables       0:off   1:off   2:off   3:off   4:off   5:off   6:off
[centos@ip-10-0-0-11 ~]$ chkconfig | grep httpd
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off
[centos@ip-10-0-0-11 ~]$ curl -I http://localhost
HTTP/1.1 403 Forbidden
Date: Sun, 29 Nov 2015 04:40:39 GMT
Server: Apache/2.2.15 (CentOS)
Accept-Ranges: bytes
Content-Length: 4961
Connection: close
Content-Type: text/html; charset=UTF-8

[centos@ip-10-0-0-11 ~]$

パーティションも10GBに拡張され、OS設定も成功しています。


◆ 補足

あとで、Webサーバの変更をしたい場合は、イベントリ(production)の webserversグループにEC2インスタンスのIPアドレスを記載します。
以下のように webservers グループだけ指定したり、タグを指定したりして一部のタスクのみ実行できます。

[infra@node01 ansible]$ ansible-playbook site.yml -i production -l webservers
[infra@node01 ansible]$ ansible-playbook site.yml -i production --tags os_basic












2015年11月12日木曜日

[CentOS6] yum と gem で serverspec をインストールする


CentOS6.7 に yum と gem で serverspec をインストールします。

まず、 yum で ruby と rubygems をいれます。
[root@localhost ~]# yum install ruby rubygems

つぎに、gem で serverspec をいれようとすると以下のようにエラーになりました。
[root@localhost ~]# gem install serverspec
ERROR:  Error installing serverspec:
       net-ssh requires Ruby version >= 2.0.


最新の net-ssh は、ruby2.0 以上が必要みたいですが、CentOS6.7 の ruby は 1.8.7 です。
[root@localhost ~]# ruby -v
ruby 1.8.7 (2013-06-27 patchlevel 374) [x86_64-linux]

インストール可能な net-ssh のバージョンを確認すると以下のとおり。
[root@localhost ~]# gem list net-ssh -ar

*** REMOTE GEMS ***

net-ssh (3.0.1, 2.9.2, 2.9.1, 2.9.0, 2.8.0, 2.7.0, 2.6.8, 2.6.7, 2.6.6, 2.6.5, 2.6.4, 2.6.3, 2.6.2, 2.6.1, 2.6.0, 2.5.2, 2.5.1, 2.5.0, 2.4.0, 2.3.0, 2.2.2, 2.2.1, 2.2.0, 2.1.4, 2.1.3, 2.1.0, 2.0.24, 2.0.23, 2.0.22, 2.0.21, 2.0.20, 2.0.19, 2.0.18, 2.0.17, 2.0.16, 2.0.15, 2.0.14, 2.0.13, 2.0.11, 2.0.10, 2.0.9, 2.0.8, 2.0.7, 2.0.6, 2.0.5, 2.0.4, 2.0.3, 2.0.2, 2.0.1, 2.0.0, 1.1.4, 1.1.3, 1.1.2, 1.1.1, 1.1.0, 1.0.10, 1.0.9, 1.0.8, 1.0.7, 1.0.6, 1.0.5, 1.0.4, 1.0.3, 1.0.2, 1.0.1, 1.0.0, 0.9.0, 0.6.0, 0.5.0)
net-ssh-askpass (0.0.3)
net-ssh-gateway (1.2.0, 1.1.0, 1.0.1, 1.0.0)
net-ssh-kerberos (0.2.7, 0.2.6, 0.2.5, 0.2.4, 0.2.3, 0.2.2, 0.2.1, 0.2.0, 0.1.3, 0.1.2, 0.1.0)
net-ssh-krb (0.4.0, 0.3.0)
net-ssh-multi (1.2.1, 1.2.0, 1.1, 1.0.1, 1.0.0)
net-ssh-net-ssh (2.0.14, 2.0.13, 2.0.12)
net-ssh-ng (2.10.2.1, 2.10.2, 2.10.1, 2.10.0, 2.9.1)
net-ssh-open3 (0.1.6, 0.1.5, 0.1.4, 0.1.3, 0.1.2)
net-ssh-plus (0.0.2, 0.0.1)
net-ssh-session (0.1.6, 0.1.5, 0.1.4, 0.1.3, 0.1.2, 0.1.1, 0.1.0)
net-ssh-shell (0.2.0, 0.1.0)
net-ssh-simple (1.6.12, 1.6.11, 1.6.10, 1.6.9, 1.6.8, 1.6.7, 1.6.6, 1.6.5, 1.6.4, 1.6.3, 1.6.2, 1.6.1, 1.6.0, 1.5.9, 1.5.8, 1.5.4, 1.5.3, 1.5.2, 1.5.1, 1.5.0, 1.4.5, 1.4.1, 1.4.0, 1.3.2, 1.3.1, 1.3.0, 1.2.1, 1.2.0, 1.1.1, 1.1.0, 1.0.1, 1.0.0, 0.9.0)
net-ssh-socks (0.0.2, 0.0.1)
net-ssh-telnet (0.0.2, 0.0.1)

とりあえず、先に net-ssh だけ、古いバージョン(2.9.2)を入れます。
[root@localhost ~]# gem install net-ssh --version "=2.9.2"
Successfully installed net-ssh-2.9.2
1 gem installed
Installing ri documentation for net-ssh-2.9.2...
Installing RDoc documentation for net-ssh-2.9.2...

これで、serverspec が入ります
[root@localhost ~]# gem install serverspec
Successfully installed net-scp-1.2.1
Successfully installed net-telnet-0.1.1
Successfully installed sfl-2.2
Successfully installed specinfra-2.44.1
Successfully installed serverspec-2.24.2
5 gems installed
Installing ri documentation for net-scp-1.2.1...
Installing ri documentation for net-telnet-0.1.1...
Installing ri documentation for sfl-2.2...
Installing ri documentation for specinfra-2.44.1...
Installing ri documentation for serverspec-2.24.2...
Installing RDoc documentation for net-scp-1.2.1...
Installing RDoc documentation for net-telnet-0.1.1...
Installing RDoc documentation for sfl-2.2...
Installing RDoc documentation for specinfra-2.44.1...
Installing RDoc documentation for serverspec-2.24.2...

最後に rake をいれます。
[root@localhost ~]# gem install rake
Successfully installed rake-10.4.2
1 gem installed
Installing ri documentation for rake-10.4.2...
Installing RDoc documentation for rake-10.4.2...










2015年11月3日火曜日

[CentOS7] Pacemaker + DRBD (Apacheクラスタ)


前回までの記事で、Pacemaker に Apache関連のリソースを登録し、stonith も実装しました。

今回は、pm01とpm02のディスクをDRBDでミラーして、Apacheのドキュメントルートを2台で共有するようにします。
これで、フェイルオーバしても、Apache は同じ情報を提供できるし、リリース先も稼働系だけでOKになります。

環境は以下のとおり。
サーバはXenServer6.5の仮想マシンです。
  • pm01: 10.1.0.71
  • pm02: 10.1.0.72
  • drbd用ディスク: /dev/xvdb


1.DRBDを導入する


1.1.DRBDをインストールする


DRBDは、ppm01とpm02に yum でインストールします。
以下にようにDRBD用にレポジトリを登録してインストールします。
[root@pm01 ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
[root@pm01 ~]# yum install http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
[root@pm01 ~]# yum install drbd84-utils kmod-drbd84
[root@pm02 ~]# rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
[root@pm02 ~]# yum install http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
[root@pm02 ~]# yum install drbd84-utils kmod-drbd84

1.1.DRBD用のボリューム(ディスク)を用意する


DRBD用に pm01とpm02 に新規でディスクを追加しました。
XenServer の仮想マシンの場合は、パーティションを切らなくてもファイルシステムを作成できるので、パーティションはきりません。
以下は、pm01 の例ですが、/dev/xvdb が DRBD 用です。
pm02 も同じ構成にします。
[root@pm01 ~]# lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvda    202:0    0    8G  0 disk
├─xvda1 202:1    0  500M  0 part /boot
└─xvda2 202:2    0  7.5G  0 part /
xvdb    202:16   0    2G  0 disk
[root@pm01 ~]# fdisk -l /dev/xvdb

Disk /dev/xvdb: 2147 MB, 2147483648 bytes, 4194304 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O サイズ (最小 / 推奨): 512 バイト / 512 バイト

1.2.DRBDのレポジトリ設定


DRBDのレポジトリを設定します。
pm01 の /etc/drbd.d/drbd0.res に以下の内容を記載します。
[root@pm01 ~]# cat /etc/drbd.d/drbd0.res
resource drbd0 {
        protocol C;

        disk /dev/xvdb;
        device /dev/drbd0;
        meta-disk internal;
        on pm01 {
                address 10.1.0.71:7789;
        }
        on pm02 {
                address 10.1.0.72:7789;
        }
}
同じファイルを pm02 にコピーします。
[root@pm01 ~]# scp -p /etc/drbd.d/drbd0.res pm02:/etc/drbd.d/.
pm01とpm02で /dev/xvdb にメタデータを書き込んで初期化します。
[root@pm01 ~]# drbdadm create-md drbd
~省略~
you are the 1574th user to install this version
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.
success
[root@pm02 ~]# drbdadm create-md drbd
~省略~
you are the 9920th user to install this version
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.
success 
pm01とpm02でリソースを有効にします。
[root@pm01 ~]# drbdadm up drbd0
[root@pm01 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R7, 2015-04-10 05:13:52
 0: cs:WFConnection ro:Secondary/Unknown ds:Inconsistent/DUnknown C r----s
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:2097052
[root@pm02 ~]# drbdadm up drbd0
[root@pm02 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R7, 2015-04-10 05:13:52
 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
    ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:2097052
同期を開始します。
pm01をプライマリとして同期したいので pm01 で以下のように drbdadm を実行し、cat で同期の状態を見ます。
[root@pm01 ~]# drbdadm primary --force drbd0
[root@pm01 ~]#  cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R7, 2015-04-10 05:13:52
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:19356 nr:0 dw:0 dr:20084 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:2077696
        [>....................] sync'ed:  1.0% (2077696/2097052)K
        finish: 0:10:36 speed: 3,224 (3,224) K/sec
同期が完了すると以下のように表示されます。
[root@pm01 ~]#  cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by phil@Build64R7, 2015-04-10 05:13:52
 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:2097052 nr:0 dw:0 dr:2097780 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
drbd-overview で見た drbd の状態は以下のとおり。
pm01 がプライマリで pm02 がセカンダリになり、pm01 ⇒ pm02の方向に同期されます。
[root@pm01 ~]# drbd-overview
 0:drbd0/0  Connected Primary/Secondary UpToDate/UpToDate
[root@pm02 ~]# drbd-overview
 0:drbd0/0  Connected Secondary/Primary UpToDate/UpToDate

1.3.ファイルシステムの作成


pm01 で DRBD用のボリュームにファイルシステムを作成します。
[root@pm01 ~]# mkfs.ext4 /dev/drbd0
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
131072 inodes, 524263 blocks
26213 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=536870912
16 block groups
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
        32768, 98304, 163840, 229376, 294912

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
マウントして、試しにディレクトリとファイルを作成してみます。
[root@pm01 ~]# mount /dev/drbd0 /mnt
[root@pm01 ~]# mkdir /mnt/test
[root@pm01 ~]# touch /mnt/xx0
[root@pm01 ~]# ls -l /mnt
合計 20
drwx------ 2 root root 16384 11月  3 08:49 lost+found
drwxr-xr-x 2 root root  4096 11月  3 08:49 test
-rw-r--r-- 1 root root     0 11月  3 08:50 xx0
[root@pm01 ~]# mount | grep drbd0
/dev/drbd0 on /mnt type ext4 (rw,relatime,data=ordered)
[root@pm01 ~]# df -Th
ファイルシス   タイプ   サイズ  使用  残り 使用% マウント位置
/dev/xvda2     ext4       7.3G  1.4G  5.6G   20% /
devtmpfs       devtmpfs   476M     0  476M    0% /dev
tmpfs          tmpfs      495M     0  495M    0% /dev/shm
tmpfs          tmpfs      495M   13M  483M    3% /run
tmpfs          tmpfs      495M     0  495M    0% /sys/fs/cgroup
/dev/xvda1     ext3       477M   66M  387M   15% /boot
/dev/drbd0     ext4       2.0G  6.1M  1.9G    1% /mnt

1.4.手動のフェイルオーバ


手動でフェイルオーバさせてみます。
まず、pm01 をセカンダリにします。
[root@pm01 ~]# umount /mnt
[root@pm01 ~]# drbdadm secondary drbd0
[root@pm01 ~]# drbd-overview
 0:drbd0/0  Connected Secondary/Secondary UpToDate/UpToDate
次に、pm02 をプライマリにして、ファイルが見えるか確認します。
[root@pm02 ~]# drbdadm primary drbd0
[root@pm02 ~]# mount /dev/drbd0 /mnt
[root@pm02 ~]# ls -l /mnt
合計 20
drwx------ 2 root root 16384 11月  3 08:49 lost+found
drwxr-xr-x 2 root root  4096 11月  3 08:49 test
-rw-r--r-- 1 root root     0 11月  3 08:50 xx0
[root@pm02 ~]# drbd-overview
 0:drbd0/0  Connected Primary/Secondary UpToDate/UpToDate /mnt ext4 2.0G 6.1M 1.9G 1%
[root@pm02 ~]#

2.Apacheのドキュメントルートを変更する


Apacheのドキュメントルート(/var/www/html)を変更します。
設定ファイルを変更してもよかったのですが、今回は、DRBD用のボリュームにシンボリックリンクしました。
pm01 と pm02 でドキュメントルートを変更します。
[root@pm01 ~]# cd /var/www/
[root@pm01 www]# ls
cgi-bin  html
[root@pm01 www]# mv html html_BK
[root@pm01 www]# ln -s /mnt ./html
[root@pm01 www]# ls -l
合計 8
drwxr-xr-x 2 root root 4096  8月 25 03:12 cgi-bin
lrwxrwxrwx 1 root root    4 11月  3 10:07 html -> /mnt
drwxr-xr-x 2 root root 4096  8月 25 03:12 html_BK
あとで、動作確認できるように、テスト用のページも作成します。
pm01 を DRBD のプライマリにして、/mnt/index.html を作成します。
内容は以下のとおり。
[root@pm01 www]# cat /mnt/index.html
<html>
<head>
<title>TEST PAGE</title>
</head>
<body>
<h1>TEST PAGE</h1>
</body>
</html>

3.PacemakerにDRBDのリソースを登録する


DRBDのサービスを有効にするリソースを登録します。
[root@pm01 ~]# pcs resource create drbd0_res ocf:linbit:drbd params drbd_resource="drbd0"
DRBDのサービスをマスタ/スレーブにします。
[root@pm01 ~]# pcs resource master ms_drbd0 drbd0_res master-max=1 master-node-max=1 clone-max=2 clone-node-max=1 notify=true
DRBD用のボリュームをマウントするリソースを登録します。
[root@pm01 ~]# pcs resource create fsdrbd0_res Filesystem device=/dev/drbd0 directory=/mnt fstype=ext4
DRBDのマウントがマスタで動くようにします。
[root@pm01 ~]# pcs constraint colocation add fsdrbd0_res ms_drbd0 INFINITY with-rsc-role=Master
[root@pm01 ~]# pcs constraint order promote ms_drbd0 then start fsdrbd0_res
Adding ms_drbd0 fsdrbd0_res (kind: Mandatory) (Options: first-action=promote then-action=start)
リソースグループを変更します。
drbdのマウントをWebGroupに入れて、VIPチェックの次に起動するようにします。
[root@pm01 ~]# pcs resource group remove WebGroup vipcheck_res vip_res httpd_res
[root@pm01 ~]# pcs resource group add WebGroup vipcheck_res fsdrbd0_res vip_res httpd_res
クラスタの状態を確認します。
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Tue Nov  3 10:49:35 2015          Last change: Tue Nov  3 10:46:21 2015 by root via crm_attribute on pm02
Stack: corosync
Current DC: pm02 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 10 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]
 fence_pm01     (stonith:fence_xenapi): Started pm02
 fence_pm02     (stonith:fence_xenapi): Started pm01
 Master/Slave Set: ms_drbd0 [drbd0_res]
     Masters: [ pm01 ]
     Slaves: [ pm02 ]
 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm01
     fsdrbd0_res        (ocf::heartbeat:Filesystem):    Started pm01
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm01
     httpd_res  (ocf::heartbeat:apache):        Started pm01

PCSD Status:
  pm01: Online
  pm02: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

4.動作確認


まずは、pm01 が稼働系の場合に、VIPにアクセスしてテストページが表示できることを確認します。
[root@pm01 ~]# pcs status resources
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]
 Master/Slave Set: ms_drbd0 [drbd0_res]
     Masters: [ pm01 ]
     Slaves: [ pm02 ]
 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started
     fsdrbd0_res        (ocf::heartbeat:Filesystem):    Started
     vip_res    (ocf::heartbeat:IPaddr2):       Started
     httpd_res  (ocf::heartbeat:apache):        Started
[root@pm01 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 4a:73:98:ab:45:82 brd ff:ff:ff:ff:ff:ff
    inet 10.1.0.71/32 brd 10.1.0.71 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.1.0.70/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::4873:98ff:feab:4582/64 scope link
       valid_lft forever preferred_lft forever
[root@pm01 ~]# curl http://10.1.0.70
<html>
<head>
<title>TEST PAGE</title>
</head>
<body>
<h1>TEST PAGE</h1>
</body>
</html>
[root@pm01 ~]#
手動でフェイルオーバさせます。
[root@pm01 ~]# pcs cluster standby pm01
VIPにアクセスしてテストページが見えることを確認します。
[root@pm01 ~]# pcs status resources
 Clone Set: ping-clone [ping]
     Started: [ pm02 ]
     Stopped: [ pm01 ]
 Master/Slave Set: ms_drbd0 [drbd0_res]
     Masters: [ pm02 ]
     Stopped: [ pm01 ]
 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started
     fsdrbd0_res        (ocf::heartbeat:Filesystem):    Started
     vip_res    (ocf::heartbeat:IPaddr2):       Started
     httpd_res  (ocf::heartbeat:apache):        Started
[root@pm01 ~]# curl http://10.1.0.70
<html>
<head>
<title>TEST PAGE</title>
</head>
<body>
<h1>TEST PAGE</h1>
</body>
</html>
[root@pm01 ~]# 


2015年11月1日日曜日

[CentOS7] Pacemaker に stonith を実装する(fence_xenapi)


前回までに リソースを登録して、Apacheクラスタ(Active/Standby)を構築しました。

今回は、stonith を実装します。 stonith については下記URLが参考になります。
私の検証環境は、XenServer6.5 の仮想マシンです。
XenServer用の fence デバイスを使って stonith を実装します。
環境は以下のとおり。
  • pm01(L81pm01): 10.1.0.71
  • pm02(L82pm02): 10.1.0.72
  • XenServerホスト(Dom0): 192.168.1.100


1.fence_xenapi の導入


pm01 と pm02 に fence_xenapi をインストールします。

fence_agent のパッケージをインストールします。
[root@pm01 ~]# yum install fence-agents-all
下記URLから fence_xenapi をダウンロードします。
ダウンロードしたファイルを、/usr/sbin/fence_xenapi に保存して、実行権限をつけます。
[root@pm01 ~]# vi /usr/sbin/fence_xenapi
[root@pm01 ~]# chmod 755 /usr/sbin/fence_xenapi
下記URLから XenAPI をダウンロードします。
ダウンロードしたファイルを、/usr/sbin/XenAPI.py に保存します。
[root@pm01 ~]# vi /usr/sbin/XenAPI.py
動作を確認します。
以下のように実行して、仮想マシンのステータスを表示できればOKです。
[root@pm01 ~]# fence_xenapi -l root -p <パスワード> -o status -s https://192.168.1.100 -n L80pm01
Status: ON

2.stonith の設定


pm01 をリブートする stonith を登録します。
相打ちにならないように delay を設定します。
[root@pm01 ~]# pcs stonith create fence_pm01 fence_xenapi session_url="https://192.168.1.100" action="reboot" login="root" passwd_script="/root/xs.pw" port="L80pm01" delay=15 pcmk_host_list=pm01 pcmk_host_check=static-list pcmk_host_map="" op monitor interval=60s
pm02 をリブートする stonith を登録します。
[root@pm01 ~]# pcs stonith create fence_pm02 fence_xenapi session_url="https://192.168.1.100" action="reboot" login="root" passwd_script="/root/xs.pw" port="L81pm02" pcmk_host_list=pm02 pcmk_host_check=static-list pcmk_host_map="" op monitor interval=60s
stonith では、自ノードをリブートしない。相手をリブートするようにします。
fence_pm01 を pm01 以外で起動するように設定します。
[root@pm01 ~]# pcs constraint location fence_pm01 prefers pm01="-INFINITY"
fence_pm02 を pm02 以外で起動するように設定します。
[root@pm01 ~]# pcs constraint location fence_pm02 prefers pm02="-INFINITY"
stonith を有効にします。
[root@pm01 ~]# pcs property set stonith-enabled=true
状態を確認します。
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 16:52:16 2015          Last change: Sun Nov  1 14:49:56 2015 by root via cibadmin on pm02
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 7 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm01
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm01
     httpd_res  (ocf::heartbeat:apache):        Started pm01
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]
 fence_pm01     (stonith:fence_xenapi): Started pm02
 fence_pm02     (stonith:fence_xenapi): Started pm01

PCSD Status:
  pm01: Online
  pm02: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

3.動作確認


手動でフェンシングを発動します。
以下のように実行して pm02 がリブートされたらOKです。
[root@pm01 ~]# stonith_admin --reboot pm02

ハートビートを遮断してみます。
pm01 で以下のように実行します。
[root@pm01 ~]# iptables -I INPUT -p all -j DROP -s 10.1.0.72
pm02 がリブートされます。
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 16:57:43 2015          Last change: Sun Nov  1 14:49:56 2015 by root via cibadmin on pm02
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 7 resources configured

Node pm02: UNCLEAN (offline)
Online: [ pm01 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm01
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm01
     httpd_res  (ocf::heartbeat:apache):        Started pm01
 Clone Set: ping-clone [ping]
     ping       (ocf::pacemaker:ping):  Started pm02 (UNCLEAN)
     Started: [ pm01 ]
 fence_pm01     (stonith:fence_xenapi): Started pm02 (UNCLEAN)
 fence_pm02     (stonith:fence_xenapi): Started pm01

PCSD Status:
  pm01: Online


[CentOS7] Pacemaker のリソースの動作確認(Apacheのクラスタ)


前回は、Pacemaker にリソースを登録して、Apacheクラスタを構築しました。

今回は、Pacemaker の動作確認をします。


1.クラスタ状態の確認


"pcs status" で状態を見ようとしたところ、反応が鈍くて、下記表示で少し待ちます。
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 08:43:48 2015          Last change: Sun Nov  1 08:42:10 2015 by root via crm_resource on pm02
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 5 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm01
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm01
     httpd_res  (ocf::heartbeat:apache):        Started pm01
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]

PCSD Status:
  pm01: Online

VIPのDNSの逆ひきで遅くなってたようなので、pm01とpm02の hosts にVIPを登録したら、反応が良くなりました。
10.1.0.70   pm00
10.1.0.71   pm01
10.1.0.72   pm02

なお、もう一つ、検証時に使える確認方法があります。
"crm_mon" コマンドを使用すると、クラスタの状態をリアルタイムで監視できます。



pm01 の仮想IPアドレスは以下のとおり。
[root@pm01 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 4a:73:98:ab:45:82 brd ff:ff:ff:ff:ff:ff
    inet 10.1.0.71/32 brd 10.1.0.71 scope global eth0
       valid_lft forever preferred_lft forever
    inet 10.1.0.70/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::4873:98ff:feab:4582/64 scope link
       valid_lft forever preferred_lft forever
Apacheのプロセスは以下のとおり。
[root@pm01 ~]# ps -ef | grep httpd
root     17503     1  0 09:56 ?        00:00:00 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run//httpd.pid
apache   17506 17503  0 09:56 ?        00:00:00 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run//httpd.pid
apache   17507 17503  0 09:56 ?        00:00:00 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run//httpd.pid
apache   17509 17503  0 09:56 ?        00:00:00 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run//httpd.pid
apache   17510 17503  0 09:56 ?        00:00:00 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run//httpd.pid
apache   17512 17503  0 09:56 ?        00:00:00 /sbin/httpd -DSTATUS -f /etc/httpd/conf/httpd.conf -c PidFile /var/run//httpd.pid
root     17935  2102  0 09:57 pts/0    00:00:00 grep --color=auto httpd

2.ApacheプロセスKILLによるF/Oの確認


Apache のプロセスを KILL してF/Oするかどうか確認します。
以下のようにして pm01 で httpd をKILLします。
[root@pm01 ~]# pkill httpd
しばらく待つと、以下のように pm02 にフェイルオーバしました。
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 09:53:00 2015          Last change: Sun Nov  1 09:45:44 2015 by root via crm_attribute on pm01
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 5 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm02
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm02
     httpd_res  (ocf::heartbeat:apache):        Started pm02
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]

Failed Actions:
* httpd_res_monitor_10000 on pm01 'not running' (7): call=139, status=complete, exitreason='none',
    last-rc-change='Sun Nov  1 09:51:23 2015', queued=0ms, exec=0ms


PCSD Status:
  pm01: Online
  pm02: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled
リソース再起動の回数を変えて、もう一度試してみます。
まず、エラーをクリアします。
[root@pm01 ~]# pcs resource cleanup httpd_res
Resource: httpd_res successfully cleaned up
次にリソースを pm01 に戻します。
pm02 を OFFLINE にして、リソースの移動を確認した後、ONLINEにもどします。
[root@pm01 ~]# rpcs cluster standby pm02
[root@pm01 ~]# pcs status
[root@pm01 ~]# pcs cluster unstandby pm02
リソースの再起動回数を "2" にします。
[root@pm01 ~]# pcs resource defaults resource-stickiness=INFINITY migration-threshold=2
これで、再テストできるようになったので、また、httpd を KILL します。
今度は、pm01 で httpd が再起動されました。
[root@pm01 ~]# pkill httpd
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 10:25:16 2015          Last change: Sun Nov  1 10:24:51 2015 by root via crm_attribute on pm01
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 5 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm01
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm01
     httpd_res  (ocf::heartbeat:apache):        Started pm01
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]

Failed Actions:
* httpd_res_monitor_10000 on pm01 'not running' (7): call=271, status=complete, exitreason='none',
    last-rc-change='Sun Nov  1 10:25:12 2015', queued=0ms, exec=0ms


PCSD Status:
  pm01: Online
  pm02: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled
この状態で、また、httpd をKILL すると、こんどは、pm02 にF/Oしました。
[root@pm01 ~]# pkill httpd
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 10:26:11 2015          Last change: Sun Nov  1 10:24:51 2015 by root via crm_attribute on pm01
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 5 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm02
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm02
     httpd_res  (ocf::heartbeat:apache):        Started pm02
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]

Failed Actions:
* httpd_res_monitor_10000 on pm01 'not running' (7): call=275, status=complete, exitreason='none',
    last-rc-change='Sun Nov  1 10:25:53 2015', queued=0ms, exec=0ms


PCSD Status:
  pm01: Online
  pm02: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled


3.ネットワーク障害によるF/Oの確認


デフォルトGWへの疎通障害でF/Oするかどうか確認します。
pm01で以下のようにして、デフォルトGWへの ping が失敗するようにします。
[root@pm01 ~]# iptables -I INPUT -p icmp -j DROP -s 10.1.0.254
しばらくすると、以下のように pm02 にF/Oします。
[root@pm01 ~]# pcs status
Cluster name: cluster_test
Last updated: Sun Nov  1 10:34:39 2015          Last change: Sun Nov  1 10:31:09 2015 by root via crm_attribute on pm01
Stack: corosync
Current DC: pm01 (version 1.1.13-a14efad) - partition with quorum
2 nodes and 5 resources configured

Online: [ pm01 pm02 ]

Full list of resources:

 Resource Group: WebGroup
     vipcheck_res       (ocf::myres:VIPCheck):  Started pm02
     vip_res    (ocf::heartbeat:IPaddr2):       Started pm02
     httpd_res  (ocf::heartbeat:apache):        Started pm02
 Clone Set: ping-clone [ping]
     Started: [ pm01 pm02 ]

PCSD Status:
  pm01: Online
  pm02: Online

Daemon Status:
  corosync: active/disabled
  pacemaker: active/disabled
  pcsd: active/enabled

pm01、pm02 の両方が、デフォルトGWに疎通NGの場合は、リソースが停止します。