📜 ⬆️ ⬇️

Configuring Active / Passive PostgreSQL Cluster using Pacemaker, Corosync, and DRBD (CentOS 5.5)

This article explains how to configure your PostgreSQL Active / Passive cluster using Pacemaker, Corosync and DRBD.
Prepared by Raphael Marangoni, from the team BRLink Servidor Linux

1. Notes:



Linux distribution:

The Centos 5.5 distribution was taken as a basis, but you can use Red Hat Linux or Fedore Core as a basis.
We will use DRBD for replicating PostgreSQL data between nodes and you need to have a disk or partition exclusively of DRBD.
Remember: disk partitioning must be done during installation.

Network equipment / Topology:

We use two Gigabit NIC's per node, one (eth0) to connect to the network (LAN), and the other (eth1) with a crossover connection cable for both nodes. A crossover cable serves for system performance.
And so, we will use two physical nodes, node1.clusterbr.int and node2.clusterbr.int:
node1.clusterbr.int: ip of the first node 10.0.0.191 (LAN) and ip 172.16.0.1 (cross connect)
node2.clusterbr.int: ip 10.0.0.192 (LAN) and IP 172.16.0.2 (cross connect)
dbip.clusterbr.int: cluster ip, 10.0.0.190 (All applications must specify this IP to access PostgreSQL)
* Cross connect I will write as cross over
')
Wheels:

Both nodes have two sections:
/ dev / sda: for OSes;
/ dev / sdb: for DRBD.

PostgreSQL:

PostgreSQL version 8.5, all data that will be stored on DRBD will be used within our cluster.

2. Preparation of nodes:


Disable SELINUX:
vi /etc/selinux/config

(We rule only this line, the rest is left as is)
SELINUX=disabled

Configure the hostname and gateway nodes:
vi /etc/sysconfig/network

node1:
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=node1.clusterbr.int
GATEWAY=10.0.0.9
node2:
NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=node2.clusterbr.int
GATEWAY=10.0.0.9


Configuring network interfaces:
node1:
LAN interface:
vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
BOOTPROTO=static
IPADDR=10.0.0.191
NETMASK=255.255.255.0
ONBOOT=yes
HWADDR=a6:1e:3d:67:66:78


Cross-over / DRBD interface:
vi /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1
BOOTPROTO=static
IPADDR=172.16.0.1
NETMASK=255.255.255.0
ONBOOT=yes
HWADDR=ee:ef:ff:9a:9a:57


node2:
LAN interface:
vi /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth0
BOOTPROTO=static
IPADDR=10.0.0.192
NETMASK=255.255.255.0
ONBOOT=yes
HWADDR=52:52:a1:1a:62:32


Cross-over / DRBD interface:
vi /etc/sysconfig/network-scripts/ifcfg-eth1

DEVICE=eth1
BOOTPROTO=static
IPADDR=172.16.0.2
NETMASK=255.255.255.0
ONBOOT=yes
HWADDR=1a:18:b2:50:96:1e


DNS Setup:
vi /etc/resolv.conf

search clusterbr.int
nameserver 10.0.0.9


Hostname setting:
The configuration is the same on both nodes:
vi /etc/hosts

127.0.0.1 localhost.localdomain localhost
10.0.0.191 node1.clusterbr.int node1
10.0.0.192 node2.clusterbr.int node2
10.0.0.190 dbip.clusterbr.int node2


Check the network:
node1:
Ping node2 (via LAN interface):
ping -c 2 node2

[root@node1 ~]# ping -c 2 node2
PING node2 (10.0.0.192) 56(84) bytes of data.
64 bytes from node2 (10.0.0.192): icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from node2 (10.0.0.192): icmp_seq=2 ttl=64 time=0.082 ms
--- node2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.082/0.085/0.089/0.009 ms


Ping node2 (via cross-over interface):
ping -c 2 172.16.0.2

[root@node1 ~]# ping -c 2 172.16.0.2
PING 172.16.0.2 (172.16.0.2) 56(84) bytes of data.
64 bytes from 172.16.0.2: icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from 172.16.0.2: icmp_seq=2 ttl=64 time=0.083 ms
--- 172.16.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.083/0.083/0.083/0.000 ms


node2:
Ping node1 (via LAN interface):
ping -c 2 node1
[root@node2 ~]# ping -c 2 node1
PING node1 (10.0.0.191) 56(84) bytes of data.
64 bytes from node1 (10.0.0.191): icmp_seq=1 ttl=64 time=0.068 ms
64 bytes from node1 (10.0.0.191): icmp_seq=2 ttl=64 time=0.063 ms
--- node1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.063/0.065/0.068/0.008 ms


Ping node1 (via cross-over interface):
ping -c 2 172.16.0.1

[root@node2 ~]# ping -c 2 172.16.0.1
PING 172.16.0.1 (172.16.0.1) 56(84) bytes of data.
64 bytes from 172.16.0.1: icmp_seq=1 ttl=64 time=1.36 ms
64 bytes from 172.16.0.1: icmp_seq=2 ttl=64 time=0.075 ms
--- 172.16.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.075/0.722/1.369/0.647 ms


Set up initialization parameters:
(The change is made only in this line, the rest is left as is)
vi /etc/inittab

id:3:initdefault:


Let's look at the running services:
chkconfig --list | grep 3:sim

[root@node1 ~]# chkconfig --list | grep 3:sim
acpid 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
anacron 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
apmd 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
atd 0:não 1:não 2:não 3:sim 4:sim 5:sim 6:não
cpuspeed 0:não 1:sim 2:sim 3:sim 4:sim 5:sim 6:não
crond 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
irqbalance 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
kudzu 0:não 1:não 2:não 3:sim 4:sim 5:sim 6:não
network 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
rawdevices 0:não 1:não 2:não 3:sim 4:sim 5:sim 6:não
sshd 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não
syslog 0:não 1:não 2:sim 3:sim 4:sim 5:sim 6:não


Now after performing the above described actions, we will overload our nodes.

3. Install the necessary software


We put the necessary package:
yum install -y postgresql84** gcc perl-mailtools perl-dbi php-pgsql

Add a repository:
rpm -Uvh download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-4.noarch.rpm

Now we install the ClusterLabs EPEL repository:
wget -O /etc/yum.repos.d/pacemaker.repo clusterlabs.org/rpm/epel-5/clusterlabs.repo

Install the cluster and DRBD packages:
yum install -y pacemaker corosync drbd83 kmod-drbd83 heartbeat

4. Configure DRBD

First, we need to configure DRBD on both nodes:
vi /etc/drbd.conf

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.clusterbr.int {
device /dev/drbd0;
disk /dev/sdb;
address 172.16.0.1:7791;
meta-disk internal;
}
on node2.clusterbr.int {
device /dev/drbd0;
disk /dev/sdb;
address 172.16.0.2:7791;
meta-disk internal;
}
}


Main configuration items:


resource: Refer to the resource that will be managed by DRBD, and we called it “Postgres”
disk: Specify the device that will use DRBD (disk or partition)
address: The IP address and port that DRBD will use (we specified the cross-over interfaces)
syncer: data transfer rate between nodes
If you have any questions or concerns, you can always use the manual: www.drbd.org/users-guide-emb

After this configuration, we can create metadata about the PostgreSQL resources.
Doing the following:
node1:
drbdadm create-md postgres

[root@node1 ~]# drbdadm create-md postgres
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.


node2:
drbdadm create-md postgres

[root@node2 ~]# drbdadm create-md postgres
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.


Next, we need to create a resource before connecting, again, perform the following actions on both nodes:
drbdadm up postgres

Now we can do the initial synchronization between the nodes, synchronize to the main node by selecting node1:
drbdadm -- --overwrite-data-of-peer primary postgres

To check the synchronization look:
cat /proc/drbd

[root@node1 ~]# cat /proc/drbd
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:09
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r----
ns:48128 nr:0 dw:0 dr:48128 al:0 bm:2 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:8340188
[>....................] sync'ed: 0.6% (8144/8188)M delay_probe: 7
finish: 0:11:29 speed: 12,032 (12,032) K/sec


Wait for the synchronization to complete. The process can take a long time, it all depends on the size, disk performance and of course the speed of the network cluster interfaces.
After the synchronization process is over, we can look at the state of the postgre resources
node1:
cat /proc/drbd

[root@node1 ~]# cat /proc/drbd
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:09
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:8388316 nr:0 dw:0 dr:8388316 al:0 bm:512 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0


node2:
cat /proc/drbd

[root@node2 ~]# cat /proc/drbd
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:09
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r----
ns:0 nr:8388316 dw:8388316 dr:0 al:0 bm:512 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0


5. Configure PostgreSQL

First, we need to start the DRBD service on both nodes.
/etc/init.d/drbd start

As previously mentioned, node1 is our main node and therefore we will execute the command on it:
cat /proc/drbd

[root@node1 ~]# cat /proc/drbd
version: 8.3.8 (api:88/proto:86-94)
GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by mockbuild@builder10.centos.org, 2010-06-04 08:04:09
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r----
ns:8388316 nr:0 dw:0 dr:8388316 al:0 bm:512 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:0


Primary / Secondary means that the local server is primary and the other is secondary.

Next we need to format DRBD and select ext3 as the file system.
node1:
mkfs.ext3 /dev/drbd0

After that, we can mount the device as a standard PostgreSQL location.
Mount the partition on the node:
node1:
mount -t ext3 /dev/drbd0 /var/lib/pgsql

Next, change the owner and mount group:
node1:
chown postgres.postgres /var/lib/pgsql

Now we initialize the PostgreSQL database:
node1:
su - postgres
initdb /var/lib/pgsql/data
exit


I prefer to verify authentication on the cluster and ip nodes:
node1:
echo "host all all 10.0.0.191/32 trust" >> /var/lib/pgsql/data/pg_hba.conf
echo "host all all 10.0.0.192/32 trust" >> /var/lib/pgsql/data/pg_hba.conf
echo "host all all 10.0.0.190/32 trust" >> /var/lib/pgsql/data/pg_hba.conf


Next we will configure PostgreSQL to work on all interfaces:
node1:
vi /var/lib/pgsql/data/postgresql.conf

Uncomment only this line:
listen_addresses = '0.0.0.0'

Run PostgreSQL:
node1:
/etc/init.d/postgresql start

Now create a user with administrator rights to manage PostgeSQL:
node1:
su - postgres
createuser --superuser admpgsql --pwprompt


You need to set the password on admpgsql

After that we will create a database and fill it:
node1:
su - postgres
createdb pgbench
pgbench -i pgbench


pgbench will fill in some base information:
pgbench -i pgbench

-bash-3.2$ pgbench -i pgbench
NOTA: tabela "pgbench_branches" não existe, ignorando
NOTA: tabela "pgbench_tellers" não existe, ignorando
NOTA: tabela "pgbench_accounts" não existe, ignorando
NOTA: tabela "pgbench_history" não existe, ignorando
creating tables...
10000 tuples done.
20000 tuples done.
30000 tuples done.
40000 tuples done.
50000 tuples done.
60000 tuples done.
70000 tuples done.
80000 tuples done.
90000 tuples done.
100000 tuples done.
set primary key...
NOTA: ALTER TABLE / ADD PRIMARY KEY criará à ndice implà cito "pgbench_branches_pkey" na tabela "pgbench_branches"
NOTA: ALTER TABLE / ADD PRIMARY KEY criará à ndice implà cito "pgbench_tellers_pkey" na tabela "pgbench_tellers"
NOTA: ALTER TABLE / ADD PRIMARY KEY criará à ndice implà cito "pgbench_accounts_pkey" na tabela "pgbench_accounts"
vacuum...done.


Now we turn to the database to check:
node1:
psql -U admpgsql -d pgbench
select * from pgbench_tellers;

psql -U admpgsql -d pgbench
psql (8.4.5)
Digite "help" para ajuda.

pgbench=# select * from pgbench_tellers;
tid | bid | tbalance | filler
-----+-----+----------+--------
1 | 1 | 0 |
2 | 1 | 0 |
3 | 1 | 0 |
4 | 1 | 0 |
5 | 1 | 0 |
6 | 1 | 0 |
7 | 1 | 0 |
8 | 1 | 0 |
9 | 1 | 0 |
10 | 1 | 0 |
(10 registros)


At this setting is over.

Check PostgreSQL for node2:
But before we start working with the Pacemaker service, it’s better to make sure that postgre will work on node2.
First, on node1 we have to stop postgresql:
node1:
/etc/init.d/postgresql stop

Then install DRBD once:
umount /dev/drbd0

Now we will make node1 as secondary on DRBD:
drbdadm secondary postgres

Now on node2 let's make DRBD primary:
node2:
drbdadm primary postgres

Next, install the DRBD device:
mount -t ext3 /dev/drbd0 /var/lib/pgsql/

and finally run PostgreSQL:
/etc/init.d/postgresql start

Now let's check if we can access pgbench by node2:
psql -U admpgsql -d pgbench
select * from pgbench_tellers;

[root@node2 ~]# psql -U admpgsql -d pgbench
psql (8.4.5)
Digite "help" para ajuda.

pgbench=# select * from pgbench_tellers;
tid | bid | tbalance | filler
-----+-----+----------+--------
1 | 1 | 0 |
2 | 1 | 0 |
3 | 1 | 0 |
4 | 1 | 0 |
5 | 1 | 0 |
6 | 1 | 0 |
7 | 1 | 0 |
8 | 1 | 0 |
9 | 1 | 0 |
10 | 1 | 0 |
(10 registros)


After we make sure everything is working fine, we need to initialize our cluster:
node2:
/etc/init.d/postgresql stop
umount /dev/drbd0
drbdadm secondary postgres
/etc/init.d/drbd stop


node1:
drbdadm primary postgres
/etc/init.d/drbd stop


We need to make all services be disabled on both nodes by executing the commands on both nodes:
chkconfig --level 35 drbd off
chkconfig --level 35 postgresql off


6. Configure Corosync (openAIS)


Making the setting of Corosync
node1:
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/`


Then check the data:
env | grep ais_

The variable ais_addr should contain the network address that the cluster will listen to. In our case, this is 10.0.0.0.
Next we will create a corosync configuration file:
cp /etc/corosync/corosync.conf.example /etc/corosync/corosync.conf
sed -i.gres "s/.*mcastaddr:.*/mcastaddr:\ $ais_mcast/g" /etc/corosync/corosync.conf
sed -i.gres "s/.*mcastport:.*/mcastport:\ $ais_port/g" /etc/corosync/corosync.conf
sed -i.gres "s/.*bindnetaddr:.*/bindnetaddr:\ $ais_addr/g" /etc/corosync/corosync.conf


Add the following to our config:
cat <<-END >>/etc/corosync/corosync.conf
aisexec {
user: root
group: root
}
END
cat <<-END >>/etc/corosync/corosync.conf
service {
# Load the Pacemaker Cluster Resource Manager
name: pacemaker
ver: 0
}
END


The /etc/corosync/corosync.conf file looks like this:
compatibility: whitetank

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

logging {
fileline: off
to_stderr: yes
to_logfile: yes
to_syslog: yes
logfile: /tmp/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
}


From node1 we will throw the configuration on node2:
scp /etc/corosync/* node2:/etc/corosync/

On both nodes we need to create a catalog of heads:
mkdir /var/log/cluster/

Now run corosync
node1:
/etc/init.d/corosync start

Let's check whether our service is in order:
node1:
grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/messages

[root@node1 bin]# grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/messages
Apr 7 12:37:21 node1 corosync[23533]: [MAIN ] Corosync Cluster Engine ('1.2.0'): started and ready to provide service.
Apr 7 12:37:21 node1 corosync[23533]: [MAIN ] Successfully read main configuration file '/etc/corosync/corosync.conf'.


Check our interfaces that corosync should listen to:
grep TOTEM /var/log/messages

[root@node1 bin]# grep TOTEM /var/log/messages
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] Initializing transport (UDP/IP).
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] Initializing transmit/receive security: libtomcrypt SOBER128/SHA1HMAC (mode 0).
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] The network interface [10.0.0.191] is now up.
Apr 7 12:37:21 node1 corosync[23533]: [TOTEM ] A processor joined or left the membership and a new membership was formed.


Next, look at the pacemaker:
grep pcmk_startup /var/log/messages

[root@node1 bin]# grep pcmk_startup /var/log/messages
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: CRM: Initialized
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] Logging: Initialized pcmk_startup
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: Maximum core file size is: 4294967295
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: Service: 9
Apr 7 12:37:21 node1 corosync[23533]: [pcmk ] info: pcmk_startup: Local hostname: node1


We look in the processes of our corosync:
ps axf

[root@node1 bin]# ps axf
(should contain something like this)
23533 ? Ssl 0:00 corosync
23539 ? SLs 0:00 \_ /usr/lib/heartbeat/stonithd
23540 ? S 0:00 \_ /usr/lib/heartbeat/cib
23541 ? S 0:00 \_ /usr/lib/heartbeat/lrmd
23542 ? S 0:00 \_ /usr/lib/heartbeat/attrd
23543 ? S 0:00 \_ /usr/lib/heartbeat/pengine
23544 ? S 0:00 \_ /usr/lib/heartbeat/crmd


If everything went well, then we can transfer the corosync to node2
node2:
/etc/init.d/corosync start

Perform a cluster check on both nodes:
crm_mon -1

[root@node1 ~]# crm_mon -1
============
Last updated: Fri Oct 29 17:44:36 2010
Stack: openais
Current DC: node1.clusterbr.int - partition with quorum
Version: 1.0.9-89bd754939df5150de7cd76835f98fe90851b677
2 Nodes configured, 2 expected votes
0 Resources configured.
============

Online: [ node1.clusterbr.int node2.clusterbr.int ]


We must be sure that both sites are defined as online.

Add corosync to autoload on both nodes:
chkconfig --level 35 corosync on

7. Configure Pacemaker


Important commands to manage the cluster:

Cluster configuration check:
crm_verify -L

Get the list and status of the cluster:
crm_mon -1

Cluster configuration list:
crm configure show

List of open crm consoles
crm

Stonith setup
When checking the cluster configuration, we should get some errors:
crm_verify -L

Thus, to disable Stonith, we need to execute the following command on one of the nodes:
crm configure property stonith-enabled=false

Now the cluster configuration check should pass without errors:
crm_verify -L

Cluster basic settings

Run the command on any node from our nodes:
crm configure property no-quorum-policy=ignore

Setting the value will change the resource to another node, thus if synchronization fails at one of the nodes, synchronization will be intercepted by another node.
crm configure rsc_defaults resource-stickiness=100

Let's see our configuration:
crm configure show

[root@node1 ~]# crm configure show
node node1.clusterbr.int
node node2.clusterbr.int
property $id="cib-bootstrap-options" \
dc-version="1.0.9-89bd754939df5150de7cd76835f98fe90851b677" \
cluster-infrastructure="openais" \
expected-quorum-votes="2" \
stonith-enabled="false" \
no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
resource-stickiness="100"


DBIP configuration

Add to the DBIP config the ip-address of our cluster:
crm configure primitive DBIP ocf:heartbeat:IPaddr2 \
params ip=10.0.0.190 cidr_netmask=24 \
op monitor interval=30s


Checking status:
crm_mon -1

[root@node1 ~]# crm_mon -1
============
Last updated: Fri Oct 29 17:47:53 2010
Stack: openais
Current DC: node1.clusterbr.int - partition with quorum
Version: 1.0.9-89bd754939df5150de7cd76835f98fe90851b677
2 Nodes configured, 2 expected votes
1 Resources configured.
============

Online: [ node2.clusterbr.int node1.clusterbr.int ]

DBIP (ocf::heartbeat:IPaddr2): Started node2.clusterbr.int


Note that the state of the cluster shows where our resource is working, at the moment the work is on node2, but it can also work on node1

DRBD configuration on cluster

Add DRBD to our cluster:
crm configure primitive drbd_postgres ocf:linbit:drbd \
params drbd_resource="postgres" \
op monitor interval="15s"


Configure the primary and secondary nodes:
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"


Install DRBD:
crm configure primitive postgres_fs ocf:heartbeat:Filesystem \
params device="/dev/drbd0" directory="/var/lib/pgsql" fstype="ext3"


Configuring PostgreSQL on a cluster

Add postgresql to our cluster:
crm configure primitive postgresql ocf:heartbeat:pgsql \
op monitor depth="0" timeout="30" interval="30"


Now we need to add our services to the postgres group
crm configure group postgres postgres_fs DBIP postgresql
crm configure colocation postgres_on_drbd inf: postgres ms_drbd_postgres:Master


Configuring postgre to run after:
DRBDcrm configure order postgres_after_drbd inf: ms_drbd_postgres:promote postgres:start

Let's look at the cluster configuration
crm configure show

[root@node1 ~]# crm configure show
node node1.clusterbr.int
node node2.clusterbr.int
primitive DBIP ocf:heartbeat:IPaddr2 \
params ip="10.0.0.190" cidr_netmask="24" \
op monitor interval="30s"
primitive drbd_postgres ocf:linbit:drbd \
params drbd_resource="postgres" \
op monitor interval="15s"
primitive postgres_fs ocf:heartbeat:Filesystem \
params device="/dev/drbd0" directory="/var/lib/pgsql" fstype="ext3"
primitive postgresql ocf:heartbeat:pgsql \
op monitor interval="30" timeout="30" depth="0" \
meta target-role="Started"
group postgres postgres_fs DBIP postgresql \
meta target-role="Started"
ms ms_drbd_postgres drbd_postgres \
meta master-max="1" master-node-max="1" clone-max="2" clone-node-max="1" notify="true"
colocation postgres_on_drbd inf: postgres ms_drbd_postgres:Master
order postgres_after_drbd inf: ms_drbd_postgres:promote postgres:start
property $id="cib-bootstrap-options" \
dc-version="1.0.9-89bd754939df5150de7cd76835f98fe90851b677" \
cluster-infrastructure="openais" \
expected-quorum-votes="2" \
stonith-enabled="false" \
no-quorum-policy="ignore"
rsc_defaults $id="rsc-options" \
resource-stickiness="100"
[root@node1 ~]#


Configure the preferred node:
crm configure location master-prefer-node1 DBIP 50: node1.clusterbr.int

Checking status:
crm_mon -1

[root@node2 ~]# crm_mon -1
============
Last updated: Fri Oct 29 19:54:09 2010
Stack: openais
Current DC: node2.clusterbr.int - partition with quorum
Version: 1.0.9-89bd754939df5150de7cd76835f98fe90851b677
2 Nodes configured, 2 expected votes
2 Resources configured.
============

Online: [ node2.clusterbr.int node1.clusterbr.int ]

Master/Slave Set: ms_drbd_postgres
Masters: [ node2.clusterbr.int ]
Slaves: [ node1.clusterbr.int ]
Resource Group: postgres
postgres_fs (ocf::heartbeat:Filesystem): Started node2.clusterbr.int
DBIP (ocf::heartbeat:IPaddr2): Started node2.clusterbr.int
postgresql (ocf::heartbeat:pgsql): Started node2.clusterbr.int


If you have errors, you must overload both nodes so that the new corosync configurations are accepted by the system. Also, after rebooting the system, we need to connect to the DBIP (10.0.0.190) via TCP port 5432 to the postgres service.

Cluster management

Transferring a resource to another node:
crm resource migrate postgres node1.clusterbr.int

Removing the migrate command:
crm resource unmigrate postgres

We clean our messages:
crm resource cleanup postgres

Stop the PostgreSQL service
crm resource stop postgresql

Starting PostgreSQL Service
crm resource start postgresql

8. Create a web interface for service status


The web interface will be convenient for monitoring our cluster.
Start apache:
/etc/init.d/httpd start
chkconfig --level 35 httpd on


Create a directory for the cluster (DocumentRoot):
mkdir /var/www/html/cluster/

To generate pages do the following:
crm_mon --daemonize --as-html /var/www/html/cluster/index.html

and let's set this whole thing to autoload:
echo "crm_mon --daemonize --as-html /var/www/html/cluster/index.html" >> /etc/rc.d/rc.local

Check the availability of our face in the browser:
10.0.0.190/cluster

9. Installing phppgAdmin to work with postgresql


Perform actions on both nodes:
mkdir /download
cd /download
wget 'http://downloads.sourceforge.net/project/phppgadmin/phpPgAdmin%20%5Bbeta%5D/phpPgAdmin-5.0/phpPgAdmin-5.0-beta2.tar.bz2?r=http%3A%2F%2Fphppgadmin.sourceforge.net%2F%3Fpage%3Ddownload&ts=1288189530&use_mirror=ufpr'


Install:
tar -jxvf phpPgAdmin-5.0-beta2.tar.bz2
mv phpPgAdmin-5.0-beta2 /var/www/html/cluster-pgadmin
chown apache.apache -R /var/www/html/cluster-pgadmin


Go to the browser at 10.0.0.190/cluster-pgadmin
P.S. Login and password were entered during postgresql installation

10. Network access


If you need access to postgresql from the local network, do not forget to set up authentication on Postgres

Here we set the MD5 network authentication to 10.0.0.0/24
echo "host all all 10.0.0.0/24 md5">> /var/lib/pgsql/data/pg_hba.conf

Restart postgres:
crm resource stop postgresql
crm resource start postgresql


11. Monitoring


Cluster monitoring is a mandatory part of the entire script execution process. I suggest you monitor using Zabbix, to do this, install Zabbix agent on each node and configure monitoring for these items:

1. Checking ping for accessibility (10.0.0.191, 10.0.0.192 and 172.16.0.1, 172.16.0.2)
2. Check availability DBIP (cluster ip) 10.0.0.190
3. Checking TCP port 5432 for DBIP 10.0.0.190
4. Checking the CPU, RAM and Disk
5. You can use the monitor_drbd.sh script (the result returns 1 when everything is OK and 0 when there are problems)
Script monitor_drbd.sh for Zabbix:
#!/bin/bash

CHECK=`cat /proc/drbd | grep UpToDate/UpToDate | cut -d: -f5 | cut -c1-17`
STRING_OK="UpToDate/UpToDate"

# Comparando as duas.
if [ "$CHECK" == "$STRING_OK" ] ; then
# Is ok, returning 1
echo 1;
else
# Not ok, returning 0
echo 0;
fi


PS If you see typos or do not match in the translation, very much I ask you to write in the LAN.
I will quickly fix everything for the benefit of society.

Source: https://habr.com/ru/post/108833/


All Articles