Notre expérience dans le développement de pilotes CSI dans Kubernetes pour Yandex.Cloud

Notre expérience dans le développement de pilotes CSI dans Kubernetes pour Yandex.Cloud

Nous sommes heureux d'annoncer que la société « Flant » renforce sa contribution aux outils Open Source pour Kubernetes en lançant la version alpha du pilote CSI (Container Storage Interface) pour Yandex.Cloud.

Mais avant de passer aux dĂ©tails de mise en Ɠuvre, rĂ©pondons Ă  la question de l'utilitĂ© de cela, Ă©tant donnĂ© que Yandex propose dĂ©jĂ  le service Managed Service for Kubernetes.

Introduction

Pourquoi faire cela ?

Au sein de notre entreprise, depuis le tout début de l'exploitation de Kubernetes en production (c'est-à-dire depuis plusieurs années), nous développons notre propre outil (deckhouse), que nous prévoyons également de rendre disponible prochainement en tant que projet Open Source. Grùce à cela, nous configurons et paramétrons uniformément tous nos clusters, et actuellement, nous en avons déjà plus de 100, sur des configurations matérielles trÚs diverses et dans tous les services cloud disponibles.

Les clusters utilisant deckhouse comportent tous les composants nécessaires au bon fonctionnement : équilibrages de charge, surveillance avec des graphiques, des métriques et des alertes pratiques, authentification des utilisateurs via des fournisseurs externes pour accéder à tous les dashboards, etc. Un cluster aussi « avancé » n'a pas de sens à déployer dans une solution gérée, car cela est souvent soit impossible, soit nécessite de désactiver la moitié des composants.

NB: C'est notre expĂ©rience, qui est assez spĂ©cifique. Nous ne prĂ©tendons en aucun cas que tout le monde devrait dĂ©ployer des clusters Kubernetes par leurs propres moyens au lieu d'utiliser des solutions toutes faites. À propos, nous n'avons pas d'expĂ©rience rĂ©elle d'exploitation de Kubernetes de la part de Yandex et nous ne donnerons pas d'Ă©valuation de ce service dans cet article.

Qu'est-ce que c'est et pour qui ?

Donc, nous avons déjà parlé de l'approche moderne des stockages dans Kubernetes : comment fonctionne le CSI et comment la communauté est arrivée à cette approche.

Actuellement, de nombreux grands fournisseurs de services cloud ont dĂ©veloppĂ© des pilotes pour utiliser leurs disques « cloud » comme Persistent Volume dans Kubernetes. Si le fournisseur n'a pas de tel pilote mais que toutes les fonctionnalitĂ©s nĂ©cessaires sont disponibles via une API, rien n'empĂȘche de dĂ©velopper un pilote par leurs propres moyens. C'est ce que nous avons fait avec Yandex.Cloud.

Nous avons pris comme base pour le développement le pilote CSI pour le cloud DigitalOcean et quelques idées du pilote pour GCP, car l'interaction avec les API de ces clouds (Google et Yandex) présente plusieurs similitudes. En particulier, l'API de GCP, et celle de Yandex retourne l'objet Opération pour suivre l'état des opérations longues (par exemple, la création d'un nouveau disque). Pour interagir avec l'API de Yandex.Cloud, le SDK Yandex.Cloud Go SDK.

Le rĂ©sultat du travail effectuĂ© est publiĂ© sur GitHub et peut ĂȘtre utile Ă  ceux qui, pour une raison quelconque, utilisent leur propre installation de Kubernetes sur des machines virtuelles de Yandex.Cloud (mais pas un cluster gĂ©rĂ©) et souhaiteraient utiliser (commander) des disques via CSI.

Mise en Ɠuvre

Fonctionnalités principales

Actuellement, le pilote prend en charge les fonctionnalités suivantes :

  • Commande de disques dans toutes les zones du cluster selon la topologie des nƓuds prĂ©sents dans le cluster ;
  • Suppression des disques commandĂ©s auparavant ;
  • Redimensionnement hors ligne pour les disques (Yandex.Cloud ne prend pas en charge augmentation des disques qui sont montĂ©s sur la machine virtuelle). Pour savoir comment le pilote a dĂ» ĂȘtre modifiĂ© afin de rĂ©aliser le redimensionnement de maniĂšre aussi indolore que possible, voir ci-dessous.

À l'avenir, nous prĂ©voyons d'implĂ©menter la prise en charge de la crĂ©ation et de la suppression de snapshots de disques.

La principale difficulté et sa surmontée

L'absence dans l'API de Yandex.Cloud de la possibilitĂ© d'augmenter les disques en temps rĂ©el — une limitation qui complique l'opĂ©ration de redimensionnement pour PV (Volume Persistant) : car dans ce cas, il est nĂ©cessaire que le pod d'application utilisant le disque soit arrĂȘtĂ©, ce qui peut entraĂźner un temps d'arrĂȘt de l'application.

Selon de la spĂ©cification CSI, si le contrĂŽleur CSI indique qu'il peut effectuer le redimensionnement des disques uniquement « hors ligne » (VolumeExpansion.OFFLINE), le processus d'augmentation du disque doit ĂȘtre le suivant :

Si le plugin n'a que VolumeExpansion.OFFLINE capacitĂ© d'expansion et que le volume est actuellement publiĂ© ou disponible sur un nƓud, alors ControllerExpandVolume DOIT ĂȘtre appelĂ© UNIQUEMENT aprĂšs l'une des conditions suivantes :

  • Le plugin a un contrĂŽleur capacitĂ© PUBLISH_UNPUBLISH_VOLUME et ControllerUnpublishVolume a Ă©tĂ© invoquĂ© avec succĂšs. OU ALORS

Le plugin n'a PAS de capacitĂ© de contrĂŽleur, le plugin a un nƓud

  • capacitĂ© STAGE_UNSTAGE_VOLUME, et capacitĂ© PUBLISH_UNPUBLISH_VOLUME et NodeUnstageVolume a Ă©tĂ© terminĂ© avec succĂšs. capacitĂ©, ni nƓud NodeUnpublishVolume a Ă©tĂ© terminĂ© avec succĂšs.

Le plugin n'a PAS de capacitĂ© de contrĂŽleur, le plugin a un nƓud

  • capacitĂ© STAGE_UNSTAGE_VOLUME, et capacitĂ© PUBLISH_UNPUBLISH_VOLUME et En substance, cela signifie la nĂ©cessitĂ© de dĂ©tacher le disque de la machine virtuelle avant de l'augmenter. a Ă©tĂ© terminĂ© avec succĂšs. capacitĂ©, ni nƓud Cependant, malheureusement, les spĂ©cifications CSI via des sidecars ne rĂ©pondent pas Ă  ces exigences :

Dans le conteneur sidecar

csi-attacher implémentation , qui est supposé assurer la présence du bon intervalle entre les montages, cette fonctionnalité n'est tout simplement pas réalisée lors du redimensionnement hors ligne. Cette discussion a été lancée

  • Dans le conteneur sidecar csi-attacher, qui est censĂ© garantir l'espace nĂ©cessaire entre les montages, cette fonctionnalitĂ© n'est tout simplement pas implĂ©mentĂ©e lors du redimensionnement hors ligne. La discussion Ă  ce sujet a Ă©tĂ© initiĂ©e ici.
  • Qu'est-ce qu'un conteneur sidecar dans ce contexte ? Le plugin CSI ne s'occupe pas de l'interaction avec l'API Kubernetes, mais rĂ©agit uniquement aux appels gRPC que lui envoient les conteneurs sidecar. Ces derniers sont dĂ©veloppĂ©s sont communautaires Kubernetes.

Dans notre cas (plugin CSI), l'opération d'augmentation du disque se présente comme suit :

  1. Nous recevons un appel gRPC ControllerExpandVolume;
  2. Nous essayons d'augmenter le disque via l'API, mais nous recevons une erreur indiquant qu'il n'est pas possible d'exécuter l'opération, car le disque est monté ;
  3. Nous sauvegardons l'identifiant du disque dans une map contenant les disques pour lesquels l'opĂ©ration d'augmentation doit ĂȘtre effectuĂ©e. Afin de simplifier, nous appellerons cette map volumeResizeRequired;
  4. Nous supprimons manuellement le pod qui utilise le disque. Kubernetes le redémarrera alors. Pour nous assurer que le disque n'est pas monté (ControllerPublishVolume) avant la fin de l'opération d'augmentation lors de la tentative de montage, nous vérifions que ce disque est toujours dans volumeResizeRequired et nous retournons une erreur ;
  5. Le driver CSI essaie de réexécuter l'opération de redimensionnement. Si l'opération réussit, nous supprimons le disque de volumeResizeRequired;
  6. Comme l'identifiant du disque est absent dans volumeResizeRequired, ControllerPublishVolume réussit, le disque est monté, le pod redémarre.

Tout cela semble assez simple, mais comme toujours, il y a des piÚges. L'augmentation des disques est gérée par external-resizer, qui, en cas d'erreur lors de l'exécution de l'opération utilise une file d'attente avec un temps d'attente exponentiel jusqu'à 1000 secondes :

func DefaultControllerRateLimiter() RateLimiter {
  return NewMaxOfRateLimiter(
  NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
  // 10 qps, 100 bucket size. C'est seulement pour la vitesse de réessaie et c'est juste le facteur global (pas par élément)
  &BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
  )
}

Cela peut occasionnellement faire en sorte que l'opération d'augmentation de disque s'étale sur 15 minutes ou plus, entraßnant ainsi l'indisponibilité du pod correspondant.

La seule option qui nous a permis de rĂ©duire facilement et sans douleur le temps d'arrĂȘt potentiel a Ă©tĂ© d'utiliser notre propre version de external-resizer avec une limite d'attente maximale de 5 secondes:

workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 5*time.Second)

Nous n'avons pas jugé nécessaire de déclencher de maniÚre urgente une discussion ou de patcher external-resizer, car le redimensionnement hors ligne des disques est un vestige qui disparaßtra bientÎt chez tous les fournisseurs de cloud.

Comment commencer Ă  utiliser ?

Le driver est supportĂ© dans Kubernetes version 1.15 et supĂ©rieure. Pour que le driver fonctionne, les exigences suivantes doivent ĂȘtre remplies :

  • Drapeau --allow-privileged dĂ©fini sur true pour l'API du serveur et kubelet ;
  • ActivĂ© --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true pour l'API du serveur et kubelet ;
  • La propagation de montage (mount propagation) doit ĂȘtre activĂ©e dans le cluster. Lors de l'utilisation de Docker, le dĂ©mon doit ĂȘtre configurĂ© pour autoriser les objets de montage partagĂ©s (shared mounts).

Tous les étapes nécessaires à l'installation proprement dite sont décrites dans le README. L'installation consiste à créer des objets dans Kubernetes à partir de manifests.

Pour que le pilote fonctionne, vous aurez besoin de :

  • Indiquer dans le manifeste l'identifiant de rĂ©pertoire (folder-id) de Yandex.Cloud (voir la documentation);
  • . Pour interagir avec l'API de Yandex.Cloud dans le pilote CSI, un compte de service est utilisĂ©. Dans le manifeste Secret, il est nĂ©cessaire de transmettre les clĂ©s d'autorisation du compte de service. Dans la documentation est dĂ©crit, il est expliquĂ© comment crĂ©er un compte de service et obtenir des clĂ©s.

En gĂ©nĂ©ral — essayez, et nous serons ravis de recevoir des retours et de nouveaux problĂšmes, si vous rencontrez des soucis !

Support ultérieur

En guise de conclusion, nous tenons Ă  souligner que ce pilote CSI a Ă©tĂ© dĂ©veloppĂ© non par un grand dĂ©sir de s'amuser Ă  Ă©crire des applications en Go, mais par une nĂ©cessitĂ© pressante au sein de l'entreprise. Nous ne considĂ©rons pas qu'il soit judicieux de maintenir notre propre implĂ©mentation, donc si Yandex montre de l'intĂ©rĂȘt et dĂ©cide de continuer Ă  soutenir le pilote, nous transmettrons volontiers le dĂ©pĂŽt Ă  leur disposition.

De plus, il est probable que Yandex ait sa propre implĂ©mentation du pilote CSI dans son cluster Kubernetes managĂ©, qu'il pourrait publier en Open Source. Ce dĂ©veloppement nous semble Ă©galement favorable — la communautĂ© pourrait utiliser un pilote Ă©prouvĂ© du fournisseur de services, et non d'une sociĂ©tĂ© tierce.

P.S.

Lisez aussi dans notre blog :

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster