Mettre à jour Kubernetes chez Ziosting
Avec l’évolution rapide des versions de Kubernetes (une version majeure tous les 4 mois en moyenne), il nous fallait intégrer un moyen simple et rapide de mettre à jour nos clusters, que cela soit pour les clusters managés où nos clients ont le contrôle total de ce qui est déployé, ou pour les clusters k8s utilisés pour déployer des ziServices sur lesquels ils n’ont qu’une vision réduite.

Chez Ziosting, l'un de nos produits principaux est le KaaS : un cluster Kubernetes managé multi-master & multi-cloud, garantissant un uptime optimal même lors d'incidents graves. Par exemple, nos clients n'ont pas ou peu été impactés lors de l'incendie d'un datacenter bien connu en 2021.
Nous proposons aussi d'héberger des services managés, comme OpenSearch, PostgreSQL ou encore Redis qui utilisent Kubernetes en technologie sous-jacente.
Pour nos clients qui utilisent le niveau de service le plus élevé nous prenons carrément en charge les montées de version des clusters en s'assurant que les objets déployés sont compatibles avant la mise à jour.
Bien qu'il y ait des débats dans la communauté vis-à-vis de Kubernetes (k8s), notamment sur la complexité de l'écosystème ainsi que sur la difficulté à effectuer la transition vers celui-ci, nous avons très vite pris la décision d'utiliser k8s quasi-exclusivement pour tous nos clients et pour nos propres besoins internes. Cette approche a un premier avantage évident : celui de nous éviter de transférer des services installés "à l'ancienne" sur des serveurs Linux vers k8s.
Dans ce contexte, et avec l'évolution rapide des versions de Kubernetes (une version majeure tous les 4 mois en moyenne), il nous fallait intégrer un moyen simple, rapide, répétable et testable de mettre à jour les clusters de nos clients ainsi que nos clusters, que cela soit pour les clusters managés Kubernetes où nos clients ont le loisir de déployer ce dont ils ont besoin, ou pour les clusters de "services" où Kubernetes est utilisé de façon invisible.
Nos outils
L'outil le plus important pour gérer nos clusters au jour le jour et qui nous aide le plus lors de mises à jour Kubernetes est Rancher. Rancher est une solution développée par SUSE, qui permet d'intégrer et gérer des clusters Kube. Rancher nous fournit trois grands avantages :
- il permet de monter un cluster k8s de zéro en quelques minutes,
- il permet de mettre à jour notre distribution de Kubernetes (le Rancher Kubernetes Engine ou RKE),
- il permet aussi de fournir une interface web qui permet à nos éléments les moins orientés "technique" de pouvoir jeter un coup d'oeil rapide à un cluster si besoin (comme Olivier, notre chargé de projet).
Voici comment nous mettons à jour Rancher via Helm, une opération qui dure généralement moins de cinq minutes :
# Mise à jour du repo Helm de Rancher
helm repo add rancher-stable https://releases.rancher.com/server-charts/stable
helm repo update
# Vérification de la version actuelle de Rancher
kubectl get pod -n cattle-system -l app=rancher -o yaml | grep image:
# Mise à jour de Rancher via Helm
helm upgrade rancher rancher-stable/rancher \
--namespace cattle-system \
--set hostname=rancher.ziosting.com \
--version 2.7.5
Rancher est utile, mais ce n'est pas le seul outil utilisé lors d'une mise à jour. En effet, nous utilisons aussi Helmfile, qui nous permet de regrouper plusieurs releases Helm en un seul fichier. Cela a l'air anodin, mais concrètement, une fois intégré à notre API, Helmfile nous permet d'installer et configurer automatiquement tous les services nécessaires à la bonne opération d'un cluster k8s au sein de Ziosting : Prometheus, Promtail ou encore NGINX pour ne citer qu'eux.
Voici un exemple de notre fichier helmfile.yaml pour déployer notre "surcouche Ziosting" :
# Exemple de fichier helmfile.yaml pour déployer la "surcouche Ziosting"
repositories:
- name: prometheus-community
url: https://prometheus-community.github.io/helm-charts
- name: grafana
url: https://grafana.github.io/helm-charts
- name: nginx-stable
url: https://helm.nginx.com/stable
releases:
- name: prometheus
namespace: monitoring
chart: prometheus-community/prometheus
version: 19.6.1
values:
- ./values/prometheus-values.yaml
- name: promtail
namespace: monitoring
chart: grafana/promtail
version: 6.11.2
values:
- ./values/promtail-values.yaml
- name: nginx-ingress
namespace: ingress
chart: nginx-stable/nginx-ingress
version: 0.17.1
values:
- ./values/nginx-values.yaml
Et voici comment nous appliquons ce Helmfile, y compris avec des variables spécifiques au client :
# Application du Helmfile
helmfile sync
# Application avec des variables d'environnement spécifiques au client
CUSTOMER_ID=client123 ENVIRONMENT=production helmfile sync
Une fois le helmfile versionné dans un repo Git, nous pouvons uniformiser la "surcouche" Ziosting que nous souhaitons installer sur nos clusters Kubernetes. Mettre à jour promtail par exemple, devient une simple merge request, redéployée sur nos clusters lorsque c'est nécessaire.
Les paramètres de cette surcouche sont sauvegardés dans notre API interne GraphQL. Il nous suffit d'un appel à notre API pour installer la dernière version en date de la surcouche Ziosting, dont les paramètres sont récupérés à la volée, ce qui nous permet d'adapter cette surcouche en fonction de nos clients.
Notre outil le plus utile pour faire une mise à jour sans accroc est très probablement kubent. Avec les releases régulières de Kubernetes, certains objets sont supprimés (les PodSecurityPolicies ont été supprimées en 1.26 par exemple) et d'autres sont mis à jour, passant d'alpha à beta puis en version stable.
Voici comment nous utilisons kubent pour vérifier les objets obsolètes :
# Installation de kubent
kubectl krew install deprecations
# Vérification des ressources obsolètes dans tous les namespaces
kubent --all-namespaces
# Vérification pour une version spécifique de Kubernetes (par exemple pour préparer une mise à jour vers 1.26)
kubent --k8s-version=1.26.0 --all-namespaces
Cela pose un problème majeur : que se passe-t-il lorsque l'on met à jour des clusters Kubernetes et que les objets déployés dessus ne sont plus pris en charge ? Généralement, cela va poser de gros problèmes de stabilité qui entraînent une interruption de service lorsque les objets en question n'existent tout simplement plus (par ex. les PodSecurityPolicies citées plus haut).
Mais même lorsque l'API Kubernetes qui gère cet objet subit une simple mise à jour, cela pourrait bloquer de futurs déploiements qui utiliseraient des versions obsolètes de ces objets, par exemple lors d'un déploiement automatisé dans la pipeline d'un client. Dans cette optique, nous avons intégré kubent à notre API interne.
Anticiper, la clé d'une mise à jour qui se déroule sans accroc
Kubent nous permet de vérifier chacun de nos clusters pour nous indiquer quels objets doivent absolument être modifiés pour que la mise à jour se passe sans encombre, et même assurer une certaine sérénité à nos clients pour leurs déploiements futurs.
Pour pouvoir mettre à jour RKE, il faut d'abord mettre à jour Rancher, une manipulation qui consiste en une simple mise à jour de release Helm. La manipulation dure généralement moins de cinq minutes.
Une fois cette mise à jour effectuée, il nous faut vérifier que chaque cluster est prêt à recevoir la mise à jour et qu'aucun objet actuellement déployé ne va faire capoter la mise à jour, ce qui est le job de kubent. Notre API va scanner tous les clusters et nous faire un retour détaillé des objets à changer (si il y en a). À ce moment-là, il nous faut parfois contacter le client pour lui demander de mettre à jour certains de ses déploiements et le conseiller sur ceux-ci.
Une fois tout cela fait, on peut vraiment attaquer la mise à jour !
En utilisant notre API, nous pouvons indiquer une heure à laquelle débuter la mise à jour du cluster. Généralement, nous le faisons en heures non ouvrées, en nous adaptant aussi aux besoins des clients (par exemple, un cluster de recette peut être mis à jour entre 12 et 14 heures).
Pour la mise à jour de Kubernetes via RKE, nous procédons ainsi :
# Vérification de la version actuelle de Kubernetes
kubectl version --short
# Sauvegarde de l'état actuel du cluster (bonne pratique)
rke etcd snapshot-save --name pre-upgrade-$(date +%Y%m%d)
# Mise à jour du cluster via RKE
rke up --update-only
# Vérification après mise à jour
kubectl get nodes
kubectl get pods --all-namespaces | grep -v Running
À l'heure convenue, notre API va déclencher le process et demander d'effectuer la mise à jour vers la dernière version supportée par Ziosting. Le processus -qui s'effectue en rolling update- de mise à jour va durer plus ou moins longtemps en fonction du nombre de noeuds dans le cluster, mais généralement dure moins de 10 minutes.
Pendant cette étape, les interruptions auront été minimes voire nulles grâce au rolling update.
Une fois la mise à jour terminée, le système d'alerting de ziosting reprend la main et nous assure que tous les services sont toujours disponibles. Nous effectuons alors une série de vérifications :
# Vérification du statut des composants système
kubectl get componentstatuses
# Vérification que tous les pods sont en état Running ou Completed
kubectl get pods --all-namespaces | grep -v "Running\|Completed"
# Vérification rapide de l'état du cluster
kubectl cluster-info
# Vérification des éventuelles erreurs dans les logs des composants système
kubectl logs -n kube-system -l component=kube-apiserver --tail=100
Conclusion
Pour une équipe de taille réduite comme celle de Ziosting, il est nécessaire d'automatiser au maximum tous les process et d'utiliser tous les outils à notre disposition dans l'écosystème Kubernetes pour garantir des mises à jour les plus rapides possibles, en réduisant au maximum les impacts pour nos clients.
Grâce à Rancher, Kubernetes, Kubent et à un peu de code interne (notre sauce secrete) et notre monitoring, nous abordons les mises à jour de façon apaisée et pouvons garantir une mise à jour sans accroc à nos clients !notre monitoring, nous abordons les mises à jour de façon apaisée et pouvons garantir une mise à jour sans accroc à nos clients !
Articles similaires
Aucun article lié n'a été trouvé.
Il ne manque plus que vous !
Du projet from scrach jusqu'aux projets Legacy, nous avons tout ce dont vous avez besoin pour passer une nouvelle étape