Automated upgrades of Kubernetes applications with Acorn

Feb 1, 2023 by Sameer Kulkarni
Automated upgrades of Kubernetes applications with Acorn

Starting with Acorn v0.4.0, you can run Acorn apps with Auto Upgrade enabled. So anytime a newer image of the Acorn app is published to the repository, Acorn will auto upgrade the deployed application running on Kubernetes to the latest version. The auto upgrade will only happen if the newer version matches the auto upgrade pattern specified while running the app. Acorn uses 3 special characters to configure the pattern, to make sure it can cater to any & all upgrade configurations required.

Configuring the auto upgrade rules

Acorn will enable auto upgrade for an app if #, * or ** appears in the image tag to run. Available image tags are sorted using the upgrade pattern specified. The newest image in that sorted list of tags is used to upgrade the application. The rules for the three characters are as below.

  • Use # if you want to sort the version segment numerically
  • Use * if you want to sort the version segment alphabetically
  • Use ** if you want to ignore the version segment while sorting

Let’s dive in to understand the above rules better. We’ll use my fork of the awesome-compose repository to run Acorn applications. In this fork I have added Acornfiles to the required docker-compose example applications in the upstream repo, to run them with Acorn. We’ll be using the nginx-golang app in the fork to demonstrate the Acorn auto upgrade functionality.

Prerequisites

Below is a detailed list of things you will need to follow the examples explained in this post.

  • A kubernetes cluster, either local or in cloud.
  • Acorn v0.4.0 CLI installed locally. Follow Acorn CLI install guide or upgrade guide as required.
  • Acorn installed on the Kubernetes cluster. Follow Acorn Kubernetes install guide for Acorn requirements & install instructions.
  • Clone my awesome-compose fork locally.
  • Login to your container registry with Acorn CLI. Refer Acorn Image publish guide for instructions.

Auto upgrade in Action

Sorting the numeric image tag segments

Let’s build the nginx-golang app in the repository. We’ll tag the first build as v1.0. After tagging we’ll also publish the Acorn app image to container registry. I’m logged in to ghcr so that is where I’ve tagged & published my image to.

$ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v1.0 . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v1.0

Now let’s run this application with Acorn with auto-upgrade enabled. For that we just need to use a pattern when specifying the image tag. Since the segments in the tag are mostly made up of numbers & higher numbers will mean later builds we should use the # special character in the pattern, as shown below.

$ acorn run -n nginx-golang ghcr.io/samkulkarni20/nginx-golang:v#.# $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v1.0 2 2 2m42s ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK

You can see that Acorn has looked up the specific repository & chosen the latest image tag to run in place of the pattern we specified. Of course, currently there is just 1 tag to choose from so let’s create & push some more tags. Let’s see if Acorn correctly selects the latest one & upgrades the running application to it.

$ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v1.1 . $ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.0 . $ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.1 . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v1.1 && \ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.0 && \ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.1 $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v2.1 2 2 55m ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK

As you can see I built 3 more tags for the application. v1.1, v2.0 & v2.1. I also updated the application slightly to include the new image tag, so that I could verify if I’m seeing the expected app version or not. Then I pushed all three tags together. After a couple of mins, Acorn picked the correct version as the latest & then upgraded the application.

Image check interval

The default interval to check new image tags is 5 minutes. You may change this interval while running the application with the flag --interval. The flag accepts duration as a string with sequence of decimal numbers, each with optional fraction and a unit suffix e.g. 2m, 1h, 2h30m, etc.

Sorting the alphabetical segments in the image tag

Let’s take the above example further in this section. If the image tags we use has any alphabetical fields, we could use the special character * to sort them. For example, we may want to create some pre-release image tags for the next application builds such as v2.2-alpha, v2.2-beta, etc. In those cases, we could modify the auto upgrade pattern as below. Let’s stop the previous application instance, followed by building & pushing a v2.2-alpha tag.

$ acorn stop nginx-golang && acorn rm -f nginx-golang && acorn apps -a NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE $ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.2-alpha . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.2-alpha

Now let’s run the application with numeric & alphabetical segments sorting.

$ acorn run -n nginx-golang "ghcr.io/samkulkarni20/nginx-golang:v#.#-*" $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v2.2-alpha 2 2 31s ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK

As you can see, it pulled the v2.2-alpha as expected. Let’s also push a_ v2.2-beta_ image tag to see the alphabetical segment upgrade in action.

$ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.2-beta . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.2-beta $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v2.2-beta 2 2 31s ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK

Ignoring a segment in image tags

In case you don’t want to consider a segment in the image tag while sorting image tags for upgrade, you can use the ** special character. An example use case for it would be when you have image tags in the format e.g. v2.2.1 & you would like to upgrade your application on every major & minor release only. In that case you could run your application with auto upgrade configured using the pattern_ v#.#.**_, which would not consider the “patch” segment of the tag when sorting the image tags for upgrade.

$ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.2.1 . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.2.1 $ acorn run -n nginx-golang "ghcr.io/samkulkarni20/nginx-golang:v#.#.**" $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v2.2.1 2 2 3m ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK

If you pushed newer major/minor tags next, Acorn will auto-upgrade your application to those, but not for every patch build.

$ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.2.2 . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.2.2 $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v2.2.1 2 2 18m ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK
$ acorn build -t ghcr.io/samkulkarni20/nginx-golang:v2.3.0 . $ acorn push ghcr.io/samkulkarni20/nginx-golang:v2.3.0 $ acorn apps NAME IMAGE HEALTHY UP-TO-DATE CREATED ENDPOINTS MESSAGE nginx-golang ghcr.io/samkulkarni20/nginx-golang:v2.3.0 2 2 22m ago http://proxy-nginx-golang-1fe838eb7a71.local.on-acorn.io => proxy:80 OK

Conclusion

We just saw that with Acorn you can auto upgrade your applications. You would need to configure the auto upgrade image tag pattern while running the application. You may also configure how frequently Acorn checks for the new image tags to upgrade. Use # for sorting the image tag segment numerically, * to sort it alphabetically & ** to not consider a segment while sorting.

Learn more about Acorn at https://docs.acorn.io or by joining a hands on training class.

Sameer Kulkarni is a software engineer with 14+ years of experience and is working as a Principal Engineer at InfraCloud. You can chat with him on Twitter & read more of his work on Medium.