You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Move best practices from dynamic admission control page to best practices page
Moved content as-is (no text changes) for a more readable diff between commits.
The following sections werent moved:
* Idempotence main section (better content in new page)
* Intercepting all versions of an object (better content in new page)
* Guaranteeing the final state of an object is seen
* Avoiding operating in the kube-system namespace
### Fail open and validate the final state {#fail-open-validate-final-state}
293
309
@@ -386,7 +402,39 @@ challenging. The following recommendations might help:
386
402
multiple times by the same webhook.
387
403
* Ensure that the scope of each mutating webhook is specific and limited.
388
404
389
-
TODO: bring examples from https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#idempotence
405
+
#### Example of idempotent mutating admission webhooks:
406
+
407
+
1. For a `CREATE` pod request, set the field `.spec.securityContext.runAsNonRoot` of the
408
+
pod to true, to enforce security best practices.
409
+
410
+
2. For a `CREATE` pod request, if the field `.spec.containers[].resources.limits`
411
+
of a container is not set, set default resource limits.
412
+
413
+
3. For a `CREATE` pod request, inject a sidecar container with name `foo-sidecar` if no container
414
+
with the name `foo-sidecar` already exists.
415
+
416
+
In the cases above, the webhook can be safely reinvoked, or admit an object that already has the fields set.
417
+
418
+
#### Example of non-idempotent mutating admission webhooks:
419
+
420
+
1. For a `CREATE` pod request, inject a sidecar container with name `foo-sidecar`
421
+
suffixed with the current timestamp (e.g. `foo-sidecar-19700101-000000`).
422
+
423
+
2. For a `CREATE`/`UPDATE` pod request, reject if the pod has label `"env"` set,
424
+
otherwise add an `"env": "prod"` label to the pod.
425
+
426
+
3. For a `CREATE` pod request, blindly append a sidecar container named
427
+
`foo-sidecar` without looking to see if there is already a `foo-sidecar`
428
+
container in the pod.
429
+
430
+
In the first case above, reinvoking the webhook can result in the same sidecar being injected multiple times to a pod, each time
431
+
with a different container name. Similarly the webhook can inject duplicated containers if the sidecar already exists in
432
+
a user-provided pod.
433
+
434
+
In the second case above, reinvoking the webhook will result in the webhook failing on its own output.
435
+
436
+
In the third case above, reinvoking the webhook will result in duplicated containers in the pod spec, which makes
437
+
the request invalid and rejected by the API server.
390
438
391
439
## Mutation testing and validation {#mutation-testing-validation}
392
440
@@ -493,6 +541,15 @@ Consider situations like the preceding example when writing your webhooks.
493
541
Exclude operations that are a result of Kubernetes responding to unavoidable
494
542
incidents.
495
543
544
+
It is recommended that admission webhooks should evaluate as quickly as possible (typically in
545
+
milliseconds), since they add to API request latency.
546
+
It is encouraged to use a small timeout for webhooks. See [Timeouts](#timeouts) for more detail.
547
+
548
+
It is recommended that admission webhooks should leverage some format of load-balancing, to
549
+
provide high availability and performance benefits. If a webhook is running within the cluster,
550
+
you can run multiple webhook backends behind a service to leverage the load-balancing that service
551
+
supports.
552
+
496
553
## Examples of good implementations {#example-good-implementations}
* If the cluster has multiple webhooks configured (possibly from independent applications deployed on
1272
-
the cluster), they can form a cycle. Webhook A must be called to process startup of webhook B's
1273
-
pods and vice versa. If both webhook A and webhook B ever become unavailable at the same time (for
1274
-
example, due to a cluster-wide outage or a node failure where both pods run on the same node)
1275
-
deadlock occurs because neither webhook pod can be recreated without the other already running.
1276
-
1277
-
One way to prevent this is to exclude webhook A's pods from being acted on be webhook B. This
1278
-
allows webhook A's pods to start, which in turn allows webhook B's pods to start. If you had a
1279
-
third webhook, webhook C, you'd need to exclude both webhook A and webhook B's pods from
1280
-
webhook C. This ensures that webhook A can _always_ start, which then allows webhook B's pods
1281
-
to start, which in turn allows webhook C's pods to start.
1282
-
1283
-
If you want to ensure protection that avoids these risks, [ValidatingAdmissionPolicies](/docs/reference/access-authn-authz/validating-admission-policy/)
1284
-
can
1285
-
provide many protection capabilities without introducing dependency cycles.
1286
-
1287
-
* Admission webhooks can intercept resources used by critical cluster add-ons, such as CoreDNS,
1288
-
network plugins, or storage plugins. These add-ons may be required to schedule or successfully run the
1289
-
pods for a particular admission webhook on the cluster. This can cause a deadlock if both the
1290
-
webhook and critical add-on is unavailable at the same time.
1291
-
1292
-
You may wish to exclude cluster infrastructure namespaces from webhooks, or make sure that
1293
-
the webhook does not depend on the particular add-on that it acts on. For exmaple, running
1294
-
a webhook as a host-networked pod ensures that it does not depend on a networking plugin.
1295
-
1296
-
If you want to ensure protection for a core add-on / or its namespace,
0 commit comments