[K3s] Upgrade Plan K3s

PLAN VOOR DE MASTER-NODE

Een manifest voor het Plan voor de K3s Server kan er alsvolgt uitzien, de uitleg staat in de comments:

---
apiVersion: upgrade.cattle.io/v1
kind: Plan

metadata:
  # De naam geeft aan om welk K3s component het gaat. Wordt tevens gebruikt in prepare op de workers.
  name: k3s-server

  # De namespace is waar de system-upgrade-controller deployed wordt.
  namespace: system-upgrade

spec:
  # Het maximaal aantal nodes dat tegelijkertijd wordt ge-update.
  concurrency: 1

  # De versie die gebruikt wordt om de nodes te upgraden.
  version: v1.20.2-k3s1

  # Gebruikt om de master-node te kunnen upgraden.
  tolerations:
    - key: "node-role.kubernetes.io/master"
      operator: "Exists"
      effect: "NoSchedule"

  # Geef aan welke nodes voor de upgrade in aanmerking komen.
  nodeSelector:
    matchExpressions:
      - {key: k3s-upgrade, operator: NotIn, values: ["disabled", "false"]}
      - {key: k3s-upgrade, operator: Exists}
      - {key: node-role.kubernetes.io/master, operator: In, values: ["true"]}
  
  # De te gebruiken service-account met de juiste rechten.
  serviceAccountName: system-upgrade

  # Keuze uit de node drainen of cordonen
  #drain:
  #  force: true
  cordon: true

  # Geef aan welke image geebruikt wordt voor de upgrade.
  upgrade:
    image: rancher/k3s-upgrade

Enkele highlights:

version: v1.20.2-k3s1

Dit geeft aan naar welke versie van K3s we willen upgraden.

tolerations:
    - key: "node-role.kubernetes.io/master"
      operator: "Exists"
      effect: "NoSchedule"

De master-node is voorzien van een taint zodat workloads op de worker-nodes ge-deployed worden. Tenzij we een toleration gebruiken en dat is uiteraard nodig als we de master-node willen upgraden.

nodeSelector:
    matchExpressions:
      - {key: k3s-upgrade, operator: NotIn, values: ["disabled", "false"]}
      - {key: k3s-upgrade, operator: Exists}
      - {key: node-role.kubernetes.io/master, operator: In, values: ["true"]}

De nodeSelector zorgt ervoor dat de upgrade alleen op de master-node uitgevoerd wordt. Daarvoor dient echter wel het label ‘k3s-upgrade‘ te bestaan waarvan de waarde niet ‘false‘ of ‘disabled‘ mag zijn.

We kiezen voor cordon van de node in plaats van drain, de workloads staan immer op de worker-nodes.

PLAN VOOR DE WORKERS

Voor de worker-nodes is het plan bijna hetzelfde, hier wordt de node echter ge-drained en we maken een voorwaarde dat eerst de master-node ge-upgrade wordt alvorens de workers aan de beurt zijn.

---
apiVersion: upgrade.cattle.io/v1
kind: Plan
metadata:
  name: k3s-agent
  namespace: system-upgrade
spec:
  concurrency: 1
  version: v1.20.2-k3s1
  nodeSelector:
    matchExpressions:
      - {key: k3s-upgrade, operator: NotIn, values: ["disabled", "false"]}
      - {key: k3s-upgrade, operator: Exists}
      - {key: node-role.kubernetes.io/master, operator: DoesNotExist}
  serviceAccountName: system-upgrade

  # Prepare is de stap die gedaan wordt voordat de node drained of cordoned wordt.
  prepare:
    image: rancher/k3s-upgrade
    args: ["prepare", "k3s-server"]
  drain:
    # deleteLocalData: true  # default
    # ignoreDaemonSets: true # default
    force: true
    skipWaitForDeleteTimeout: 60
  #cordon: true
  upgrade:
    image: rancher/k3s-upgrade

de highlights

prepare:
    image: rancher/k3s-upgrade
    args: ["prepare", "k3s-server"]

Dit geeft dus aan dat er eerst gewacht wordt op een upgrade van de master-node.

Verder mag de role master niet aanwezig zijn maar moet wel het label ‘k3s-upgrade’ aanwezig zijn.

Zowel de server als de agent manifest worden ge-applied met kubectl en daardoor ontstaan er twee jobs die wachten op geldigheid voor taint en labels.

$ kubectl apply -f k3s-server.yml
plan.upgrade.cattle.io/k3s-server created

$ kubectl apply -f k3s-agent.yml
plan.upgrade.cattle.io/k3s-agent created

Nu is het dus een kwestie van de labels op de nodes zetten om de upgrade-jobs te laten starten:

$ kubectl label node rpi-1 rpi-2 rpi-3 k3s-upgrade=true

Als eerste wordt nu dus de master-node ge-upgrade en zodra deze weer in Ready state is volgen de worker-nodes.

Uiteindelijk zijn alle nodes ge-upgrade naar K3s versie v1.20.2-k3s1 en zijn voorzien van een label met de upgrade ID van de Plans.

Via de CLI:

kubectl get nodes --sort-by=.metadata.name
NAME    STATUS   ROLES                  AGE   VERSION
rpi-1   Ready    control-plane,master   36h   v1.20.2+k3s1
rpi-2   Ready    worker                 34h   v1.20.2+k3s1
rpi-3   Ready    worker                 34h   v1.20.2+k3s1

via het Dashboard van de Cluster Explorer:

Bewerken