Declarative Management of Kubernetes Objects Using Configuration Files [page]deterministic
Kubernetes objects can be created, updated, and deleted by storing multiple object configuration files in a directory and using `kubectl apply` to recursively create and update those objects as needed. This method retains writes made to live objects without merging the changes back into the object configuration files. `kubectl diff` also gives you a preview of what changes `apply` will make.
##
Install [`kubectl`](/docs/tasks/tools/).
## Trade-offs
The `kubectl` tool supports three kinds of object management:
* Imperative commands * Imperative object configuration * Declarative object configuration
See [Kubernetes Object Management](/docs/concepts/overview/working-with-objects/object-management/) for a discussion of the advantages and disadvantage of each kind of object management.
## Overview
Declarative object configuration requires a firm understanding of the Kubernetes object definitions and configuration. Read and complete the following documents if you have not already:
* [Managing Kubernetes Objects Using Imperative Commands](/docs/tasks/manage-kubernetes-objects/imperative-command/) * [Imperative Management of Kubernetes Objects Using Configuration Files](/docs/tasks/manage-kubernetes-objects/imperative-config/)
Following are definitions for terms used in this document:
- *object configuration file / configuration file*: A file that defines the configuration for a Kubernetes object. This topic shows how to pass configuration files to `kubectl apply`. Configuration files are typically stored in source control, such as Git.
- *live object configuration / live configuration*: The live configuration values of an object, as observed by the Kubernetes cluster. These are kept in the Kubernetes cluster storage, typically etcd.
- *declarative configuration writer / declarative writer*: A person or software component that makes updates to a live object. The live writers referred to in this topic make changes to object configuration files and run `kubectl apply` to write the changes.
## How to create objects
Use `kubectl apply` to create all objects, except those that already exist, defined by configuration files in a specified directory:
```shell kubectl apply -f <directory> ```
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.
Here's an example of an object configuration file:
Run `kubectl diff` to print the object that will be created:
```shell kubectl diff -f https://k8s.io/examples/application/simple_deployment.yaml ```
> Note: `diff` uses [server-side dry-run](/docs/reference/using-api/api-concepts/#dry-run), which needs to be enabled on `kube-apiserver`.
Since `diff` performs a server-side apply request in dry-run mode, it requires granting `PATCH`, `CREATE`, and `UPDATE` permissions. See [Dry-Run Authorization](/docs/reference/using-api/api-concepts#dry-run-authorization) for details.
Create the object using `kubectl apply`:
```shell kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml ```
Print the live configuration using `kubectl get`:
```shell kubectl get -f https://k8s.io/examples/application/simple_deployment.yaml -o yaml ```
The output shows that the `kubectl.kubernetes.io/last-applied-configuration` annotation was written to the live configuration, and it matches the configuration file:
```yaml kind: Deployment metadata: annotations: # ... # This is the json representation of simple_deployment.yaml # It was written by kubectl apply when the object was created kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"apps/v1","kind":"Deployment", "metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"}, "spec":{"minReadySeconds":5,"selector":{"matchLabel …(trimmed)