Skip to content

Commit 9134dd3

Browse files
committed
Fixes 11087
1 parent e0bf254 commit 9134dd3

File tree

11 files changed

+333
-20
lines changed

11 files changed

+333
-20
lines changed

charts/ingress-nginx/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
annotations:
22
artifacthub.io/changes: |
3-
- Update Ingress-Nginx version controller-v1.12.2
3+
- Add electionID label to controller pods when leader election is enabled
44
artifacthub.io/prerelease: "false"
55
apiVersion: v2
66
appVersion: 1.12.2
@@ -20,4 +20,4 @@ maintainers:
2020
name: ingress-nginx
2121
sources:
2222
- https://github.com/kubernetes/ingress-nginx
23-
version: 4.12.2
23+
version: 4.12.3
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Changelog
2+
3+
This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org).
4+
5+
### 4.12.3
6+
7+
* Add electionID label to controller pods when leader election is enabled
8+
9+
**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.12.2...helm-chart-4.12.3

charts/ingress-nginx/templates/controller-daemonset.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ spec:
3434
labels:
3535
{{- include "ingress-nginx.labels" . | nindent 8 }}
3636
app.kubernetes.io/component: controller
37+
{{- if not .Values.controller.disableLeaderElection }}
38+
nginx.ingress.kubernetes.io/electionID: {{ include "ingress-nginx.controller.electionID" . }}
39+
{{- end }}
3740
{{- with .Values.controller.labels }}
3841
{{- toYaml . | nindent 8 }}
3942
{{- end }}

charts/ingress-nginx/templates/controller-deployment.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ spec:
4040
labels:
4141
{{- include "ingress-nginx.labels" . | nindent 8 }}
4242
app.kubernetes.io/component: controller
43+
{{- if not .Values.controller.disableLeaderElection }}
44+
nginx.ingress.kubernetes.io/electionID: {{ include "ingress-nginx.controller.electionID" . }}
45+
{{- end }}
4346
{{- with .Values.controller.labels }}
4447
{{- toYaml . | nindent 8 }}
4548
{{- end }}

charts/ingress-nginx/tests/controller-daemonset_test.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,30 @@ tests:
208208
- equal:
209209
path: spec.template.spec.runtimeClassName
210210
value: myClass
211+
212+
- it: should create a DaemonSet with the electionID label on the pod template when leader election is enabled
213+
set:
214+
controller.kind: DaemonSet
215+
controller.disableLeaderElection: false
216+
asserts:
217+
- equal:
218+
path: spec.template.metadata.labels.[nginx.ingress.kubernetes.io/electionID]
219+
value: RELEASE-NAME-ingress-nginx-leader
220+
221+
- it: should create a DaemonSet with the custom electionID label on the pod template when controller.electionID is set and leader election is enabled
222+
set:
223+
controller.kind: DaemonSet
224+
controller.disableLeaderElection: false
225+
controller.electionID: custom-election-id
226+
asserts:
227+
- equal:
228+
path: spec.template.metadata.labels.[nginx.ingress.kubernetes.io/electionID]
229+
value: custom-election-id
230+
231+
- it: should create a DaemonSet without the electionID label on the pod template when leader election is disabled
232+
set:
233+
controller.kind: DaemonSet
234+
controller.disableLeaderElection: true
235+
asserts:
236+
- notExists:
237+
path: spec.template.metadata.labels.[nginx.ingress.kubernetes.io/electionID]

charts/ingress-nginx/tests/controller-deployment_test.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,27 @@ tests:
231231
- equal:
232232
path: spec.template.spec.runtimeClassName
233233
value: myClass
234+
235+
- it: should create a Deployment with the electionID label on the pod template when leader election is enabled
236+
set:
237+
controller.disableLeaderElection: false
238+
asserts:
239+
- equal:
240+
path: spec.template.metadata.labels.[nginx.ingress.kubernetes.io/electionID]
241+
value: RELEASE-NAME-ingress-nginx-leader
242+
243+
- it: should create a Deployment with the custom electionID label on the pod template when controller.electionID is set and leader election is enabled
244+
set:
245+
controller.disableLeaderElection: false
246+
controller.electionID: custom-election-id
247+
asserts:
248+
- equal:
249+
path: spec.template.metadata.labels.[nginx.ingress.kubernetes.io/electionID]
250+
value: custom-election-id
251+
252+
- it: should create a Deployment without the electionID label on the pod template when leader election is disabled
253+
set:
254+
controller.disableLeaderElection: true
255+
asserts:
256+
- notExists:
257+
path: spec.template.metadata.labels.[nginx.ingress.kubernetes.io/electionID]

internal/ingress/controller/controller.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ type Configuration struct {
143143

144144
DisableSyncEvents bool
145145

146+
UseElectionIDSelectorOnShutdown bool
147+
146148
EnableTopologyAwareRouting bool
147149
}
148150

internal/ingress/controller/nginx.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ func NewNGINXController(config *Configuration, mc metric.Collector) *NGINXContro
152152
IngressLister: n.store,
153153
UpdateStatusOnShutdown: config.UpdateStatusOnShutdown,
154154
UseNodeInternalIP: config.UseNodeInternalIP,
155+
UseElectionIDSelectorOnShutdown: config.UseElectionIDSelectorOnShutdown,
156+
ElectionID: config.ElectionID,
155157
})
156158
} else {
157159
klog.Warning("Update of Ingress status is disabled (flag --update-status)")

internal/ingress/status/status.go

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ import (
4040
"k8s.io/ingress-nginx/pkg/apis/ingress"
4141
)
4242

43+
const (
44+
// ElectionIDLabelKey is the label key used to identify controller pods by election ID
45+
ElectionIDLabelKey = "nginx.ingress.kubernetes.io/electionID"
46+
)
47+
4348
// UpdateInterval defines the time interval, in seconds, in
4449
// which the status should check if an update is required.
4550
var UpdateInterval = 60
@@ -68,6 +73,10 @@ type Config struct {
6873

6974
UseNodeInternalIP bool
7075

76+
UseElectionIDSelectorOnShutdown bool
77+
78+
ElectionID string
79+
7180
IngressLister ingressLister
7281
}
7382

@@ -175,6 +184,36 @@ func nameOrIPToLoadBalancerIngress(nameOrIP string) v1.IngressLoadBalancerIngres
175184

176185
// runningAddresses returns a list of IP addresses and/or FQDN where the
177186
// ingress controller is currently running
187+
// listControllerPods returns a list of running pods with controller labels
188+
func (s *statusSync) listControllerPods(useElectionID bool) (*apiv1.PodList, error) {
189+
podLabel := make(map[string]string)
190+
191+
if useElectionID {
192+
// When using electionID, only look for pods with the electionID label
193+
// This is more specific and will correctly identify pods belonging to the same controller group
194+
// Note: This requires the electionID label to be set on the pods (done by helm chart)
195+
podLabel[ElectionIDLabelKey] = s.Config.ElectionID
196+
} else {
197+
// As a standard, app.kubernetes.io are "reserved well-known" labels.
198+
// In our case, we add those labels as identifiers of the Ingress
199+
// deployment in this namespace, so we can select it as a set of Ingress instances.
200+
// As those labels are also generated as part of a HELM deployment, we can be "safe" they
201+
// cover 95% of the cases
202+
for k, v := range k8s.IngressPodDetails.Labels {
203+
// Skip labels that are frequently modified by deployment controllers
204+
if k != "pod-template-hash" && k != "controller-revision-hash" && k != "pod-template-generation" {
205+
podLabel[k] = v
206+
}
207+
}
208+
}
209+
210+
return s.Client.CoreV1().Pods(k8s.IngressPodDetails.Namespace).List(
211+
context.TODO(),
212+
metav1.ListOptions{
213+
LabelSelector: labels.SelectorFromSet(podLabel).String(),
214+
})
215+
}
216+
178217
func (s *statusSync) runningAddresses() ([]v1.IngressLoadBalancerIngress, error) {
179218
if s.PublishStatusAddress != "" {
180219
re := regexp.MustCompile(`,\s*`)
@@ -191,9 +230,7 @@ func (s *statusSync) runningAddresses() ([]v1.IngressLoadBalancerIngress, error)
191230
}
192231

193232
// get information about all the pods running the ingress controller
194-
pods, err := s.Client.CoreV1().Pods(k8s.IngressPodDetails.Namespace).List(context.TODO(), metav1.ListOptions{
195-
LabelSelector: labels.SelectorFromSet(k8s.IngressPodDetails.Labels).String(),
196-
})
233+
pods, err := s.listControllerPods(false)
197234
if err != nil {
198235
return nil, err
199236
}
@@ -230,21 +267,7 @@ func (s *statusSync) runningAddresses() ([]v1.IngressLoadBalancerIngress, error)
230267
}
231268

232269
func (s *statusSync) isRunningMultiplePods() bool {
233-
// As a standard, app.kubernetes.io are "reserved well-known" labels.
234-
// In our case, we add those labels as identifiers of the Ingress
235-
// deployment in this namespace, so we can select it as a set of Ingress instances.
236-
// As those labels are also generated as part of a HELM deployment, we can be "safe" they
237-
// cover 95% of the cases
238-
podLabel := make(map[string]string)
239-
for k, v := range k8s.IngressPodDetails.Labels {
240-
if k != "pod-template-hash" && k != "controller-revision-hash" && k != "pod-template-generation" {
241-
podLabel[k] = v
242-
}
243-
}
244-
245-
pods, err := s.Client.CoreV1().Pods(k8s.IngressPodDetails.Namespace).List(context.TODO(), metav1.ListOptions{
246-
LabelSelector: labels.SelectorFromSet(podLabel).String(),
247-
})
270+
pods, err := s.listControllerPods(s.UseElectionIDSelectorOnShutdown) // Use election ID-compatible labels if configured
248271
if err != nil {
249272
return false
250273
}

0 commit comments

Comments
 (0)