Skip to content

Commit 404d09e

Browse files
committed
Add Helm-managed webhook with kube-webhook-certgen
Signed-off-by: Omer Aplatony <[email protected]>
1 parent dffccf2 commit 404d09e

16 files changed

+566
-17
lines changed

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

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,53 @@ 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+
- The application handles its own certificate generation
53+
54+
## Migration Guides
55+
56+
### Migrating from vpa-up.sh script
57+
TBD
58+
59+
### Migrating from Application-managed to Helm-managed webhook
60+
If you previously deployed with registerWebhook: true and want to switch to Helm-managed:
61+
- Delete the existing webhook:
62+
```bash
63+
kubectl delete mutatingwebhookconfiguration vpa-webhook-config
64+
```
65+
- Delete the existing secret (to allow certgen to create new certificates):
66+
```bash
67+
kubectl delete secret -n <namespace> vpa-tls-certs
68+
```
69+
- Upgrade with the new values:
70+
```bash
71+
helm upgrade <release-name> <chart> \
72+
--set admissionController.registerWebhook=false \
73+
--set admissionController.certGen.enabled=true
74+
```
2875
## Values
2976

3077
| Key | Type | Default | Description |
@@ -33,19 +80,36 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
3380
| admissionController.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].labelSelector.matchExpressions[0].operator | string | `"In"` | |
3481
| admissionController.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].labelSelector.matchExpressions[0].values[0] | string | `"admission-controller"` | |
3582
| admissionController.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution[0].topologyKey | string | `"kubernetes.io/hostname"` | |
83+
| admissionController.certGen.affinity | object | `{}` | |
84+
| admissionController.certGen.enabled | bool | `true` | |
85+
| admissionController.certGen.env | object | `{}` | Additional environment variables to be added to the certgen container. Format is KEY: Value format |
86+
| admissionController.certGen.image.pullPolicy | string | `"IfNotPresent"` | The pull policy for the certgen image. Recommend not changing this |
87+
| admissionController.certGen.image.repository | string | `"registry.k8s.io/ingress-nginx/kube-webhook-certgen"` | An image that contains certgen for creating certificates. |
88+
| admissionController.certGen.image.tag | string | `"v20231011-8b53cabe0"` | An image tag for the admissionController.certGen.image.repository image. |
89+
| admissionController.certGen.nodeSelector | object | `{}` | |
90+
| admissionController.certGen.podSecurityContext | object | `{"runAsNonRoot":true,"runAsUser":65534,"seccompProfile":{"type":"RuntimeDefault"}}` | The securityContext block for the certgen pod(s) |
91+
| admissionController.certGen.resources | object | `{}` | The resources block for the certgen pod |
92+
| admissionController.certGen.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}` | The securityContext block for the certgen container(s) |
93+
| admissionController.certGen.tolerations | list | `[]` | |
3694
| admissionController.enabled | bool | `true` | |
3795
| admissionController.extraArgs | list | `[]` | |
3896
| admissionController.extraEnv | list | `[]` | |
3997
| admissionController.image.pullPolicy | string | `"IfNotPresent"` | |
4098
| admissionController.image.repository | string | `"registry.k8s.io/autoscaling/vpa-admission-controller"` | |
4199
| admissionController.image.tag | string | `nil` | |
100+
| admissionController.mutatingWebhookConfiguration.annotations | object | `{}` | Additional annotations for the MutatingWebhookConfiguration |
101+
| admissionController.mutatingWebhookConfiguration.failurePolicy | string | `"Ignore"` | The failurePolicy for the mutating webhook. Allowed values are: Ignore, Fail |
102+
| admissionController.mutatingWebhookConfiguration.namespaceSelector | object | `{}` | The namespaceSelector controls which namespaces are affected by the webhook |
103+
| admissionController.mutatingWebhookConfiguration.objectSelector | object | `{}` | The objectSelector can filter objects on e.g. labels |
104+
| admissionController.mutatingWebhookConfiguration.timeoutSeconds | int | `5` | Sets the amount of time the API server will wait on a response from the webhook service |
42105
| admissionController.nodeSelector | object | `{}` | |
43106
| admissionController.podAnnotations | object | `{}` | |
44107
| admissionController.podDisruptionBudget.enabled | bool | `true` | |
45108
| 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. |
46109
| 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. |
47110
| admissionController.podLabels | object | `{}` | |
48111
| admissionController.priorityClassName | string | `nil` | |
112+
| admissionController.registerWebhook | bool | `false` | |
49113
| admissionController.replicas | int | `2` | |
50114
| admissionController.resources | object | `{}` | |
51115
| admissionController.service.annotations | object | `{}` | |
@@ -58,7 +122,7 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
58122
| admissionController.serviceAccount.labels | object | `{}` | |
59123
| admissionController.tls.caCert | string | `""` | |
60124
| admissionController.tls.cert | string | `""` | |
61-
| admissionController.tls.existingSecret | string | `""` | |
125+
| admissionController.tls.create | bool | `false` | |
62126
| admissionController.tls.key | string | `""` | |
63127
| admissionController.tls.secretName | string | `"vpa-tls-certs"` | |
64128
| admissionController.tolerations | list | `[]` | |
@@ -67,6 +131,12 @@ helm upgrade -i vertical-pod-autoscaler autoscalers/vertical-pod-autoscaler
67131
| admissionController.volumeMounts[0].readOnly | bool | `true` | |
68132
| admissionController.volumes[0].name | string | `"tls-certs"` | |
69133
| admissionController.volumes[0].secret.defaultMode | int | `420` | |
134+
| admissionController.volumes[0].secret.items[0].key | string | `"ca"` | |
135+
| admissionController.volumes[0].secret.items[0].path | string | `"caCert.pem"` | |
136+
| admissionController.volumes[0].secret.items[1].key | string | `"cert"` | |
137+
| admissionController.volumes[0].secret.items[1].path | string | `"serverCert.pem"` | |
138+
| admissionController.volumes[0].secret.items[2].key | string | `"key"` | |
139+
| admissionController.volumes[0].secret.items[2].path | string | `"serverKey.pem"` | |
70140
| admissionController.volumes[0].secret.secretName | string | `"vpa-tls-certs"` | |
71141
| commonLabels | object | `{}` | |
72142
| containerSecurityContext | object | `{}` | |

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,51 @@ 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+
- The application handles its own certificate generation
50+
51+
## Migration Guides
52+
53+
### Migrating from vpa-up.sh script
54+
TBD
55+
56+
### Migrating from Application-managed to Helm-managed webhook
57+
If you previously deployed with registerWebhook: true and want to switch to Helm-managed:
58+
- Delete the existing webhook:
59+
```bash
60+
kubectl delete mutatingwebhookconfiguration vpa-webhook-config
61+
```
62+
- Delete the existing secret (to allow certgen to create new certificates):
63+
```bash
64+
kubectl delete secret -n <namespace> vpa-tls-certs
65+
```
66+
- Upgrade with the new values:
67+
```bash
68+
helm upgrade <release-name> <chart> \
69+
--set admissionController.registerWebhook=false \
70+
--set admissionController.certGen.enabled=true
71+
```
2572
{{ template "chart.valuesSection" . }}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
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: admission-controller application
22+
{{- else if .Values.admissionController.certGen.enabled }}
23+
Mode: Helm-managed (recommended)
24+
- Webhook registered by: Helm (MutatingWebhookConfiguration)
25+
- Certificates managed by: certgen job
26+
{{- else if .Values.admissionController.tls.create }}
27+
Mode: Helm-managed with Helm-generated certificates
28+
- Webhook registered by: Helm (MutatingWebhookConfiguration)
29+
- Certificates managed by: Helm (auto-generated)
30+
31+
⚠️ WARNING: Helm-generated certificates
32+
The TLS certificates are generated by Helm and will be regenerated on each
33+
'helm upgrade', which may cause brief disruptions. For production, consider:
34+
- Using certGen (admissionController.certGen.enabled: true)
35+
- Using cert-manager with a custom secret
36+
{{- else }}
37+
⚠️ WARNING: No TLS certificate source configured!
38+
The admission controller may fail to start. Please set one of:
39+
- admissionController.certGen.enabled: true (recommended)
40+
- admissionController.tls.create: true
41+
- admissionController.registerWebhook: true (application-managed)
42+
{{- end }}
43+
{{- end }}
44+
45+
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)