Friday, June 19, 2015

High Availability Cluster Failover Menggunakan Pacemaker, Corosync dan PCS di CentOS 7

Teknologi High Availabilty menggunakan pacemaker pada dasarnya serupa dengan heartbeat, namun konon katanya memiliki banyak keunggulan serta merupakan teknologi yang lebih baru dan fresh ketimbang heartbeat.


Di dunia persilatan banyak sekali skenario implementasi high availability, namun seperti judul tulisan kali ini kita akan fokus pada "Penerapan high availability pada 2 node yang menjalankan web services dengan metode cluster failover".

Untuk membuat system seperti ini kita akan membuat simpel cluster. Dimana Virtual IP Address akan merepresentasikan sebuah cluster node (terlepas dari berapa pun jumlah servernya). Pada intinya client hanya butuh virtual ip address yang kita buat saja, mereka tidak butuh mengetahui ip server ktia.

Dalam kondisi normal, topologi dari sistem yang akan kita buat akan berjalan seperti dibawah ini.



Dari gambar topologi diatas apabila pada kondisi tertentu terjadi error pada node01 misalnya system crash, daemon service error, node unreacheble, dsb maka node02 akan otomatis menggantikan peran node01 dan menjalankan layanan web service dalam cluster tsb.



Pada skenario inilah terlihat fungsi penting dari virtual ip dalam cluster node tsb, pada sisi klien tidak perlu ada perubahan sama sekali. Mereka tidak tahu sama sekali apabila web server di node01 crash karna IP Address yang mereka kunjungi adalah Virtual IP Address.

Untuk membangun cluster seperti diatas, kita membutuhkan beberapa komponen.
  • Definisikan service yang ingin kita implementasikan (Webserver, Mailserver, dsb).
  • Resource manager (Pacemaker).
  • Messaging component untuk komunikasi membership dalam cluster (Corosync).
  • Optional : File synchronize yang menjaga file system konsisten dengan semua cluster node (DRBD atau GlusterFS). 
  • Optional : Cluster manager untuk memanage cluster settings dalam semua nodes (PSC).

PRE-INSTALASI
- Konfigurasi static IP Address,
- Konfigurasi static hostname,
- Pastikan kedua node tsb (node01 dan node02) ada dalam subnet yang sama.

Cek Node01
[root@node01 ~]# uname -n
node01
[root@node01 ~]# ip addr show | grep "inet "
    inet 127.0.0.1/8 scope host lo
    inet 192.168.227.139/24 brd 192.168.227.255 scope global dynamic eno16777736

Cek Node02
[root@node02 ~]# uname -n
node02
[root@node02 ~]# ip addr show | grep "inet "
    inet 127.0.0.1/8 scope host lo
    inet 192.168.227.140/24 brd 192.168.227.255 scope global dynamic eno16777736


Apabila belum sesuai seperti diatas maka setting dulu konfigurasinya sebagai berikut ini.

Konfigurasi Hostname
Node01
[root@node01 ~]# vi /etc/hostname 
#Isi file ini menjadi node01#
node01

Node02
[root@node02 ~]# vi /etc/hostname 
#Isi file ini menjadi node02#
node02

Konfigurasi Network
Node01
[root@node01 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eno16777736
##Isi parameter dibawah menjadi seperti dibawah ini##
HWADDR=00:0C:29:90:97:93
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=eno16777736
UUID=f9292821-a79f-4104-abab-3b5e6f0b7623

ONBOOT=yes
IPADDR=192.168.227.139
NETMASK=255.255.255.0
GATEWAY=192.168.227.1

Save file lalu restart service
[root@node01 ~]# systemctl restart network.service

[root@node01 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.227.139 node01
192.168.227.140 node02

Node02
[root@node02 ~]# vi /etc/sysconfig/network-scripts/ifcfg-eno16777736
##Isi parameter dibawah menjadi seperti dibawah ini##
HWADDR=00:0C:29:FD:BC:46
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=eno16777736
UUID=f9292821-a79f-4104-abab-3b5e6f0b7623

ONBOOT=yes
IPADDR=192.168.227.140
NETMASK=255.255.255.0
GATEWAY=192.168.227.1

Save file lalu restart service
[root@node02 ~]# systemctl restart network.service

[root@node02 ~]# vi /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.227.139 node01
192.168.227.140 node02

Turn Off Firewall dan Selinux
Node01
[root@node01 ~]# systemctl status firewalld.service
[root@node01 ~]# setenforce 0

Node02
[root@node02 ~]# systemctl status firewalld.service
[root@node02 ~]# setenforce 0



TAHAP INSTALASI & KONFIGURASI AWAL
Instalasi Package
Node01
[root@node01 ~]# yum install corosync pcs pacemaker

Node02
[root@node02 ~]# yum install corosync pcs pacemaker

Notes
Kita akan menggunakan PCS untuk memanage cluster. Setelah install package diatas, maka system akan secara otomatis membuat user hacluster. Sebelum lanjut ke tahap selanjutnya, change password hacluster di kedua node agar PCS dapat digunakan.


Ganti Password User hacluster
Node01
[root@node01 ~]# passwd hacluster

Node02
[root@node02 ~]# passwd hacluster


Turn on pcsd service di kedua node
Node01
[root@node01 ~]# systemctl start pcsd

Node02
[root@node02 ~]# systemctl start pcsd

Authentikasi Cluster Node, Gunakan Password yg dari Tahap Setting Password hacluster
Node01 (Lakukan hanya di Node01)
[root@node01 ~]# pcs cluster auth node01 node02

Notes
Setelah selesai tahap diatas, maka pada tahap selanjutnya kita bisa mengontrol cluster dengan PCS dari node01, jadi konfigurasi gak perlu diulang di semua server karna sudah bisa dikontrol dari node01.

Buat Cluster Lalu Tambahkan Node
[root@node01 ~]# pcs cluster setup --name cluster_web node01 node02

Start Cluster yang Telah Dibuat
[root@node01 ~]# pcs cluster start --all

Cek & Verifikasi Status Cluster
[root@node01 ~]# pcs status cluster
Cluster Status:
 Last updated: Fri Jun 19 18:08:01 2015
 Last change: Fri Jun 19 11:38:57 2015
 Stack: corosync
 Current DC: node02 (2) - partition with quorum
 Version: 1.1.12-a14efad
 2 Nodes configured

 1 Resources configured

Cek Status Node Cluster
[root@node01 ~]# pcs status nodes
Pacemaker Nodes:
 Online: node01 node02 
 Standby: 

 Offline:

[root@node01 ~]# corosync-cmapctl | grep members
runtime.totem.pg.mrp.srp.members.1.config_version (u64) = 0
runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(192.168.227.139) 
runtime.totem.pg.mrp.srp.members.1.join_count (u32) = 1
runtime.totem.pg.mrp.srp.members.1.status (str) = joined
runtime.totem.pg.mrp.srp.members.2.config_version (u64) = 0
runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(192.168.227.140) 
runtime.totem.pg.mrp.srp.members.2.join_count (u32) = 1

runtime.totem.pg.mrp.srp.members.2.status (str) = joined

[root@node01 ~]# pcs status corosync

Membership information
----------------------
    Nodeid      Votes Name
         1          1 node01 (local)

         2          1 node02


KONFIGURASI CLUSTER
Cek Stonith Status & Turn Off
[root@node01 ~]# crm_verify -L -V
error: unpack_resources: Resource start-up disabled since no STONITH resources have been defined
 error: unpack_resources: Either configure some or disable STONITH with the stonith-enabled option
 error: unpack_resources: NOTE: Clusters with shared data need STONITH to ensure data integrity

 Errors found during check: config not valid

Notes
Apabila output seperti diatas, maka masih ada error di STONITH (Shoot The Other Node In The Head). STONITH adalah mekanisme untuk memastikan agar cluster tidak berakhir dengan dua node yang mereka keduanya aktif dan mengklaim sebagai pemilik IP virtual, teknik ini juga disebut sebagai split brain. Karna cluster kita sederhana maka kita bisa matikan saja, gunakan command.

[root@node01 ~]# pcs property set stonith-enabled=false

Konfigurasi Quorom
Setelah selesai konfigurasi behavior cluster, maka kita masuk ke tahap konfigurasi Quorom. Quorom adalah minimum jumlah nodes dalam cluster yang harus diaktifkan agar cluster dapat berjalan. Teknik ini bisa sangat berguna ketika banyak node memprovide computing power secara simultan. Nah ketika jumlah node terlalu rendah, maka sebaiknya cluster dihentikan daripada mendeliver service yang tidak dapat berjalan sebagaimana mestinya. Secara default, quorum dianggap terlalu rendah apabila jumlah node lebih kecil dari dua kali jumlah node yang aktif. Nah untuk cluster yang terdiri dari 2 node, maka berarti kedua node tersebut harus ada agar cluster dapat berjalan.

Namun dalam praktek kali ini kita akan ignore low quorom, gunakan command dibawah ini.

[root@node01 ~]# pcs property set no-quorum-policy=ignore
[root@node01 ~]# pcs property
Cluster Properties:
 cluster-infrastructure: corosync
 cluster-name: cluster_web
 dc-version: 1.1.12-a14efad
 have-watchdog: false
 no-quorum-policy: ignore
 stonith-enabled: false

Set Virtual IP Address
[root@node01 ~]# pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=192.168.227.138 cidr_netmask=32 op monitor interval=30s
[root@node01 ~]# pcs status resources

 virtual_ip (ocf::heartbeat:IPaddr2): Started 

Verifikasi Virtual IP Address Sudah Aktif
[root@node01 ~]# ping 192.168.227.138

Untuk Melihat Current Owner Resource Virtual IP Address, Gunakan Command.
[root@node01 ~]# pcs status|grep virtual_ip

 virtual_ip (ocf::heartbeat:IPaddr2): Started node01 


KONFIGURASI APACHE WEB-SERVICES
Install Apache
Node01
[root@node01 ~]# yum install httpd -y

Node02
[root@node02 ~]# yum install httpd -y

Buat Script Test-Mechanism di Node01 dan Node02
Node01
[root@node01 ~]# vi /etc/httpd/conf.d/serverstatus.conf
#isi dengan konfigurasi seperti dibawah ini#
Listen 127.0.0.1:80
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1

</Location>

Node02
[root@node02 ~]# vi /etc/httpd/conf.d/serverstatus.conf
#Isi dengan konfigurasi seperti dibawah ini#
Listen 127.0.0.1:80
<Location /server-status>
SetHandler server-status
Order deny,allow
Deny from all
Allow from 127.0.0.1

</Location>

Disabled Listen Statement, Untuk Menghindari Apache Listen ke Port yg Sama
Node01
[root@node01 ~]# sed -i 's/Listen/#Listen/' /etc/httpd/conf/httpd.conf

Node02
[root@node02 ~]# sed -i 's/Listen/#Listen/' /etc/httpd/conf/httpd.conf

Start Apache dan Verifikasi Status Page yg Telah Dibuat Bekerja
Node01
[root@node01 ~]# systemctl restart httpd.service
[root@node01 ~]# wget http://127.0.0.1/server-status

Node02
[root@node02 ~]# systemctl restart httpd.service
[root@node02 ~]# wget http://127.0.0.1/server-status

Buat Web-Page Sederhana di Document Root Apache
Node01
[root@node01 ~]# vi /var/www/html/index.html
##Isi seperti dibawah ini##
<html>
<h1>node01</h1>
</html>

Node02
[root@node02 ~]# vi /var/www/html/index.html
##Isi seperti dibawah ini##
<html>
<h1>node02</h1>
</html>

Buat Agar Cluster yg Mengkontrol Apache

Pertama, Stop Apache di Kedua Node
Node01
[root@node01 ~]# systemctl stop httpd

Node02
[root@node02 ~]# systemctl stop httpd

Kedua, Konfigurasi Apache Agar Listen ke Virtual IP Address
Node01
[root@node01 ~]# echo "Listen 192.168.227.138:80"|sudo tee --append /etc/httpd/conf/httpd.conf

Node02
[root@node02 ~]# echo "Listen 192.168.227.138:80"|sudo tee --append /etc/httpd/conf/httpd.conf

Sekarang apache sudah siap dikontrol oleh cluster.

Ketiga, Manage Cluster dengan PCS
[root@node01 ~]# pcs resource create webserver ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf statusurl="http://localhost/server-status" op monitor interval=1min
[root@node01 ~]# pcs constraint colocation add webserver virtual_ip INFINITY
[root@node01 ~]# pcs constraint order virtual_ip then webserver
[root@node01 ~]# pcs constraint location webserver prefers node01=50

Keempat, Verifikasi PCS Constraint dan Restart Cluster
[root@node01 ~]# pcs constraint
Location Constraints:
  Resource: webserver
    Enabled on: node01 (score:50)
Ordering Constraints:
  start virtual_ip then start webserver (kind:Mandatory)
Colocation Constraints:

  webserver with virtual_ip (score:INFINITY)

[root@node01 ~]# pcs cluster stop --all && sudo pcs cluster start --all
node02: Starting Cluster...

node01: Starting Cluster...

[root@node01 ~]# pcs status
Cluster name: cluster_web
Last updated: Fri Jun 19 18:56:03 2015
Last change: Fri Jun 19 18:28:59 2015
Stack: corosync
Current DC: node01 (1) - partition with quorum
Version: 1.1.12-a14efad
2 Nodes configured
2 Resources configured


Online: [ node01 node02 ]

Full list of resources:

 virtual_ip (ocf::heartbeat:IPaddr2): Started node01 
 webserver (ocf::heartbeat:apache): Started node01 

PCSD Status:
  node01: Online
  node02: Online

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

  pcsd: active/enabled

Dari output hasil verifikasi diatas terlihat bahwa virtual ip dan web service berjalan di node01.


Kelima, Akses Virtual IP dari Web-Browser & Pastikan Output adalah "Node01"
Akses web-service dari browser ke http://192.168.227.138



Keenam, Test Fail-Over dan Pastikan Berjalan Sesuai
Matikan node01 dari Cluster 
[root@node01 ~]# pcs cluster stop node01

Hit Virtual IP Address dari browser, seharusnya outputnya adalah "Node02".



Terakhir, Enables Cluster Component Persistent (Start Up Ketika Booting).
Node01
[root@node01 ~]# systemctl enable pcsd
[root@node01 ~]# systemctl enable corosync
[root@node01 ~]# systemctl enable pacemaker

Node02
[root@node02 ~]# systemctl enable pcsd
[root@node02 ~]# systemctl enable corosync
[root@node02 ~]# systemctl enable pacemaker

NOTES PENTING
Pada tahap ini ketika reboot cluster tidak akan berjalan, ketika di cek di /var/log/messages akan ada output seperti dibawah ini.

Jun 19 22:43:36 node01 corosync: Starting Corosync Cluster Engine (corosync): [FAILED]^M[  OK  ]
Jun 19 22:43:36 node01 systemd: corosync.service: control process exited, code=exited status=1
Jun 19 22:43:36 node01 systemd: Failed to start Corosync Cluster Engine.
Jun 19 22:43:36 node01 systemd: Dependency failed for Pacemaker High Availability Cluster Manager.
Jun 19 22:43:36 node01 systemd:
Jun 19 22:43:36 node01 systemd: Unit corosync.service entered failed state.

Apabila agan membaca di forum redhat, hal ini terjadi karena bugs yang sudah dideskripsikan di Redhat bugzilla bug #1030583.

Solusinya adalah edit systemd-service dari corosync service di node01 dan node02, lalu menambah jeda dengan sleep 10 detik. Langkahnya ialah, edit file /usr/lib/systemd/system/corosync.service lalu edit bagian [Service] dan tambahkan ExecStartPre=/usr/bin/sleep 10.

[Unit]
Description=Corosync Cluster Engine
ConditionKernelCommandLine=!nocluster
Requires=network-online.target
After=network-online.target

[Service]
ExecStartPre=/usr/bin/sleep 10
ExecStart=/usr/share/corosync/corosync start
ExecStop=/usr/share/corosync/corosync stop
Type=forking

[Install]
WantedBy=multi-user.target

Setelah selesai edit di kedua node langkah selanjutnya adalah reload daemon-service, gunakan command dibawah ini.
Node01
[root@node01 ~]# systemctl daemon-reload

Node02
[root@node02 ~]# systemctl daemon-reload


Done! Semoga bermanfaat...

No comments:

Post a Comment