Using Diff in Kubernetes
As you might probably know one of the most important concepts in Kubernetes is its Objects model. The Kubernetes objects are persistent entities in the K8S system. Kubernetes uses these entities to represent the state of your cluster. They can describe what containerized applications are running, on which nodes, the resources available to those applications, the policies around, etc.
A Kubernetes object is a “record of intent”, which means that once you create
the object, the K8S will constantly work to ensure that object exists. By
creating an object you tell the system the desired state. To work with
Kubernetes objects, which are stored in its database, the user
uses the Kubernetes API, for example, by using the kubectl
command-line
interface which makes the necessary Kubernetes API calls for you.
Understanding the differences between the current state and the desired state,
it is important to highlight one of the most useful, and sometimes ignored,
commands: kubectl diff
. Let’s see an example, we are going to create a simple
deployment like the following:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
kubectl apply -f deployment.nginx.yaml
Now let’s change the deployment parameters to deploy an additional replica (replicas: 2
) and, since we want to check the difference between the current deployment and the new one, we check it by executing:
kubectl diff -f deployment.nginx.yaml
And this is the output:
diff -u -N /tmp/LIVE-417333416/apps.v1.Deployment.language.nginx /tmp/MERGED-411218407/apps.v1.Deployment.language.nginx
--- /tmp/LIVE-417333416/apps.v1.Deployment.language.nginx 2021-03-14 16:47:47.205057892 +0200
+++ /tmp/MERGED-411218407/apps.v1.Deployment.language.nginx 2021-03-14 16:47:47.229058257 +0200
@@ -6,7 +6,7 @@
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx","namespace":"language"},"spec":{"replicas":2,"selector":{"matchLabels":{"app":"nginx"}},"strategy":{"type":"Recreate"},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx","name":"nginx","ports":[{"containerPort":80}]}]}}}}
creationTimestamp: "2021-03-14T14:39:46Z"
- generation: 1
+ generation: 2
managedFields:
- apiVersion: apps/v1
fieldsType: FieldsV1
@@ -17,7 +17,6 @@
f:kubectl.kubernetes.io/last-applied-configuration: {}
f:spec:
f:progressDeadlineSeconds: {}
- f:replicas: {}
f:revisionHistoryLimit: {}
f:selector: {}
f:strategy:
@@ -84,13 +83,21 @@
manager: k3s
operation: Update
time: "2021-03-14T14:39:49Z"
+ - apiVersion: apps/v1
+ fieldsType: FieldsV1
+ fieldsV1:
+ f:spec:
+ f:replicas: {}
+ manager: kubectl-client-side-apply
+ operation: Update
+ time: "2021-03-14T14:47:47Z"
name: nginx
namespace: language
resourceVersion: "743562"
uid: f58929e1-1a69-4f4b-9bee-d6ef6fb4e556
spec:
progressDeadlineSeconds: 600
- replicas: 2
+ replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
You can see the additions and removals.
As described in [1], you can even set your favorite external diff tool by setting the KUBECTL_EXTERNAL_DIFF environment variable, for example:
KUBECTL_EXTERNAL_DIFF=meld kubectl diff -f some-resources.yaml
I find really useful this diff tool called Dyff to highlight the changes using different colors and summarizing what is important:
KUBECTL_EXTERNAL_DIFF="dyff between --omit-header --set-exit-code"
$ kubectl diff -f deployments/deployment.nginx.yaml
metadata.generation
± value change
- 1
+ 2
metadata.managedFields
+ one list entry added:
- apiVersion: apps/v1
│ fieldsType: FieldsV1
│ fieldsV1:
│ │ f:spec:
│ │ │ f:replicas: {}
│ manager: kubectl-client-side-apply
│ operation: Update
│ time: "2021-03-14T15:36:27Z"
metadata.managedFields.kubectl-create.fieldsV1.f:spec
- one map entry removed:
f:replicas: {}
spec.replicas
± value change
- 2
+ 1