diff --git a/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md b/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md index 7968ab71d4..fda41e836f 100644 --- a/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md +++ b/content/en/docs/concepts/overview/object-management-kubectl/declarative-config.md @@ -59,7 +59,9 @@ This sets the `kubectl.kubernetes.io/last-applied-configuration: '{...}'` annotation on each object. The annotation contains the contents of the object configuration file that was used to create the object. -**Note**: Add the `-R` flag to recursively process directories. +{{< note >}} +**Note:** Add the `-R` flag to recursively process directories. +{{< /note >}} Here's an example of an object configuration file: @@ -80,7 +82,7 @@ kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/s The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation was written to the live configuration, and it matches the configuration file: -```shell +```yaml kind: Deployment metadata: annotations: @@ -131,7 +133,9 @@ if those objects already exist. This approach accomplishes the following: kubectl apply -f / ``` -**Note**: Add the `-R` flag to recursively process directories. +{{< note >}} +**Note:** Add the `-R` flag to recursively process directories. +{{< /note >}} Here's an example configuration file: @@ -143,8 +147,10 @@ Create the object using `kubectl apply`: kubectl apply -f https://k8s.io/docs/concepts/overview/object-management-kubectl/simple_deployment.yaml ``` +{{< note >}} **Note:** For purposes of illustration, the preceding command refers to a single configuration file instead of a directory. +{{< /note >}} Print the live configuration using `kubectl get`: @@ -155,7 +161,7 @@ kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/s The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation was written to the live configuration, and it matches the configuration file: -```shell +```yaml kind: Deployment metadata: annotations: @@ -210,7 +216,7 @@ kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/s The output shows that the `replicas` field has been set to 2, and the `last-applied-configuration` annotation does not contain a `replicas` field: -``` +```yaml apiVersion: apps/v1 kind: Deployment metadata: @@ -274,7 +280,7 @@ The output shows the following changes to the live configuration: - The `minReadySeconds` field has been cleared. - The `last-applied-configuration` annotation no longer contains the `minReadySeconds` field. -```shell +```yaml apiVersion: apps/v1 kind: Deployment metadata: @@ -315,10 +321,12 @@ spec: # ... ``` -**Warning**: Mixing `kubectl apply` with the imperative object configuration commands +{{< warning >}} +**Warning:** Mixing `kubectl apply` with the imperative object configuration commands `create` and `replace` is not supported. This is because `create` and `replace` do not retain the `kubectl.kubernetes.io/last-applied-configuration` that `kubectl apply` uses to compute updates. +{{< /warning >}} ## How to delete objects @@ -338,11 +346,15 @@ kubectl delete -f Only use this if you know what you are doing. +{{< warning >}} **Warning:** `kubectl apply --prune` is in alpha, and backwards incompatible changes might be introduced in subsequent releases. +{{< /warning >}} -**Warning**: You must be careful when using this command, so that you +{{< warning >}} +**Warning:** You must be careful when using this command, so that you do not delete objects unintentionally. +{{< /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` @@ -360,11 +372,13 @@ TODO(pwittrock): We need to change the behavior to prevent the user from running kubectl apply -f --prune -l ``` -**Important:** Apply with prune should only be run against the root directory +{{< warning >}} +**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 ` and do not appear in the subdirectory. +{{< /warning >}} ## How to view an object @@ -376,10 +390,12 @@ kubectl get -f -o yaml ## How apply calculates differences and merges changes -**Definition:** A *patch* is an update operation that is scoped to specific +{{< caution >}} +**Caution:** A *patch* is an update operation that is scoped to specific fields of an object instead of the entire object. This enables updating only a specific set of fields on an object without reading the object first. +{{< /caution >}} When `kubectl apply` updates the live configuration for an object, it does so by sending a patch request to the API server. The @@ -405,7 +421,7 @@ Here's an example. Suppose this is the configuration file for a Deployment objec Also, suppose this is the live configuration for the same Deployment object: -```shell +```yaml apiVersion: apps/v1 kind: Deployment metadata: @@ -460,7 +476,7 @@ Here are the merge calculations that would be performed by `kubectl apply`: Here is the live configuration that is the result of the merge: -```shell +```yaml apiVersion: apps/v1 kind: Deployment metadata: @@ -532,7 +548,9 @@ and merged. Primitive fields are replaced or cleared. +{{< note >}} **Note:** '-' is used for "not applicable" because the value is not used. +{{< /note >}} | Field in object configuration file | Field in live object configuration | Field in last-applied-configuration | Action | |-------------------------------------|------------------------------------|-------------------------------------|-------------------------------------------| @@ -545,7 +563,9 @@ Primitive fields are replaced or cleared. Fields that represent maps are merged by comparing each of the subfields or elements of the map: +{{< note >}} **Note:** '-' is used for "not applicable" because the value is not used. +{{< /note >}} | Key in object configuration file | Key in live object configuration | Field in last-applied-configuration | Action | |-------------------------------------|------------------------------------|-------------------------------------|----------------------------------| @@ -671,10 +691,12 @@ by `name`. As of Kubernetes 1.5, merging lists of primitive elements is not supported. +{{< note >}} **Note:** Which of the above strategies is chosen for a given field is controlled by the `patchStrategy` tag in [types.go](https://git.k8s.io/api/core/v1/types.go#L2565) If no `patchStrategy` is specified for a field of type list, then the list is replaced. +{{< /note >}} {{< comment >}} TODO(pwittrock): Uncomment this for 1.6 @@ -711,7 +733,7 @@ kubectl get -f https://k8s.io/docs/concepts/overview/object-management-kubectl/s The output shows that the API server set several fields to default values in the live configuration. These fields were not specified in the configuration file. -```shell +```yaml apiVersion: apps/v1 kind: Deployment # ... @@ -857,8 +879,10 @@ cleared by a merge operation. Here are some workarounds: Option 1: Remove the field by directly modifying the live object. +{{< note >}} **Note:** As of Kubernetes 1.5, `kubectl edit` does not work with `kubectl apply`. Using these together will cause unexpected behavior. +{{< /note >}} Option 2: Remove the field through the configuration file. @@ -902,7 +926,9 @@ an imperative writer requires manual steps: Kubernetes objects should be managed using only one method at a time. Switching from one method to another is possible, but is a manual process. -**Exception:** It is OK to use imperative deletion with declarative management. +{{< note >}} +**Note:** It is OK to use imperative deletion with declarative management. +{{< /note >}} {{< comment >}} TODO(pwittrock): We need to make using imperative commands with @@ -919,16 +945,20 @@ configuration involves several manual steps: 1. Export the live object to a local configuration file: - kubectl get / -o yaml --export > _.yaml + ```shell + kubectl get / -o yaml --export > _.yaml + ``` 1. Manually remove the `status` field from the configuration file. - **Note:** This step is optional, as `kubectl apply` does not update the status field - even if it is present in the configuration file. + {{< note >}}**Note:** This step is optional, as `kubectl apply` does not update the status field + even if it is present in the configuration file.{{< /note >}} 1. Set the `kubectl.kubernetes.io/last-applied-configuration` annotation on the object: - kubectl replace --save-config -f _.yaml + ```shell + kubectl replace --save-config -f _.yaml + ``` 1. Change processes to use `kubectl apply` for managing the object exclusively. @@ -940,13 +970,17 @@ TODO(pwittrock): Why doesn't export remove the status field? Seems like it shou 1. Set the `kubectl.kubernetes.io/last-applied-configuration` annotation on the object: - kubectl replace --save-config -f _.yaml + ```shell + kubectl replace --save-config -f _.yaml + ``` 1. Change processes to use `kubectl apply` for managing the object exclusively. ## Defining controller selectors and PodTemplate labels -**Warning**: Updating selectors on controllers is strongly discouraged. +{{< warning >}} +**Warning:** Updating selectors on controllers is strongly discouraged. +{{< /warning >}} The recommended approach is to define a single, immutable PodTemplate label used only by the controller selector with no other semantic meaning.