In any running applications, sometimes we may need to change the configurations. Same applies for the Kubernetes, here either you can update it directly in the Yaml file or you can kubectl patch command. In this article let us learn about Kubernetes patch in detail.
We all aware, the kubectl command line utility offers a lot of functionality to us to help to manage our Kubernetes resources. Part of that, we have kubectl patch command, which allows us to change running configurations immediately.
In this guide, we will see how we can use the kubectl patch command to manipulate our Kubernetes resources, and we will learn the different options presented to you by this command. You will then learn some best practices that you can follow to ensure that your usage of this command is as sustainable as possible.
Why Do We Need kubectl patch?
kubectl gives us several different ways to update running configurations. The main ways are the apply, edit, and patch commands. Like if we need to update API objects in place, kubectl patch is one of the commands available to us that we will likely want to consider using.
The patch command lets us to apply a change to our running configuration by specifying only small patch value that we wish to change and then using one of three different patch types to apply this change. There are three patch types each vary slightly in how they apply the change, and as such, each is suitable for different use cases. Applying small changes like this can be useful if we want to test configuration changes or perform some testing, but do not want to update the whole configuration file. However, if we decide to keep the changes permanently, it is good idea to manage via Yaml in local or store in GIT for better tracking or follow via GitOps way.
kubectl patch
The best way to learn any command line utilities are by using it. If you want to follow along with the examples in this article, you will need a Kubernetes cluster to experiment with. You can either create one with a cloud provider such as AKS, or set up a local cluster using one of the various tools available to do so.
If you are using Mac or Windows, you can get a simple single-node cluster via Docker Desktop. If you are running a Linux-based OS, there are several options available to you, such as minikube and MicroK8s.
Using kubectl patch
To understand about the kubectl patch command, lets create one sample resource to try our changes. The following configuration file will create a simple deployment with a single replica,
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: patch-test
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx
Run the following command to apply the manifest.
# kubectl apply -f deployment.yaml
Now you could see the pads are deployed, you can see using “kubectl get pods” .
The first way to use patch is by running the command with your patch object inline. In this case, if you wanted to patch the deployment to have two replicas, it would look something like this:
# kubectl patch deployment patch-demo -p '{"spec": {"replicas": 2}}'
If you run kubectl get pods again, you will see two replicas, where previously there was only one. This approach can be useful for small changes or cases where repeatability is not a key consideration. Some real use case for doing your patches inline is that sometimes when trying to delete a PersistentVolume or some others resources like deleting namespace, or some pods or if you are using ArgoCD, applications will seemingly hang indefinitely. You can easily resolve these issues by running inline patches as follows:
# kubectl patch {{ resource }} {{ resource_name }} -p '{"metadata":{"finalizers":null}}'
# kubectl patch pvc pvc_name -p '{"metadata":{"finalizers":null}}'
# kubectl patch pv pv_name -p '{"metadata":{"finalizers":null}}'
# kubectl patch pod pod_name -p '{"metadata":{"finalizers":null}}'
In many instances, however, it is a good idea to apply your patches from a patch file, which is a partial YAML file saved to your disk/or you can store in Git repo. If you were to do this with the above example of increasing the replicas in your deployment to two, you would first need to create a new file called patch-file.yaml or your own naming pattern, which would contain your patch object:
spec:
replicas: 2
From the terminal, you can now patch your deployment by providing the file, instead of the object itself:
# kubectl patch deployment patch-test --patch-file patch-file.yaml
Different Patch Types
A few different types of patches can be performed when applying configs with the patch command. In the above examples, kubectl uses the strategic merge type by default. The available types are:
- json: A JSON patch allows you to provide an operation or operations to carry out on the object.
- json<strong> </strong>merge: A JSON merge patch allows you to naively override keys in an object.
- strategic: A strategic merge patch will either replace or merge values based on the object’s patchStrategy as defined in the Kubernetes source code. This is the default patch type.
Lets see one by one patch types with some examples.
Strategic Patch
Let’s start by applying a patch with the default mode: strategic.
Start by retrieving detailed information about the nginx containers we’re running. This command retrieves the current pods and parses out the container types, then it filters for names that include nginx.
# kubectl get pods -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |grep nginx
As expected, we’re running two instances of nginx’s latest image. Let’s patch the deployment with a specific version of the container.
Start by creating a new YAML file named nginx_patch.yaml
:
spec:
template:
spec:
containers:
- name: nginx
image: nginx:1.23.0-alpine
This file contains just enough information for patch to figure out what we’re trying to do: replace image: nginx:latest
with image: nginx:1.23.0-alpine
.
Let’s apply this patch with kubectl patch:
# kubectl patch deployment nginx-deployment --patch-file nginx_patch.yaml
deployment.apps/patch-test patched
Wait a few seconds, and then retrieve the container details again.
# kubectl get pods -o jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |grep nginx
Kubectl updated the configuration and restarted the containers for us.
We can retrieve the YAML configuration for one of the pods and see the change:
# kubectl get pod patch-test-rsq213s-42hc3 -o yaml
apiVersion: v1
kind: Pod
metadata:
spec:
containers:
- image: nginx:1.23.0-alpine
imagePullPolicy: Always
name: nginx
With a strategic patch, kubectl does the work of figuring out how to apply the changes we supplied it. Here, we replaced a node in a list with a new value. Depending on the change and the underlying type, the changes can get more complicated, so the default merge type is often your best option.
Continue Reading it on Kubectl Patch — Why we need and How to use it — FoxuTech