chart: ingress-nginx update version
diff --git a/charts/ingress-nginx/templates/NOTES.txt b/charts/ingress-nginx/templates/NOTES.txt
index 03ece9c..9fe35c7 100644
--- a/charts/ingress-nginx/templates/NOTES.txt
+++ b/charts/ingress-nginx/templates/NOTES.txt
@@ -29,27 +29,36 @@
 
 An example Ingress that makes use of the controller:
 
+{{- $isV1 := semverCompare ">=1" .Chart.AppVersion}}
   apiVersion: networking.k8s.io/v1
   kind: Ingress
   metadata:
-    annotations:
-      kubernetes.io/ingress.class: {{ .Values.controller.ingressClassResource.name }}
     name: example
     namespace: foo
+    {{- if eq $isV1 false }}
+    annotations:
+      kubernetes.io/ingress.class: {{ .Values.controller.ingressClass }}
+    {{- end }}
   spec:
+    {{- if $isV1 }}
+    ingressClassName: {{ .Values.controller.ingressClassResource.name }}
+    {{- end }}
     rules:
       - host: www.example.com
         http:
           paths:
-            - backend:
-                serviceName: exampleService
-                servicePort: 80
+            - pathType: Prefix
+              backend:
+                service:
+                  name: exampleService
+                  port:
+                    number: 80
               path: /
     # This section is only required if TLS is to be enabled for the Ingress
     tls:
-        - hosts:
-            - www.example.com
-          secretName: example-tls
+      - hosts:
+        - www.example.com
+        secretName: example-tls
 
 If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
 
@@ -62,10 +71,3 @@
     tls.crt: <base64 encoded cert>
     tls.key: <base64 encoded key>
   type: kubernetes.io/tls
-
-{{- if .Values.controller.headers }}
-#################################################################################
-######   WARNING: `controller.headers` has been deprecated!                 #####
-######            It has been renamed to `controller.proxySetHeaders`.      #####
-#################################################################################
-{{- end }}
diff --git a/charts/ingress-nginx/templates/_helpers.tpl b/charts/ingress-nginx/templates/_helpers.tpl
index 8b1fd09..7db5b2c 100644
--- a/charts/ingress-nginx/templates/_helpers.tpl
+++ b/charts/ingress-nginx/templates/_helpers.tpl
@@ -30,6 +30,53 @@
 {{- end -}}
 {{- end -}}
 
+
+{{/*
+Container SecurityContext.
+*/}}
+{{- define "controller.containerSecurityContext" -}}
+{{- if .Values.controller.containerSecurityContext -}}
+{{- toYaml .Values.controller.containerSecurityContext -}}
+{{- else -}}
+capabilities:
+  drop:
+  - ALL
+  add:
+  - NET_BIND_SERVICE
+  {{- if .Values.controller.image.chroot }}
+  - SYS_CHROOT
+  {{- end }}
+runAsUser: {{ .Values.controller.image.runAsUser }}
+allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }}
+{{- end }}
+{{- end -}}
+
+{{/*
+Get specific image
+*/}}
+{{- define "ingress-nginx.image" -}}
+{{- if .chroot -}}
+{{- printf "%s-chroot" .image -}}
+{{- else -}}
+{{- printf "%s" .image -}}
+{{- end }}
+{{- end -}}
+
+{{/*
+Get specific image digest
+*/}}
+{{- define "ingress-nginx.imageDigest" -}}
+{{- if .chroot -}}
+{{- if .digestChroot -}}
+{{- printf "@%s" .digestChroot -}}
+{{- end }}
+{{- else -}}
+{{ if .digest -}}
+{{- printf "@%s" .digest -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
 {{/*
 Create a default fully qualified controller name.
 We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
@@ -39,6 +86,16 @@
 {{- end -}}
 
 {{/*
+Construct a unique electionID.
+Users can provide an override for an explicit electionID if they want via `.Values.controller.electionID`
+*/}}
+{{- define "ingress-nginx.controller.electionID" -}}
+{{- $defElectionID := printf "%s-leader" (include "ingress-nginx.fullname" .) -}}
+{{- $electionID := default $defElectionID .Values.controller.electionID -}}
+{{- print $electionID -}}
+{{- end -}}
+
+{{/*
 Construct the path for the publish-service.
 
 By convention this will simply use the <namespace>/<controller-name> to match the name of the
@@ -70,7 +127,11 @@
 {{- if .Chart.AppVersion }}
 app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
 {{- end }}
+app.kubernetes.io/part-of: {{ template "ingress-nginx.name" . }}
 app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- if .Values.commonLabels}}
+{{ toYaml .Values.commonLabels }}
+{{- end }}
 {{- end -}}
 
 {{/*
@@ -132,3 +193,20 @@
 {{ toYaml .Values.controller.ingressClassResource.parameters | indent 4}}
   {{ end }}
 {{- end -}}
+
+{{/*
+Extra modules.
+*/}}
+{{- define "extraModules" -}}
+
+- name: {{ .name }}
+  image: {{ .image }}
+  command: ['sh', '-c', '/usr/local/bin/init_module.sh']
+  {{- if (.containerSecurityContext) }}
+  securityContext: {{ .containerSecurityContext | toYaml | nindent 4 }}
+  {{- end }}
+  volumeMounts:
+    - name: {{ toYaml "modules"}}
+      mountPath: {{ toYaml "/modules_mount"}}
+
+{{- end -}}
diff --git a/charts/ingress-nginx/templates/_params.tpl b/charts/ingress-nginx/templates/_params.tpl
new file mode 100644
index 0000000..a1aef01
--- /dev/null
+++ b/charts/ingress-nginx/templates/_params.tpl
@@ -0,0 +1,65 @@
+{{- define "ingress-nginx.params" -}}
+- /nginx-ingress-controller
+{{- if .Values.defaultBackend.enabled }}
+- --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }}
+{{- end }}
+{{- if and .Values.controller.publishService.enabled .Values.controller.service.enabled }}
+{{- if .Values.controller.service.external.enabled }}
+- --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}
+{{- else if .Values.controller.service.internal.enabled }}
+- --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}-internal
+{{- end }}
+{{- end }}
+- --election-id={{ include "ingress-nginx.controller.electionID" . }}
+- --controller-class={{ .Values.controller.ingressClassResource.controllerValue }}
+{{- if .Values.controller.ingressClass }}
+- --ingress-class={{ .Values.controller.ingressClass }}
+{{- end }}
+- --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }}
+{{- if .Values.tcp }}
+- --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp
+{{- end }}
+{{- if .Values.udp }}
+- --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp
+{{- end }}
+{{- if .Values.controller.scope.enabled }}
+- --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }}
+{{- end }}
+{{- if and (not .Values.controller.scope.enabled) .Values.controller.scope.namespaceSelector }}
+- --watch-namespace-selector={{ default "" .Values.controller.scope.namespaceSelector }}
+{{- end }}
+{{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }}
+- --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }}
+{{- end }}
+{{- if .Values.controller.admissionWebhooks.enabled }}
+- --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }}
+- --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }}
+- --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }}
+{{- end }}
+{{- if .Values.controller.maxmindLicenseKey }}
+- --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }}
+{{- end }}
+{{- if .Values.controller.healthCheckHost }}
+- --healthz-host={{ .Values.controller.healthCheckHost }}
+{{- end }}
+{{- if not (eq .Values.controller.healthCheckPath "/healthz") }}
+- --health-check-path={{ .Values.controller.healthCheckPath }}
+{{- end }}
+{{- if .Values.controller.ingressClassByName }}
+- --ingress-class-by-name=true
+{{- end }}
+{{- if .Values.controller.watchIngressWithoutClass }}
+- --watch-ingress-without-class=true
+{{- end }}
+{{- if .Values.controller.enableTopologyAwareRouting }}
+- --enable-topology-aware-routing=true
+{{- end }}
+{{- range $key, $value := .Values.controller.extraArgs }}
+{{- /* Accept keys without values or with false as value */}}
+{{- if eq ($value | quote | len) 2 }}
+- --{{ $key }}
+{{- else }}
+- --{{ $key }}={{ $value }}
+{{- end }}
+{{- end }}
+{{- end -}}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
index fd762f9..f9ec709 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
@@ -1,4 +1,4 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
@@ -9,6 +9,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 rules:
   - apiGroups:
       - admissionregistration.k8s.io
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
index 4990fb1..8719532 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
@@ -1,14 +1,17 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
-  name:  {{ include "ingress-nginx.fullname" . }}-admission
+  name: {{ include "ingress-nginx.fullname" . }}-admission
   annotations:
     "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
     "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
index 1f58bdc..d93433e 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
@@ -1,4 +1,4 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: batch/v1
 kind: Job
 metadata:
@@ -7,9 +7,15 @@
   annotations:
     "helm.sh/hook": pre-install,pre-upgrade
     "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+    {{- with .Values.controller.admissionWebhooks.annotations }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 spec:
 {{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
   # Alpha feature since k8s 1.12
@@ -24,6 +30,9 @@
       labels:
         {{- include "ingress-nginx.labels" . | nindent 8 }}
         app.kubernetes.io/component: admission-webhook
+        {{- with .Values.controller.admissionWebhooks.patch.labels }}
+        {{- toYaml . | nindent 8 }}
+        {{- end }}
     spec:
     {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }}
       priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }}
@@ -47,6 +56,12 @@
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
+          {{- if .Values.controller.admissionWebhooks.extraEnvs }}
+            {{- toYaml .Values.controller.admissionWebhooks.extraEnvs | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.createSecretJob.securityContext }}
+          securityContext: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.securityContext | nindent 12 }}
+          {{- end }}
           {{- if .Values.controller.admissionWebhooks.createSecretJob.resources }}
           resources: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.resources | nindent 12 }}
           {{- end }}
@@ -58,7 +73,8 @@
     {{- if .Values.controller.admissionWebhooks.patch.tolerations }}
       tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }}
     {{- end }}
+      {{- if .Values.controller.admissionWebhooks.patch.securityContext }}
       securityContext:
-        runAsNonRoot: true
-        runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }}
+        {{- toYaml .Values.controller.admissionWebhooks.patch.securityContext | nindent 8 }}
+      {{- end }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
index 6d01ad2..0fa3ff9 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
@@ -1,4 +1,4 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: batch/v1
 kind: Job
 metadata:
@@ -7,9 +7,15 @@
   annotations:
     "helm.sh/hook": post-install,post-upgrade
     "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+    {{- with .Values.controller.admissionWebhooks.annotations }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 spec:
 {{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }}
   # Alpha feature since k8s 1.12
@@ -24,6 +30,9 @@
       labels:
         {{- include "ingress-nginx.labels" . | nindent 8 }}
         app.kubernetes.io/component: admission-webhook
+        {{- with .Values.controller.admissionWebhooks.patch.labels }}
+        {{- toYaml . | nindent 8 }}
+        {{- end }}
     spec:
     {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }}
       priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }}
@@ -49,6 +58,12 @@
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
+          {{- if .Values.controller.admissionWebhooks.extraEnvs }}
+            {{- toYaml .Values.controller.admissionWebhooks.extraEnvs | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.admissionWebhooks.patchWebhookJob.securityContext }}
+          securityContext: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.securityContext | nindent 12 }}
+          {{- end }}
           {{- if .Values.controller.admissionWebhooks.patchWebhookJob.resources }}
           resources: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.resources | nindent 12 }}
           {{- end }}
@@ -60,7 +75,8 @@
     {{- if .Values.controller.admissionWebhooks.patch.tolerations }}
       tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }}
     {{- end }}
+      {{- if .Values.controller.admissionWebhooks.patch.securityContext }}
       securityContext:
-        runAsNonRoot: true
-        runAsUser: {{ .Values.controller.admissionWebhooks.patch.runAsUser }}
+        {{- toYaml .Values.controller.admissionWebhooks.patch.securityContext | nindent 8 }}
+      {{- end }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml
new file mode 100644
index 0000000..08b3225
--- /dev/null
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml
@@ -0,0 +1,26 @@
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.networkPolicyEnabled }}
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-admission
+  namespace: {{ .Release.Namespace }}
+  annotations:
+    "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
+    "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
+spec:
+  podSelector:
+    matchLabels:
+      {{- include "ingress-nginx.labels" . | nindent 6 }}
+      app.kubernetes.io/component: admission-webhook
+  policyTypes:
+  - Ingress
+  - Egress
+  egress:
+  - {}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
index d2c7de6..e19c955 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml
@@ -1,3 +1,4 @@
+{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }}
 {{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled .Values.podSecurityPolicy.enabled (empty .Values.controller.admissionWebhooks.existingPsp) -}}
 apiVersion: policy/v1beta1
 kind: PodSecurityPolicy
@@ -9,6 +10,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 spec:
   allowPrivilegeEscalation: false
   fsGroup:
@@ -34,3 +38,4 @@
   - secret
   - downwardAPI
 {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
index 9b083ee..ea7c208 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
@@ -1,8 +1,8 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: rbac.authorization.k8s.io/v1
 kind: Role
 metadata:
-  name:  {{ include "ingress-nginx.fullname" . }}-admission
+  name: {{ include "ingress-nginx.fullname" . }}-admission
   namespace: {{ .Release.Namespace }}
   annotations:
     "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
@@ -10,6 +10,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 rules:
   - apiGroups:
       - ""
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
index edda07f..60c3f4f 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
@@ -1,4 +1,4 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: rbac.authorization.k8s.io/v1
 kind: RoleBinding
 metadata:
@@ -10,6 +10,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: Role
diff --git a/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml b/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
index 1ff0f7f..00be54e 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
@@ -1,4 +1,4 @@
-{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled -}}
+{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}}
 apiVersion: v1
 kind: ServiceAccount
 metadata:
@@ -10,4 +10,7 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.patch.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
index 712f74f..f27244d 100644
--- a/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
+++ b/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
@@ -4,12 +4,20 @@
 apiVersion: admissionregistration.k8s.io/v1
 kind: ValidatingWebhookConfiguration
 metadata:
+  annotations:
+  {{- if .Values.controller.admissionWebhooks.certManager.enabled }}
+    certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-admission" .Release.Namespace (include "ingress-nginx.fullname" .) | quote }}
+    cert-manager.io/inject-ca-from: {{ printf "%s/%s-admission" .Release.Namespace (include "ingress-nginx.fullname" .) | quote }}
+  {{- end }}
   {{- if .Values.controller.admissionWebhooks.annotations }}
-  annotations: {{ toYaml .Values.controller.admissionWebhooks.annotations | nindent 4 }}
+    {{- toYaml .Values.controller.admissionWebhooks.annotations | nindent 4 }}
   {{- end }}
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: admission-webhook
+    {{- with .Values.controller.admissionWebhooks.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}-admission
 webhooks:
   - name: validate.nginx.ingress.kubernetes.io
diff --git a/charts/ingress-nginx/templates/clusterrole.yaml b/charts/ingress-nginx/templates/clusterrole.yaml
index c1f901d..51bc500 100644
--- a/charts/ingress-nginx/templates/clusterrole.yaml
+++ b/charts/ingress-nginx/templates/clusterrole.yaml
@@ -10,6 +10,9 @@
 metadata:
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}
 rules:
   - apiGroups:
@@ -20,6 +23,16 @@
       - nodes
       - pods
       - secrets
+{{- if not .Values.controller.scope.enabled }}
+      - namespaces
+{{- end}}
+    verbs:
+      - list
+      - watch
+  - apiGroups:
+      - coordination.k8s.io
+    resources:
+      - leases
     verbs:
       - list
       - watch
@@ -76,6 +89,14 @@
       - get
       - list
       - watch
+  - apiGroups:
+      - discovery.k8s.io
+    resources:
+      - endpointslices
+    verbs:
+      - list
+      - watch
+      - get
 {{- end }}
 
 {{- end }}
diff --git a/charts/ingress-nginx/templates/clusterrolebinding.yaml b/charts/ingress-nginx/templates/clusterrolebinding.yaml
index 81be52b..acbbd8b 100644
--- a/charts/ingress-nginx/templates/clusterrolebinding.yaml
+++ b/charts/ingress-nginx/templates/clusterrolebinding.yaml
@@ -4,6 +4,9 @@
 metadata:
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}
 roleRef:
   apiGroup: rbac.authorization.k8s.io
diff --git a/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml b/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml
index e0b7a0f..dfd49a1 100644
--- a/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml
+++ b/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}-custom-add-headers
   namespace: {{ .Release.Namespace }}
 data: {{ toYaml .Values.controller.addHeaders | nindent 2 }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml b/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml
index 91f22f0..38feb72 100644
--- a/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml
+++ b/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml
@@ -1,16 +1,14 @@
-{{- if or .Values.controller.proxySetHeaders .Values.controller.headers -}}
+{{- if .Values.controller.proxySetHeaders -}}
 apiVersion: v1
 kind: ConfigMap
 metadata:
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}-custom-proxy-headers
   namespace: {{ .Release.Namespace }}
-data:
-{{- if .Values.controller.proxySetHeaders }}
-{{ toYaml .Values.controller.proxySetHeaders | indent 2 }}
-{{ else if and .Values.controller.headers (not .Values.controller.proxySetHeaders) }}
-{{ toYaml .Values.controller.headers | indent 2 }}
-{{- end }}
+data: {{ toYaml .Values.controller.proxySetHeaders | nindent 2 }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-tcp.yaml b/charts/ingress-nginx/templates/controller-configmap-tcp.yaml
index aaf336f..0f6088e 100644
--- a/charts/ingress-nginx/templates/controller-configmap-tcp.yaml
+++ b/charts/ingress-nginx/templates/controller-configmap-tcp.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 {{- if .Values.controller.tcp.annotations }}
   annotations: {{ toYaml .Values.controller.tcp.annotations | nindent 4 }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap-udp.yaml b/charts/ingress-nginx/templates/controller-configmap-udp.yaml
index 7f46791..3772ec5 100644
--- a/charts/ingress-nginx/templates/controller-configmap-udp.yaml
+++ b/charts/ingress-nginx/templates/controller-configmap-udp.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 {{- if .Values.controller.udp.annotations }}
   annotations: {{ toYaml .Values.controller.udp.annotations | nindent 4 }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/controller-configmap.yaml b/charts/ingress-nginx/templates/controller-configmap.yaml
index 6973892..9ec2b83 100644
--- a/charts/ingress-nginx/templates/controller-configmap.yaml
+++ b/charts/ingress-nginx/templates/controller-configmap.yaml
@@ -4,6 +4,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 {{- if .Values.controller.configAnnotations }}
   annotations: {{ toYaml .Values.controller.configAnnotations | nindent 4 }}
 {{- end }}
@@ -14,13 +17,12 @@
 {{- if .Values.controller.addHeaders }}
   add-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-add-headers
 {{- end }}
-{{- if or .Values.controller.proxySetHeaders .Values.controller.headers }}
+{{- if .Values.controller.proxySetHeaders }}
   proxy-set-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-proxy-headers
 {{- end }}
 {{- if .Values.dhParam }}
-  ssl-dh-param: {{ printf "%s/%s" .Release.Namespace (include "ingress-nginx.controller.fullname" .) }}
+  ssl-dh-param: {{ .Release.Namespace }}/{{ include "ingress-nginx.controller.fullname" . }}
 {{- end }}
 {{- range $key, $value := .Values.controller.config }}
-    {{ $key | nindent 2 }}: {{ $value | quote }}
+  {{- $key | nindent 2 }}: {{ $value | quote }}
 {{- end }}
-
diff --git a/charts/ingress-nginx/templates/controller-daemonset.yaml b/charts/ingress-nginx/templates/controller-daemonset.yaml
index 68291ed..bce21a7 100644
--- a/charts/ingress-nginx/templates/controller-daemonset.yaml
+++ b/charts/ingress-nginx/templates/controller-daemonset.yaml
@@ -33,8 +33,11 @@
       {{- end }}
     {{- end }}
       labels:
-        {{- include "ingress-nginx.selectorLabels" . | nindent 8 }}
+        {{- include "ingress-nginx.labels" . | nindent 8 }}
         app.kubernetes.io/component: controller
+        {{- with .Values.controller.labels }}
+        {{- toYaml . | nindent 8 }}
+        {{- end }}
       {{- if .Values.controller.podLabels }}
         {{- toYaml .Values.controller.podLabels | nindent 8 }}
       {{- end }}
@@ -65,77 +68,21 @@
           value: {{ $value | quote }}
     {{- end }}
     {{- end }}
+    {{- if .Values.controller.shareProcessNamespace }}
+      shareProcessNamespace: {{ .Values.controller.shareProcessNamespace }}
+    {{- end }}
       containers:
         - name: {{ .Values.controller.containerName }}
           {{- with .Values.controller.image }}
-          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ include "ingress-nginx.image" . }}{{- end -}}:{{ .tag }}{{ include "ingress-nginx.imageDigest" . }}"
           {{- end }}
           imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
         {{- if .Values.controller.lifecycle }}
           lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }}
         {{- end }}
           args:
-            - /nginx-ingress-controller
-          {{- if .Values.defaultBackend.enabled }}
-            - --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }}
-          {{- end }}
-          {{- if .Values.controller.publishService.enabled }}
-            - --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}
-          {{- end }}
-            - --election-id={{ .Values.controller.electionID }}
-            - --controller-class={{ .Values.controller.ingressClassResource.controllerValue }}
-            - --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }}
-          {{- if .Values.tcp }}
-            - --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp
-          {{- end }}
-          {{- if .Values.udp }}
-            - --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp
-          {{- end }}
-          {{- if .Values.controller.scope.enabled }}
-            - --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }}
-          {{- end }}
-          {{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }}
-            - --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }}
-          {{- end }}
-          {{- if .Values.controller.admissionWebhooks.enabled }}
-            - --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }}
-            - --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }}
-            - --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }}
-          {{- end }}
-          {{- if .Values.controller.maxmindMirror }}
-            - --maxmind-mirror={{ .Values.controller.maxmindMirror }}
-          {{- end}}
-          {{- if .Values.controller.maxmindLicenseKey }}
-            - --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }}
-          {{- end }}
-          {{- if not (eq .Values.controller.healthCheckPath "/healthz") }}
-            - --health-check-path={{ .Values.controller.healthCheckPath }}
-          {{- end }}
-          {{- if .Values.controller.healthCheckHost }}
-            - --healthz-host={{ .Values.controller.healthCheckHost }}
-          {{- end }}
-          {{- if .Values.controller.ingressClassByName }}
-            - --ingress-class-by-name=true
-          {{- end }}
-          {{- if .Values.controller.watchIngressWithoutClass }}
-            - --watch-ingress-without-class=true
-          {{- end }}
-          {{- range $key, $value := .Values.controller.extraArgs }}
-            {{- /* Accept keys without values or with false as value */}}
-            {{- if eq ($value | quote | len) 2 }}
-            - --{{ $key }}
-            {{- else }}
-            - --{{ $key }}={{ $value }}
-            {{- end }}
-          {{- end }}
-          securityContext:
-            capabilities:
-                drop:
-                - ALL
-                add:
-                - NET_BIND_SERVICE
-            runAsUser: {{ .Values.controller.image.runAsUser }}
-            allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }}
+            {{- include "ingress-nginx.params" . | nindent 12 }}
+          securityContext: {{ include "controller.containerSecurityContext" . | nindent 12 }}
           env:
             - name: POD_NAME
               valueFrom:
@@ -155,8 +102,12 @@
           {{- if .Values.controller.startupProbe }}
           startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }}
           {{- end }}
+          {{- if .Values.controller.livenessProbe }}
           livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.readinessProbe }}
           readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }}
+          {{- end }}
           ports:
           {{- range $key, $value := .Values.controller.containerPort }}
             - name: {{ $key }}
@@ -167,7 +118,7 @@
               {{- end }}
           {{- end }}
           {{- if .Values.controller.metrics.enabled }}
-            - name: metrics
+            - name: {{ .Values.controller.metrics.portName }}
               containerPort: {{ .Values.controller.metrics.port }}
               protocol: TCP
           {{- end }}
@@ -177,7 +128,7 @@
               protocol: TCP
           {{- end }}
           {{- range $key, $value := .Values.tcp }}
-            - name: {{ $key }}-tcp
+            - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp
               containerPort: {{ $key }}
               protocol: TCP
               {{- if $.Values.controller.hostPort.enabled }}
@@ -185,15 +136,19 @@
               {{- end }}
           {{- end }}
           {{- range $key, $value := .Values.udp }}
-            - name: {{ $key }}-udp
+            - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp
               containerPort: {{ $key }}
               protocol: UDP
               {{- if $.Values.controller.hostPort.enabled }}
               hostPort: {{ $key }}
               {{- end }}
           {{- end }}
-        {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled) }}
+        {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraModules) }}
           volumeMounts:
+          {{- if .Values.controller.extraModules }}
+            - name: modules
+              mountPath: /modules_mount
+          {{- end }}
           {{- if .Values.controller.customTemplate.configMapName }}
             - mountPath: /etc/nginx/template
               name: nginx-template-volume
@@ -214,8 +169,23 @@
       {{- if .Values.controller.extraContainers }}
         {{ toYaml .Values.controller.extraContainers | nindent 8 }}
       {{- end }}
-    {{- if .Values.controller.extraInitContainers }}
-      initContainers: {{ toYaml .Values.controller.extraInitContainers | nindent 8 }}
+
+
+    {{- if (or .Values.controller.extraInitContainers .Values.controller.extraModules) }}
+      initContainers:
+      {{- if .Values.controller.extraInitContainers }}
+        {{ toYaml .Values.controller.extraInitContainers | nindent 8 }}
+      {{- end }}
+      {{- if .Values.controller.extraModules }}
+        {{- range .Values.controller.extraModules }}
+          {{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
+{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }}
+        {{- end }}
+      {{- end }}
+      {{- if .Values.controller.opentelemetry.enabled}}
+          {{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
+          {{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext) | nindent 8}}
+      {{- end}}
     {{- end }}
     {{- if .Values.controller.hostNetwork }}
       hostNetwork: {{ .Values.controller.hostNetwork }}
@@ -234,8 +204,12 @@
     {{- end }}
       serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
       terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
-    {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes) }}
+    {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }}
       volumes:
+      {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled)}}
+        - name: modules
+          emptyDir: {}
+      {{- end }}
       {{- if .Values.controller.customTemplate.configMapName }}
         - name: nginx-template-volume
           configMap:
@@ -248,6 +222,13 @@
         - name: webhook-cert
           secret:
             secretName: {{ include "ingress-nginx.fullname" . }}-admission
+        {{- if .Values.controller.admissionWebhooks.certManager.enabled }}
+            items:
+              - key: tls.crt
+                path: cert
+              - key: tls.key
+                path: key
+        {{- end }}
       {{- end }}
       {{- if .Values.controller.extraVolumes }}
         {{ toYaml .Values.controller.extraVolumes | nindent 8 }}
diff --git a/charts/ingress-nginx/templates/controller-deployment.yaml b/charts/ingress-nginx/templates/controller-deployment.yaml
index 24714a5..323d876 100644
--- a/charts/ingress-nginx/templates/controller-deployment.yaml
+++ b/charts/ingress-nginx/templates/controller-deployment.yaml
@@ -37,8 +37,11 @@
       {{- end }}
     {{- end }}
       labels:
-        {{- include "ingress-nginx.selectorLabels" . | nindent 8 }}
+        {{- include "ingress-nginx.labels" . | nindent 8 }}
         app.kubernetes.io/component: controller
+        {{- with .Values.controller.labels }}
+        {{- toYaml . | nindent 8 }}
+        {{- end }}
       {{- if .Values.controller.podLabels }}
         {{- toYaml .Values.controller.podLabels | nindent 8 }}
       {{- end }}
@@ -54,7 +57,7 @@
       imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
     {{- end }}
     {{- if .Values.controller.priorityClassName }}
-      priorityClassName: {{ .Values.controller.priorityClassName }}
+      priorityClassName: {{ .Values.controller.priorityClassName | quote }}
     {{- end }}
     {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }}
       securityContext:
@@ -69,74 +72,21 @@
           value: {{ $value | quote }}
     {{- end }}
     {{- end }}
+    {{- if .Values.controller.shareProcessNamespace }}
+      shareProcessNamespace: {{ .Values.controller.shareProcessNamespace }}
+    {{- end }}
       containers:
         - name: {{ .Values.controller.containerName }}
           {{- with .Values.controller.image }}
-          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}"
+          image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ include "ingress-nginx.image" . }}{{- end -}}:{{ .tag }}{{ include "ingress-nginx.imageDigest" . }}"
           {{- end }}
           imagePullPolicy: {{ .Values.controller.image.pullPolicy }}
         {{- if .Values.controller.lifecycle }}
           lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }}
         {{- end }}
           args:
-            - /nginx-ingress-controller
-          {{- if .Values.defaultBackend.enabled }}
-            - --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }}
-          {{- end }}
-          {{- if .Values.controller.publishService.enabled }}
-            - --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}
-          {{- end }}
-            - --election-id={{ .Values.controller.electionID }}
-            - --controller-class={{ .Values.controller.ingressClassResource.controllerValue }}
-            - --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }}
-          {{- if .Values.tcp }}
-            - --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp
-          {{- end }}
-          {{- if .Values.udp }}
-            - --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp
-          {{- end }}
-          {{- if .Values.controller.scope.enabled }}
-            - --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }}
-          {{- end }}
-          {{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }}
-            - --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }}
-          {{- end }}
-          {{- if .Values.controller.admissionWebhooks.enabled }}
-            - --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }}
-            - --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }}
-            - --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }}
-          {{- end }}
-          {{- if .Values.controller.maxmindLicenseKey }}
-            - --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }}
-          {{- end }}
-          {{- if .Values.controller.healthCheckHost }}
-            - --healthz-host={{ .Values.controller.healthCheckHost }}
-          {{- end }}
-          {{- if not (eq .Values.controller.healthCheckPath "/healthz") }}
-            - --health-check-path={{ .Values.controller.healthCheckPath }}
-          {{- end }}
-          {{- if .Values.controller.ingressClassByName }}
-            - --ingress-class-by-name=true
-          {{- end }}
-          {{- if .Values.controller.watchIngressWithoutClass }}
-            - --watch-ingress-without-class=true
-          {{- end }}
-          {{- range $key, $value := .Values.controller.extraArgs }}
-            {{- /* Accept keys without values or with false as value */}}
-            {{- if eq ($value | quote | len) 2 }}
-            - --{{ $key }}
-            {{- else }}
-            - --{{ $key }}={{ $value }}
-            {{- end }}
-          {{- end }}
-          securityContext:
-            capabilities:
-                drop:
-                - ALL
-                add:
-                - NET_BIND_SERVICE
-            runAsUser: {{ .Values.controller.image.runAsUser }}
-            allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }}
+            {{- include "ingress-nginx.params" . | nindent 12 }}
+          securityContext: {{ include "controller.containerSecurityContext" . | nindent 12 }}
           env:
             - name: POD_NAME
               valueFrom:
@@ -156,8 +106,12 @@
           {{- if .Values.controller.startupProbe }}
           startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }}
           {{- end }}
+          {{- if .Values.controller.livenessProbe }}
           livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }}
+          {{- end }}
+          {{- if .Values.controller.readinessProbe }}
           readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }}
+          {{- end }}
           ports:
           {{- range $key, $value := .Values.controller.containerPort }}
             - name: {{ $key }}
@@ -168,7 +122,7 @@
               {{- end }}
           {{- end }}
           {{- if .Values.controller.metrics.enabled }}
-            - name: metrics
+            - name: {{ .Values.controller.metrics.portName }}
               containerPort: {{ .Values.controller.metrics.port }}
               protocol: TCP
           {{- end }}
@@ -178,7 +132,7 @@
               protocol: TCP
           {{- end }}
           {{- range $key, $value := .Values.tcp }}
-            - name: {{ $key }}-tcp
+            - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp
               containerPort: {{ $key }}
               protocol: TCP
               {{- if $.Values.controller.hostPort.enabled }}
@@ -186,15 +140,23 @@
               {{- end }}
           {{- end }}
           {{- range $key, $value := .Values.udp }}
-            - name: {{ $key }}-udp
+            - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp
               containerPort: {{ $key }}
               protocol: UDP
               {{- if $.Values.controller.hostPort.enabled }}
               hostPort: {{ $key }}
               {{- end }}
           {{- end }}
-        {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled) }}
+        {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }}
           volumeMounts:
+          {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }}
+            - name: modules
+            {{ if .Values.controller.image.chroot }}
+              mountPath: /chroot/modules_mount
+            {{ else }}
+              mountPath: /modules_mount
+            {{ end }}
+          {{- end }}
           {{- if .Values.controller.customTemplate.configMapName }}
             - mountPath: /etc/nginx/template
               name: nginx-template-volume
@@ -215,8 +177,21 @@
       {{- if .Values.controller.extraContainers }}
         {{ toYaml .Values.controller.extraContainers | nindent 8 }}
       {{- end }}
-    {{- if .Values.controller.extraInitContainers }}
-      initContainers: {{ toYaml .Values.controller.extraInitContainers | nindent 8 }}
+    {{- if (or .Values.controller.extraInitContainers .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }}
+      initContainers:
+      {{- if .Values.controller.extraInitContainers }}
+        {{ toYaml .Values.controller.extraInitContainers | nindent 8 }}
+      {{- end }}
+      {{- if .Values.controller.extraModules }}
+        {{- range .Values.controller.extraModules }}
+          {{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }}
+{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }}
+        {{- end }}
+      {{- end }}
+      {{- if .Values.controller.opentelemetry.enabled}}
+          {{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }}
+          {{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext) | nindent 8}}
+      {{- end}}
     {{- end }}
     {{- if .Values.controller.hostNetwork }}
       hostNetwork: {{ .Values.controller.hostNetwork }}
@@ -235,8 +210,12 @@
     {{- end }}
       serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }}
       terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
-    {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes) }}
+    {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }}
       volumes:
+      {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled)}}
+        - name: modules
+          emptyDir: {}
+      {{- end }}
       {{- if .Values.controller.customTemplate.configMapName }}
         - name: nginx-template-volume
           configMap:
@@ -249,6 +228,13 @@
         - name: webhook-cert
           secret:
             secretName: {{ include "ingress-nginx.fullname" . }}-admission
+        {{- if .Values.controller.admissionWebhooks.certManager.enabled }}
+            items:
+              - key: tls.crt
+                path: cert
+              - key: tls.key
+                path: key
+        {{- end }}
       {{- end }}
       {{- if .Values.controller.extraVolumes }}
         {{ toYaml .Values.controller.extraVolumes | nindent 8 }}
diff --git a/charts/ingress-nginx/templates/controller-hpa.yaml b/charts/ingress-nginx/templates/controller-hpa.yaml
index 876315f..d1e78bd 100644
--- a/charts/ingress-nginx/templates/controller-hpa.yaml
+++ b/charts/ingress-nginx/templates/controller-hpa.yaml
@@ -1,7 +1,7 @@
 {{- if and .Values.controller.autoscaling.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}}
 {{- if not .Values.controller.keda.enabled }}
 
-apiVersion: autoscaling/v2beta2
+apiVersion: {{ .Values.controller.autoscaling.apiVersion }}
 kind: HorizontalPodAutoscaler
 metadata:
   annotations:
@@ -11,6 +11,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.controller.fullname" . }}
   namespace: {{ .Release.Namespace }}
 spec:
diff --git a/charts/ingress-nginx/templates/controller-keda.yaml b/charts/ingress-nginx/templates/controller-keda.yaml
index c7eebf5..875157e 100644
--- a/charts/ingress-nginx/templates/controller-keda.yaml
+++ b/charts/ingress-nginx/templates/controller-keda.yaml
@@ -7,6 +7,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.controller.fullname" . }}
   {{- if .Values.controller.keda.scaledObject.annotations }}
   annotations: {{ toYaml .Values.controller.keda.scaledObject.annotations | nindent 4 }}
diff --git a/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml b/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml
index 9556f58..899d3cc 100644
--- a/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml
+++ b/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.controller.fullname" . }}
   namespace: {{ .Release.Namespace }}
 spec:
@@ -12,5 +15,9 @@
     matchLabels:
       {{- include "ingress-nginx.selectorLabels" . | nindent 6 }}
       app.kubernetes.io/component: controller
+  {{- if .Values.controller.minAvailable }}
   minAvailable: {{ .Values.controller.minAvailable }}
+  {{- else if .Values.controller.maxUnavailable }}
+  maxUnavailable: {{ .Values.controller.maxUnavailable }}
+  {{- end }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/controller-prometheusrules.yaml b/charts/ingress-nginx/templates/controller-prometheusrules.yaml
index ca54275..78b5362 100644
--- a/charts/ingress-nginx/templates/controller-prometheusrules.yaml
+++ b/charts/ingress-nginx/templates/controller-prometheusrules.yaml
@@ -1,4 +1,4 @@
-{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.prometheusRule.enabled -}}
+{{- if and ( .Values.controller.metrics.enabled ) ( .Values.controller.metrics.prometheusRule.enabled ) ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) -}}
 apiVersion: monitoring.coreos.com/v1
 kind: PrometheusRule
 metadata:
diff --git a/charts/ingress-nginx/templates/controller-psp.yaml b/charts/ingress-nginx/templates/controller-psp.yaml
index bdb8563..3c499b9 100644
--- a/charts/ingress-nginx/templates/controller-psp.yaml
+++ b/charts/ingress-nginx/templates/controller-psp.yaml
@@ -1,3 +1,4 @@
+{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }}
 {{- if and .Values.podSecurityPolicy.enabled (empty .Values.controller.existingPsp) -}}
 apiVersion: policy/v1beta1
 kind: PodSecurityPolicy
@@ -6,9 +7,15 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 spec:
   allowedCapabilities:
     - NET_BIND_SERVICE
+  {{- if .Values.controller.image.chroot }}
+    - SYS_CHROOT
+  {{- end }}
 {{- if .Values.controller.sysctls }}
   allowedUnsafeSysctls:
   {{- range $sysctl, $value := .Values.controller.sysctls }}
@@ -21,9 +28,9 @@
   volumes:
     - 'configMap'
     - 'emptyDir'
-    #- 'projected'
+    - 'projected'
     - 'secret'
-    #- 'downwardAPI'
+    - 'downwardAPI'
 {{- if .Values.controller.hostNetwork }}
   hostNetwork: {{ .Values.controller.hostNetwork }}
 {{- end }}
@@ -84,3 +91,4 @@
   seLinux:
     rule: 'RunAsAny'
 {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-role.yaml b/charts/ingress-nginx/templates/controller-role.yaml
index 97c627d..d1aa9aa 100644
--- a/charts/ingress-nginx/templates/controller-role.yaml
+++ b/charts/ingress-nginx/templates/controller-role.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}
   namespace: {{ .Release.Namespace }}
 rules:
@@ -56,18 +59,18 @@
       - list
       - watch
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - configmaps
+      - leases
     resourceNames:
-      - {{ .Values.controller.electionID }}
+      - {{ include "ingress-nginx.controller.electionID" . }}
     verbs:
       - get
       - update
   - apiGroups:
-      - ""
+      - coordination.k8s.io
     resources:
-      - configmaps
+      - leases
     verbs:
       - create
   - apiGroups:
@@ -77,6 +80,14 @@
     verbs:
       - create
       - patch
+  - apiGroups:
+      - discovery.k8s.io
+    resources:
+      - endpointslices
+    verbs:
+      - list
+      - watch
+      - get
 {{- if .Values.podSecurityPolicy.enabled }}
   - apiGroups:      [{{ template "podSecurityPolicy.apiGroup" . }}]
     resources:      ['podsecuritypolicies']
diff --git a/charts/ingress-nginx/templates/controller-rolebinding.yaml b/charts/ingress-nginx/templates/controller-rolebinding.yaml
index 5ec3bc7..e846a11 100644
--- a/charts/ingress-nginx/templates/controller-rolebinding.yaml
+++ b/charts/ingress-nginx/templates/controller-rolebinding.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}
   namespace: {{ .Release.Namespace }}
 roleRef:
diff --git a/charts/ingress-nginx/templates/controller-secret.yaml b/charts/ingress-nginx/templates/controller-secret.yaml
new file mode 100644
index 0000000..f374423
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-secret.yaml
@@ -0,0 +1,15 @@
+{{- if .Values.dhParam -}}
+apiVersion: v1
+kind: Secret
+metadata:
+  labels:
+    {{- include "ingress-nginx.labels" . | nindent 4 }}
+    app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
+  name: {{ include "ingress-nginx.controller.fullname" . }}
+  namespace: {{ .Release.Namespace }}
+data:
+  dhparam.pem: {{ .Values.dhParam }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/controller-service-internal.yaml b/charts/ingress-nginx/templates/controller-service-internal.yaml
index 5994498..87146b7 100644
--- a/charts/ingress-nginx/templates/controller-service-internal.yaml
+++ b/charts/ingress-nginx/templates/controller-service-internal.yaml
@@ -29,9 +29,9 @@
   {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }}
   {{- if .Values.controller.service.enableHttp }}
     - name: http
-      port: {{ .Values.controller.service.ports.http }}
+      port: {{ .Values.controller.service.internal.ports.http | default .Values.controller.service.ports.http }}
       protocol: TCP
-      targetPort: {{ .Values.controller.service.targetPorts.http }}
+      targetPort: {{ .Values.controller.service.internal.targetPorts.http | default .Values.controller.service.targetPorts.http }}
     {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
       appProtocol: http
     {{- end }}
@@ -41,9 +41,9 @@
   {{- end }}
   {{- if .Values.controller.service.enableHttps }}
     - name: https
-      port: {{ .Values.controller.service.ports.https }}
+      port: {{ .Values.controller.service.internal.ports.https | default .Values.controller.service.ports.https }}
       protocol: TCP
-      targetPort: {{ .Values.controller.service.targetPorts.https }}
+      targetPort: {{ .Values.controller.service.internal.targetPorts.https | default .Values.controller.service.targetPorts.https }}
     {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
       appProtocol: https
     {{- end }}
@@ -52,10 +52,10 @@
     {{- end }}
   {{- end }}
   {{- range $key, $value := .Values.tcp }}
-    - name: {{ $key }}-tcp
+    - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp
       port: {{ $key }}
       protocol: TCP
-      targetPort: {{ $key }}-tcp
+      targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp
     {{- if $.Values.controller.service.nodePorts.tcp }}
     {{- if index $.Values.controller.service.nodePorts.tcp $key }}
       nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }}
@@ -63,10 +63,10 @@
     {{- end }}
   {{- end }}
   {{- range $key, $value := .Values.udp }}
-    - name: {{ $key }}-udp
+    - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp
       port: {{ $key }}
       protocol: UDP
-      targetPort: {{ $key }}-udp
+      targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp
     {{- if $.Values.controller.service.nodePorts.udp }}
     {{- if index $.Values.controller.service.nodePorts.udp $key }}
       nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }}
diff --git a/charts/ingress-nginx/templates/controller-service-metrics.yaml b/charts/ingress-nginx/templates/controller-service-metrics.yaml
index 1b69019..b178401 100644
--- a/charts/ingress-nginx/templates/controller-service-metrics.yaml
+++ b/charts/ingress-nginx/templates/controller-service-metrics.yaml
@@ -31,9 +31,10 @@
   externalTrafficPolicy: {{ .Values.controller.metrics.service.externalTrafficPolicy }}
 {{- end }}
   ports:
-    - name: metrics
+    - name: {{ .Values.controller.metrics.portName }}
       port: {{ .Values.controller.metrics.service.servicePort }}
-      targetPort: metrics
+      protocol: TCP
+      targetPort: {{ .Values.controller.metrics.portName }}
     {{- $setNodePorts := (or (eq .Values.controller.metrics.service.type "NodePort") (eq .Values.controller.metrics.service.type "LoadBalancer")) }}
     {{- if (and $setNodePorts (not (empty .Values.controller.metrics.service.nodePort))) }}
       nodePort: {{ .Values.controller.metrics.service.nodePort }}
diff --git a/charts/ingress-nginx/templates/controller-service-webhook.yaml b/charts/ingress-nginx/templates/controller-service-webhook.yaml
index ae3b1fc..2aae24f 100644
--- a/charts/ingress-nginx/templates/controller-service-webhook.yaml
+++ b/charts/ingress-nginx/templates/controller-service-webhook.yaml
@@ -8,6 +8,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.controller.fullname" . }}-admission
   namespace: {{ .Release.Namespace }}
 spec:
diff --git a/charts/ingress-nginx/templates/controller-service.yaml b/charts/ingress-nginx/templates/controller-service.yaml
index 9248818..2b28196 100644
--- a/charts/ingress-nginx/templates/controller-service.yaml
+++ b/charts/ingress-nginx/templates/controller-service.yaml
@@ -1,4 +1,4 @@
-{{- if .Values.controller.service.enabled -}}
+{{- if and .Values.controller.service.enabled .Values.controller.service.external.enabled -}}
 apiVersion: v1
 kind: Service
 metadata:
@@ -37,6 +37,16 @@
 {{- if .Values.controller.service.healthCheckNodePort }}
   healthCheckNodePort: {{ .Values.controller.service.healthCheckNodePort }}
 {{- end }}
+{{- if semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version -}}
+{{- if .Values.controller.service.ipFamilyPolicy }}
+  ipFamilyPolicy: {{ .Values.controller.service.ipFamilyPolicy }}
+{{- end }}
+{{- end }}
+{{- if semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version -}}
+{{- if .Values.controller.service.ipFamilies }}
+  ipFamilies: {{ toYaml .Values.controller.service.ipFamilies | nindent 4 }}
+{{- end }}
+{{- end }}
   ports:
   {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }}
   {{- if .Values.controller.service.enableHttp }}
@@ -44,7 +54,7 @@
       port: {{ .Values.controller.service.ports.http }}
       protocol: TCP
       targetPort: {{ .Values.controller.service.targetPorts.http }}
-    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+    {{- if and (semverCompare ">=1.20" .Capabilities.KubeVersion.Version) (.Values.controller.service.appProtocol) }}
       appProtocol: http
     {{- end }}
     {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }}
@@ -56,7 +66,7 @@
       port: {{ .Values.controller.service.ports.https }}
       protocol: TCP
       targetPort: {{ .Values.controller.service.targetPorts.https }}
-    {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }}
+    {{- if and (semverCompare ">=1.20" .Capabilities.KubeVersion.Version) (.Values.controller.service.appProtocol) }}
       appProtocol: https
     {{- end }}
     {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }}
@@ -64,10 +74,10 @@
     {{- end }}
   {{- end }}
   {{- range $key, $value := .Values.tcp }}
-    - name: {{ $key }}-tcp
+    - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp
       port: {{ $key }}
       protocol: TCP
-      targetPort: {{ $key }}-tcp
+      targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp
     {{- if $.Values.controller.service.nodePorts.tcp }}
     {{- if index $.Values.controller.service.nodePorts.tcp $key }}
       nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }}
@@ -75,10 +85,10 @@
     {{- end }}
   {{- end }}
   {{- range $key, $value := .Values.udp }}
-    - name: {{ $key }}-udp
+    - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp
       port: {{ $key }}
       protocol: UDP
-      targetPort: {{ $key }}-udp
+      targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp
     {{- if $.Values.controller.service.nodePorts.udp }}
     {{- if index $.Values.controller.service.nodePorts.udp $key }}
       nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }}
diff --git a/charts/ingress-nginx/templates/controller-serviceaccount.yaml b/charts/ingress-nginx/templates/controller-serviceaccount.yaml
index 50a718d..e6e776d 100644
--- a/charts/ingress-nginx/templates/controller-serviceaccount.yaml
+++ b/charts/ingress-nginx/templates/controller-serviceaccount.yaml
@@ -5,7 +5,14 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: controller
+    {{- with .Values.controller.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ template "ingress-nginx.serviceAccountName" . }}
   namespace: {{ .Release.Namespace }}
+  {{- if .Values.serviceAccount.annotations }}
+  annotations:
+  {{- toYaml .Values.serviceAccount.annotations | nindent 4 }}
+  {{- end }}
 automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/controller-servicemonitor.yaml b/charts/ingress-nginx/templates/controller-servicemonitor.yaml
index 17894c8..8ab16f0 100644
--- a/charts/ingress-nginx/templates/controller-servicemonitor.yaml
+++ b/charts/ingress-nginx/templates/controller-servicemonitor.yaml
@@ -1,4 +1,4 @@
-{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}}
+{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}}
 apiVersion: monitoring.coreos.com/v1
 kind: ServiceMonitor
 metadata:
@@ -14,11 +14,14 @@
   {{- end }}
 spec:
   endpoints:
-    - port: metrics
+    - port: {{ .Values.controller.metrics.portName }}
       interval: {{ .Values.controller.metrics.serviceMonitor.scrapeInterval }}
     {{- if .Values.controller.metrics.serviceMonitor.honorLabels }}
       honorLabels: true
     {{- end }}
+    {{- if .Values.controller.metrics.serviceMonitor.relabelings }}
+      relabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.relabelings | nindent 8 }}
+    {{- end }}
     {{- if .Values.controller.metrics.serviceMonitor.metricRelabelings }}
       metricRelabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.metricRelabelings | nindent 8 }}
     {{- end }}
@@ -27,7 +30,7 @@
 {{- end }}
 {{- if .Values.controller.metrics.serviceMonitor.namespaceSelector }}
   namespaceSelector: {{ toYaml .Values.controller.metrics.serviceMonitor.namespaceSelector | nindent 4 }}
-{{ else }}
+{{- else }}
   namespaceSelector:
     matchNames:
       - {{ .Release.Namespace }}
diff --git a/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml b/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml
new file mode 100644
index 0000000..f74c2fb
--- /dev/null
+++ b/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml
@@ -0,0 +1,19 @@
+{{- if .Values.controller.admissionWebhooks.enabled }}
+{{- if .Values.controller.admissionWebhooks.networkPolicyEnabled }}
+
+apiVersion: networking.k8s.io/v1
+kind: NetworkPolicy
+metadata:
+  name: {{ include "ingress-nginx.fullname" . }}-webhooks-allow
+  namespace: {{ .Release.Namespace }}
+spec:
+  ingress:
+  - {}
+  podSelector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "ingress-nginx.name" . }}
+  policyTypes:
+    - Ingress
+
+{{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-deployment.yaml b/charts/ingress-nginx/templates/default-backend-deployment.yaml
index 9934526..87aced4 100644
--- a/charts/ingress-nginx/templates/default-backend-deployment.yaml
+++ b/charts/ingress-nginx/templates/default-backend-deployment.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
   namespace: {{ .Release.Namespace }}
 spec:
@@ -16,6 +19,11 @@
   replicas: {{ .Values.defaultBackend.replicaCount }}
 {{- end }}
   revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
+  {{- if .Values.defaultBackend.updateStrategy }}
+  strategy:
+    {{ toYaml .Values.defaultBackend.updateStrategy | nindent 4 }}
+  {{- end }}
+  minReadySeconds: {{ .Values.defaultBackend.minReadySeconds }}
   template:
     metadata:
     {{- if .Values.defaultBackend.podAnnotations }}
@@ -24,6 +32,9 @@
       labels:
         {{- include "ingress-nginx.selectorLabels" . | nindent 8 }}
         app.kubernetes.io/component: default-backend
+        {{- with .Values.defaultBackend.labels }}
+        {{- toYaml . | nindent 8 }}
+        {{- end }}
       {{- if .Values.defaultBackend.podLabels }}
         {{- toYaml .Values.defaultBackend.podLabels | nindent 8 }}
       {{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-hpa.yaml b/charts/ingress-nginx/templates/default-backend-hpa.yaml
index e31fda3..924125f 100644
--- a/charts/ingress-nginx/templates/default-backend-hpa.yaml
+++ b/charts/ingress-nginx/templates/default-backend-hpa.yaml
@@ -1,10 +1,13 @@
 {{- if and .Values.defaultBackend.enabled .Values.defaultBackend.autoscaling.enabled }}
-apiVersion: autoscaling/v2beta1
+apiVersion: {{ .Values.defaultBackend.autoscaling.apiVersion }}
 kind: HorizontalPodAutoscaler
 metadata:
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ template "ingress-nginx.defaultBackend.fullname" . }}
   namespace: {{ .Release.Namespace }}
 spec:
@@ -19,12 +22,16 @@
     - type: Resource
       resource:
         name: cpu
-        targetAverageUtilization: {{ . }}
+        target:
+          type: Utilization
+          averageUtilization: {{ . }}
 {{- end }}
 {{- with .Values.defaultBackend.autoscaling.targetMemoryUtilizationPercentage }}
     - type: Resource
       resource:
         name: memory
-        targetAverageUtilization: {{ . }}
+        target:
+          type: Utilization
+          averageUtilization: {{ . }}
 {{- end }}
 {{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml b/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml
index 9e586aa..00891ce 100644
--- a/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml
+++ b/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml
@@ -1,3 +1,4 @@
+{{- if .Values.defaultBackend.enabled -}}
 {{- if or (gt (.Values.defaultBackend.replicaCount | int) 1) (gt (.Values.defaultBackend.autoscaling.minReplicas | int) 1) }}
 apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }}
 kind: PodDisruptionBudget
@@ -5,6 +6,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
   namespace: {{ .Release.Namespace }}
 spec:
@@ -14,3 +18,4 @@
       app.kubernetes.io/component: default-backend
   minAvailable: {{ .Values.defaultBackend.minAvailable }}
 {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-psp.yaml b/charts/ingress-nginx/templates/default-backend-psp.yaml
index 716dbf1..c144c8f 100644
--- a/charts/ingress-nginx/templates/default-backend-psp.yaml
+++ b/charts/ingress-nginx/templates/default-backend-psp.yaml
@@ -1,3 +1,4 @@
+{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }}
 {{- if and .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled (empty .Values.defaultBackend.existingPsp) -}}
 apiVersion: policy/v1beta1
 kind: PodSecurityPolicy
@@ -6,6 +7,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
 spec:
   allowPrivilegeEscalation: false
   fsGroup:
@@ -31,3 +35,4 @@
   - secret
   - downwardAPI
 {{- end }}
+{{- end }}
diff --git a/charts/ingress-nginx/templates/default-backend-role.yaml b/charts/ingress-nginx/templates/default-backend-role.yaml
index 5d29a2d..a2b457c 100644
--- a/charts/ingress-nginx/templates/default-backend-role.yaml
+++ b/charts/ingress-nginx/templates/default-backend-role.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}-backend
   namespace: {{ .Release.Namespace }}
 rules:
diff --git a/charts/ingress-nginx/templates/default-backend-rolebinding.yaml b/charts/ingress-nginx/templates/default-backend-rolebinding.yaml
index 4a9cb92..dbaa516 100644
--- a/charts/ingress-nginx/templates/default-backend-rolebinding.yaml
+++ b/charts/ingress-nginx/templates/default-backend-rolebinding.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.fullname" . }}-backend
   namespace: {{ .Release.Namespace }}
 roleRef:
diff --git a/charts/ingress-nginx/templates/default-backend-service.yaml b/charts/ingress-nginx/templates/default-backend-service.yaml
index f59eb1e..5f1d09a 100644
--- a/charts/ingress-nginx/templates/default-backend-service.yaml
+++ b/charts/ingress-nginx/templates/default-backend-service.yaml
@@ -8,6 +8,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ include "ingress-nginx.defaultBackend.fullname" . }}
   namespace: {{ .Release.Namespace }}
 spec:
diff --git a/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml b/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml
index 0c00e93..b45a95a 100644
--- a/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml
+++ b/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml
@@ -5,6 +5,9 @@
   labels:
     {{- include "ingress-nginx.labels" . | nindent 4 }}
     app.kubernetes.io/component: default-backend
+    {{- with .Values.defaultBackend.labels }}
+    {{- toYaml . | nindent 4 }}
+    {{- end }}
   name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }}
   namespace: {{ .Release.Namespace }}
 automountServiceAccountToken: {{ .Values.defaultBackend.serviceAccount.automountServiceAccountToken }}
diff --git a/charts/ingress-nginx/templates/dh-param-secret.yaml b/charts/ingress-nginx/templates/dh-param-secret.yaml
deleted file mode 100644
index 12e7a4f..0000000
--- a/charts/ingress-nginx/templates/dh-param-secret.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-{{- with .Values.dhParam -}}
-apiVersion: v1
-kind: Secret
-metadata:
-  name: {{ include "ingress-nginx.controller.fullname" $ }}
-  labels:
-    {{- include "ingress-nginx.labels" $ | nindent 4 }}
-data:
-  dhparam.pem: {{ . }}
-{{- end }}