15 Mart 2013 Cuma

Centos üzerinde DRBD, Pacemaker ve Corosync ile Postgresql Cluster kurulumu


Bir arkadaşın ricası üzerine sanal sunucularda postgresql cluster denemesi yapmak icab etti. Bu nedenle aşağıdaki dökümanı yazmaya çalıştım. Biraz karışık gibi görünse de birilerine yararlı olursa ne mutlu bana.

Bu kurulumda postgresql’i aktif/pasif çalıştırıyoruz. Aktif düştüğünde pasif db’nin yerine geçmesini bekliyoruz. Data senkronizasyonunu da drbd ile sağlıyoruz. Pacemaker ve corosync ile de cluster yönetimini yapıyoruz.

İlk önce vmware üzerinde centos 6.3 kurulumlarını yapıyoruz. Ram olarak 4gb, disk boyutu olarak 32gb verdim.
Sunucuların adı node1 ve node2
Sunuculara internet çıkışı verdim.
IP ayarları:
node1: 172.25.6.27 (eth0)
node1: 172.25.7.27 (eth1 – replikasyon bu bacaktan yapılacak)
node2: 172.25.6.28 (eth0)
node2: 172.25.7.28 (eth1 – replikasyon bu bacaktan yapılacak)
VIP: 172.25.6.29 (ortak ip)
Firewall’u ve selinux’u kapatıyoruz. Sonrasında sunucuları kapatıp vmware üstünden 8 gb’lık ayrı bir disk alanı açıyoruz. Bu alanı şimdilik formatlamıyor ve mount etmiyoruz.
Sunucuları açtığımızda her iki sunucu için de fdisk -l /dev/sdb cevabı dolu gelmeli.

----------------------------------------------------------------
Şimdi  her iki sunucu içine gerekli paketleri yüklemeye başlıyoruz. Paketlerin yüklenip yüklenmediğinin rpm -qa ile kontrolü tavsiye edilir.
yum install postgresql* gcc perl-MailTools perl-DBI php-pgsql
yum install pacemaker corosync
Şimdi epel repoyu ekleyip diğer paketleri kuralım.
wget http://elrepo.org/elrepo-release-6-4.el6.elrepo.noarch.rpm
rpm -ivUh elrepo-release-6-4.el6.elrepo.noarch.rpm
yum --enablerepo=elrepo install drbd83-utils kmod-drbd83
Son olarak;
wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -ivh epel-release-6*.rpm
yum --enablerepo=epel install heartbeat

Her iki sunucu içinde /etc/drbd.conf dosyalarını düzenleyelim. (dosya dolu ise var olan satırları # ile iptal edin)
global {
    usage-count no;
}
common {
    syncer { rate 100M; }
    protocol      C;
}
resource postgres {
    startup {
       wfc-timeout 0;
       degr-wfc-timeout
       120;
    }
    disk { on-io-error detach; }
    on node1 {
       device      /dev/drbd0;
       disk        /dev/sdb;
       address     172.25.7.27:7791;
       meta-disk   internal;
    }
    on node2 {
       device      /dev/drbd0;
       disk        /dev/sdb;
       address     172.25.7.28:7791;
       meta-disk   internal;
    }
}


Açıklamalar:
resource: DRBD tarafında yönetilecek kaynağın adı, biz burda "postgres" adını verdik.
disk: DRBD’nin kullanacağı disk veya partition adı
address: DRBD’nin kullanacağı eth1 bacaklarının ip adresi
syncer: Node’lar arası transfer hızı. Gigabit kartı var kabul edip 100M verdik.
Bu aşamada sunucuya reboot atıyoruz. (Modüllerin yüklemesi vs. ile ilgili sorunlar çıktı, bu aşamada reboot atınca düzeldi.)

Her iki sunucuda;
drbdadm create-md postgres
komutunu çalıştırıyoruz ve aşağıdakine benzer bir çıktı bekliyoruz.
[root@node1 ~]# drbdadm create-md postgres
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.

Sonrasında her iki sunucuda da;
drbdadm up postgres
komutunu çalıştırıyoruz.
Burada 0: Failure: (124) Device is attached to a disk (use detach first) benzeri bir hata alırsak;
drbdadm detach postgres
drbdadm disconnect postgres
drbdadm up postgres
komutlarını çalıştırıyoruz.

Sadece node1’de;
drbdadm -- --overwrite-data-of-peer primary postgres
komutunu veriyoruz.

Bu komuttan sonra node1’de cat /proc/drbd çıktısı olarak aşağıdakine benzer bir çıktı görmeliyiz. (Önemli yerler koyu ile işaretli)
[root@node1 ~]# cat /proc/drbd
version: 8.3.15 (api:88/proto:86-97)
GIT-hash: 0ce4d235fc02b5c53c1c52c53433d11a694eab8c build by phil@Build64R6, 2012-12-20 20:09:51
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---n-
    ns:201920 nr:0 dw:0 dr:210464 al:0 bm:9 lo:3 pe:91 ua:64 ap:0 ep:1 wo:f oos:8197980
        [>....................] sync'ed:  2.3% (8004/8188)M
        finish: 0:07:53 speed: 17,300 (17,300) K/sec

Node2’de ise aşağıdakine benzer bir çıktı olmalı.
[root@node2 ~]# cat /proc/drbd
version: 8.3.15 (api:88/proto:86-97)
GIT-hash: 0ce4d235fc02b5c53c1c52c53433d11a694eab8c build by phil@Build64R6, 2012-12-20 20:09:51
 0: cs:SyncTarget ro:Secondary/Primary ds:Inconsistent/UpToDate C r-----
    ns:0 nr:735488 dw:727296 dr:0 al:0 bm:42 lo:65 pe:7438 ua:64 ap:0 ep:1 wo:f oos:7661020
        [>...................] sync'ed:  8.7% (7480/8188)M
        finish: 0:07:13 speed: 17,676 (17,316) want: 102,400 K/sec

Primary/Secondary ile lokal sunucunun Primary, diğer sunucunun Secondary olduğunu belirtiyor.
UpToDate/UpToDate iki sunucuda resource’nin up olduğunu söylüyor.

Her iki sunucuda /etc/init.d/drbd start komutu ile drbd servisini başlatıyoruz ve cat /proc/drbd komutu ile çıktıların yukarıdaki gibi gelip gelmediğini tekrar kontrol ediyoruz.
Sadece node1’de;
mkfs.ext3 /dev/drbd0
mount -t ext3 /dev/drbd0 /var/lib/pgsql
chown postgres.postgres /var/lib/pgsql
su - postgres
initdb /var/lib/pgsql/data
exit

echo "host all all 172.25.6.27/32 trust" >> /var/lib/pgsql/data/pg_hba.conf
echo "host all all 172.25.6.28/32 trust" >> /var/lib/pgsql/data/pg_hba.conf
echo "host all all 172.25.6.29/32 trust" >> /var/lib/pgsql/data/pg_hba.conf
komutlarını çalıştırıyoruz.

Yine sadece node1’de vi /var/lib/pgsql/data/postgresql.conf yazıp bu dosyada
listen_addresses = '0.0.0.0'
olarak ayarlıyoruz ve /etc/init.d/postgresql start komutu ile postgresql’i başlatıyoruz.

Yine sadece node1’de test için kullanıcı adı ve db oluşturuyoruz.
su - postgres
createuser --superuser admpgsql –pwprompt
şifre girişi
createdb pgbench
pgbench -i pgbench

Ufak bir test yapalım;
psql -U admpgsql -d pgbench
select count(*) from pgbench_tellers;
Sorgu çıktısı bende 10 olarak geldi.
--------------------------------------------------
Şimdi node1’deki postgresql servisini kapatıp node2’ye aktarmaya çalışalım. Burada drbd’yi unmount ediyoruz ve node1 secondary’dir diyoruz.
/etc/init.d/postgresql stop
umount /dev/drbd0
drbdadm secondary postgres

Node2’de ise aşağıdaki komutları çalıştırıyoruz.
drbdadm primary postgres
mount -t ext3 /dev/drbd0 /var/lib/pgsql/
/etc/init.d/postgresql start
su - postgres
psql -U admpgsql -d pgbench
select count(*) from pgbench_tellers;

Çıktı yine yukarıdakinin aynısı gelmeli.

Şimdi cluster ayarlarını yapmak için servisleri durduruyoruz. Node2 üzerinde;
/etc/init.d/postgresql stop
umount /dev/drbd0
drbdadm secondary postgres
/etc/init.d/drbd stop

Node1 üzerinde;
drbdadm primary postgres
/etc/init.d/drbd stop
komutlarını çalıştırıyoruz.

(Node1 üzerinde drbd stop deyince ERROR: Module drbd is in use benzeri bir hata alırsanız komutu 30sn. sonra tekrar çalıştırmayı deneyin)
Yapacağımız ayarlarla ilgili olarak aşağıdaki servislerin başlangıçta çalışmamaları gerekiyor. Bunun için her iki sunucuda da aşağıdaki komutları çalıştırıyoruz.
chkconfig --level 35 drbd off
chkconfig --level 35 postgresql off

Geldik corosync kurulumuna;
Sadece node1’de;
export ais_port=4000
export ais_mcast=226.94.1.1
export ais_addr=`ip address show eth0 | grep "inet " | tail -n 1 | awk '{print $4}' | sed s/255/0/`
komutlarını çalıştıralım ve env | grep ais_ komutu ile kontrol edelim. export ais_addr satırında kendi lokal network adresimizi görmemiz lazım. (ais_addr=172.25.6.0)

Coresync için konfigürasyon dosyası aşağıdaki gibi olmalı. (vi /etc/corosync/corosync.conf)

compatibility: whitetank

totem {
   version: 2
   secauth: off
   threads: 0
   interface {
       ringnumber: 0
       bindnetaddr: 172.25.6.0
       mcastaddr: 226.94.1.1
       mcastport: 4000
   }
}

logging {
   fileline: off
   to_stderr: yes
   to_logfile: yes
   to_syslog: yes
   logfile: /var/log/cluster/corosync.log
   debug: off
   timestamp: on
   logger_subsys {
      subsys: AMF
      debug: off
   }
}

amf {
   mode: disabled
}
aisexec {
   user: root
   group: root
}
service {
   # Load the Pacemaker Cluster Resource Manager
   name: pacemaker
   ver: 0

scp /etc/corosync/*.conf node2:/etc/corosync/
komutu ile konfigürasyon dosyasını diğer sunucuya kopyalıyoruz.

Her iki sunucuda;
mkdir /var/log/cluster/  
komutunu çalıştırıyoruz.
(File exists hatası gelirse sorun yok, klasör var demektir)

Bu aşamada node1’de corosync servisini başlatıyoruz.
/etc/init.d/corosync start
Aşağıdaki komutlar ile kontroller yapıyoruz ve aldığımız çıktıya benzer çıktılar gelmesi gerekiyor.

[root@node1 ~]# grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/messages
Mar  6 23:12:43 node1 corosync[5546]:   [MAIN  ] Corosync Cluster Engine ('1.4.1'): started and ready to provide service.
Mar  6 23:12:43 node1 corosync[5546]:   [MAIN  ] Successfully read main configuration file '/etc/corosync/corosync.conf'.



[root@node1 ~]# grep TOTEM /var/log/messages
Mar  6 23:12:43 node1 corosync[5546]:   [TOTEM ] Initializing transport (UDP/IP Multicast).
Mar  6 23:12:43 node1 corosync[5546]:   [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).
Mar  6 23:12:43 node1 corosync[5546]:   [TOTEM ] The network interface [172.25.6.27] is now up.
Mar  6 23:12:43 node1 corosync[5546]:   [TOTEM ] A processor joined or left the membership and a new membership was formed.


[root@node1 ~]# grep pcmk_startup /var/log/messages
Mar  6 23:12:43 node1 corosync[5546]:   [pcmk  ] Logging: Initialized pcmk_startup


[root@node1 ~]# ps axf
 5552 ?        S      0:00  \_ /usr/libexec/pacemaker/cib
 5553 ?        S      0:00  \_ /usr/libexec/pacemaker/stonithd
 5554 ?        S      0:00  \_ /usr/lib64/heartbeat/lrmd
 5555 ?        S      0:00  \_ /usr/libexec/pacemaker/attrd
 5556 ?        S      0:00  \_ /usr/libexec/pacemaker/pengine
 5557 ?        S      0:00  \_ /usr/libexec/pacemaker/crmd


Node1 tarafında her şey tamamsa node2’de;
/etc/init.d/corosync start
komutunu veriyoruz.

Her iki sunucuda da;
crm_mon -1
komutu ile aşağıdakine benzer çıktı elde etmeliyiz.

[root@node1 ~]# crm_mon -1
============
Last updated: Wed Mar  6 23:18:14 2013
Last change: Wed Mar  6 23:17:21 2013 via crmd on node1
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.7-6.el6-148fccfd5985c5590cc601123c6c16e966b85d14
2 Nodes configured, 2 expected votes
0 Resources configured.
============

Online: [ node1 node2 ]

Şimdi her iki sunucuda coresync servisinin başlangıçta açılmasını sağlayan komutu giriyoruz.
chkconfig --level 35 corosync on

Node1 üzerinde;
crm configure property stonith-enabled=false
komutu ile stonith özelliğini kapatıyoruz.

Pacemaker konfigürasyonunu,
crm_verify -L
komutu ile test ettiğimizde hata gelmiyorsa sorun yok demektir.

Cluster ayarları için aşağıdaki komutları node1’de çalıştırıyoruz.
crm configure property no-quorum-policy=ignore
crm configure rsc_defaults resource-stickiness=100
crm configure show komutu ile cluster’ın durumunu görebiliyoruz.

Şimdi db’nin cluster ip’sini verelim.
Yine node1 üzerinde;
crm configure primitive DBIP ocf:heartbeat:IPaddr2 params ip=172.25.6.29 cidr_netmask=24 op monitor interval=30s
komutunu tek satır olacak şekilde çalıştıyoruz. Burada DBIP sanırım /etc/hosts dosyasındaki DBIP olabilir, emin değilim.

crm_mon -1 komutu ile kontrol edelim. Aşağıdakine benzer bir çıktı makbuldür.
[root@node1 ~]# crm_mon -1
============
Last updated: Wed Mar  6 23:33:00 2013
Last change: Wed Mar  6 23:29:51 2013 via cibadmin on node1
Stack: openais
Current DC: node1 - partition with quorum
Version: 1.1.7-6.el6-148fccfd5985c5590cc601123c6c16e966b85d14
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ node1 node2 ]

 DBIP   (ocf::heartbeat:IPaddr2):       Started node1

Cluster ayarları için aşağıdaki komutları node1’de tek satır olacak şekilde çalıştırıyoruz. Gelen saniye uyarılarına takılmıyoruz.
crm configure primitive drbd_postgres ocf:linbit:drbd params drbd_resource="postgres" op monitor interval="15s"
crm configure ms ms_drbd_postgres drbd_postgres meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
crm configure primitive postgres_fs ocf:heartbeat:Filesystem params device="/dev/drbd0" directory="/var/lib/pgsql" fstype="ext3"
crm configure primitive postgresql ocf:heartbeat:pgsql op monitor depth="0" timeout="30" interval="30"
crm configure group postgres postgres_fs DBIP postgresql
crm configure colocation postgres_on_drbd inf: postgres ms_drbd_postgres:Master
crm configure order postgres_after_drbd inf: ms_drbd_postgres:promote postgres:start
Node1’in öncelikle çalışması için;
crm configure location master-prefer-node1 DBIP 50: node1
Bu aşamadan sonra bazı hatalar gelebilir. İki sunucuya da reboot atılması öneriliyor.

NOT:
Kurulumu yaptıktan sonra iki sunucuda gördüğüm loglar şöyle idi. Bu loglara göre iki sunucu da Standalone görünüyordu ve karşı sunucu ile senkronize değillerdi.


[root@node1 ~]# cat /proc/drbd
version: 8.3.15 (api:88/proto:86-97)
GIT-hash: 0ce4d235fc02b5c53c1c52c53433d11a694eab8c build by phil@Build64R6, 2012-12-20 20:09:51
 0: cs:StandAlone ro:Primary/Unknown ds:UpToDate/DUnknown   r-----
    ns:0 nr:0 dw:1824 dr:2997 al:1 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:28368
[root@node2 ~]# cat /proc/drbd
version: 8.3.15 (api:88/proto:86-97)
GIT-hash: 0ce4d235fc02b5c53c1c52c53433d11a694eab8c build by phil@Build64R6, 2012-12-20 20:09:51
 0: cs:StandAlone ro:Secondary/Unknown ds:UpToDate/DUnknown   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:132372

Secondary olan node2’de;
drbdadm secondary all
drbdadm disconnect all
drbdadm -- --discard-my-data connect all


Primary olan node1'de;
drbdadm primary all
drbdadm disconnect all
drbdadm connect all


komutlarını çalıştırdığımda sorunun çözüldüğünü gördüm.

[root@node1 ~]# cat /proc/drbd
version: 8.3.15 (api:88/proto:86-97)
GIT-hash: 0ce4d235fc02b5c53c1c52c53433d11a694eab8c build by phil@Build64R6, 2012-12-20 20:09:51
 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:132716 nr:0 dw:3424 dr:136037 al:1 bm:14 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

[root@node2 ~]# cat /proc/drbd
version: 8.3.15 (api:88/proto:86-97)
GIT-hash: 0ce4d235fc02b5c53c1c52c53433d11a694eab8c build by phil@Build64R6, 2012-12-20 20:09:51
 0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
    ns:0 nr:132768 dw:132768 dr:0 al:0 bm:15 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

Sorunun tekrar yaşanmaması için her iki sunucunun /etc/drbd.conf dosyasına aşağıdaki satırları ekliyoruz. (Bu durum test edilmedi, ekledikten sonra servisleri de reboot etmedim)

net {
  after-sb-0pri discard-zero-changes;
  after-sb-1pri discard-secondary;
  after-sb-2pri disconnect;
}


Eğer sistemde httpd servisi varsa (centos default ayarları ile);
mkdir /var/www/html/cluster/
crm_mon --daemonize --as-html /var/www/html/cluster/index.html
echo "crm_mon --daemonize --as-html /var/www/html/cluster/index.html" >> /etc/rc.d/rc.local
komutları girildikten sonra http://172.25.6.29/cluster/ adresinden cluster’ın durumu görülebilir.

Bu aşamada cluster’ımız kuruldu. Örnek tablolardan veri silip primary db’yi reboot ettiğimde 4 ping kaybı ile cluster VIP’sine (172.25.6.29) ping geldiğini, secondary db’nin primary olduğunu ve silinen dataların secondary db’de de silinmiş olduğunu gördüm.

Benim anlatımım burda bitti ama tabi ki her şey kurulumla bitmiyor. Ciddi testler yapmanızı ve çıkabilecek sorunlarını araştırmanızı tavsiye ediyorum.



Ek not:Eğer pasif sunucunuz hep offline durumda kalıyorsa ve aktiften pasife geçiş yapılamıyorsa;cluster veya system loglarınızdacorosync[3501]:   [TOTEM ] Retransmit List: 8 b d f 11 14 16 18 1a 1c benzeri satırlar varsa;

veya aşağıdaki satırlara benzer satırlar varsa;info: crm_timer_popped: Wait Timer (I_NULL) just popped (2000ms)warning: do_lrm_control: Failed to sign on to the LRM 22 (30 max) times

iki sunucuyu da tamamen kapatın. Mümkünse fişten çekin ve tekrar başlatın. Bu şekilde sorun düzeldi.

Hiç yorum yok:

Yorum Gönder