Mit den richtigen Zutaten ist es natürlich möglich einen Patroni-Cluster aufzubauen, der sich über mehrere völlig unabhängige Cloud-Umgebungen erstreckt.
Und die Zutaten kennen wir schon: Ein funktionierender Consul-Cluster (idealerweise auch über mehrere unabhängige Cloud-Umgebungen hinweg aufgebaut) und nebula:
bzw. die "managed" Variante von defined.net:

Sowohl bei den Consul Servern, die den Cluster bilden, als auch auf den Consul Clients, die auf den Patroni-Nodes installiert werden, muß darauf geachtet werden, die verschiedenen Dienste an das Netzwerkinterface des Overlay-Netzes zu binden.
bind_addr = "{{ GetInterfaceIP \"nebula1\" }}"
advertise_addr = "{{ GetInterfaceIP \"nebula1\" }}"
client_addr = "{{ GetInterfaceIP \"nebula1\" }}"
addresses {
http = "{{ GetInterfaceIP \"nebula1\" }}"
https = "{{ GetInterfaceIP \"nebula1\" }}"
grpc = "{{ GetInterfaceIP \"nebula1\" }}"
}
Da der Cluster in verschiedenen Cloud-Umgebungen aufgebaut wird, ist ein automatisches Cloud Auto Join leider nicht möglich.
Für die Patroni-Konfiguration ist es sinnvoll, den Namen des Knotens so zu wählen, dass die jeweilige Cloud-Umgebung daraus hervorgeht.
Auch in der Patroni-Konfiguration müssen die Dienste an das Netzwerkinterface des Overlay-Netzes gebunden werden:
scope: patroni42
namespace: terra42
name: prod1-postgresql-0
restapi:
listen: 10.21.20.53:8008
connect_address: 10.21.20.53:8008
consul:
host: 10.21.20.53:8500
register_service: true
cacert: /etc/consul/certificates/ca.pem
cert: /etc/consul/certificates/cert.pem
key: /etc/consul/certificates/private_key.pem
dc: de-west
bootstrap:
dcs:
ttl: 30
loop_wait: 10
[...]
pg_hba: # Add following lines to pg_hba.conf after running 'initdb'
- host replication replicator 127.0.0.1/32 md5
- host replication replicator 10.21.20.0/24 md5
- host all all 0.0.0.0/0 md5
- local all pmm md5
[...]
postgresql:
listen: "*:5432"
connect_address: 10.21.20.53:5432
data_dir: /var/lib/postgresql/data
[...]
Natürlich müssen die entsprechenden Ports auch in der Nebula-Konfiguration bzw. in der defined-Role freigegeben werden:
[...]
firewall:
outbound_action: drop
inbound_action: drop
conntrack:
tcp_timeout: 12m
udp_timeout: 3m
default_timeout: 10m
outbound:
- port: any
proto: any
host: any
inbound:
- port: any
proto: icmp
host: any
- port: 8600
proto: tcp
host: any
[...]
- port: 5432
proto: tcp
host: any
- port: 8008
proto: tcp
host: any
Beim Start von Patroni baut sich dann der Cluster auf:
postgres@postgresql-0:~$ patronictl -c patroni.yml list
+ Cluster: patroni42 (7550685979936816804) --+-----------+----+-----------+
| Member | Host | Role | State | TL | Lag in MB |
+--------------------+-------------+---------+-----------+----+-----------+
| prod1-postgresql-0 | 10.21.20.53 | Leader | running | 2 | |
| prod4-postgresql-0 | 10.21.20.54 | Replica | streaming | 2 | 0 |
+--------------------+-------------+---------+-----------+----+-----------+
Für die Datenbank-Clients ist der Status des Clusters jederzeit per Consul-DNS zu erkennen, da Patroni den Dienst ja automatisch im Consul registiert hat:
root@triton-consul-0:~# consul catalog services -tags
consul
patroni42 master,primary,replica
postgres@postgresql-0:~$ dig +short @10.21.20.53 -p 8600 consul.service.consul
10.21.20.50
10.21.20.52
10.21.20.51
postgres@postgresql-0:~$ dig +short @10.21.20.53 -p 8600 primary.patroni42.service.consul
10.21.20.53
postgres@postgresql-0:~$ dig +short @10.21.20.53 -p 8600 replica.patroni42.service.consul
10.21.20.54
Ich empfehle, DNS lokal so zu konfigurieren, dass Anfragen an die Domain "service.consul." immer an den lokalen Consul Client umgeleitet werden. Die Consul Dokumentation enthält dafür die entsprechenden Anleitungen. Ich hatte das unter "systemd-resolved vs. split-horizon DNS" auch schon beschrieben.
Natürlich kann und sollte man auch in so einem Setup dann "Percona Monitoring and Management - PMM" (inzwischen schon in der Version 3.4.0 erschienen) einsetzen, um einen Einblick in die Vorgänge im Cluster zu bekommen.