Skip to content

Commit 934a600

Browse files
authored
Merge pull request #8870 from omerap12/webhook-certgen
Add Helm-managed webhook with kube-webhook-certgen
2 parents f87a3cd + 0c69630 commit 934a600

16 files changed

+574
-17
lines changed

vertical-pod-autoscaler/charts/vertical-pod-autoscaler/README.md

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,54 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
2525
| adrianmoisey | <[email protected]> | |
2626
| omerap12 | <[email protected]> | |
2727

28+
## Webhook Management
29+
The admission controller requires a `MutatingWebhookConfiguration` and TLS certificates. This chart supports two mutually exclusive modes:
30+
31+
### Helm-managed (default)
32+
```yaml
33+
admissionController:
34+
registerWebhook: false
35+
certGen:
36+
enabled: true
37+
```
38+
In this mode:
39+
- Helm creates the MutatingWebhookConfiguration
40+
- The kube-webhook-certgen job generates TLS certificates and stores them in a Secret
41+
- The certificates are automatically injected into the webhook configuration
42+
43+
### Application-managed
44+
```yaml
45+
admissionController:
46+
registerWebhook: true
47+
certGen:
48+
enabled: false
49+
```
50+
In this mode:
51+
- The VPA admission controller creates and manages the webhook itself
52+
Important: You are responsible for creating the TLS secret before or after installing the chart. The admission controller will only create the `MutatingWebhookConfiguration` once the secret exists.
53+
If the secret is created after the Helm install, you must restart the admission controller pod to trigger webhook registration.
54+
55+
## Migration Guides
56+
57+
### Migrating from vpa-up.sh script
58+
TBD
59+
60+
### Migrating from Application-managed to Helm-managed webhook
61+
If you previously deployed with registerWebhook: true and want to switch to Helm-managed:
62+
- Delete the existing webhook:
63+
```bash
64+
kubectl delete mutatingwebhookconfiguration vpa-webhook-config
65+
```
66+
- Delete the existing secret (to allow certgen to create new certificates):
67+
```bash
68+
kubectl delete secret -n <namespace> vpa-tls-certs
69+
```
70+
- Upgrade with the new values:
71+
```bash
72+
helm upgrade <release-name> <chart> \
73+
--set admissionController.registerWebhook=false \
74+
--set admissionController.certGen.enabled=true
75+
```
2876
## Values
2977

3078
| Key | Type | Default | Description |
@@ -33,19 +81,36 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
3381
| admissionController.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].labelSelector.matchExpressions[0].operator | string | `"In"` | |
3482
| admissionController.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].labelSelector.matchExpressions[0].values[0] | string | `"admission-controller"` | |
3583
| admissionController.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey | string | `"kubernetes.io/hostname"` | |
84+
| admissionController.certGen.affinity | object | `{}` | |
85+
| admissionController.certGen.enabled | bool | `true` | |
86+
| admissionController.certGen.env | object | `{}` | Additional environment variables to be added to the certgen container. Format is KEY: Value format |
87+
| admissionController.certGen.image.pullPolicy | string | `"IfNotPresent"` | The pull policy for the certgen image. Recommend not changing this |
88+
| admissionController.certGen.image.repository | string | `"registry.k8s.io/ingress-nginx/kube-webhook-certgen"` | An image that contains certgen for creating certificates. |
89+
| admissionController.certGen.image.tag | string | `"v20231011-8b53cabe0"` | An image tag for the admissionController.certGen.image.repository image. |
90+
| admissionController.certGen.nodeSelector | object | `{}` | |
91+
| admissionController.certGen.podSecurityContext | object | `{"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}}` | The securityContext block for the certgen pod(s) |
92+
| admissionController.certGen.resources | object | `{}` | The resources block for the certgen pod |
93+
| admissionController.certGen.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}` | The securityContext block for the certgen container(s) |
94+
| admissionController.certGen.tolerations | list | `[]` | |
3695
| admissionController.enabled | bool | `true` | |
3796
| admissionController.extraArgs | list | `[]` | |
3897
| admissionController.extraEnv | list | `[]` | |
3998
| admissionController.image.pullPolicy | string | `"IfNotPresent"` | |
4099
| admissionController.image.repository | string | `"registry.k8s.io/autoscaling/vpa-admission-controller"` | |
41100
| admissionController.image.tag | string | `nil` | |
101+
| admissionController.mutatingWebhookConfiguration.annotations | object | `{}` | Additional annotations for the MutatingWebhookConfiguration |
102+
| admissionController.mutatingWebhookConfiguration.failurePolicy | string | `"Ignore"` | The failurePolicy for the mutating webhook. Allowed values are: Ignore, Fail |
103+
| admissionController.mutatingWebhookConfiguration.namespaceSelector | object | `{}` | The namespaceSelector controls which namespaces are affected by the webhook |
104+
| admissionController.mutatingWebhookConfiguration.objectSelector | object | `{}` | The objectSelector can filter objects on e.g. labels |
105+
| admissionController.mutatingWebhookConfiguration.timeoutSeconds | int | `5` | Sets the amount of time the API server will wait on a response from the webhook service |
42106
| admissionController.nodeSelector | object | `{}` | |
43107
| admissionController.podAnnotations | object | `{}` | |
44108
| admissionController.podDisruptionBudget.enabled | bool | `true` | |
45109
| admissionController.podDisruptionBudget.maxUnavailable | int or string | `nil` | Maximum number/percentage of pods that can be unavailable after the eviction. IMPORTANT: You can specify either 'minAvailable' or 'maxUnavailable', but not both. |
46110
| admissionController.podDisruptionBudget.minAvailable | int or string | `1` | Minimum number/percentage of pods that must be available after the eviction. IMPORTANT: You can specify either 'minAvailable' or 'maxUnavailable', but not both. |
47111
| admissionController.podLabels | object | `{}` | |
48112
| admissionController.priorityClassName | string | `nil` | |
113+
| admissionController.registerWebhook | bool | `false` | |
49114
| admissionController.replicas | int | `2` | |
50115
| admissionController.resources | object | `{}` | |
51116
| admissionController.service.annotations | object | `{}` | |
@@ -58,7 +123,7 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
58123
| admissionController.serviceAccount.labels | object | `{}` | |
59124
| admissionController.tls.caCert | string | `""` | |
60125
| admissionController.tls.cert | string | `""` | |
61-
| admissionController.tls.existingSecret | string | `""` | |
126+
| admissionController.tls.create | bool | `false` | |
62127
| admissionController.tls.key | string | `""` | |
63128
| admissionController.tls.secretName | string | `"vpa-tls-certs"` | |
64129
| admissionController.tolerations | list | `[]` | |
@@ -67,6 +132,12 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
67132
| admissionController.volumeMounts[0].readOnly | bool | `true` | |
68133
| admissionController.volumes[0].name | string | `"tls-certs"` | |
69134
| admissionController.volumes[0].secret.defaultMode | int | `420` | |
135+
| admissionController.volumes[0].secret.items[0].key | string | `"ca"` | |
136+
| admissionController.volumes[0].secret.items[0].path | string | `"caCert.pem"` | |
137+
| admissionController.volumes[0].secret.items[1].key | string | `"cert"` | |
138+
| admissionController.volumes[0].secret.items[1].path | string | `"serverCert.pem"` | |
139+
| admissionController.volumes[0].secret.items[2].key | string | `"key"` | |
140+
| admissionController.volumes[0].secret.items[2].path | string | `"serverKey.pem"` | |
70141
| admissionController.volumes[0].secret.secretName | string | `"vpa-tls-certs"` | |
71142
| commonLabels | object | `{}` | |
72143
| containerSecurityContext | object | `{}` | |

vertical-pod-autoscaler/charts/vertical-pod-autoscaler/README.md.gotmpl

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,52 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
2222

2323
{{ template "chart.requirementsSection" . }}
2424

25+
## Webhook Management
26+
The admission controller requires a `MutatingWebhookConfiguration` and TLS certificates. This chart supports two mutually exclusive modes:
27+
28+
### Helm-managed (default)
29+
```yaml
30+
admissionController:
31+
registerWebhook: false
32+
certGen:
33+
enabled: true
34+
```
35+
In this mode:
36+
- Helm creates the MutatingWebhookConfiguration
37+
- The kube-webhook-certgen job generates TLS certificates and stores them in a Secret
38+
- The certificates are automatically injected into the webhook configuration
39+
40+
### Application-managed
41+
```yaml
42+
admissionController:
43+
registerWebhook: true
44+
certGen:
45+
enabled: false
46+
```
47+
In this mode:
48+
- The VPA admission controller creates and manages the webhook itself
49+
Important: You are responsible for creating the TLS secret before or after installing the chart. The admission controller will only create the `MutatingWebhookConfiguration` once the secret exists.
50+
If the secret is created after the Helm install, you must restart the admission controller pod to trigger webhook registration.
51+
52+
## Migration Guides
53+
54+
### Migrating from vpa-up.sh script
55+
TBD
56+
57+
### Migrating from Application-managed to Helm-managed webhook
58+
If you previously deployed with registerWebhook: true and want to switch to Helm-managed:
59+
- Delete the existing webhook:
60+
```bash
61+
kubectl delete mutatingwebhookconfiguration vpa-webhook-config
62+
```
63+
- Delete the existing secret (to allow certgen to create new certificates):
64+
```bash
65+
kubectl delete secret -n <namespace> vpa-tls-certs
66+
```
67+
- Upgrade with the new values:
68+
```bash
69+
helm upgrade <release-name> <chart> \
70+
--set admissionController.registerWebhook=false \
71+
--set admissionController.certGen.enabled=true
72+
```
2573
{{ template "chart.valuesSection" . }}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{{- $componentsList := list }}
2+
{{- if .Values.admissionController.enabled }}{{ $componentsList = append $componentsList "admission-controller" }}{{- end }}
3+
{{- if .Values.recommender.enabled }}{{ $componentsList = append $componentsList "recommender" }}{{- end }}
4+
{{- if .Values.updater.enabled }}{{ $componentsList = append $componentsList "updater" }}{{- end }}
5+
6+
Vertical Pod Autoscaler has been installed!
7+
8+
Components deployed:
9+
{{- range $componentsList }}
10+
✓ {{ . }}
11+
{{- end }}
12+
13+
Namespace: {{ .Release.Namespace }}
14+
15+
{{- if .Values.admissionController.enabled }}
16+
17+
Webhook Configuration:
18+
{{- if .Values.admissionController.registerWebhook }}
19+
Mode: Application-managed
20+
- Webhook registered by: admission-controller application
21+
- Certificates managed by: User (you must provide the TLS secret)
22+
23+
⚠️ IMPORTANT: You must create the TLS secret '{{ include "vertical-pod-autoscaler.admissionController.tls.secretName" . }}'
24+
The admission controller will only register the webhook once this secret exists.
25+
If the secret is created after this install, restart the admission controller:
26+
27+
kubectl rollout restart deployment/{{ include "vertical-pod-autoscaler.admissionController.fullname" . }} -n {{ .Release.Namespace }}
28+
{{- else if .Values.admissionController.certGen.enabled }}
29+
Mode: Helm-managed (recommended)
30+
- Webhook registered by: Helm (MutatingWebhookConfiguration)
31+
- Certificates managed by: certgen job
32+
{{- else if .Values.admissionController.tls.create }}
33+
Mode: Helm-managed with Helm-generated certificates
34+
- Webhook registered by: Helm (MutatingWebhookConfiguration)
35+
- Certificates managed by: Helm (auto-generated)
36+
37+
⚠️ WARNING: Helm-generated certificates
38+
The TLS certificates are generated by Helm and will be regenerated on each
39+
'helm upgrade', which may cause brief disruptions. For production, consider:
40+
- Using certGen (admissionController.certGen.enabled: true)
41+
- Using cert-manager with a custom secret
42+
{{- else }}
43+
⚠️ WARNING: No TLS certificate source configured!
44+
The admission controller may fail to start. Please set one of:
45+
- admissionController.certGen.enabled: true (recommended)
46+
- admissionController.tls.create: true
47+
- admissionController.registerWebhook: true (application-managed)
48+
{{- end }}
49+
{{- end }}
50+
51+
Documentation: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler

vertical-pod-autoscaler/charts/vertical-pod-autoscaler/templates/_helpers.tpl

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,33 @@ app.kubernetes.io/component: admission-controller
6666
Create the name of the tls secret to use
6767
*/}}
6868
{{- define "vertical-pod-autoscaler.admissionController.tls.secretName" -}}
69-
{{- if .Values.admissionController.tls.existingSecret -}}
70-
{{ .Values.admissionController.tls.existingSecret }}
69+
{{- if .Values.admissionController.tls.secretName -}}
70+
{{ .Values.admissionController.tls.secretName }}
7171
{{- else -}}
7272
{{- printf "%s-%s" (include "vertical-pod-autoscaler.admissionController.fullname" .) "tls" | trunc 63 | trimSuffix "-" -}}
7373
{{- end -}}
7474
{{- end -}}
7575

76+
{{/*
77+
admissionController webhook
78+
*/}}
79+
80+
{{- define "vertical-pod-autoscaler.admissionController.webhook.configName" -}}
81+
{{ include "vertical-pod-autoscaler.fullname" . }}-webhook-config
82+
{{- end }}
83+
84+
{{/*
85+
admissionController certGen
86+
*/}}
87+
{{- define "vertical-pod-autoscaler.admissionController.certGen.fullname" -}}
88+
{{ include "vertical-pod-autoscaler.fullname" . }}-admission-certgen
89+
{{- end }}
90+
91+
{{- define "vertical-pod-autoscaler.admissionController.certGen.labels" -}}
92+
{{ include "vertical-pod-autoscaler.labels" . }}
93+
app.kubernetes.io/component: admission-certgen
94+
{{- end }}
95+
7696

7797
{{/*
7898
updater
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{{- if and .Values.admissionController.enabled .Values.admissionController.certGen.enabled -}}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRole
4+
metadata:
5+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}
6+
annotations:
7+
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
8+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
9+
"helm.sh/hook-weight": "-10"
10+
labels:
11+
{{- include "vertical-pod-autoscaler.admissionController.certGen.labels" . | nindent 4 }}
12+
rules:
13+
- apiGroups:
14+
- admissionregistration.k8s.io
15+
resources:
16+
- mutatingwebhookconfigurations
17+
verbs:
18+
- get
19+
- update
20+
- patch
21+
{{- end -}}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{{- if and .Values.admissionController.enabled .Values.admissionController.certGen.enabled -}}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: ClusterRoleBinding
4+
metadata:
5+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}
6+
annotations:
7+
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
8+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
9+
"helm.sh/hook-weight": "-10"
10+
labels:
11+
{{- include "vertical-pod-autoscaler.admissionController.certGen.labels" . | nindent 4 }}
12+
roleRef:
13+
apiGroup: rbac.authorization.k8s.io
14+
kind: ClusterRole
15+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}
16+
subjects:
17+
- kind: ServiceAccount
18+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}
19+
namespace: {{ .Release.Namespace }}
20+
{{- end -}}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{{- if and .Values.admissionController.enabled .Values.admissionController.certGen.enabled -}}
2+
apiVersion: batch/v1
3+
kind: Job
4+
metadata:
5+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}-patch
6+
namespace: {{ .Release.Namespace }}
7+
annotations:
8+
"helm.sh/hook": post-install,post-upgrade
9+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
10+
labels:
11+
{{- include "vertical-pod-autoscaler.admissionController.certGen.labels" . | nindent 4 }}
12+
spec:
13+
ttlSecondsAfterFinished: 300
14+
template:
15+
metadata:
16+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}-patch
17+
labels:
18+
{{- include "vertical-pod-autoscaler.admissionController.certGen.labels" . | nindent 8 }}
19+
spec:
20+
restartPolicy: OnFailure
21+
serviceAccountName: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}
22+
{{- with .Values.imagePullSecrets }}
23+
imagePullSecrets:
24+
{{- toYaml . | nindent 8 }}
25+
{{- end }}
26+
{{- with .Values.priorityClassName }}
27+
priorityClassName: {{ . }}
28+
{{- end }}
29+
containers:
30+
- name: patch
31+
image: {{ printf "%s:%s" .Values.admissionController.certGen.image.repository .Values.admissionController.certGen.image.tag }}
32+
imagePullPolicy: {{ .Values.admissionController.certGen.image.pullPolicy }}
33+
args:
34+
- patch
35+
- --webhook-name={{ include "vertical-pod-autoscaler.admissionController.webhook.configName" . }}
36+
- --namespace={{ .Release.Namespace }}
37+
- --secret-name={{ include "vertical-pod-autoscaler.admissionController.tls.secretName" . }}
38+
- --patch-validating=false
39+
{{- with .Values.admissionController.certGen.env }}
40+
env:
41+
{{- range $key, $value := . }}
42+
- name: {{ $key }}
43+
value: {{ $value | quote }}
44+
{{- end }}
45+
{{- end }}
46+
{{- with .Values.admissionController.certGen.resources }}
47+
resources:
48+
{{- toYaml . | nindent 12 }}
49+
{{- end }}
50+
{{- with .Values.admissionController.certGen.securityContext }}
51+
securityContext:
52+
{{- toYaml . | nindent 12 }}
53+
{{- end }}
54+
{{- with .Values.admissionController.certGen.podSecurityContext }}
55+
securityContext:
56+
{{- toYaml . | nindent 8 }}
57+
{{- end }}
58+
{{- with .Values.admissionController.certGen.nodeSelector }}
59+
nodeSelector:
60+
{{- toYaml . | nindent 8 }}
61+
{{- end }}
62+
{{- with .Values.admissionController.certGen.affinity }}
63+
affinity:
64+
{{- toYaml . | nindent 8 }}
65+
{{- end }}
66+
{{- with .Values.admissionController.certGen.tolerations }}
67+
tolerations:
68+
{{- toYaml . | nindent 8 }}
69+
{{- end }}
70+
{{- end -}}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{{- if and .Values.admissionController.enabled .Values.admissionController.certGen.enabled -}}
2+
apiVersion: rbac.authorization.k8s.io/v1
3+
kind: Role
4+
metadata:
5+
name: {{ include "vertical-pod-autoscaler.admissionController.certGen.fullname" . }}
6+
namespace: {{ .Release.Namespace }}
7+
annotations:
8+
"helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade
9+
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
10+
"helm.sh/hook-weight": "-10"
11+
labels:
12+
{{- include "vertical-pod-autoscaler.admissionController.certGen.labels" . | nindent 4 }}
13+
rules:
14+
- apiGroups:
15+
- ""
16+
resources:
17+
- secrets
18+
verbs:
19+
- get
20+
- create
21+
{{- end -}}

0 commit comments

Comments
 (0)