Kubernetes provides several commands that appear to do the same thing, and two of the most commonly confused are kubectl apply and kubectl create.
Both commands can create Kubernetes resources. However, there is an important difference:
kubectl createcreates a resource that does not already exist.kubectl applydeclares the desired configuration of a resource and can create it or apply changes to an existing resource.
If you run kubectl create for a resource that already exists, Kubernetes normally returns an AlreadyExists error. Run kubectl apply against an existing resource, and Kubernetes instead attempts to reconcile the resource with the configuration you supplied.
That's why kubectl apply is commonly used when Kubernetes manifests are stored in source control and repeatedly applied as the application's configuration changes.
Is kubectl create imperative or declarative?
One reason the difference between kubectl apply and kubectl create can be confusing is that create supports more than one style of resource creation.
You can create a resource imperatively by describing it directly on the command line:
kubectl create deployment mydeployment --image=nginxYou can also tell kubectl create to create resources described in a manifest:
kubectl create -f mydeployment.yamlThe important characteristic of create is that it is a creation operation. The resource is expected not to exist yet.
By comparison, kubectl apply is designed around declarative configuration. You describe the desired resource in a manifest and apply that configuration to the cluster:
kubectl apply -f mydeployment.yamlIf the resource doesn't exist, apply can create it. If it does exist, apply can update it.
Kubectl apply example
Consider the following Kubernetes Deployment manifest. It describes an Nginx Deployment with three replicas:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80Save the manifest as mydeployment.yaml and apply it with the following command:
kubectl apply -f mydeployment.yamlIf the Deployment does not already exist, the output will look similar to this:
deployment.apps/mydeployment createdNow inspect the Deployment:
kubectl get deployment mydeploymentAfter the Pods become ready, the output will look similar to this:
NAME READY UP-TO-DATE AVAILABLE AGE
mydeployment 3/3 3 3 1mThe important point isn't the exact output or age of the Deployment. It's that kubectl apply created the resource because it didn't already exist.
Kubectl create example
Now suppose we attempt to create another Deployment named mydeployment:
kubectl create deployment mydeployment --image=nginxKubernetes rejects the request because a Deployment with that name already exists:
Error from server (AlreadyExists): deployments.apps "mydeployment" already existsThis behavior illustrates one of the fundamental differences between kubectl create and kubectl apply.
The create command expects to create a new resource. It isn't intended to reconcile changes with the existing mydeployment Deployment.
However, if we create a Deployment with a new name, the command succeeds:
kubectl create deployment yourdeployment --image=nginxThe result is:
deployment.apps/yourdeployment createdThat's a perfectly reasonable use of kubectl create. For quick, one-off resource creation from the command line, the imperative command is convenient and easy to understand.
Update a resource with kubectl apply
Now let's demonstrate where kubectl apply becomes particularly useful.
Our original mydeployment.yaml manifest requested three replicas. Suppose the application needs another replica.
Change replicas from 3 to 4:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80Then apply the manifest again:
kubectl apply -f mydeployment.yamlThis time, the Deployment already exists. Instead of returning an AlreadyExists error, kubectl apply applies the changed configuration:
deployment.apps/mydeployment configuredCheck the Deployment again:
kubectl get deployment mydeploymentOnce the additional Pod becomes available, the output will look similar to this:
NAME READY UP-TO-DATE AVAILABLE AGE
mydeployment 4/4 4 4 10mThe same manifest that originally created the Deployment has now been used to change its desired state from three replicas to four.
Kubectl create with a YAML file
It's worth emphasizing that YAML manifests aren't exclusive to kubectl apply.
You can also run:
kubectl create -f mydeployment.yamlIf mydeployment does not exist, Kubernetes creates it.
Run the same command again, however, and the operation fails because create expects a new resource.
That's different from:
kubectl apply -f mydeployment.yamlwhich is designed to apply the manifest's desired configuration repeatedly as that configuration evolves.
Kubectl apply vs. create comparison
| Behavior | kubectl create | kubectl apply |
|---|---|---|
| Create a new resource | Yes | Yes |
| Use a YAML manifest | Yes | Yes |
| Create directly from command-line arguments | Yes | Not its primary usage |
| Resource can already exist | No | Yes |
| Apply changes to an existing resource | No | Yes |
| Best suited to repeatedly managed manifests | No | Yes |
When should you use kubectl create?
Use kubectl create when the operation you're performing is fundamentally about creating a new Kubernetes resource.
It's especially convenient for quick command-line operations such as:
kubectl create deployment nginx-demo --image=nginxIt can also be useful when you deliberately want creation to fail if a resource with the same name already exists.
When should you use kubectl apply?
Use kubectl apply when a manifest represents the desired configuration of a resource and you expect to manage that resource over time.
The workflow becomes straightforward:
- Define the Kubernetes resource in YAML.
- Store the manifest with your application's configuration.
- Run
kubectl applyto create the resource. - Edit the manifest when the desired configuration changes.
- Run
kubectl applyagain to apply those changes.
That repeatability is the main reason kubectl apply is so closely associated with declarative Kubernetes resource management.
Kubectl apply vs. create explained
The difference between kubectl create and kubectl apply ultimately comes down to intent.
kubectl create says: Create this resource.
kubectl apply says: Make the resource's configuration match this declared state.
Both commands can create Kubernetes resources, and both can work with manifest files. But if you expect to maintain a resource declaratively and apply configuration changes to it over time, kubectl apply is the command designed for that workflow.