Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions content/en/docs/reference/labels-annotations-taints/_index.md
Copy link
Contributor

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.

Copy link
Contributor Author

@KnVerey KnVerey Mar 20, 2023

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 apply itself (the old client-side implementation; SSA works differently).

Copy link
Contributor

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.

Original file line number Diff line number Diff line change
Expand Up @@ -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.

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.
Copy link
Contributor

Choose a reason for hiding this comment

The 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
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.
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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a shorter anchor is good enough?

Suggested change
### applyset.kubernetes.io/contains-group-resources (alpha) {#applyset-kubernetes-io-contains-group-resources}
### applyset.kubernetes.io/contains-group-resources (alpha) {#applyset-contains-group-resources}

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

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.

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)

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.

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.

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"`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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.
There's another aspect too: keys are “insta-durable” in as much as the first use we make of them, we're on the hook forever to explain what that label does or did mean. Plenty of the well-known labels are documented as deprecated, but a bit like with stable APIs, once they're registered we never delete the registration.

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:
Expand Down Expand Up @@ -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" >}}/)