K3s system upgrade controller

Voortbordurend op de multi-node cluster is er de mogelijkheid om (semi) automatisch upgrades uit te voeren op de K3s cluster. Momenteel ziet het cluster er alsvolgt uit:

of via de CLI:

$ kubectl get nodes --sort-by=.metadata.name

NAME    STATUS   ROLES                  AGE   VERSION
rpi-1   Ready    control-plane,master   22h   v1.19.3+k3s1
rpi-2   Ready    worker                 21h   v1.19.3+k3s1
rpi-3   Ready    worker                 21h   v1.19.3+k3s1

Rancher heeft een repository op GitHub waar de ‘System Upgrade Controller‘ opgehaald kan worden en ‘applied’ met kubectl.

Er wordt een ‘Custom Resource Definition‘ (CRD) ingeladen om het mogelijk te maken of er een ‘Plan‘ aanwezig is voor een upgrade van componenten in een ‘Node‘. Als die er is, wordt een ‘Job‘ aangemaakt die de upgrade gaat uitvoeren voor die node(s).

Om die CRD te kunnen gebruiken wordt een Service Account ‘system-upgrade’ gemaakt met de bijbehorende (cluster)Roles. Dit in een nieuwe namespace genaamd ‘system-upgrade’.

---
apiVersion: v1
kind: Namespace
metadata:
  name: system-upgrade
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: system-upgrade
  namespace: system-upgrade
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name:  system-upgrade
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: system-upgrade
  namespace: system-upgrade

Voordat de deployment gemaakt wordt zal een ConfigMap de nodige variables bevatten die gebruikt gaan worden:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: default-controller-env
  namespace: system-upgrade
data:
  SYSTEM_UPGRADE_CONTROLLER_DEBUG: "false"
  SYSTEM_UPGRADE_CONTROLLER_THREADS: "2"
  SYSTEM_UPGRADE_JOB_ACTIVE_DEADLINE_SECONDS: "900"
  SYSTEM_UPGRADE_JOB_BACKOFF_LIMIT: "99"
  SYSTEM_UPGRADE_JOB_IMAGE_PULL_POLICY: "Always"
  SYSTEM_UPGRADE_JOB_KUBECTL_IMAGE: "rancher/kubectl:v1.20.2"
  SYSTEM_UPGRADE_JOB_PRIVILEGED: "true"
  SYSTEM_UPGRADE_JOB_TTL_SECONDS_AFTER_FINISH: "900"
  SYSTEM_UPGRADE_PLAN_POLLING_INTERVAL: "15m"

Tenslotte de deployment zelf voor de CRD:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: system-upgrade-controller
  namespace: system-upgrade
spec:
  selector:
    matchLabels:
      upgrade.cattle.io/controller: system-upgrade-controller
  template:
    metadata:
      labels:
        upgrade.cattle.io/controller: system-upgrade-controller # necessary to avoid drain
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - {key: "node-role.kubernetes.io/master", operator: In, values: ["true"]}
      serviceAccountName: system-upgrade
      tolerations:
        - key: "node-role.kubernetes.io/master"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: system-upgrade-controller
          image: rancher/system-upgrade-controller:v0.5.0
          imagePullPolicy: IfNotPresent
          envFrom:
            - configMapRef:
                name: default-controller-env
          env:
            - name: SYSTEM_UPGRADE_CONTROLLER_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['upgrade.cattle.io/controller']
            - name: SYSTEM_UPGRADE_CONTROLLER_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
          volumeMounts:
            - name: etc-ssl
              mountPath: /etc/ssl
            - name: tmp
              mountPath: /tmp
      volumes:
        - name: etc-ssl
          hostPath:
            path: /etc/ssl
            type: Directory
        - name: tmp
          emptyDir: {}

CRD

Er is geen noodzaak deze yaml files over te nemen, het is ter illustratie want om de laatste versie op te halen voor de K3s cluster volstaat het volgende commando:

$ kustomize build github.com/rancher/system-upgrade-controller | kubectl apply -f - 
$ kubectl get deploy -n system-upgrade

NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
system-upgrade-controller   1/1     1            1           67m

Nadat de CRD geladen is dient er een ‘Plan‘ gemaakt te worden zodat er Job’s worden gegenereerd.

Plan

Er zijn diverse upgrade paden te bewandelen en een aantal voorbeelden vind je op de GitHub pagina van Rancher.

Hieronder een aantal Plans voor de RPI-Cluster:

  • Plan voor K3s Server en Agent upgrade
  • Plan voor K3s apt-upgrade