Aller au contenu

Garder les services de son cluster k8s à jour depuis son canapé

Si vous maintenez un cluster Kubernetes, vous vous êtes sans déjà vu mettre à jour les images de vos pods. Que ce soit parce qu’une vulnérabilité a été détectée ou de nouveaux bufixes, mettre à jour les versions de patchs (ou mineures) des services qui tournent sur son cluster est un besoin voire une bonne pratique.

Plusieurs manières de faire pour y arriver :

  • kubectl rollout restart -n <namespace> pod/<pod-id>
  • kubectl set image -n <namespace> deployment/<deployment-name> <container>=<image>:<tag>

Cela nécessite de connaître l’ensemble de ses services pour venir y appliquer ces commandes et déclencher le téléchargement de ces nouvelles images.

Dans tous les cas, cela reste quelque chose de fastidieux et qu’il faut prévoir à l’avance ou bien être capable de réagir suite à une alerte.

L’alternative

A /mnt nous adoptons une solution un peu différente : krar. Concrètement il s’agit d’un chart Helm qui lancera des CronJob défini par l’utilisateur et qui viendra réaliser ces mises à jour à votre place sur les ressources ciblées. Aujourd’hui krar est capable de relancer une ressource (Deployment, DaemonSet et Statefulset) afin de provoquer un comportement de Kubernetes : télécharger le tag de l’image qui a pu être mis à jour depuis le dernier lancement.

krar ne fonctionne pas seulement qu’avec les ressources où est défini imagePullPolicy: Always mais c’est tout de même préconisé pour éviter tout quiproquo.

Il s’agit d’un Keel en plus léger, qui se consacre seulement sur cet aspect. Aucun controller n’est nécessaire.

Comment ça fonctionne ?

Le fonctionnement est simple : il suffit d’ajouter une annotation aux ressources que l’on souhaite.

Exemple : krar.slash-mnt.com/rollout-policy: once-a-month

Ce qui pourrait donner le Deployment suivante :

# From https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
    krar.slash-mnt.com/rollout-policy: once-a-month
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80

Customisation de krar

Tout se joue dans le values.yaml :

image:
  repository: alpine
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: 3.19.1

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

resources:
  requests:
    memory: 10Mi

podAnnotations: {}
podLabels: {}

podSecurityContext: {}
  # fsGroup: 2000

securityContext: {}
  # capabilities:
  #   drop:
  #   - ALL
  # readOnlyRootFilesystem: true
  # runAsNonRoot: true
  # runAsUser: 1000

nodeSelector: {}
tolerations: []
affinity: {}

roleClusterAnnotations: {}
roleClusterBindingAnnotations: {}
serviceAccountAnnotations: {}

jobs:
  - name: once-a-month
    schedule: 0 0 1 * *
    podLabels: []
    filter:
      label:
        domain: krar.slash-mnt.com
        name: rollout-policy
        policyName: "" # Overrides the job name.
      resources:
        - deployments
        - statefulsets
        - daemonsets
      namespaces:
        all: true
        specific: []

cluster:
  kubernetes:
    version: 1.17.5

Résultat

Plus besoin de venir périodiquement mettre à jour ses ressources. Tout se fait automatiquement sur les ressources ciblées. Evidemment, toutes les autres restent sous votre vigilance ;).

krar est maintenu par /mnt. Toutes propositions d’améliorations peuvent être déclarées sur le repository Github https://github.com/slash-mnt/krar.