-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Add docs for ApplySet-based pruning in kubectl apply #39818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
be6f319
9eccf9d
2d00945
0a4e016
0207e38
eb007f2
1b58266
07b2089
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -92,6 +92,69 @@ Common forms of values include: | |||||||||||
|
|
||||||||||||
| One of the [recommended labels](/docs/concepts/overview/working-with-objects/common-labels/#labels). | ||||||||||||
|
|
||||||||||||
| ### applyset.kubernetes.io/additional-namespaces (alpha) {#applyset-kubernetes-io-additional-namespaces} | ||||||||||||
|
|
||||||||||||
| Example: `applyset.kubernetes.io/additional-namespaces: "namespace1,namespace2"` | ||||||||||||
|
|
||||||||||||
| Used on: Objects being used as ApplySet parents. | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| Use of this annotation is alpha. | ||||||||||||
| For Kubernetes version {{< skew currentVersion >}}, you can use this annotation on Secrets, ConfigMaps, or custom resources if the {{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinition" >}} defining them has the `applyset.kubernetes.io/is-parent-type` label. | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please help wrap the long lines for the benefits of downstream localization teams. For example:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there an explanation of what the desired wrapping is, or perhaps automation (like a make task) that can take care of the toil if this is required? I'm also curious why that helps localization. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have a script that identifies lines that have changed. Long lines don't work well with that. It'd be nice to see this wrapped (eg at around 100 characters). Can happen after this merges. |
||||||||||||
|
|
||||||||||||
| Part of the specification used to implement [ApplySet-based pruning in kubectl](/docs/tasks/manage-kubernetes-objects/declarative-config/#alternative-kubectl-apply-f-directory-prune). This annotation is applied to the parent object used to track an ApplySet to extend the scope of the ApplySet beyond the parent object's own namespace (if any). The value is a comma-separated list of the names of namespaces other than the parent's namespace in which objects are found. | ||||||||||||
|
|
||||||||||||
| ### applyset.kubernetes.io/contains-group-resources (alpha) {#applyset-kubernetes-io-contains-group-resources} | ||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe a shorter anchor is good enough?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These aren't priced by the byte, you know. The fragment identifies in this page are typically quite long. I think it's OK. The important bit is that they're stable. |
||||||||||||
|
|
||||||||||||
| Example: `applyset.kubernetes.io/contains-group-resources: "certificates.cert-manager.io,configmaps,deployments.apps,secrets,services"` | ||||||||||||
|
|
||||||||||||
| Used on: Objects being used as ApplySet parents. | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| Use of this annotation is alpha. | ||||||||||||
| For Kubernetes version {{< skew currentVersion >}}, you can use this annotation on Secrets, ConfigMaps, or custom resources if the {{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinition" >}} defining them has the `applyset.kubernetes.io/is-parent-type` label. | ||||||||||||
|
|
||||||||||||
| Part of the specification used to implement [ApplySet-based pruning in kubectl](/docs/tasks/manage-kubernetes-objects/declarative-config/#alternative-kubectl-apply-f-directory-prune). This annotation is applied to the parent object used to track an ApplySet to optimize listing of ApplySet member objects. It is optional in the ApplySet specification, as tools can perform discovery or use a different optimization. However, as of Kubernetes version {{< skew currentVersion >}}, it is required by kubectl. When present, the value of this annotation must be a comma separated list of the group-kinds, in the fully-qualified name format, i.e. `<resource>.<group>`. | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| ### applyset.kubernetes.io/id (alpha) {#applyset-kubernetes-io-id} | ||||||||||||
|
|
||||||||||||
| Example: `applyset.kubernetes.io/id: "applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1"` | ||||||||||||
|
|
||||||||||||
| Used on: Objects being used as ApplySet parents. | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| Use of this label is alpha. | ||||||||||||
| For Kubernetes version {{< skew currentVersion >}}, you can use this label on Secrets, ConfigMaps, or custom resources if the {{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinition" >}} defining them has the `applyset.kubernetes.io/is-parent-type` label. | ||||||||||||
|
|
||||||||||||
| Part of the specification used to implement [ApplySet-based pruning in kubectl](/docs/tasks/manage-kubernetes-objects/declarative-config/#alternative-kubectl-apply-f-directory-prune). This label is what makes an object an ApplySet parent object. Its value is the unique ID of the ApplySet, which is derived from the identity of the parent object itself. This ID **must** be the base64 encoding (using the URL safe encoding of RFC4648) of the hash of the group-kind-name-namespace of the object it is on, in the form: `<base64(sha256(<name>.<namespace>.<kind>.<group>))>`. There is no relation between the value of this label and object UIDs. | ||||||||||||
|
|
||||||||||||
| ### applyset.kubernetes.io/is-parent-type (alpha) {#applyset-kubernetes-io-is-parent-type} | ||||||||||||
|
|
||||||||||||
| Example: `applyset.kubernetes.io/is-parent-type: "true"` | ||||||||||||
|
|
||||||||||||
| Used on: Custom Resource Definition (CRD) | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| Use of this label is alpha. | ||||||||||||
| Part of the specification used to implement [ApplySet-based pruning in kubectl](/docs/tasks/manage-kubernetes-objects/declarative-config/#alternative-kubectl-apply-f-directory-prune). You can set this label on a {{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinition" >}} (CRD) to identify the custom resource type it defines (not the CRD itself) as an allowed parent for an ApplySet. The only permitted value for this label is `"true"`; if you want to mark a CRD as not being a valid parent for ApplySets, omit this label. | ||||||||||||
|
|
||||||||||||
| ### applyset.kubernetes.io/part-of (alpha) {#applyset-kubernetes-io-part-of} | ||||||||||||
|
|
||||||||||||
| Example: `applyset.kubernetes.io/part-of: "applyset-0eFHV8ySqp7XoShsGvyWFQD3s96yqwHmzc4e0HR1dsY-v1"` | ||||||||||||
|
|
||||||||||||
| Used on: All objects. | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| Use of this label is alpha. | ||||||||||||
| Part of the specification used to implement [ApplySet-based pruning in kubectl](/docs/tasks/manage-kubernetes-objects/declarative-config/#alternative-kubectl-apply-f-directory-prune). This label is what makes an object a member of an ApplySet. The value of the label **must** match the value of the `applyset.kubernetes.io/id` label on the parent object. | ||||||||||||
|
|
||||||||||||
| ### applyset.kubernetes.io/tooling (alpha) {#applyset-kubernetes-io-tooling} | ||||||||||||
|
|
||||||||||||
| Example: `applyset.kubernetes.io/tooling: "kubectl/v{{< skew currentVersion >}}"` | ||||||||||||
|
|
||||||||||||
| Used on: Objects being used as ApplySet parents. | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| Use of this annotation is alpha. | ||||||||||||
| For Kubernetes version {{< skew currentVersion >}}, you can use this annotation on Secrets, ConfigMaps, or custom resources if the {{< glossary_tooltip term_id="CustomResourceDefinition" text="CustomResourceDefinition" >}} defining them has the `applyset.kubernetes.io/is-parent-type` label. | ||||||||||||
|
|
||||||||||||
| Part of the specification used to implement [ApplySet-based pruning in kubectl](/docs/tasks/manage-kubernetes-objects/declarative-config/#alternative-kubectl-apply-f-directory-prune). This annotation is applied to the parent object used to track an ApplySet to indicate which tooling manages that ApplySet. Tooling should refuse to mutate ApplySets belonging to other tools. The value must be in the format `<toolname>/<semver>`. | ||||||||||||
|
|
||||||||||||
| ### cluster-autoscaler.kubernetes.io/safe-to-evict | ||||||||||||
|
|
||||||||||||
| Example: `cluster-autoscaler.kubernetes.io/safe-to-evict: "true"` | ||||||||||||
|
|
||||||||||||
KnVerey marked this conversation as resolved.
Show resolved
Hide resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -371,44 +371,82 @@ to result in the user deleting something unintentionally: | |
| kubectl delete -f <filename> | ||
| ``` | ||
|
|
||
| ### Alternative: `kubectl apply -f <directory/> --prune -l your=label` | ||
| ### Alternative: `kubectl apply -f <directory/> --prune` | ||
|
|
||
| Only use this if you know what you are doing. | ||
| As an alternative to `kubectl delete`, you can use `kubectl apply` to identify objects to be deleted after | ||
| their manifests have been removed from a directory in the local filesystem. | ||
|
|
||
| {{< warning >}} | ||
| `kubectl apply --prune` is in alpha, and backwards incompatible | ||
| changes might be introduced in subsequent releases. | ||
| {{< /warning >}} | ||
| In Kubernetes {{< skew currentVersion >}}, there are two pruning modes available in kubectl apply: | ||
| - Allowlist-based pruning: This mode has existed since kubectl v1.5 but is still in alpha due to usability, correctness and performance issues with its design. The ApplySet-based mode is designed to replace it. | ||
| - ApplySet-based pruning: An _apply set_ is a server-side object (by default, a Secret) that kubectl can use to accurately and efficiently track set membership across **apply** operations. This mode was introduced in alpha in kubectl v1.27 as a replacement for allowlist-based pruning. | ||
|
|
||
| {{< tabs name="kubectl_apply_prune" >}} | ||
| {{% tab name="Allow list" %}} | ||
|
|
||
| {{< feature-state for_k8s_version="v1.5" state="alpha" >}} | ||
|
|
||
| {{< warning >}} | ||
| You must be careful when using this command, so that you | ||
| do not delete objects unintentionally. | ||
| Take care when using `--prune` with `kubectl apply` in allow list mode. Which objects are pruned depends on the values of the `--prune-allowlist`, `--selector` and `--namespace` flags, and relies on dynamic discovery of the objects in scope. Especially if flag values are changed between invocations, this can lead to objects being unexpectedly deleted or retained. | ||
| {{< /warning >}} | ||
|
|
||
| As an alternative to `kubectl delete`, you can use `kubectl apply` to identify objects to be deleted after their | ||
| configuration files have been removed from the directory. Apply with `--prune` | ||
| queries the API server for all objects matching a set of labels, and attempts | ||
| to match the returned live object configurations against the object | ||
| configuration files. If an object matches the query, and it does not have a | ||
| configuration file in the directory, and it has a `last-applied-configuration` annotation, | ||
| To use allowlist-based pruning, add the following flags to your `kubectl apply` invocation: | ||
| - `--prune`: Delete previously applied objects that are not in the set passed to the current invocation. | ||
| - `--prune-allowlist`: A list of group-version-kinds (GVKs) to consider for pruning. This flag is optional but strongly encouraged, as its default value is a partial list of both namespaced and cluster-scoped types, which can lead to surprising results. | ||
| - `--selector/-l`: Use a label selector to constrain the set of objects selected for pruning. This flag is optional but strongly encouraged. | ||
| - `--all`: use instead of `--selector/-l` to explicitly select all previously applied objects of the allowlisted types. | ||
|
|
||
| Allowlist-based pruning queries the API server for all objects of the allowlisted GVKs that match the given labels (if any), and attempts to match the returned live object configurations against the object | ||
| manifest files. If an object matches the query, and it does not have a | ||
| manifest in the directory, and it has a `kubectl.kubernetes.io/last-applied-configuration` annotation, | ||
| it is deleted. | ||
|
|
||
| {{< comment >}} | ||
| TODO(pwittrock): We need to change the behavior to prevent the user from running apply on subdirectories unintentionally. | ||
| {{< /comment >}} | ||
|
|
||
| ```shell | ||
| kubectl apply -f <directory/> --prune -l <labels> | ||
| kubectl apply -f <directory/> --prune -l <labels> --prune-allowlist=<gvk-list> | ||
| ``` | ||
|
|
||
| {{< warning >}} | ||
| Apply with prune should only be run against the root directory | ||
| containing the object configuration files. Running against sub-directories | ||
| can cause objects to be unintentionally deleted if they are returned | ||
| by the label selector query specified with `-l <labels>` and | ||
| do not appear in the subdirectory. | ||
| containing the object manifests. Running against sub-directories | ||
| can cause objects to be unintentionally deleted if they were previously applied, | ||
| have the labels given (if any), and do not appear in the subdirectory. | ||
| {{< /warning >}} | ||
|
|
||
| {{% /tab %}} | ||
|
|
||
| {{% tab name="Apply set" %}} | ||
|
|
||
| {{< feature-state for_k8s_version="v1.27" state="alpha" >}} | ||
|
|
||
| {{< caution >}} | ||
| `kubectl apply --prune --applyset` is in alpha, and backwards incompatible | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This warning is why I'd probably not document the labels in the other file, not yet. If we decide to go with a resource, rather than label it'll be confusing and we'll have users relying on alpha feature, which is not plainly obvious in that other file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm fine documenting it here, under the alpha tag, if there's a desire. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We register labels or annotation as soon as released code might either set them or heed them. If someone sees a label set on an object and we've not documented that label, it doesn't leave as good an impression. If it's helpful to, we can: -### applyset.k8s.io/tooling
+### applyset.k8s.io/tooling (alpha) {#applyset-k8s-io-tooling}and similar, to mark that the key is alpha. No problem there. Notice how I overrode the fragment identifier so that bookmarks etc still work after graduation to beta or stable. |
||
| changes might be introduced in subsequent releases. | ||
| {{< /caution >}} | ||
|
|
||
| To use ApplySet-based pruning, set the `KUBECTL_APPLYSET=true` environment variable, and add the following flags to your `kubectl apply` invocation: | ||
| - `--prune`: Delete previously applied objects that are not in the set passed to the current invocation. | ||
| - `--applyset`: The name of an object that kubectl can use to accurately and efficiently track set membership across `apply` operations. | ||
|
|
||
| ```shell | ||
| KUBECTL_APPLYSET=true kubectl apply -f <directory/> --prune --applyset=<name> | ||
| ``` | ||
|
|
||
| By default, the type of the ApplySet parent object used is a Secret. However, ConfigMaps can also be used in the format: `--applyset=configmaps/<name>`. When using a Secret or ConfigMap, kubectl will create the object if it does not already exist. | ||
|
|
||
| It is also possible to use custom resources as ApplySet parent objects. To enable this, label the Custom Resource Definition (CRD) that defines the resource you want to use with the following: `applyset.kubernetes.io/is-parent-type: true`. Then, create the object you want to use as an ApplySet parent (kubectl does not do this automatically for custom resources). Finally, refer to that object in the applyset flag as follows: `--applyset=<resource>.<group>/<name>` (for example, `widgets.custom.example.com/widget-name`). | ||
|
|
||
| With ApplySet-based pruning, kubectl adds the `applyset.kubernetes.io/part-of=<parentID>` label to each object in the set before they are sent to the server. For performance reasons, it also collects the list of resource types and namespaces that the set contains and adds these in annotations on the live parent object. Finally, at the end of the apply operation, it queries the API server for objects of those types in those namespaces (or in the cluster scope, as applicable) that belong to the set, as defined by the `applyset.kubernetes.io/part-of=<parentID>` label. | ||
|
|
||
| Caveats and restrictions: | ||
| - Each object may be a member of at most one set. | ||
| - The `--namespace` flag is required when using any namespaced parent, including the default Secret. This means that ApplySets spanning multiple namespaces must use a cluster-scoped custom resource as the parent object. | ||
| - To safely use ApplySet-based pruning with multiple directories, use a unique ApplySet name for each. | ||
|
|
||
| {{% /tab %}} | ||
|
|
||
| {{< /tabs >}} | ||
|
|
||
|
|
||
| ## How to view an object | ||
|
|
||
| You can use `kubectl get` with `-o yaml` to view the configuration of a live object: | ||
|
|
@@ -1007,5 +1045,3 @@ template: | |
| * [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/tasks/manage-kubernetes-objects/imperative-config/) | ||
| * [Kubectl Command Reference](/docs/reference/generated/kubectl/kubectl-commands/) | ||
| * [Kubernetes API Reference](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to document
kubectl.kubernetes.io/last-applied-configuration(used for legacy pruning) too.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That should got in my other PR against main, or maybe even its own PR. I'm quite shocked that it isn't already documented; that one has been in use since the very beginning AFAIK. Pruning hijacks it, but it is critical to the functioning of
applyitself (the old client-side implementation; SSA works differently).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Help welcome here. This PR can merge, anyway.