Auto-upgrade k3s using the system-upgrade-controller

3 min read | by Jordi Prats

A kubernetes cluster can get outdated pretty soon since Kubernetes keeps evolving at every release. If we have a k3s cluster we can use the system-upgrade-controller for automatically handling the upgrades. Let's take a look on how to configure it

We can install the system-upgrade-controller by going to the releases page and looking for the yaml file attached to the release. It will install a deployment that uses a service-account, a clusterRoleBinding, and a configmap. At the time of this writing the latest release is v0.6.2 so to install it you would go like this:

$ kubectl apply -f https://github.com/rancher/system-upgrade-controller/releases/download/v0.6.2/system-upgrade-controller.yaml
namespace/system-upgrade created
serviceaccount/system-upgrade created
clusterrolebinding.rbac.authorization.k8s.io/system-upgrade created
configmap/default-controller-env created
deployment.apps/system-upgrade-controller created

Once it is installed we just need to create the update plans to configure it. If we want to use the release channel to update the cluster as soon as they the releases are tagged as stable we just needs to set the following:

# Server plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: server-plan
  namespace: system-upgrade
spec:
  concurrency: 1
  cordon: true
  nodeSelector:
    matchExpressions:
    - key: node-role.kubernetes.io/master
      operator: In
      values:
      - "true"
  serviceAccountName: system-upgrade
  upgrade:
    image: rancher/k3s-upgrade
  channel: https://update.k3s.io/v1-release/channels/stable
---
# Agent plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: agent-plan
  namespace: system-upgrade
spec:
  concurrency: 1
  cordon: true
  nodeSelector:
    matchExpressions:
    - key: node-role.kubernetes.io/master
      operator: DoesNotExist
  prepare:
    args:
    - prepare
    - server-plan
    image: rancher/k3s-upgrade
  serviceAccountName: system-upgrade
  upgrade:
    image: rancher/k3s-upgrade
  channel: https://update.k3s.io/v1-release/channels/stable

If you take a look at the k3s releases you will be able to see that not every release goes straight to the release channel, meaning that your cluster won't be updated to the cutting edge version which feels a lot safer:

As v1.21 releases include a number of significant changes from previous versions, we will not make v1.21 available via the stable release channel until a later date.

On the other hand, if you want to update the cluster to a specific version you can also do it using the system-upgrade-controller. Instead of setting a channel you'll have to specify the version tag you want to use:

# Server plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: server-plan
  namespace: system-upgrade
spec:
  concurrency: 1
  cordon: true
  nodeSelector:
    matchExpressions:
    - key: node-role.kubernetes.io/master
      operator: In
      values:
      - "true"
  serviceAccountName: system-upgrade
  upgrade:
    image: rancher/k3s-upgrade
  version: v1.21.0+k3s1
---
# Agent plan
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: agent-plan
  namespace: system-upgrade
spec:
  concurrency: 1
  cordon: true
  nodeSelector:
    matchExpressions:
    - key: node-role.kubernetes.io/master
      operator: DoesNotExist
  prepare:
    args:
    - prepare
    - server-plan
    image: rancher/k3s-upgrade
  serviceAccountName: system-upgrade
  upgrade:
    image: rancher/k3s-upgrade
  version: v1.21.0+k3s1

Posted on 26/05/2021