How to deploy new Docker images to your Kubernetes cluster? Of course, there are many ways and one of the most common ways is to use kubectl set image, for example:

1
kubectl set image deployment/nginx-deployment nginx=nginx:1.17.5-alpine

However, what happens if you have more containers in your deployment pod spec? And what if you also have initContainers? Fortunately, kubectl patch can help. Let’s assume we have two containers and one init container. Here is the patch file (patch.yaml) we can use:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
spec:
  template:
    spec:
      initContainers:
        - name: foo
          image: mycompany/fooimage:1.0.1
      containers:
        - name: bar
          image: mycompany/barimage:8743b520
        - name: baz
          image: mycompany/bazimage:2.15.8

We can simply apply this by the following command:

1
kubectl patch deployment mydeployment -p "$(cat patch.yaml)"

And voilà, all images in the deployment are updated at once.

Of course, you may ask what happens when image tags are variable? Of course, this information may differ in each deployment. You can use git tags or maybe git hashes for this, but how to pass it to your patch file. We can simply replace tags with variables and then use sed to replace these dummy values with the real ones. Let’s consider this template:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
spec:
  template:
    spec:
      initContainers:
        - name: foo
          image: mycompany/fooimage:FOOVER
      containers:
        - name: bar
          image: mycompany/barimage:BARVER
        - name: baz
          image: mycompany/bazimage:BAZVER

Now let’s use sed to replace these variables with the real values:

1
2
3
sed -i -e "s,FOOVER,1.0.1,g" patch.yaml
sed -i -e "s,BARVER,8743b520,g" patch.yaml
sed -i -e "s,BAZVER,2.15.8,g" patch.yaml

And we are done, now just apply kubectl patch the same way as above.