01- Patroni Cluster on Ubuntu22.04 - Postgresql & ETCD Installation & Configuration (on the same node)

Today we are going to setup a Postgresql Patroni Cluster with HAProxy. A Patroni cluster is a high availability PostgreSQL cluster managed by Patroni, an open-source tool that automates PostgreSQL replication and failover. Patroni makes a PostgreSQL cluster "smart" by using a distributed key-value store to elect a leader node (primary) and manage replica nodes (standbys).  It ensures there's always one writable primary and handles automatic failover if that primary becomes unavailable. For leader election and cluster coordination we will be using ETCD (Distributed Key-Value Store -DCS) . The OS I am using is Ubuntu 22.04 and Postgresql version is 17.04 which is the latest stable version at the moment. In this article, I will be installing ETCD and Patroni on the same nodes.

 

The infrastructure that I am building today is:

 

The procedure that I will be following is as follows:

Install Postgresql
Install & Configure and Start ETCD
Install & Configure and Start Patroni
Install & Configure HAProxy and Keepalived

 

On all Postgres nodes (postgres01,02 and 03):

Update the postgresql repo.

#first switch to user root
sudo su
apt update
apt install -y postgresql-common 
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh

 

Install Postgres and additional modules

apt update
apt install -y postgresql postgresql-contrib

 

We will configure Postgresql later. Stop & disable postgresql service because patroni will handle the lifecycle of postgres and systemctl will not manage the service.

systemctl stop postgresql
systemctl disable postgresql

 

ETCD Installation:

On all Postgres nodes (postgres01,02 and 03):

Make sure curl is installed on your system

apt install -y wget curl

 

I am going to install ETCD version 3.5.19.

You can check the current etcd releases from: https://github.com/etcd-io/etcd/releases.

wget https://github.com/etcd-io/etcd/releases/download/v3.5.19/etcd-v3.5.19-linux-amd64.tar.gz
tar xvf etcd-v3.5.19-linux-amd64.tar.gz
mv etcd-v3.5.19-linux-amd64 etcd

 

In etcd folder I see 3 binary files. Their filename starts with etcd.  Move these files to /usr/local/bin

mv etcd/etcd* /usr/local/bin/

 

Create a service user for etcd service. This user's home directory is /var/lib/etcd and user can not sign in.

useradd --system --home /var/lib/etcd --shell /bin/false etcd

 

ETCD Configuration:

Create a data directory for etcd. I am also cretaing an environment file for the service. Once the etcd service starts these environmental variables will be applied.

mkdir -p /etc/etcd
chown -R etcd:etcd /etc/etcd
nano /etc/etcd/etcd.env

 

Cluster state is new for now. We will change it to existing after ETCD cluster up and running.

etcd.env Node1:

ETCD_NAME="postgresql-01"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_INITIAL_CLUSTER="postgresql-01=http://192.168.1.144:2380,postgresql-02=http://192.168.1.145:2380,postgresql-03=http://192.168.1.146:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.144:2380"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.144:2379"

etcd.env Node2:

ETCD_NAME="postgresql-02"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_INITIAL_CLUSTER="postgresql-01=http://192.168.1.144:2380,postgresql-02=http://192.168.1.145:2380,postgresql-03=http://192.168.1.146:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.145:2380"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.145:2379"

etcd.env Node3:

ETCD_NAME="postgresql-03"
ETCD_DATA_DIR="/var/lib/etcd"
ETCD_INITIAL_CLUSTER="postgresql-01=http://192.168.1.144:2380,postgresql-02=http://192.168.1.145:2380,postgresql-03=http://192.168.1.146:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.1.146:2380"
ETCD_LISTEN_PEER_URLS="http://0.0.0.0:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.146:2379"

 

Now let’s create a service for etcd on all 3 nodes. Configuration is the same on all etcd nodes.

nano /etc/systemd/system/etcd.service
[Unit]
Description=etcd key-value store
Documentation=https://github.com/etcd-io/etcd
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd
EnvironmentFile=/etc/etcd/etcd.env
ExecStart=/usr/local/bin/etcd
Restart=always
RestartSec=10s
LimitNOFILE=40000
User=etcd
Group=etcd

[Install]
WantedBy=multi-user.target

 

We need to create a directory for etcd (ETCD_DATA_DIR) defined in environment file.

mkdir -p /var/lib/etcd
chown -R etcd:etcd /var/lib/etcd

 

Reload daemon and enable the service all on 3 nodes

systemctl daemon-reload
systemctl enable etcd

 

Then start service on all 3 nodes (this looks like it’s hanging on the first node but once you add another node it will complete). 

Status should be active. You can see etcd log by using journalctl command like below. 

systemctl start etcd
systemctl status etcd
journalctl -u etcd -f
etcdctl member list --endpoints=http://localhost:2379

 

The last command above lists the cluster members

 

To see the leader node, run

etcdctl --endpoints=http://192.168.1.144:2379,http://192.168.1.145:2379,http://192.168.1.146:2379 endpoint status --write-out=table

 

To check etcd node health status

etcdctl endpoint health --endpoints=http://192.168.1.144:2379,http://192.168.1.145:2379,http://192.168.1.146:2379 endpoint status --write-out=table

 

In the next article, We will install and configure Patroni.