Catégories
Start-up et applications

gRPC dans le monde réel: l'interface d'exécution du conteneur Kubernetes

Dans les versions précédentes de cette série, nous avons examiné les événements historiques qui ont conduit à la création de gRPC ainsi que les détails de la programmation à l'aide de gRPC. Nous avons discuté des concepts clés de la spécification gRPC. Nous avons jeté un coup d'œil à l'application de démonstration que nous avons créée spécialement pour cette série. Et, nous avons examiné comment utiliser l'outil de génération automatique, protocole fourni par gRPC pour créer du code standard dans une variété de langages de programmation afin d'accélérer le développement de gRPC. Nous avons également parlé de la manière de se lier de manière statique et dynamique à un protobuf lors de la programmation sous gRPC. De plus, nous avons créé un certain nombre de leçons sur l'environnement d'apprentissage interactif de Katacoda qui soutiennent les concepts et les pratiques que nous avons abordés dans les articles d'introduction.

Après avoir présenté les bases nécessaires pour comprendre ce qu'est gRPC et comment il fonctionne, nous allons maintenant faire quelques versements sur la façon dont gRPC est utilisé dans le monde réel. Dans cet article, nous allons voir comment gRPC est utilisé par Kubernetes dans sa technologie Container Runtime Interface (CRI).

Mais, avant d'entrer dans les détails sur gRPC et Kubernetes CRI, nous devons répondre à une question posée par beaucoup de ceux qui viennent à gRPC pour la première fois: pourquoi ne voyons-nous pas autant de gRPC sur le front-end? C'est une question qui a été posée par beaucoup et qui mérite une réponse. Alors, allons-y.

Où est le gRPC?

Depuis sa sortie en tant que projet open source en 2015, gRPC a connu une croissance dans les entreprises, grandes et petites. Pourtant, malgré sa popularité en tant que technologie côté serveur, le gRPC est peu présent dans les API publiques. Cela est principalement dû à deux raisons. Premièrement, gRPC s'appuie sur HTTP / 2 comme protocole de transport. Alors que les principaux navigateurs côté client prennent en charge HTTP / 2 depuis 2015, en juillet 2020, moins de la moitié des sites Web sur Internet prennent en charge le protocole côté serveur. La traction pour l'utilisation de gRPC entre les clients et les serveurs Web n'est tout simplement pas encore là.

La deuxième raison pour laquelle l'adoption publique de gRPC a été lente à s'implanter est que les clients utilisant une API basée sur gRPC particulière doivent avoir accès à la même définition de schéma utilisée par le serveur. (La définition de schéma pour une API gRPC donnée est stockée dans un fichier protobuf.)

Le fait de devoir partager un fichier protobuf commun est une contrainte importante par rapport à un format d'API tel que REST qui utilise HTTP / 1.1 et oblige les clients consommateurs à ne pas connaître à l'avance les structures de données fournies par l'API. Avec REST, vous appelez simplement une URL et certaines données sont renvoyées dans un format de données auto-descriptif tel que JSON, XML ou YAML.

En bref, la complexité du gRPC rend son adoption difficile pour les sites Web commerciaux standard et les API publiques. Cependant, la technologie est florissante du côté serveur. Comme le dit Matt Debergalis, CTO d'Apollo GraphQL, l'une des principales sociétés qui publient des outils et des serveurs pour GraphQL,

«De nombreux clients construisent le graphique de données au-dessus de gRPC. Dans une entreprise typique, vous disposez désormais de centaines de services, et gRPC est la meilleure technologie pour les API de ces microservices, car elle est très ciblée; elle est si efficace. conçu pour ce cas d'utilisation «à l'intérieur du centre de données», mais ce n'est pas la bonne technologie pour se connecter à vos applications.

Alors là vous l'avez. gRPC est en effet beaucoup utilisé, mais pour la plupart, il est caché à la vue du public. Il est utilisé pour faciliter une communication ultra-rapide et efficace entre les services backend côté serveur, et très souvent dans les cas où les ressources du centre de données augmentent et diminuent automatiquement en réponse à des charges qui fluctuent en temps réel.

Et, l'un des meilleurs exemples de la façon dont gRPC est utilisé dans le monde réel est dans l'interface d'exécution du conteneur Kubernetes (K8S CRI); une technologie qui est pratiquement synonyme d'une telle mise à l'échelle automatique. L'une des principales fonctionnalités de Kubernetes est l'orchestration de conteneurs. Le CRI K8S est un composant essentiel pour la gestion des conteneurs sous Kubernetes. Et, gRPC est tissé dans le tissu de la technologie d'orchestration. Nous allons jeter un coup d'oeil.

Kubernetes: utilisation de gRPC dans l'interface d'exécution du conteneur

Afin de comprendre comment gRPC est utilisé comme mécanisme de communication pour Container Runtime Interface (CRI), vous devez avoir une compréhension de haut niveau du fonctionnement de Kubernetes, en particulier du rôle que jouent les conteneurs dans son architecture.

Kubernetes est une technologie de gestion des services et d'orchestration de conteneurs conçue pour prendre en charge les applications distribuées qui s'exécutent à l'échelle du Web. La logique essentielle derrière l'architecture Kubernetes est que la fonctionnalité d'une application ou d'une API est représentée dans Kubernetes par une ressource appelée service. Un service est une abstraction de l'application sur le réseau. La logique réelle que représente le service donné réside dans une autre ressource abstraite appelée cosse.

Comprendre les services et les pods Kubernetes

La figure 1 ci-dessous montre un exemple de trois services qui existent dans une application. Un service fournit une fonctionnalité d'accès. Un autre fournit des informations sur le catalogue et le troisième fournit des fonctionnalités d'achat. Chacun de ces services peut être identifié sur le réseau par une adresse IP ou un nom DNS. Par conséquent, les consommateurs utilisant l'application appelleront le service sur le réseau en conséquence. Cependant, le service n'a aucune fonctionnalité propre. La fonctionnalité d'un service est plutôt fournie par une logique qui réside dans un ou plusieurs pods auxquels un service est lié. (Pour en savoir plus sur la liaison de service Kubernetes, consultez ProgrammableWeb cours interactif sur Katacoda disponible ici.)

Figure 1: Dans Kubernetes, la logique d'application réside dans des pods représentés sur le réseau par des services

Figure 1: Dans Kubernetes, la logique d'application réside dans des pods représentés sur le réseau par des services

Comme mentionné ci-dessus, un pod est une ressource abstraite. Un pod est une unité d'organisation pour l'hébergement de conteneurs Linux. Un conteneur est un mécanisme pour encapsuler et isoler un processus qui exécute la logique de programmation. (Voir la figure 2 ci-dessous.)

Figure 2: Un pod est une unité d'organisation abstraite pour héberger un ou plusieurs conteneurs Linux

Figure 2: Un pod est une unité d'organisation abstraite pour héberger un ou plusieurs conteneurs Linux

Des exemples de processus qui s'exécutent dans un conteneur sont les serveurs Web, les courtiers de messages, les bases de données et d'autres types de binaires exécutables. Un pod peut héberger un ou plusieurs conteneurs dans lesquels la fonctionnalité de chaque conteneur est unique. En d'autres termes, il est tout à fait possible d'avoir un pod qui héberge à la fois un conteneur de serveur Web et un conteneur de base de données. Cependant, sachez que la configuration d'un pod ne consiste pas simplement à inclure un nombre aléatoire de conteneurs à héberger. La définition de la structure d'un pod avec plusieurs conteneurs est une entreprise complexe qui nécessite une expérience dans la mise en œuvre d'architectures Kubernetes.

La chose importante à savoir est la suivante: dans Kubernetes, un service représente une fonctionnalité sur le réseau. Cette fonctionnalité réside dans les pods. L'implémentation de la fonctionnalité dans un pod donné est exécutée dans les conteneurs hébergés dans le pod.

Ce qui nous amène aux conteneurs. Les conteneurs n'apparaissent pas dans Kubernetes par magie. Ils doivent être fabriqués et ils doivent être réalisés de manière éphémère. Kubernetes est une technologie dynamique. Il peut augmenter et réduire ses ressources pour répondre aux besoins du moment. Cela inclut la création et la destruction de conteneurs à la demande.

Garantir l'état d'un conteneur

Il existe une ressource abstraite dans Kubernetes appelée déploiement. Le travail d'un déploiement consiste à garantir que tous les conteneurs censés s'exécuter dans un déploiement Kubernetes donné sont effectivement en cours d'exécution. Ceci est important car Kubernetes garantit que l'état défini pour le cluster sera toujours conservé.

La garantie d'État est une fonctionnalité très puissante de Kubernetes. De plus, comme mentionné ci-dessus, cela nécessite un contrôle important de la gestion des conteneurs.

C'est là que l'interface d'exécution de conteneur entre en jeu. Alors que Kubernetes est en charge de la liaison des services aux pods et de la garantie que les pods qui sont censés être en cours d'exécution sont, en fait, en cours d'exécution, c'est le runtime du conteneur qui fait le travail de création du ou des conteneurs dont un pod a besoin.

La mécanique de la réalisation des conteneurs

Avant d'entrer dans le runtime du conteneur et le rôle que joue gRPC dans le processus de réalisation du conteneur, il est utile de connaître les mécanismes derrière la réalisation du conteneur.

Dans Kubernetes, une machine virtuelle est appelée un nœud. Un cluster Kubernetes est composé d'un nœud de contrôleur qui contrôle les activités dans un tableau de nœuds de travail constituants. En bref, le nœud de contrôleur est le patron et les nœuds de travail font le travailleur. (Voir la figure 3 ci-dessous.)

Figure 3: La hiérarchie organisationnelle d'un cluster Kubernetes

Figure 3: La hiérarchie organisationnelle d'un cluster Kubernetes

L'une des activités que le nœud de contrôleur coordonne avec les nœuds de travail est la création et la destruction des conteneurs Linux associés aux pods.

Chaque nœud de travail dans un cluster Kubernetes a un agent nommé kubelet. Vous pouvez considérer kubelet comme le contremaître du nœud. Il prend les commandes du plan contrôleur pour effectuer des travaux sur son nœud, puis s'assure que le travail est terminé. L'une des tâches de kubelet est de créer et de détruire des conteneurs sur son nœud worker.

Cependant, kubelet ne fait pas ce travail. (Rappelez-vous, kubelet est un contremaître.) Au contraire, il dit à Container Runtime Interface (CRI) de faire le travail. (Voir la figure 4 ci-dessous)

Figure 4: L'instance kubelet exécutée dans chaque nœud de travail Kubernetes indique au CRI de créer des conteneurs en réponse à une notification du serveur d'API s'exécutant sur le nœud Kubernetes Controller

Figure 4: L'instance kubelet s'exécutant dans chaque nœud de travail Kubernetes indique au CRI de créer des conteneurs en réponse à une notification du serveur d'API s'exécutant sur le nœud Kubernetes Controller

gRPC et le CRI

La manière dont kubelet indique au CRI ce qu'il doit faire est d'interagir avec un serveur gRPC intégré au CRI. (Voir la figure 5 ci-dessous.)

Figure 5: kubelet interagit avec Container Runtime Interface à l'aide de gRPC pour créer et détruire des conteneurs sur un nœud worker

Figure 5: kubelet interagit avec Container Runtime Interface à l'aide de gRPC pour créer et détruire des conteneurs sur un nœud worker

Lorsqu'il est temps de créer ou de détruire un conteneur sur un nœud, kubelet envoie un message au serveur gRPC s'exécutant sur l'instance CRI du nœud pour faire l'acte, puis le CRI interagit avec le moteur d'exécution du conteneur installé sur le nœud worker pour faire ce qui est nécessaire.

Par exemple, lorsque kubelet souhaite créer un conteneur, il utilise son client gRPC pour envoyer un CreateContainerRequest message à la fonction RPC (Remote Procedure Call) CreateContainer () qui est hébergé sur le composant CRI. le CreateContainer fonction et CreateContainerRequest sont présentés ci-dessous dans la liste 1.

// CreateContainer creates a new container in specified PodSandbox
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}

message CreateContainerRequest {
    // ID of the PodSandbox in which the container should be created.
    string pod_sandbox_id = 1;
    // Config of the container.
    ContainerConfig config = 2;
    // Config of the PodSandbox. This is the same config that was passed
    // to RunPodSandboxRequest to create the PodSandbox. It is passed again
    // here just for easy reference. The PodSandboxConfig is immutable and
    // remains the same throughout the lifetime of the pod.
    PodSandboxConfig sandbox_config = 3;
}

Liste 1: La fonction gRPC et le type de message utilisés pour créer un conteneur à l'aide de Kubernetes Container Runtime Interface

Le CRI, à son tour, envoie la demande de création au moteur d'exécution du conteneur installé sur le nœud. Le runtime du conteneur crée le conteneur.

Kubernetes vous permet d'en installer un à partir de divers environnements d'exécution de conteneur sur un nœud. Vous pouvez installer le runtime Docker éprouvé, mais il existe d'autres runtimes qui peuvent être installés, par exemple, containerd, rkt ou cri-o, prononcé, cree-oh. (Le choix de l'environnement d'exécution de conteneur le mieux adapté à l'installation de Kubernetes donnée offre un degré supplémentaire de flexibilité lors de la personnalisation d'un cluster.)

Une fois la création du conteneur terminée, le CRI renvoie un CreateContainerResponse message tel que défini dans le fichier protobuf qui est partagé à la fois par le client et le serveur gRPC. La définition de CreateContainerResponse est montré ci-dessous dans la liste 2.

message CreateContainerResponse {
    // ID of the created container.
    string container_id = 1;
}

Liste 2: Le serveur CRI gRPC renvoie un message CreateContainerResponse qui a l'identificateur unique du conteneur créé.

La création et la destruction de conteneurs ne sont que deux des activités exécutées à partir de Container Runtime Interface. Il y en a d'autres, comme l'arrêt d'un conteneur, le redémarrage, la liste des conteneurs dans un pod et la mise à jour des informations de configuration d'un conteneur, pour n'en nommer que quelques-uns.

gRPC gère tous les échanges de messages qui se produisent entre kubelet et le CRI. Gardez à l'esprit que l'échange de messages entre kubelet et le CRI doit se faire très rapidement, parfois de l'ordre de la nanoseconde. Un cluster Kubernetes typique fonctionnant à l'échelle du Web peut avoir des dizaines de milliers de conteneurs en vigueur s'exécutant sur des dizaines, voire des centaines de nœuds. Par conséquent, la vitesse et l'efficacité sont essentielles dans le pipeline de communication. gPRC correspond à la facture et plus encore.

Mettre tous ensemble

Quand il s'agit d'utiliser gRPC dans le monde réel, Kubernetes est le gorille de 800 lb. Kubernetes et gRPC ont tous deux commencé chez Google, il est donc naturel que les deux technologies occupent une place importante et facilement dans le paysage technologique. Mais, comme mentionné au début de cet article, l'adoption augmente régulièrement. De nombreuses autres entreprises utilisent gRPC dans leur pile technologique. Il y a une raison pour laquelle gRPC est rapide, efficace et fiable. Les applications critiques qui pilotent un centre de données ont besoin de ce type d'alimentation. Comme mentionné ci-dessus, gRPC correspond à la facture et plus encore.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *