Google Cloud Platform使用Alias IP簡易達成DRBD + Heartbeat HA

Google Cloud Platform使用Alias IP簡易達成DRBD + Heartbeat HA
Google Cloud Platform的虛擬機Alias IP(別名IP)功能已有大幅增加, 支援了應用程式高可靠性, 以往使用路由方式達成的Linux DRBD + Heartbeat方式在Google Cloud Platform上更容易實現, 變更Alias IP也比改路由快上許多, 在前作GCP虛擬主機建構MySQL基於DRBD與Heartbeat的高可靠性資料庫伺服器一文中便是使用更改路由實作DRBD + Heartbeat, 本文實際範例使用Alias IP更容易設定, 也更快在VM間切換!

Google Cloud Platform的虛擬機設定


Google Cloud Platform使用Alias IP簡易達成DRBD + Heartbeat HA
要使用gcloud命令切換Alias IP, 必須將Compute Engine Cloud API設定為"讀寫"

Google Cloud Platform使用Alias IP簡易達成DRBD + Heartbeat HA
只要在Primary Node上先設好Alias IP(別名IP)

在範例中, 使用兩台VM, 除了自身的開機SSD磁碟外, 額外增加了空白SSD磁碟給DRBD使用, 請依照您自己的使用情境設定
Primary Node: test-1, 內部IP 10.140.0.11, 別名IP 10.140.0.100
Secondary Node: test-2, 內部IP 10.140.0.12, 不設定別名IP
別名IP 10.140.0.100在此處將是提供其他VM連接的服務用IP, 例如MySQL Server聽在10.140.0.100:3306
各機作業系統: Linux Debian 9, Boot Disk 10GB與額外的10GB磁碟放置MySQL Server資料

Google Cloud Platform官方範例: Improving application availability with Alias IPs, now with hot standby

掛載空白磁碟與格式化


切換到root
sudo su -


列出磁碟
lsblk

空白磁碟是/dev/sdb

檢視目前系統掛載磁碟
df -h

輸出範例
Filesystem      Size  Used Avail Use% Mounted on
udev 840M 0 840M 0% /dev
tmpfs 171M 7.0M 164M 5% /run
/dev/sda1 9.8G 1004M 8.3G 11% /
tmpfs 851M 0 851M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 851M 0 851M 0% /sys/fs/cgroup


格式化新磁碟
mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb


掛載新磁碟到/srv
mount -o discard,defaults /dev/sdb /srv

/srv是系統已內建目錄, 計畫給MySQL Server放置資料, 或是由您另開新目錄來掛載新磁碟/dev/sdb

確認掛載/srv
df -h

輸出範例
Filesystem      Size  Used Avail Use% Mounted on
udev 840M 0 840M 0% /dev
tmpfs 171M 7.0M 164M 5% /run
/dev/sda1 9.8G 1004M 8.3G 11% /
tmpfs 851M 0 851M 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 851M 0 851M 0% /sys/fs/cgroup
/dev/sdb 9.8G 37M 9.8G 1% /srv


檢視磁碟的UUID
blkid /dev/sdb

輸出範例
/dev/sdb: UUID="704efcbf-40af-4f3c-8f41-724f3c6be689" TYPE="ext4"


開機自動掛載
nano /etc/fstab

加入/srv
UUID=879722dd-2c57-476f-b2ab-c566723051a0 / ext4 defaults 1 1
UUID=704efcbf-40af-4f3c-8f41-724f3c6be689 /srv ext4 discard,defaults 0 2

其實/srv的設定後續用不到, 不過還是列出掛載範例

安裝DRBD


安裝DRBD (Distributed Replicated Block Device)
apt-get install drbd8-utils


備份現有設定檔
mv /etc/drbd.d/global_common.conf /etc/drbd.d/global_common.bak


編輯新設定檔
nano /etc/drbd.d/global_common.conf

貼上設定
global {
usage-count no;
}
common {
protocol C;
}


卸載/srv
umount /srv


修改/etc/fstab
nano /etc/fstab

/srv的UUID前加上"#"即可
UUID=879722dd-2c57-476f-b2ab-c566723051a0 / ext4 defaults 1 1
#UUID=704efcbf-40af-4f3c-8f41-724f3c6be689 /srv ext4 discard,defaults 0 2


加入resource檔
nano /etc/drbd.d/r0.res

貼上設定
resource r0 {
meta-disk internal;
device /dev/drbd0;

on test-1 {
disk /dev/sdb;
address 10.140.0.11:7789;
}

on test-2 {
disk /dev/sdb;
address 10.140.0.12:7789;
}
}


載入DRBD
modprobe drbd


清除/dev/sdb磁區
dd if=/dev/zero of=/dev/sdb bs=1k count=1024

輸出範例
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB, 1.0 MiB) copied, 0.173223 s, 6.1 MB/s


接著建立resource r0
drbdadm create-md r0

輸出範例
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.


啟動DRBD
drbdadm up r0


主要伺服器(test-1)需要複寫整個r0資源, 但是預備伺服器(test-2)不需要做此動作
drbdadm -- --overwrite-data-of-peer primary r0


將/dev/drbd0格式化, 這裡SSD使用EXT4檔案格式
mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/drbd0

輸出範例
mke2fs 1.43.4 (31-Jan-2017)
Discarding device blocks: done
Creating filesystem with 2621351 4k blocks and 655360 inodes
Filesystem UUID: 0b1153f7-cc19-47de-9605-f877e996ab70
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

格式化會花上一段時間, 請耐心等待

檢視/proc/drbd可以看鏡像磁區的同步狀況
cat /proc/drbd

輸出範例
version: 8.4.7 (api:1/proto:86-101)
srcversion: 0904DF2CCF7283ACE07D07A
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:3480328 nr:0 dw:10719140 dr:3247700 al:82 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


檢視Secondary Node
cat /proc/drbd

輸出範例
version: 8.4.7 (api:1/proto:86-101)
srcversion: 0904DF2CCF7283ACE07D07A
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
ns:0 nr:3480328 dw:13965732 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0


將Primary Node掛載/dev/drbd到/srv
mount -o discard,defaults /dev/drbd0 /srv


設定DRBD開機時啟動
update-rc.d drbd defaults
update-rc.d drbd enable


安裝MySQL Server


這裡採用Percona Server, 下載Percona Server repository packages
wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb


安裝Percona Server repository packages
dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb


更新repository
apt-get update


安裝Percona Server 5.5 (或是其他版本)
apt-get install percona-server-server-5.5


停止Percona Server
/etc/init.d/mysql stop


建立my.cnf
nano /etc/mysql/conf.d/my.cnf


本次範例的VM只有1 CPU, 1.75GB RAM
[mysqld]
binlog_format = ROW
character_set_server = utf8
collation_server = utf8_unicode_ci
datadir = /var/lib/mysql
default_storage_engine = InnoDB
expire_logs_days = 7
innodb_additional_mem_pool_size = 64M
innodb_buffer_pool_instances = 1 # 1 CPU = 1
innodb_buffer_pool_size = 1190M # 70% RAM
innodb_data_file_path = ibdata1:64M;ibdata2:64M:autoextend
innodb_file_format = Barracuda
innodb_file_per_table
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_io_capacity = 200 # 1 CPU = 200
innodb_log_file_size = 64M
innodb_print_all_deadlocks = 1
innodb_support_xa = FALSE
key_buffer_size = 32M
log-bin = mysqld-bin
log-queries-not-using-indexes
log-slave-updates
long_query_time = 1
max_allowed_packet = 64M
max_connect_errors = 4294967295
max_connections = 4096
port = 3306
skip-name-resolve
slow_query_log = 0
table_cache = 4096
thread_cache = 1024
tmpdir = /srv/tmp
transaction_isolation = REPEATABLE-READ
user = mysql
wait_timeout = 60
server-id = 1


建立暫存目錄(tmpdir設定值)
mkdir /srv/tmp
chmod 1777 /srv/tmp


以下的步驟, 只有test-1需要做
將mysql目錄的所有資料移到DRBD的/srv/mysql
cd /var/lib
mv mysql /srv/mysql
ln -s /srv/mysql /var/lib/mysql
chown -R mysql:mysql /srv/mysql


移除InnoDB初始資料
cd /srv/mysql
rm ibdata1
rm ib_logfile*


測試啟動Percona Server
/etc/init.d/mysql start


再次停止Percona Server, 後面需要安裝Heartbeat
/etc/init.d/mysql stop


test-2依照前面的安裝步驟設好Percona Server, 移除/var/lib/mysql下的資料。
cd /var/lib
rm -rf mysql
ln -s /srv/mysql


更改test-2 VM上的/etc/mysql/debian.cnf
以Primary Node的密碼為準, 檢視test-1 VM的密碼設定值
cat /etc/mysql/debian.cnf

輸出範例
# Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host = localhost
user = debian-sys-maint
password = mypassword
socket = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host = localhost
user = debian-sys-maint
password = mypassword
socket = /var/run/mysqld/mysqld.sock
basedir = /usr

記下password的字串, 將test-2的/etc/mysql/debian.cnf改跟test-1一樣

移除Percona Server的開機啟動程序
update-rc.d -f mysql remove


安裝Heartbeat


安裝監控軟體Heartbeat
apt-get install heartbeat


加入MySQL Server的開關script
nano /etc/heartbeat/resource.d/mysql

貼上以下內容
#!/bin/bash
#
# This script is inteded to be used as resource script by heartbeat
#
# Mar 2006 by Monty Taylor
#
###

. /etc/ha.d/shellfuncs

case "$1" in
start)
res=`/etc/init.d/mysql start`
ret=$?
ha_log $res
exit $ret
;;
stop)
res=`/etc/init.d/mysql stop`
ret=$?
ha_log $res
exit $ret
;;
status)
if [[ `ps -ef | grep '[m]ysqld'` > 1 ]] ; then
echo "running"
else
echo "stopped"
fi
;;
*)
echo "Usage: mysql {start|stop|status}"
exit 1
;;
esac

exit 0

將此script設為可執行
chmod +x /etc/heartbeat/resource.d/mysql


加入Alias IP切換script
nano /etc/heartbeat/resource.d/gcpaliasip

此為test-1 (Primary Node)使用
#!/bin/bash
gcloud compute instances network-interfaces update test-2 --zone asia-east1-a --aliases ""
gcloud compute instances network-interfaces update test-1 --zone asia-east1-a --aliases "10.140.0.100/32"

10.140.0.100是之前設定的Alias IP

所以test-2 (Secondary Node)上的/etc/heartbeat/resource.d/gcpaliasip
#!/bin/bash
gcloud compute instances network-interfaces update test-1 --zone asia-east1-a --aliases ""
gcloud compute instances network-interfaces update test-2 --zone asia-east1-a --aliases "10.140.0.100/32"


均設定可執行
chmod +x /etc/heartbeat/resource.d/gcpaliasip


試試看test-1釋放Alias IP
gcloud compute instances network-interfaces update test-1 --zone asia-east1-a --aliases ""

大約花個一秒可完成釋放, 兩邊切換約三秒

設定Heartbeat的ha.cf, authkeys與haresources檔案
cd /etc/heartbeat

到Heartbeat的設定檔目錄

編輯ha.cf
nano ha.cf

將以下內容貼到ha.cf, 給test-1用的
logfile /var/log/ha.log
keepalive 2
deadtime 10
warntime 5
initdead 20
udpport 694
auto_failback off
ucast eth0 10.140.0.12
node test-1
node test-2


在test-2, 使用此設定
logfile /var/log/ha.log
keepalive 2
deadtime 10
warntime 5
initdead 20
udpport 694
auto_failback off
ucast eth0 10.140.0.11
node test-1
node test-2

請注意ucast eth0的設定, eth0為內部網路介面(如果不是eth0請換其他名稱), 互相指定對方的IP位址

設定authkeys檔案
nano authkeys

將以下內容貼上
auth 1
1 md5 mykey

"mykey"為結點以MD5編碼後的驗證密碼, 請替換為您自己的key

將authkeys變更權限, 只有root才能讀寫
chmod 600 authkeys


建立haresources
nano haresources

貼上以下內容
test-1 drbddisk::r0 Filesystem::/dev/drbd0::/srv::ext4::discard,defaults gcpaliasip mysql

gcpaliasip與mysql是前面設定的開關script
執行的順序是
1. 啟動DRBD r0資源
2. 掛載/srv, 使用EXT4檔案格式, 並且使用discard,defaults掛載參數
3. gcpaliasip釋放對方的Alias IP, 並在自己的網路介面綁定
4. mysql為起始MySQL Server

啟動Heartbeat
Primary(test-1)與Secondary Node(test-2)都起動Heartbeat
update-rc.d heartbeat defaults
update-rc.d heartbeat enable
/etc/init.d/heartbeat start

以上設定完成, 可使用Heartbeat hb_takeover工具程式手動切換資源
/usr/share/heartbeat/hb_takeover


如果需要整個系統關機, 且服務在Primary Node(test-1)
/etc/init.d/heartbeat stop

Secondary Node(test-2)此時開始接手服務

將Primary Node關機
poweroff


轉到Secondary Node, 停止MySQL Server
/etc/init.d/mysql stop


將Secondary Node關機
poweroff


若需要重新啟動, 先開啟Primary Node(test-1) VM, 啟動完後接著開啟Secondary Node(test-2) VM
檢查DRBD狀態
cat /proc/drbd

如果出現兩邊Secondary/Secondary, 將Primary Node把DRBD設為自己是Primary
像是此情況
version: 8.4.7 (api:1/proto:86-101)
srcversion: 0904DF2CCF7283ACE07D07A
0: cs:Connected ro:Secondary/Secondary ds:UpToDate/UpToDate C r-----
ns:16 nr:0 dw:0 dr:16 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

設自己為Primary
drbdadm primary r0


以上是在Google Clpud Platform實作DRBD + Heartbeat HA的範例
5分送上!

很詳盡的文章,文中有的專業術語還沒聽過。

最近在研究Cloud service,選了微軟的Azure將相關service佈署到虛擬機器上。

業界似乎用AWS比較多的樣子?!
AWS開始得早有其優勢, GCP則是價格便宜
peter5240 wrote:
5分送上!很詳盡的文...(恕刪)
非常棒的分享~
不過,我看樓主的設定是只有針對內部 IP 的設定
外部的 IP 設定為臨時的,應該無法達成持續的提供外部服務吧!

我自己的實作應用是用來提供外部的服務 (Apache + Mariadb)
舉例,我申請一個 Domain --> service.test.com
我的 Primary Node 是放在台灣的彰化機房
我的 Secondary Node 是放在新加坡機房

平常一般 User 訪問 service.test.com 的時候,是 Primary Node(彰化) 提供服務
當 Primary Node 掛點的時候,自動由 Secondary Node(新加坡) 接手服務 (前提是要使用 Round Robin DNS)
由於轉移時間如同樓主述,幾秒鐘內就可以完成

這樣的就可以完成跨國的異地備援機制了!

如果是使用傳統的作法,軟硬體的相關設備成本就不知道要投入多少了
現在有 GCP 這樣的雲端服務,真的可以讓企業省下不少投資成本了!!

-------------------------------------------------------------
對了,我以前還沒使用 GCP 實作 DRBD + Heartbeat 時
是用 Vmware ESXi 安裝 Ubuntu 來完成

後來使用 GCP 安裝 Ubuntu 時,似乎 GCP 上的 Ubuntu 內核不支援 DRBD
後來換成 Debian 就可以了!


發現Debian 9上安裝heartbeat會連帶把corosync與pacemaker也裝進去(雖然是建議套件但連帶安裝也太自動了吧...), 雖然不會有影響, 但未完整的corosync與pacemaker設定會一直產生錯誤訊息到syslog與pacemaker log檔, 以下是移除這兩種服務的方法, 不影響原有DRBD + Heartbeat運作

關閉corosync與pacemaker
systemctl stop pacemaker
systemctl stop corosync


停止機器開機時啟動
systemctl disable pacemaker
systemctl disable corosync

今日熱門文章 網友點擊推薦!

文章分享
評分
複製連結