Skip to content

Commit 0f030c4

Browse files
authored
feat: leader election (#17)
* feat: leader election * app version
1 parent a7dd13d commit 0f030c4

7 files changed

Lines changed: 81 additions & 6 deletions

File tree

Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ apiVersion: v2
22
name: pgdog-control
33
description: PgDog Control
44
type: application
5-
version: 0.2.12
6-
appVersion: "1a6d7fd0"
5+
version: 0.2.13
6+
appVersion: "29a6513b"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ When `control.rbac.create` is `true` (default), the chart renders:
267267

268268
- A `ServiceAccount` for the control pod. If `control.aws.roleArn` is set, the ServiceAccount also carries the `eks.amazonaws.com/role-arn` annotation, which is what EKS IRSA looks for when handing the pod temporary AWS credentials.
269269
- A `ClusterRole` and `ClusterRoleBinding` granting **read-only** access cluster-wide. This is enough for the dashboard to list namespaces and read deployments, statefulsets, pods, services, configmaps, and secrets in any namespace. It cannot change anything. Pod logs are included so the deployment log view works.
270+
- A namespace-scoped `Role` and `RoleBinding` in the release namespace granting access to `coordination.k8s.io` `Lease` objects for control-plane leader election.
270271
- For each namespace you list in `control.rbac.writeNamespaces`, a namespace-scoped `Role` and `RoleBinding` granting **write** access (create, update, patch, delete) on the resources PgDog actually manages: deployments, statefulsets, services, configmaps, secrets, service accounts, roles, role bindings, and pod disruption budgets. Namespaces not on the list stay strictly read-only.
271272

272273
A typical setup grants write access only to the namespaces where you want PgDog clusters to live:

templates/configmap.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,26 @@ data:
106106
{{- end }}
107107
{{- end }}
108108
109+
{{- with $config.leader }}
110+
111+
[leader]
112+
{{- if hasKey . "enabled" }}
113+
enabled = {{ .enabled }}
114+
{{- end }}
115+
{{- with .lease_name }}
116+
lease_name = {{ . | quote }}
117+
{{- end }}
118+
{{- with .lease_duration_secs }}
119+
lease_duration_secs = {{ . }}
120+
{{- end }}
121+
{{- with .renew_interval_secs }}
122+
renew_interval_secs = {{ . }}
123+
{{- end }}
124+
{{- with .release_timeout_secs }}
125+
release_timeout_secs = {{ . }}
126+
{{- end }}
127+
{{- end }}
128+
109129
{{- with $config.helm }}
110130
111131
[helm]

templates/deployment.yaml

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,22 @@ spec:
99
selector:
1010
matchLabels:
1111
{{- include "pgdog-control.selectorLabels" . | nindent 6 }}
12+
# Readiness is leader-aware so only the elected control pod receives
13+
# Service traffic. New pods normally start as followers, so they do not
14+
# become Ready while the old leader still holds the Lease. Allowing the
15+
# whole old ReplicaSet to be unavailable lets Kubernetes terminate the
16+
# old leader, release the Lease, and promote a new-version pod instead
17+
# of waiting forever for a follower to become Ready.
18+
strategy:
19+
type: RollingUpdate
20+
rollingUpdate:
21+
maxSurge: 0
22+
maxUnavailable: 100%
1223
template:
1324
metadata:
1425
annotations:
26+
meta.helm.sh/release-name: {{ .Release.Name | quote }}
27+
meta.helm.sh/release-namespace: {{ .Release.Namespace | quote }}
1528
# Roll the deployment when any rendered config / secret content
1629
# changes. Each annotation hashes the *template output*, not
1730
# values directly, so transformations applied inside the
@@ -169,12 +182,12 @@ spec:
169182
failureThreshold: 3
170183
readinessProbe:
171184
httpGet:
172-
path: /healthz
185+
path: /readyz
173186
port: {{ .Values.control.port }}
174187
initialDelaySeconds: 30
175-
periodSeconds: 10
176-
timeoutSeconds: 3
177-
failureThreshold: 3
188+
periodSeconds: 2
189+
timeoutSeconds: 1
190+
failureThreshold: 1
178191
volumes:
179192
- name: config
180193
configMap:

templates/rbac.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,35 @@ subjects:
5454
- kind: ServiceAccount
5555
name: {{ include "pgdog-control.control.serviceAccountName" . }}
5656
namespace: {{ .Release.Namespace }}
57+
---
58+
# Namespace-scoped access for control-plane leader election.
59+
apiVersion: rbac.authorization.k8s.io/v1
60+
kind: Role
61+
metadata:
62+
name: {{ include "pgdog-control.control.clusterFullname" . }}-leader
63+
namespace: {{ .Release.Namespace }}
64+
labels:
65+
{{- include "pgdog-control.labels" . | nindent 4 }}
66+
rules:
67+
- apiGroups: ["coordination.k8s.io"]
68+
resources: ["leases"]
69+
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
70+
---
71+
apiVersion: rbac.authorization.k8s.io/v1
72+
kind: RoleBinding
73+
metadata:
74+
name: {{ include "pgdog-control.control.clusterFullname" . }}-leader
75+
namespace: {{ .Release.Namespace }}
76+
labels:
77+
{{- include "pgdog-control.labels" . | nindent 4 }}
78+
roleRef:
79+
apiGroup: rbac.authorization.k8s.io
80+
kind: Role
81+
name: {{ include "pgdog-control.control.clusterFullname" . }}-leader
82+
subjects:
83+
- kind: ServiceAccount
84+
name: {{ include "pgdog-control.control.serviceAccountName" . }}
85+
namespace: {{ .Release.Namespace }}
5786
{{- range $ns := .Values.control.rbac.writeNamespaces }}
5887
---
5988
# Namespace-scoped write access for workloads the control plane manages.

test/values-full.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ control:
3535
autoreload: "immediately"
3636
autoscaling:
3737
pool_size: true
38+
leader:
39+
enabled: true
40+
lease_name: pgdog-control-leader
41+
lease_duration_secs: 20
42+
renew_interval_secs: 7
43+
release_timeout_secs: 4
3844
helm:
3945
chart: pgdog
4046
repo: pgdogdev

values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,12 @@ control:
107107
# autoreload: off
108108
autoscaling: {}
109109
# pool_size: false
110+
leader: {}
111+
# enabled: true
112+
# lease_name: "" # Empty means derive from Helm release.
113+
# lease_duration_secs: 15
114+
# renew_interval_secs: 5
115+
# release_timeout_secs: 3
110116
helm: {}
111117
# chart: pgdog
112118
# repo: pgdogdev

0 commit comments

Comments
 (0)