In this article, we will look at the kubectl apply
and kubectl create
commands to understand how to use them and the differences between the two. We will then look at some usage examples on an Azure Kubernetes Service cluster (AKS).
To understand the differences between the commands, we first need an understanding of declarative and imperative management. But in short, the difference between kubectl apply and kubectl create is that kubectl apply
is best to use to take advantage of version control, while kubectl create
is a good option if you are experimenting or troubleshooting.
Declarative management is where we specify the required outcome, not the individual steps needed to achieve that outcome.
For each kind of resource specified in our YAML configuration files, a dedicated controller checks what we currently have and tries to converge it with what we want.
kubectl apply
— This is a declarative command.
Imperative management means giving a series of instructions or steps to reach the goal. We specify what and how we should reach the goal.
This is where we tell K8S what to create, replace, delete, etc., using the API. Objects are created and managed using the kubectl
command on the command line interface (CLI).
kubectl create
— This is an imperative command.
The kubectl apply
command applies a configuration to a resource by file name or stdin. The resource name must be specified.
This resource will be created if it doesn’t exist yet. If the resource already exists, this command will not error. JSON and YAML formats are accepted. The file used with the apply command can be incomplete.
kubectl apply (-f FILENAME | -k DIRECTORY)
The kubectl create
command creates a resource from a file or from stdin. JSON and YAML formats are accepted. If the resource already exists, kubectl create
will error.
kubectl create -f FILENAME
If you want to have all the kubectl commands in one place, check out our Kubernetes Cheat Sheet.
Below you can find a comparison table for these two commands.
kubectl apply | kubectl create |
|
|
This is a declarative command. |
This is an imperative command. |
JSON and YAML formats are accepted. |
JSON and YAML formats are accepted. |
Applies a configuration to a resource by file name or stdin. |
Creates a resource from a file or from stdin. |
If the resource already exists, this command will not error. |
If the resource already exists, this command will error. |
Can be used to update an already existing deployment. |
Can only be used when the resource does not already exist. |
To further understand the two commands, take a look at the example below:
1. Create a YAML file using the demo app from the official Azure documentation.
aks-helloworld-one.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-one
spec:
replicas: 1
selector:
matchLabels:
app: aks-helloworld-one
template:
metadata:
labels:
app: aks-helloworld-one
spec:
containers:
- name: aks-helloworld-one
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "Welcome to Azure Kubernetes Service (AKS)"
2. Connect to Azure on the command line.
az login
az account set --subcription <subscription id>
az aks get-credentials --resource-group <rg name> --name <aks name>
3. With the file in the same directory, run kubectl apply
:
kubectl apply -f .\aks-helloworld-one.yaml
You should see the message: ‘deployment.apps/aks-helloworld-one created’.
4. Check the deployment worked:
kubectl get deployment
5. Now, we will try to deploy the same file using the kubectl create
command.
kubectl create deployment aks-helloworld-one --image aks-helloworld-one
You will see an error as the deployment already exists. This is expected behavior when using the kubectl create
command:
6. We will try kubectl create
again, with a different deployment name.
kubectl create deployment aks-helloworld-two --image aks-helloworld-two
This time the deployment will be successful:
7. Modify the aks-helloworld-one.yaml file to increase the number of replicas from 1 to 3 (shown below).
apiVersion: apps/v1
kind: Deployment
metadata:
name: aks-helloworld-one
spec:
replicas: 3
selector:
matchLabels:
app: aks-helloworld-one
template:
metadata:
labels:
app: aks-helloworld-one
spec:
containers:
- name: aks-helloworld-one
image: mcr.microsoft.com/azuredocs/aks-helloworld:v1
ports:
- containerPort: 80
env:
- name: TITLE
value: "Welcome to Azure Kubernetes Service (AKS)"
8. Apply the new configuration:
kubectl apply -f .\aks-helloworld-one.yaml
The output should show that the change has been configured.
9. Check the deployment:
kubectl get deployment
You should now see three pods running in the deployment:
You can see from the example that the kubectl apply
command can be used to update an already existing deployment, kubectl create
but cannot. kubectl create
can only be used when the resource does not already exist.
Using both kubectl apply
and kubectl create
can be useful in different situations, depending on which deployment management method you want to use. kubectl apply
is best to use to take advantage of version control, where if you are experimenting or troubleshooting, kubectl create
is a good option.
You can check out the command reference for both commands on the official kubernetes.io website.
Additionally, Spacelift can help you manage the complexities and compliance challenges of using Kubernetes. Anything that can be run via kubectl can be run within a Spacelift stack. Read more about how Spacelift works with Kubernetes.
Cheers!
The most Flexible CI/CD Automation Tool
Spacelift is an alternative to using homegrown solutions on top of a generic CI. It helps overcome common state management issues and adds several must-have capabilities s for infrastructure management.