Skip to content

Commit 641a79e

Browse files
vlsiclaude
andcommitted
feat: replace pod IP with DNS name for Patroni connectivity
Replace LISTEN_ADDR (pod IP) with POD_DNS_NAME (DNS FQDN) for Patroni REST API and PostgreSQL connect addresses to enable stable addressing across pod restarts. Changes: - Add POD_NAME, HEADLESS_SERVICE, and POD_DNS_NAME environment variables to Patroni StatefulSet pods - Create patroni-headless Service for DNS-based pod discovery - Update patroni.config.yaml to use ${POD_DNS_NAME} for pod_ip, connect_address (PostgreSQL), and connect_address (REST API) - Register patroni-headless service creation in reconciler Reasons: - Pod IPs are ephemeral and change on restarts, causing connection issues - DNS names (pod-name.service.namespace.svc.cluster.local) are stable - Improves reliability of Patroni DCS registration and cluster communication - Aligns with Kubernetes best practices for StatefulSet networking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 2377963 commit 641a79e

6 files changed

Lines changed: 58 additions & 9 deletions

File tree

build/configs/patroni.config.yaml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ kubernetes:
5151
app: ${PATRONI_CLUSTER_NAME}
5252
role_label: pgtype
5353
scope_label: app
54-
pod_ip: ${LISTEN_ADDR}
54+
pod_ip: ${POD_DNS_NAME}
5555
postgresql:
5656
authentication:
5757
replication:
@@ -67,17 +67,17 @@ postgresql:
6767
on_role_change: /setup_endpoint_callback.py
6868
on_start: /setup_endpoint_callback.py
6969
on_stop: /setup_endpoint_callback.py
70-
connect_address: ${LISTEN_ADDR}:5432
70+
connect_address: ${POD_DNS_NAME}:5432
7171
data_dir: /var/lib/pgsql/data/postgresql_${NODE_NAME}
72-
listen: '0.0.0.0, ::0:5432'
72+
listen: '*:5432'
7373
parameters:
7474
unix_socket_directories: /var/run/postgresql, /tmp
7575
pgpass: /tmp/pgpass0
7676
restapi:
77-
connect_address: ${LISTEN_ADDR}:8008
78-
listen: ${LISTEN_ADDR}:8008
77+
connect_address: ${POD_DNS_NAME}:8008
78+
listen: '*:8008'
7979
tags:
8080
clonefrom: false
8181
nofailover: ${DR_MODE}
8282
noloadbalance: false
83-
nosync: false
83+
nosync: false

charts/patroni-services/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ connectionPooler:
410410
'*': "host=pg-patroni-direct port=5432"
411411
pgbouncer:
412412
listen_port: '6432'
413-
listen_addr: '0.0.0.0'
413+
listen_addr: '*'
414414
auth_type: 'md5'
415415
auth_file: '/etc/pgbouncer/userlist.txt'
416416
auth_user: 'pgbouncer'

docs/public/installation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,7 @@ For more information on how to do the Major Upgrade of PostgreSQL, please, follo
833833
```yaml
834834
pgbouncer:
835835
listen_port: '6432'
836-
listen_addr: '0.0.0.0'
836+
listen_addr: '*'
837837
auth_type: 'md5'
838838
auth_file: '/etc/pgbouncer/userlist.txt'
839839
auth_user: 'pgbouncer'

pkg/deployment/patroni.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,23 @@ func NewPatroniStatefulset(cr *patroniv1.PatroniCore, deploymentIdx int, cluster
242242
},
243243
},
244244
},
245+
{
246+
Name: "POD_NAME",
247+
ValueFrom: &corev1.EnvVarSource{
248+
FieldRef: &corev1.ObjectFieldSelector{
249+
APIVersion: "v1",
250+
FieldPath: "metadata.name",
251+
},
252+
},
253+
},
254+
{
255+
Name: "HEADLESS_SERVICE",
256+
Value: "patroni-headless",
257+
},
258+
{
259+
Name: "POD_DNS_NAME",
260+
Value: "$(POD_NAME).$(HEADLESS_SERVICE).$(POD_NAMESPACE).svc.cluster.local",
261+
},
245262
{
246263
Name: "PG_RESOURCES_LIMIT_MEM",
247264
ValueFrom: &corev1.EnvVarSource{
@@ -309,7 +326,7 @@ func NewPatroniStatefulset(cr *patroniv1.PatroniCore, deploymentIdx int, cluster
309326
DNSPolicy: corev1.DNSClusterFirst,
310327
},
311328
},
312-
ServiceName: "backrest-headless",
329+
ServiceName: "patroni-headless",
313330
PodManagementPolicy: appsv1.OrderedReadyPodManagement,
314331
UpdateStrategy: appsv1.StatefulSetUpdateStrategy{Type: appsv1.RollingUpdateStatefulSetStrategyType},
315332
RevisionHistoryLimit: ptr.To[int32](10),

pkg/deployment/pgbackrest.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,30 @@ func GetBackrestHeadless() *corev1.Service {
182182
}
183183
}
184184

185+
func GetPatroniHeadless(clusterName string) *corev1.Service {
186+
labels := map[string]string{"app": clusterName}
187+
ports := []corev1.ServicePort{
188+
{Name: "postgresql", Port: 5432},
189+
{Name: "patroni-api", Port: 8008},
190+
}
191+
return &corev1.Service{
192+
TypeMeta: metav1.TypeMeta{
193+
APIVersion: "v1",
194+
Kind: "Service",
195+
},
196+
ObjectMeta: metav1.ObjectMeta{
197+
Name: "patroni-headless",
198+
Namespace: util.GetNameSpace(),
199+
},
200+
201+
Spec: corev1.ServiceSpec{
202+
Selector: labels,
203+
Ports: ports,
204+
ClusterIP: "None",
205+
},
206+
}
207+
}
208+
185209
func getPgBackRestSettings(pgBackrestSpec *v1.PgBackRest, isStandby bool) string {
186210
var listSettings []string
187211
listSettings = append(listSettings, "[global]")

pkg/reconciler/patroni.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,14 @@ func (r *PatroniReconciler) processPatroniServices(cr *v1.PatroniCore, patroniSp
473473
}
474474
}
475475
}
476+
477+
// Create patroni headless service for DNS-based pod discovery
478+
patroniHeadless := deployment.GetPatroniHeadless(r.cluster.ClusterName)
479+
if err := r.helper.ResourceManager.CreateOrUpdateService(patroniHeadless); err != nil {
480+
logger.Error(fmt.Sprintf("Cannot create service %s", patroniHeadless.Name), zap.Error(err))
481+
return err
482+
}
483+
476484
return nil
477485
}
478486

0 commit comments

Comments
 (0)