`kubectl apply` | Certified Kubernetes Administrator CKA guide - Part 3/10

`kubectl apply` | Certified Kubernetes Administrator CKA guide - Part 3/10

kubectl apply -f <filename.yaml>

Well, if we have come this far, you should have known the kubectl apply command that's the one command that stands out for its versatile usage in Kubernetes. In this blog, we shall explore how it actually works under the hood!

Quick recall from the previous blog where we saw Imperative and Declarative commands, kubectl apply is a declarative command. It can create, update, or delete objects in a Declarative way (i.e. from a configuration file).

Syntax: kubectl apply -f <definition-file-name.yaml>

When you run this command, kubectl apply is smart enough to CREATE the object, if it doesn't exists, or UPDATE the object if it already exists!

But this was high level overview, how is it working under the hood?

When you execute kubectl apply -f filename.yaml the command considers the 1. local configuration file, the 2. live Kubernetes object definition, and the 3. last applied configuration. If the object doesn't exist, it gets created. A "live object configuration" is also generated, mirroring our local setup but with additional fields for status storage.

When using kubectl apply there's an extra step. The YAML representation (local config file) undergoes conversion to JSON format that will serve as a last applied configuration for storage.

Example, suppose you change the image in your local file. When you run the kubectl apply command, this updated value is compared to corresponding value in the last applied configuration. If there is a difference, the live object configuration is modified to reflect the new value. Then the


Local configuration file is stored in our local system.

Live Object configuration is stored in the Kubernetes memory.

Last Applied configuration is stored in a JSON format within the live object configuration file as an annotation with the name "last applied configuration". Keeping it in the Live Object configuration helps the system to easily compare and update configurations as needed.

Example:

apiVersion: v1
kind: Pod
metadata:
   name: annotations-demo
   annotations:
   kubectl.kubernetes.io/last-applied-configuration:
   {"apiVersion": "v1","kind": "Pod","metadata": {"name": "annotations-demo"},"spec": {"containers": [{"name": "nginxcontainer","image": "nginx:1.12"
}]}}
spec:
   containers:
   - name: nginxcontainer
     image: nginx:1.12
status:
  conditions:
  - lastProbeTime: null
    status: "True"
    type: Initialized

Hopefully you know by now, using the declarative kubectl apply command on the local file stores the last applied configuration as an annotations which will further aids in tracking changes between local file and live configuration and help in updating them in the live configuration.

On the other hand, if you used imperative methods like kubectl create or kubectl replace, they will not log, instead directly create/replace object without preserving the last applied configuration.