Conditions requises pour développer une application dans Kubernetes

Aujourd'hui, je prévois de parler de la façon d'écrire des applications et des conditions requises pour que votre application fonctionne correctement dans Kubernetes. Pour qu'il n'y ait pas de problèmes avec l'application, pour que vous n'ayez pas à inventer et à construire des «cratchs» autour d'elle - et que tout fonctionne comme Kubernetes lui-même l'avait prévu.

Cette conférence fait partie de "École du soir Slurm sur Kubernetes" Vous pouvez consulter les cours théoriques ouverts de l'École du soir sur Youtube, regroupés dans une playlist. Pour ceux qui préfèrent le texte plutôt que la vidéo, nous avons préparé cet article.

Je m'appelle Pavel Selivanov, je suis actuellement le principal ingénieur DevOps chez Mail.ru Cloud Solutions, nous créons des cloud, nous créons des kubernetes de gestion, etc. Mes tâches incluent désormais l'assistance au développement, le déploiement de ces cloud, le déploiement des applications que nous écrivons et le développement direct des outils que nous mettons à disposition de nos utilisateurs.

Conditions requises pour développer une application dans Kubernetes

Je fais du DevOps, je pense, depuis probablement trois ans. Mais, en principe, je fais ce que fait DevOps depuis probablement environ cinq ans maintenant. Avant cela, j'étais principalement impliqué dans des tâches administratives. J'ai commencé à travailler avec Kubernetes il y a longtemps - environ quatre ans se sont probablement écoulés depuis que j'ai commencé à travailler avec.

En général, j'ai commencé lorsque Kubernetes était probablement en version 1.3, et peut-être en 1.2 - alors qu'il en était encore à ses balbutiements. Aujourd'hui, il n'en est plus à ses balbutiements - et il est évident qu'il existe sur le marché une énorme demande d'ingénieurs qui aimeraient pouvoir faire de Kubernetes. Et les entreprises ont une très forte demande pour ces personnes. C'est pourquoi, en fait, cette conférence est apparue.

Si nous parlons selon le plan de ce dont je vais parler, cela ressemble à ceci, entre parenthèses il est écrit (TL;DR) - « trop long ; ne lis pas". Ma présentation d’aujourd’hui consistera en des listes interminables.

Conditions requises pour développer une application dans Kubernetes

En fait, je n'aime pas moi-même de telles présentations lorsqu'elles sont faites, mais c'est un tel sujet que lorsque je préparais cette présentation, je n'ai tout simplement pas vraiment compris comment organiser ces informations différemment.

Parce que, en gros, ces informations sont « ctrl+c, ctrl+v », provenant, entre autres, de notre Wiki dans la section DevOps, où nous avons écrit des exigences pour les développeurs : « les gars, pour que nous lancions votre application dans Kubernetes, ça devrait être comme ça."

C’est pourquoi la présentation s’est avérée être une liste si longue. Désolé. J'essaierai d'en raconter le plus possible pour que ce ne soit pas ennuyeux si possible.

Ce que nous allons regarder maintenant :

  • ce sont d'abord des logs (journaux d'application ?), que faire avec eux dans Kubernetes, que faire avec eux, ce qu'ils doivent être ;
  • que faire des configurations dans Kubernetes, quelles sont les meilleures et les pires façons de configurer une application pour Kubernetes ;
  • Parlons de ce que sont les contrôles d'accessibilité en général, de ce à quoi ils devraient ressembler ;
  • parlons de ce qu'est un arrêt progressif ;
  • reparlons des ressources ;
  • Abordons à nouveau le sujet du stockage des données ;
  • et à la fin, je vous dirai quel est le terme de cette mystérieuse application cloud native. Cloudnativeness, comme adjectif de ce terme.

Les journaux

Je suggère de commencer par les journaux - par l'endroit où ces journaux doivent être placés dans Kubernetes. Vous avez maintenant lancé une application dans Kubernetes. Selon les classiques, auparavant, les applications écrivaient toujours des journaux quelque part dans un fichier. Les mauvaises applications ont écrit des journaux dans un fichier du répertoire personnel du développeur qui a lancé l'application. Les bonnes applications écrivaient des journaux dans un fichier quelque part dans /var/log.

Conditions requises pour développer une application dans Kubernetes

En conséquence, en outre, les bons administrateurs avaient configuré certaines choses dans leurs infrastructures pour que ces journaux puissent tourner - le même rsyslog, qui examine ces journaux et quand quelque chose leur arrive, il y en a beaucoup, il crée des copies de sauvegarde, y place les journaux , supprime les anciens fichiers, plus d'une semaine, six mois et à d'autres moments. En théorie, nous devrions prévoir des dispositions pour que, simplement parce que l'application écrit des journaux, l'espace sur les serveurs de production (serveurs de combat ?) ne s'épuise pas. Et par conséquent, toute la production ne s’est pas arrêtée à cause des grumes.

Lorsque nous passons au monde de Kubernetes et y exécutons la même chose, la première chose à laquelle vous pouvez prêter attention est le fait que les gens, lorsqu'ils écrivent des journaux dans un fichier, continuent de les écrire.

Il s'avère que si nous parlons de Kubernetes, le bon endroit pour écrire des journaux quelque part à partir d'un conteneur Docker est simplement de les écrire depuis l'application vers ce qu'on appelle Stdout/Stderr, c'est-à-dire les flux de sortie standard du système d'exploitation, l'erreur standard sortir . C'est la manière la plus correcte, la plus simple et la plus logique de mettre en principe des logs dans Docker et plus particulièrement dans Kubernetis. Parce que si votre application écrit des journaux sur Stdout/Stderr, c'est à Docker et au module complémentaire Kubernetes de décider quoi faire de ces journaux. Docker construira par défaut ses fichiers spéciaux au format JSON.

Ici, la question se pose : que ferez-vous ensuite avec ces journaux ? Le moyen le plus simple est clair, nous avons la possibilité de le faire kubectl logs et regardez ces journaux de ces « pods ». Mais ce n'est probablement pas une très bonne option - il faut faire autre chose avec les journaux.

Pour l'instant, parlons en même temps, puisque nous avons abordé le sujet des journaux, de ce à quoi devraient ressembler les journaux. Autrement dit, cela ne s'applique pas directement à Kubernetes, mais lorsque nous commençons à réfléchir à ce qu'il faut faire avec les journaux, il serait bien d'y penser également.

Nous avons besoin d'une sorte d'outil, à l'amiable, qui prendra ces journaux que notre docker met dans ses fichiers et les enverra quelque part. Dans l'ensemble, nous lançons généralement une sorte d'agent à l'intérieur de Kubernetes sous la forme d'un DaemonSet - un collecteur de journaux, qui indique simplement où se trouvent les journaux collectés par Docker. Et cet agent de collecte les prend simplement, peut-être même les analyse d'une manière ou d'une autre en cours de route, peut-être les enrichit de méta-informations supplémentaires et, finalement, les envoie pour stockage quelque part. Des variantes y sont déjà possibles. Le plus courant est probablement Elasticsearch, où vous pouvez stocker des journaux et les récupérer facilement à partir de là. Ensuite, à l'aide d'une requête, en utilisant Kibana par exemple, créez des graphiques basés sur celles-ci, créez des alertes basées sur elles, etc.

L’idée la plus importante, je tiens à la répéter encore une fois, est que dans Docker, en particulier dans Kubernetes, stocker vos logs dans un fichier est une très mauvaise idée.

Parce que premièrement, il est difficile de récupérer les journaux à l’intérieur du conteneur dans un fichier. Vous devez d'abord aller dans le conteneur, y exécuter, puis consulter les journaux. Le point suivant est que si vous avez des journaux dans un fichier, les conteneurs ont généralement un environnement minimaliste et aucun utilitaire n'est généralement nécessaire pour le travail normal avec les journaux. Enterrez-les, regardez-les, ouvrez-les dans un éditeur de texte. Le moment suivant est lorsque nous avons des journaux dans un fichier à l'intérieur d'un conteneur, si ce conteneur est supprimé, vous comprenez, les journaux mourront avec lui. Ainsi, tout redémarrage du conteneur signifie qu’il n’y a plus de logs. Encore une fois, mauvaise option.

Et le dernier point est qu'à l'intérieur des conteneurs, vous avez généralement votre application et c'est tout - c'est généralement le seul processus en cours d'exécution. Il n'est pas du tout question d'un processus qui ferait pivoter les fichiers avec vos journaux. Dès que les journaux commencent à être écrits dans un fichier, cela signifie que, excusez-moi, nous allons commencer à perdre le serveur de production. Parce que, premièrement, ils sont difficiles à trouver, personne ne les suit et personne ne les contrôle - en conséquence, le fichier se développe sans fin jusqu'à ce que l'espace sur le serveur soit tout simplement épuisé. Par conséquent, je répète que se connecter dans Docker, en particulier dans Kubernetes, à un fichier est une mauvaise idée.

Le point suivant, ici, je veux en reparler - puisque nous abordons le sujet des journaux, il serait bien de parler de l'apparence des journaux afin de faciliter leur travail. Comme je l'ai dit, le sujet n'est pas directement lié à Kubernetes, mais il se rapporte très bien au sujet du DevOps. Sur le thème de la culture de développement et de l'amitié entre ces deux départements différents - Dev et Ops, pour que tout le monde soit à l'aise.

Cela signifie qu’idéalement, aujourd’hui, les logs devraient être écrits au format JSON. Si vous possédez une application incompréhensible qui écrit des journaux dans des formats incompréhensibles parce que vous insérez une sorte d'impression ou quelque chose comme ça, alors il est temps de rechercher sur Google une sorte de framework, une sorte de wrapper qui vous permet d'implémenter une journalisation normale ; activez les paramètres de journalisation dans JSON ici, car JSON est un format simple, son analyse est simple.

Si votre JSON ne fonctionne pas selon certains critères, personne ne sait quoi, alors écrivez au moins les journaux dans un format qui peut être analysé. Ici, il convient plutôt de réfléchir au fait que, par exemple, si vous exécutez un tas de conteneurs ou simplement des processus avec nginx, et que chacun a ses propres paramètres de journalisation, il semble probablement qu'il sera très gênant pour vous de analysez-les. Parce que pour chaque nouvelle instance nginx, vous devez écrire votre propre analyseur, car ils écrivent les journaux différemment. Encore une fois, cela valait probablement la peine de penser à s'assurer que toutes ces instances nginx avaient la même configuration de journalisation et écrivaient tous leurs journaux de manière absolument uniforme. La même chose s'applique à absolument toutes les applications.

En fin de compte, je souhaite également ajouter de l'huile sur le feu en disant que, idéalement, les bûches au format multiligne devraient être évitées. Voici le problème : si vous avez déjà travaillé avec des collecteurs de journaux, vous avez probablement vu ce qu'ils vous promettent, à savoir qu'ils peuvent travailler avec des journaux multilignes, savoir comment les collecter, etc. En fait, à mon avis, aucun collecteur aujourd'hui ne peut collecter des journaux multilignes normalement, entièrement et sans erreurs. D'une manière humaine, pour que ce soit pratique et sans erreur.

Conditions requises pour développer une application dans Kubernetes

Mais la trace de la pile est toujours constituée de journaux multilignes et comment les éviter. La question ici est qu'un journal est un enregistrement d'un événement et que stactrace n'est pas réellement un journal. Si nous collectons des journaux et les plaçons quelque part dans Elasticsearch, puis en tirons des graphiques, créons des rapports sur l'activité des utilisateurs sur votre site, alors lorsque vous obtenez une trace de pile, cela signifie que quelque chose d'inattendu se produit, une situation non gérée dans votre application. Et il est logique de télécharger automatiquement une trace de pile quelque part dans un système capable de les suivre.

Il s'agit d'un logiciel (le même Sentry) spécialement conçu pour fonctionner avec la trace de pile. Il peut immédiatement créer des tâches automatisées, les attribuer à quelqu'un, alerter lorsque des stacttraces se produisent, regrouper ces stacttraces par un seul type, etc. En principe, cela n’a pas beaucoup de sens de parler de stactraces lorsque nous parlons de logs, car ce sont, après tout, des choses différentes avec des objectifs différents.

Configuration

Nous parlons ensuite de la configuration dans Kubernetes : que faire avec et comment les applications dans Kubernetes doivent être configurées. En général, je dis habituellement que Docker ne concerne pas les conteneurs. Tout le monde sait que Docker concerne les conteneurs, même ceux qui n'ont pas beaucoup travaillé avec Docker. Je le répète, Docker ne concerne pas les conteneurs.

Docker, à mon avis, concerne les normes. Et il existe des normes pour pratiquement tout : des normes pour créer votre application, des normes pour installer votre application.

Conditions requises pour développer une application dans Kubernetes

Et cette chose - nous l'avons utilisée auparavant, elle est devenue particulièrement populaire avec l'avènement des conteneurs - cette chose s'appelle les variables ENV (environnement), c'est-à-dire les variables d'environnement qui se trouvent dans votre système d'exploitation. C'est généralement un moyen idéal pour configurer votre application, car si vous avez des applications en JAVA, Python, Go, Perl, Dieu nous en préserve, et qu'elles peuvent toutes lire l'hôte de la base de données, l'utilisateur de la base de données, les variables de mot de passe de la base de données, alors c'est idéal. Vous disposez d’applications dans quatre langues différentes configurées dans le plan base de données de la même manière. Il n'y a plus de configurations différentes.

Tout peut être configuré à l'aide des variables ENV. Lorsque nous parlons de Kubernetes, il existe un excellent moyen de déclarer les variables ENV directement dans Deployment. Par conséquent, si nous parlons de données secrètes, nous pouvons alors immédiatement transférer les données secrètes des variables ENV (mots de passe vers les bases de données, etc.) dans un secret, créer un cluster secret et indiquer dans la description ENV dans Déploiement que nous ne déclarons pas directement la valeur de cette variable et la valeur de cette variable de mot de passe de base de données seront lues à partir du secret. Il s’agit du comportement standard de Kubernetes. Et c'est l'option la plus idéale pour configurer vos applications. Juste au niveau du code, cela s'applique encore une fois aux développeurs. Si vous êtes DevOps, vous pouvez demander : « Les gars, veuillez apprendre à votre application à lire les variables d'environnement. Et nous serons tous heureux."

Si tout le monde dans l’entreprise lit les mêmes variables d’environnement nommées, alors c’est parfait. Pour qu'il n'arrive pas que certains attendent la base de données postgres, d'autres attendent le nom de la base de données, d'autres attendent autre chose, d'autres attendent un dbn quelconque, de sorte que, par conséquent, il y ait une uniformité.

Le problème survient lorsque vous avez tellement de variables d'environnement que vous ouvrez simplement le déploiement - et qu'il y a cinq cents lignes de variables d'environnement. Dans ce cas, vous avez simplement dépassé les variables d'environnement - et vous n'avez plus besoin de vous torturer. Dans ce cas, il serait logique de commencer à utiliser les configurations. Autrement dit, entraînez votre application à utiliser les configurations.

La seule question est que les configurations ne sont pas ce que vous pensez. Config.pi n'est pas une configuration pratique à utiliser. Ou une configuration dans votre propre format, alternativement douée - ce n'est pas non plus la configuration dont je parle.

Je parle d'une configuration dans des formats acceptables, c'est-à-dire que le standard de loin le plus populaire est le standard .yaml. Il est clair comment le lire, il est lisible par l'homme, il est clair comment le lire depuis l'application.

Par conséquent, en plus de YAML, vous pouvez également, par exemple, utiliser JSON, l'analyse est à peu près aussi pratique que YAML en termes de lecture de la configuration de l'application à partir de là. Il est nettement plus gênant pour les gens de lire. Vous pouvez essayer le format, à la ini. C'est assez pratique à lire, d'un point de vue humain, mais il peut être gênant de le traiter automatiquement, dans le sens où si jamais vous souhaitez générer vos propres configurations, le format ini peut déjà être peu pratique à générer.

Mais dans tous les cas, quel que soit le format que vous choisissez, le fait est que du point de vue de Kubernetes, il est très pratique. Vous pouvez placer l'intégralité de votre configuration dans Kubernetes, dans le ConfigMap. Et puis prenez cette carte de configuration et demandez-lui d'être montée dans votre pod dans un répertoire spécifique, où votre application lira la configuration de cette carte de configuration comme s'il s'agissait simplement d'un fichier. C’est en fait ce qu’il est bon de faire lorsque vous disposez de nombreuses options de configuration dans votre application. Ou c'est juste une sorte de structure complexe, il y a une imbrication.

Si vous disposez d'une carte de configuration, vous pouvez très bien apprendre à votre application, par exemple, à suivre automatiquement les modifications dans le fichier dans lequel la carte de configuration est montée, et également à recharger automatiquement votre application lorsque les configurations changent. Ce serait généralement une option idéale.

Encore une fois, j'en ai déjà parlé - les informations secrètes ne sont pas dans la carte de configuration, les informations secrètes ne sont pas dans les variables, les informations secrètes ne sont pas dans les secrets. À partir de là, reliez ces informations secrètes à la diplomatie. Habituellement, nous stockons toutes les descriptions des objets, déploiements, cartes de configuration et services Kubernetes dans git. En conséquence, mettre le mot de passe de la base de données dans git, même s'il s'agit de votre git, que vous possédez en interne dans l'entreprise, est une mauvaise idée. Parce qu'au minimum, git se souvient de tout et supprimer simplement les mots de passe n'est pas si simple.

Bilan de santé

Le point suivant est ce qu'on appelle le bilan de santé. En général, un bilan de santé consiste simplement à vérifier que votre application fonctionne. Dans le même temps, nous parlons le plus souvent de certaines applications Web, pour lesquelles, par conséquent, du point de vue du contrôle de santé (il vaut mieux ne pas traduire ici et plus loin), il s'agira d'une URL spéciale, qu'elles traitent comme une norme, ils le font habituellement /health.

En conséquence, en accédant à cette URL, notre application dit soit « oui, d'accord, tout va bien pour moi, 200 » ou « non, tout ne va pas pour moi, environ 500 ». En conséquence, si notre application n'est pas http, ni une application Web, nous parlons maintenant d'une sorte de démon, nous pouvons comprendre comment effectuer des contrôles de santé. Autrement dit, ce n'est pas nécessaire, si l'application n'est pas http, alors tout fonctionne sans contrôle de santé et cela ne peut en aucun cas être fait. Vous pouvez périodiquement mettre à jour certaines informations dans le fichier, vous pouvez proposer une commande spéciale pour votre démon, comme : daemon status, qui dira « oui, tout va bien, le démon fonctionne, il est vivant ».

Pourquoi est-ce? La première et la plus évidente est probablement la raison pour laquelle un bilan de santé est nécessaire : pour comprendre que l'application fonctionne. Je veux dire, c'est juste stupide, quand c'est en ligne maintenant, on dirait que ça marche, donc tu peux être sûr que ça marche. Et il s'avère que l'application est en cours d'exécution, le conteneur est en cours d'exécution, l'instance fonctionne, tout va bien - et puis les utilisateurs ont déjà coupé tous les numéros de téléphone du support technique et disent « qu'est-ce que tu fais..., tu Je me suis endormi, rien ne fonctionne.

Un bilan de santé n’est qu’un moyen de voir du point de vue de l’utilisateur que cela fonctionne. Une des méthodes. Disons-le de cette façon. Du point de vue de Kubernetes, c'est aussi un moyen de comprendre quand l'application démarre, car on comprend qu'il y a une différence entre le moment où le conteneur a été lancé, créé et démarré, et le moment où l'application a été lancée directement dans ce conteneur. Parce que si nous prenons une application Java moyenne et essayons de la lancer dans le dock, alors pendant quarante secondes, voire une minute, voire dix, elle peut très bien démarrer. Dans ce cas, vous pouvez au moins frapper sur ses ports, il n'y répondra pas, c'est-à-dire qu'il n'est pas encore prêt à recevoir du trafic.

Encore une fois, avec l'aide d'un bilan de santé et avec l'aide de ce que nous tournons ici, nous pouvons comprendre dans Kubernetes que non seulement un conteneur s'est levé dans l'application, mais que l'application elle-même a démarré, elle répond déjà au bilan de santé, ce qui signifie que nous pouvons y envoyer du trafic.

Conditions requises pour développer une application dans Kubernetes

Ce dont je parle maintenant s'appelle les tests de préparation/d'activité au sein de Kubernetes ; en conséquence, nos tests de préparation sont responsables de la disponibilité de l'application en équilibrage. Autrement dit, si des tests de préparation sont effectués dans l'application, alors tout va bien, le trafic client va vers l'application. Si les tests de préparation ne sont pas effectués, l'application ne participe tout simplement pas, cette instance particulière ne participe pas à l'équilibrage, elle est supprimée de l'équilibrage, le trafic client ne circule pas. Par conséquent, des tests de vivacité dans Kubernetes sont nécessaires afin que si l'application reste bloquée, elle puisse être redémarrée. Si le test d'activité ne fonctionne pas pour une application déclarée dans Kubernetes, l'application n'est pas simplement supprimée de l'équilibrage, elle est redémarrée.

Et voici un point important que je voudrais mentionner : d'un point de vue pratique, le test de préparation est généralement utilisé plus souvent et est plus souvent nécessaire que le test de vivacité. Autrement dit, déclarer simplement sans réfléchir à la fois les tests de préparation et d’activité, car Kubernetes peut le faire, et utilisons tout ce qu’il peut faire, n’est pas une très bonne idée. Je vais vous expliquer pourquoi. Parce que le point numéro deux des tests est que ce serait une bonne idée de vérifier le service sous-jacent dans vos contrôles de santé. Cela signifie que si vous avez une application Web qui fournit des informations, elles doivent naturellement provenir de quelque part. Dans une base de données par exemple. Eh bien, il enregistre les informations entrant dans cette API REST dans la même base de données. Ensuite, en conséquence, si votre bilan de santé répond simplement comme contacté slashhealth, l'application dit « 200, d'accord, tout va bien », et en même temps la base de données de votre application est inaccessible, et l'application de contrôle de santé dit « 200, d'accord, tout va bien ». " - C'est un mauvais bilan de santé. Ce n’est pas ainsi que cela devrait fonctionner.

C'est-à-dire votre candidature, lorsqu'une demande lui parvient /health, il ne se contente pas de répondre « 200, ok », il va d'abord, par exemple, à la base de données, essaie de s'y connecter, y fait quelque chose de très basique, comme en sélectionner un, vérifie simplement qu'il y a une connexion dans le base de données et vous pouvez interroger la base de données. Si tout cela a réussi, alors la réponse est « 200, ok ». Si l'opération échoue, cela indique qu'il y a une erreur et que la base de données n'est pas disponible.

Par conséquent, à cet égard, je reviens à nouveau aux tests de préparation/d'activité - pourquoi vous avez probablement besoin d'un test de préparation, mais un test d'activité est en question. Parce que si vous décrivez les contrôles de santé exactement comme je viens de le dire, il s'avérera qu'ils ne sont pas disponibles dans la partie instanceв или со всех instancedans une base de données par exemple. Lorsque vous avez déclaré un test de préparation, nos contrôles de santé ont commencé à échouer et, par conséquent, toutes les applications à partir desquelles la base de données n'est pas accessible sont simplement désactivées de l'équilibrage et en fait « se bloquent » simplement dans un état négligé et attendent que leurs bases de données soient travail.

Si nous avons déclaré un test d'activité, alors imaginez, notre base de données est en panne et dans votre Kubernetes, la moitié de tout commence à redémarrer car le test d'activité échoue. Cela signifie que vous devez redémarrer. Ce n'est pas du tout ce que l'on souhaite, j'ai même eu une expérience personnelle dans la pratique. Nous avions une application de chat écrite en JS et introduite dans une base de données Mongo. Et le problème était que c'était au début de mon travail avec Kubernetes, nous avons décrit l'état de préparation, la vivacité des tests sur le principe que Kubernetes peut le faire, donc nous allons l'utiliser. En conséquence, à un moment donné, Mongo est devenu un peu « ennuyeux » et l'échantillon a commencé à échouer. En conséquence, selon le test de pluie, les gousses ont commencé à « tuer ».

Comme vous le comprenez, lorsqu'ils sont « tués », il s'agit d'un chat, c'est-à-dire qu'il y a beaucoup de connexions de clients qui y sont accrochées. Ils sont également « tués » - non, pas des clients, seulement des connexions - pas tous en même temps, et du fait qu'ils ne sont pas tués en même temps, certains plus tôt, d'autres plus tard, ils ne commencent pas en même temps. temps. En plus du caractère aléatoire standard, nous ne pouvons pas prédire avec une précision de la milliseconde l'heure de démarrage de l'application à chaque fois, ils le font donc une instance à la fois. Un infospot monte, s'ajoute à l'équilibrage, tous les clients y viennent, il ne peut pas supporter une telle charge, car il est seul, et, grosso modo, il y en a une dizaine qui y travaillent, et ça tombe. Le suivant se lève, toute la charge repose sur lui, il tombe aussi. Eh bien, ces chutes continuent de tomber en cascade. En fin de compte, comment cela a été résolu : nous avons simplement dû arrêter strictement le trafic des utilisateurs vers cette application, laisser toutes les instances augmenter, puis démarrer tout le trafic des utilisateurs en même temps afin qu'il soit déjà réparti entre les dix instances.

Si ce test d'activité n'avait pas été annoncé, ce qui obligerait le tout à redémarrer, l'application s'en serait très bien occupée. Mais tout, depuis l'équilibrage, est désactivé pour nous, car les bases de données sont inaccessibles et tous les utilisateurs sont « tombés ». Ensuite, lorsque cette base de données devient disponible, tout est inclus dans l'équilibrage, mais les applications n'ont pas besoin de redémarrer, et il n'est pas nécessaire de perdre du temps et des ressources là-dessus. Ils sont tous déjà là, ils sont prêts pour la circulation, donc la circulation s'ouvre, tout va bien - l'application est en place, tout continue de fonctionner.

Par conséquent, les tests de préparation et de vivacité sont différents, et de plus, vous pouvez théoriquement effectuer différents contrôles de santé, un type rayon, un type liv, par exemple, et vérifier différentes choses. Pendant les tests de préparation, vérifiez vos backends. Et sur un test d'activité, par exemple, vous ne vérifiez pas du point de vue que le test d'activité est généralement simplement une application qui répond, si elle est capable de répondre du tout.

Parce que le test de vivacité, dans l’ensemble, se produit lorsque nous sommes « coincés ». Une boucle sans fin a commencé ou autre chose - et plus aucune demande n'est traitée. Par conséquent, il est même logique de les séparer - et d'y mettre en œuvre une logique différente.

Concernant ce à quoi vous devez répondre lorsque vous passez un test, lorsque vous effectuez des contrôles de santé. C'est juste vraiment pénible. Ceux qui connaissent cela vont probablement rire - mais sérieusement, j'ai vu dans ma vie des services qui répondent « 200 » dans XNUMX % des cas. Autrement dit, qui réussit. Mais en même temps, dans le corps de la réponse, ils écrivent « telle ou telle erreur ».

C'est-à-dire que le statut de la réponse vous parvient - tout est réussi. Mais en même temps, vous devez analyser le corps, car le corps dit « désolé, la demande s'est terminée par une erreur » et ce n'est que la réalité. J'ai vu ça dans la vraie vie.

Et pour que certains ne trouvent pas cela drôle et que d’autres trouvent cela très douloureux, cela vaut quand même la peine de respecter une règle simple. Lors des contrôles de santé et, en principe, lorsque vous travaillez avec des applications Web.

Si tout s'est bien passé, répondez avec la deux centième réponse. En principe, n'importe quelle deux centième réponse vous conviendra. Si vous lisez très bien ragsy et savez que certains statuts de réponse sont différents des autres, répondez avec ceux qui conviennent : 204, 5, 10, 15, peu importe. Si ce n’est pas très bon, alors juste « deux zéro zéro ». Si tout se passe mal et que le bilan de santé ne répond pas, répondez par cinq centièmes. Encore une fois, si vous comprenez comment répondre, en quoi les différents statuts de réponse diffèrent les uns des autres. Si vous ne comprenez pas, le 502 est votre option pour répondre aux contrôles de santé en cas de problème.

C'est un autre point, je souhaite revenir un peu sur la vérification des services sous-jacents. Si vous commencez, par exemple, à vérifier tous les services sous-jacents qui se trouvent derrière votre application – tout en général. Ce que nous obtenons du point de vue de l'architecture des microservices, nous avons un concept tel que « faible couplage » - c'est-à-dire lorsque vos services dépendent peu les uns des autres. Si l'un d'eux échoue, tous les autres sans cette fonctionnalité continueront simplement à fonctionner. Certaines fonctionnalités ne fonctionnent tout simplement pas. En conséquence, si vous liez tous les contrôles de santé les uns aux autres, alors vous vous retrouverez avec une défaillance dans l'infrastructure, et parce qu'elle est tombée, tous les contrôles de santé de tous les services commencent également à échouer - et il y a plus d'infrastructures en général pour le toute l'architecture du microservice n° Là, tout est devenu sombre.

Par conséquent, je tiens à répéter que vous devez vérifier les services sous-jacents, ceux sans lesquels votre application dans cent pour cent des cas ne peut pas faire son travail. Autrement dit, il est logique que si vous disposez d'une API REST via laquelle l'utilisateur enregistre dans la base de données ou récupère de la base de données, alors en l'absence de base de données, vous ne pouvez pas garantir le travail avec vos utilisateurs.

Mais si vos utilisateurs, lorsque vous les retirez de la base de données, sont en outre enrichis de quelques autres métadonnées, provenant d'un autre backend, que vous saisissez avant d'envoyer une réponse au frontend - et que ce backend n'est pas disponible, cela signifie que vous donnez votre réponse sans aucune partie des métadonnées.

Ensuite, nous sommes également confrontés à l’un des problèmes pénibles lors du lancement d’applications.

En fait, cela ne s'applique pas uniquement à Kubernetes dans son ensemble : il se trouve que la culture d'une sorte de développement de masse, et DevOps en particulier, a commencé à se répandre à peu près en même temps que Kubernetes. Par conséquent, dans l’ensemble, il s’avère que vous devez arrêter progressivement votre application sans Kubernetes. Même avant Kubernetes, les gens faisaient cela, mais avec l'avènement de Kubernetes, nous avons commencé à en parler en masse.

Arrêt gracieux

En général, qu’est-ce que Graceful Shutdown et pourquoi est-il nécessaire ? Il s'agit du moment où votre application plante pour une raison quelconque, vous devez le faire app stop - ou vous recevez, par exemple, un signal du système d'exploitation, votre application doit le comprendre et faire quelque chose. Le pire des cas, bien sûr, est lorsque votre application reçoit un SIGTERM et dit « SIGTERM, tenons le coup, travaillons, ne faisons rien ». C’est carrément une mauvaise option.

Conditions requises pour développer une application dans Kubernetes

Une option presque tout aussi mauvaise est lorsque votre application reçoit un SIGTERM et dit « ils ont dit segterm, cela signifie que nous terminons, je n'ai pas vu, je ne connais aucune demande des utilisateurs, je ne sais pas quel genre de demandes sur lesquelles je travaille en ce moment, ils ont dit SIGTERM, ça veut dire qu'on termine " C'est aussi une mauvaise option.

Quelle option est la bonne ? Le premier point est de prendre en compte la réalisation des opérations. Une bonne option est que votre serveur tienne toujours compte de ce qu'il fait s'il reçoit un SIGTERM.

SIGTERM est un arrêt en douceur, il est spécialement conçu, il peut être intercepté au niveau du code, il peut être traité, disons que maintenant, attendez, nous allons d'abord terminer le travail que nous avons, puis nous quitterons.

Du point de vue de Kubernetes, voici à quoi cela ressemble. Lorsque nous disons à un pod qui s'exécute dans le cluster Kubernetes : « s'il vous plaît, arrêtez, partez », ou nous sommes redémarrés, ou une mise à jour se produit lorsque Kubernetes recrée les pods, Kubernetes envoie exactement le même message SIGTERM au pod, attend un certain temps, et c'est le temps qu'il attend, il est également configuré, il y a un paramètre si spécial dans les diplômes et il s'appelle Graceful ShutdownTimeout. Comme vous l’avez compris, ça ne s’appelle pas ainsi pour rien, et ce n’est pas pour rien qu’on en parle maintenant.

Là, nous pouvons spécifiquement dire combien de temps nous devons attendre entre le moment où nous envoyons SIGTERM à l'application et le moment où nous comprenons que l'application semble être devenue folle pour quelque chose ou est « bloquée » et ne va pas se terminer - et nous devons envoyez-le SIGKILL, c'est-à-dire terminez dur son travail. Autrement dit, nous avons une sorte de démon en cours d'exécution, il traite les opérations. Nous comprenons qu'en moyenne nos opérations sur lesquelles le démon travaille ne durent pas plus de 30 secondes à la fois. Ainsi, lorsque SIGTERM arrive, nous comprenons que notre démon peut, au maximum, terminer 30 secondes après SIGTERM. Nous l'écrivons, par exemple, 45 secondes au cas où et disons que SIGTERM. Après cela, nous attendons 45 secondes. En théorie, pendant ce temps, le démon aurait dû terminer son travail et se terminer. Mais si tout d’un coup ce n’est plus possible, cela signifie qu’il est probablement bloqué : il ne traite plus nos demandes normalement. Et en 45 secondes, vous pouvez le clouer en toute sécurité.

Et ici, en fait, même 2 aspects peuvent être pris en compte. Tout d'abord, comprenez que si vous avez reçu une demande, vous avez commencé à travailler avec elle d'une manière ou d'une autre et n'avez pas répondu à l'utilisateur, mais vous avez reçu SIGTERM, par exemple. Il est logique de l'affiner et de donner une réponse à l'utilisateur. C’est le point numéro un à cet égard. Le deuxième point ici est que si vous écrivez votre propre application, construisez généralement l'architecture de telle manière que vous recevez une demande pour votre application, puis vous commencez à travailler, commencez à télécharger des fichiers quelque part, à télécharger une base de données, etc. Que. En général, votre utilisateur, votre demande se bloque pendant une demi-heure et attend que vous lui répondiez - alors, très probablement, vous devrez travailler sur l'architecture. Autrement dit, tenez simplement compte du bon sens : si vos opérations sont courtes, il est alors logique d'ignorer SIGTERM et de le modifier. Si vos opérations sont longues, cela n'a aucun sens d'ignorer SIGTERM dans ce cas. Il est logique de repenser l’architecture pour éviter des opérations aussi longues. Pour que les utilisateurs ne se contentent pas d’attendre. Je ne sais pas, créez une sorte de websocket là-bas, créez des hooks inversés que votre serveur enverra déjà au client, n'importe quoi d'autre, mais ne forcez pas l'utilisateur à se bloquer pendant une demi-heure et attendez simplement une session jusqu'à ce que vous réponds-lui. Parce qu'il est imprévisible où il pourrait se briser.

Lorsque votre application se termine, vous devez fournir un code de sortie approprié. Autrement dit, si votre application a été invitée à se fermer, à s'arrêter et qu'elle a pu s'arrêter normalement, vous n'avez pas besoin de renvoyer une sorte de code de sortie 1,5,255, etc. Tout ce qui n'est pas du code zéro, du moins dans les systèmes Linux, j'en suis sûr, est considéré comme un échec. Autrement dit, on considère que votre candidature dans ce cas s'est terminée par une erreur. Ainsi, à l'amiable, si votre candidature s'est terminée sans erreur, vous dites 0 sur la sortie. Si votre application échoue pour une raison quelconque, vous dites non 0 dans la sortie. Et vous pouvez travailler avec ces informations.

Et la dernière option. C'est mauvais lorsque votre utilisateur envoie une demande et reste bloqué pendant une demi-heure pendant que vous la traitez. Mais en général, je voudrais aussi parler de ce qui en vaut généralement la peine du côté du client. Peu importe que vous ayez une application mobile, un front-end, etc. Il faut tenir compte du fait qu’en général la session de l’utilisateur peut être interrompue, tout peut arriver. Une demande peut être envoyée, par exemple, sous-traitée et aucune réponse n'est renvoyée. Votre frontend ou votre application mobile – n’importe quel frontend en général, disons-le ainsi – devrait en tenir compte. Si vous travaillez avec des websockets, c'est généralement la pire douleur que j'ai jamais eue.

Lorsque les développeurs de certains chats réguliers ne le savent pas, il s'avère que le websocket peut se briser. Pour eux, lorsque quelque chose se produit au niveau du proxy, nous modifions simplement la configuration et il effectue un rechargement. Naturellement, toutes les sessions de longue durée sont déchirées dans ce cas. Les développeurs accourent vers nous et nous disent : « Les gars, qu'est-ce que vous faites, le chat est en panne pour tous nos clients ! Nous leur disons : « Qu'est-ce que tu fais ? Vos clients ne parviennent pas à se reconnecter ? Ils disent : « Non, il faut que les séances ne soient pas déchirées. » Bref, c'est en fait un non-sens. Le côté client doit être pris en compte. Surtout, comme je l'ai dit, avec des sessions de longue durée telles que les websockets, cela peut se briser et, sans que l'utilisateur ne le remarque, vous devez pouvoir réinstaller ces sessions. Et puis tout est parfait.

Ressources

En fait, ici, je vais juste vous raconter une histoire simple. Encore une fois de la vraie vie. La chose la plus dingue que j'ai jamais entendue à propos des ressources.

Les ressources dans ce cas, je veux dire, certaines sortes de requêtes, de limites que vous pouvez imposer aux pods de vos clusters Kubernetes. La chose la plus drôle que j'ai entendue de la part d'un développeur... Un de mes collègues développeurs sur un ancien lieu de travail a dit un jour : "Mon application ne démarre pas dans le cluster." J’ai regardé pour voir que cela ne démarrait pas, mais soit cela ne correspondait pas aux ressources, soit ils avaient fixé de très petites limites. Bref, l'application ne peut pas démarrer à cause des ressources. Je dis : « Cela ne démarrera pas à cause des ressources, vous décidez de la quantité dont vous avez besoin et fixez une valeur adéquate. » Il dit : « Quel genre de ressources ? » J'ai commencé à lui expliquer qu'il fallait définir Kubernetes, les limites des requêtes et bla, bla, bla. L’homme a écouté pendant cinq minutes, a hoché la tête et a déclaré : « Je suis venu ici pour travailler en tant que développeur, je ne veux rien savoir des ressources. Je suis venu ici pour écrire du code et c’est tout. C'est triste. C'est un concept très triste du point de vue d'un développeur. Surtout dans le monde moderne, pour ainsi dire, des développeurs progressistes.

Pourquoi des ressources sont-elles nécessaires ? Il existe 2 types de ressources dans Kubernetes. Certaines sont appelées demandes, d’autres sont appelées limites. Par ressources, nous comprendrons qu'il n'y a en principe toujours que deux restrictions fondamentales. Autrement dit, les limites de temps CPU et de RAM pour un conteneur exécuté dans Kubernetes.

Une limite impose une limite supérieure à la manière dont une ressource peut être utilisée dans votre application. Autrement dit, si vous dites 1 Go de RAM dans les limites, votre application ne pourra pas utiliser plus de 1 Go de RAM. Et s'il veut et essaie soudainement de le faire, alors un processus appelé oom killer, à mémoire insuffisante, viendra tuer votre application - c'est-à-dire qu'elle redémarrera simplement. Les applications ne redémarreront pas en fonction du processeur. En termes de CPU, si une application essaie d'en utiliser beaucoup, plus que spécifié dans les limites, le CPU sera simplement strictement sélectionné. Cela ne conduit pas à des redémarrages. C'est la limite – c'est la limite supérieure.

Et il y a une demande. Une requête indique comment Kubernetes comprend comment les nœuds de votre cluster Kubernetes sont remplis d'applications. Autrement dit, une requête est une sorte de validation de votre application. Il dit ce que je veux utiliser : « J’aimerais que vous me réserviez autant de processeur et autant de mémoire. » Une analogie si simple. Et si nous avions un nœud qui possède, je ne sais pas, 8 processeurs au total. Et un pod arrive là-bas, dont les requêtes indiquent 1 CPU, ce qui signifie qu'il reste 7 CPU au nœud. Autrement dit, dès que 8 pods arrivent sur ce nœud, chacun ayant 1 CPU dans leurs requêtes, le nœud, comme du point de vue de Kubernetes, est à court de CPU et plus de pods avec des requêtes ne peuvent pas être lancé sur ce nœud. Si tous les nœuds manquent de CPU, Kubernetes commencera à dire qu'il n'y a pas de nœuds appropriés dans le cluster pour exécuter vos pods car le CPU est épuisé.

Pourquoi les requêtes sont-elles nécessaires et pourquoi sans requêtes, je pense qu'il n'est pas nécessaire de lancer quoi que ce soit dans Kubernetes ? Imaginons une situation hypothétique. Vous lancez votre application sans requêtes, Kubernetes ne sait pas quelle quantité de ce vous avez, ni sur quels nœuds vous pouvez la pousser. Eh bien, il pousse, pousse, pousse sur les nœuds. À un moment donné, vous commencerez à générer du trafic vers votre application. Et l'une des applications commence soudainement à utiliser les ressources jusqu'aux limites dont elle dispose conformément aux limites. Il s'avère qu'il existe une autre application à proximité et qu'elle a également besoin de ressources. Le nœud commence en fait à manquer physiquement de ressources, par exemple OP. Le nœud commence en fait à manquer physiquement de ressources, par exemple de mémoire vive (RAM). Lorsqu'un nœud manque d'énergie, le docker cessera d'abord de répondre, puis le cubelet, puis le système d'exploitation. Ils perdront simplement connaissance et TOUT cessera définitivement de fonctionner pour vous. Autrement dit, cela entraînera le blocage de votre nœud et vous devrez le redémarrer. Bref, la situation n'est pas très bonne.

Et lorsque vous avez des demandes, les limites ne sont pas très différentes, du moins pas plusieurs fois supérieures aux limites ou aux demandes, vous pouvez alors avoir un remplissage aussi normal et rationnel des applications sur les nœuds des clusters Kubernetes. Dans le même temps, Kubernetes est approximativement conscient de la quantité de ce qu'il met, où, de la quantité de ce qui est utilisée, où. Autrement dit, c’est juste un tel moment. Il est important de le comprendre. Et il est important de contrôler que cela soit indiqué.

Stockage de données

Notre prochain point concerne le stockage des données. Que faire avec eux et en général, que faire de la persistance dans Kubernetes ?

Je pense, encore une fois, au sein de notre École du soir, il y avait un sujet sur la base de données dans Kubernetes. Et il me semble que je sais même à peu près ce que vos collègues vous ont dit lorsqu'on vous a demandé : « Est-il possible d'exécuter une base de données dans Kubernetes ? Pour une raison quelconque, il me semble que vos collègues auraient dû vous dire que si vous vous posez la question de savoir s'il est possible d'exécuter une base de données dans Kubernetes, alors c'est impossible.

La logique ici est simple. Juste au cas où, je vais vous expliquer encore une fois, si vous êtes un gars vraiment cool qui peut construire un système de stockage réseau distribué assez tolérant aux pannes, comprenez comment intégrer une base de données dans ce cas, comment le cloud natif dans les conteneurs devrait fonctionner dans une base de données en général. Très probablement, vous n'avez aucune question sur la façon de l'exécuter. Si vous avez une telle question et que vous voulez vous assurer que tout se déroule et se déroule jusqu'à la mort dans la production et ne tombe jamais, alors cela n'arrive pas. Vous êtes assuré de vous tirer une balle dans le pied avec cette approche. Il vaut donc mieux ne pas le faire.

Que devons-nous faire des données que notre application souhaite stocker, des images que les utilisateurs téléchargent, de certaines choses que notre application génère pendant son fonctionnement, au démarrage par exemple ? Que faire avec eux dans Kubernetes ?

En général, idéalement, oui, bien sûr, Kubernetes est très bien conçu et a généralement été initialement conçu pour des applications sans état. Autrement dit, pour les applications qui ne stockent aucune information. C'est idéal.

Mais bien entendu, l’option idéale n’existe pas toujours. Et alors? Le premier et le plus simple est de prendre une sorte de S3, mais pas un produit fait maison, dont on ne sait pas non plus comment il fonctionne, mais provenant d'un fournisseur. Un bon fournisseur normal - et apprenez à votre application à utiliser S3. Autrement dit, lorsque votre utilisateur souhaite télécharger un fichier, dites « ici, s'il vous plaît, téléchargez-le sur S3 ». Lorsqu'il souhaite le recevoir, dites : "Voici un lien vers S3 et prenez-le à partir d'ici." C'est idéal.

Si soudainement, pour une raison quelconque, cette option idéale ne vous convient pas, que vous avez une application que vous n'avez pas écrite, que vous ne développez pas, ou qu'il s'agit d'une sorte d'héritage terrible, elle ne peut pas utiliser le protocole S3, mais doit fonctionner avec des répertoires locaux dans dossiers locaux. Prenez quelque chose de plus ou moins simple, déployez Kubernetes. Autrement dit, confier immédiatement Ceph à certaines tâches minimes, me semble-t-il, est une mauvaise idée. Parce que Ceph, bien sûr, est bon et à la mode. Mais si vous ne comprenez pas vraiment ce que vous faites, une fois que vous avez mis quelque chose sur Ceph, vous pouvez très facilement et simplement ne plus jamais l'en sortir. Car, comme vous le savez, Ceph stocke les données dans son cluster sous forme binaire, et non sous forme de simples fichiers. Par conséquent, si soudainement le cluster Ceph tombe en panne, il existe une forte probabilité que vous n'obteniez plus jamais vos données à partir de là.

Nous aurons un cours sur Ceph, vous pourrez Familiarisez-vous avec le programme et soumettez votre candidature..

Par conséquent, il est préférable de faire quelque chose de simple comme un serveur NFS. Kubernetes peut fonctionner avec eux, vous pouvez monter un répertoire sous un serveur NFS - votre application est comme un répertoire local. En même temps, bien sûr, vous devez comprendre que, encore une fois, vous devez faire quelque chose avec votre NFS, vous devez comprendre que parfois il peut devenir inaccessible et réfléchir à la question de savoir ce que vous ferez dans ce cas. Peut-être devrait-il être sauvegardé quelque part sur une machine distincte.

Le point suivant dont j'ai parlé est de savoir quoi faire si votre application génère des fichiers pendant son fonctionnement. Par exemple, au démarrage, il génère un fichier statique basé sur certaines informations que l'application reçoit uniquement au moment du lancement. Quel moment. S'il n'y a pas beaucoup de données de ce type, vous n'avez pas à vous en soucier du tout, installez simplement cette application pour vous-même et travaillez. La seule question ici est de savoir quoi, regardez. Très souvent, toutes sortes de systèmes hérités, tels que WordPress, etc., en particulier avec des plugins intelligents modifiés, des développeurs PHP intelligents, savent souvent comment faire en sorte qu'ils génèrent eux-mêmes une sorte de fichier. En conséquence, l'un génère un fichier, le second génère un deuxième fichier. Ils sont différents. L'équilibrage se produit dans le cluster Kubernetes des clients simplement par hasard. En conséquence, il s’avère qu’ils ne savent pas comment travailler ensemble par exemple. L’un donne une information, l’autre donne à l’utilisateur une autre information. C'est quelque chose que vous devriez éviter. Autrement dit, dans Kubernetes, tout ce que vous lancez est assuré de pouvoir fonctionner dans plusieurs instances. Parce que Kubernetes est une chose en mouvement. Ainsi, il peut déplacer n'importe quoi, quand il le souhaite, sans rien demander à personne. Il faut donc compter sur cela. Tout ce qui est lancé en une seule fois échouera tôt ou tard. Plus vous avez de réservations, mieux c'est. Mais encore une fois, je dis que si vous avez quelques fichiers de ce type, vous pouvez les placer directement sous vous, ils pèsent peu. S’il y en a un peu plus, vous ne devriez probablement pas les pousser à l’intérieur du conteneur.

Je dirais qu'il y a une chose tellement merveilleuse dans Kubernetes que vous pouvez utiliser le volume. Il existe notamment un volume de type vide dir. Autrement dit, Kubernetes créera automatiquement un répertoire dans ses répertoires de services sur le serveur sur lequel vous avez démarré. Et il vous le donnera pour que vous puissiez l'utiliser. Il n'y a qu'un seul point important. Autrement dit, vos données ne seront pas stockées à l’intérieur du conteneur, mais plutôt sur l’hôte sur lequel vous exécutez. De plus, Kubernetes peut contrôler ces répertoires vides dans une configuration normale et est capable de contrôler leur taille maximale et de ne pas permettre qu'elle soit dépassée. Le seul point est que ce que vous avez écrit dans un répertoire vide n'est pas perdu lors du redémarrage du pod. Autrement dit, si votre pod tombe par erreur et remonte, les informations contenues dans le répertoire vide n'iront nulle part. Il peut l’utiliser à nouveau lors d’un nouveau départ – et c’est bien. Si votre pod part quelque part, il partira naturellement sans données. Autrement dit, dès que le pod du nœud où il a été lancé avec un répertoire vide disparaît, le répertoire vide est supprimé.

Qu'y a-t-il d'autre de bien dans un répertoire vide ? Par exemple, il peut être utilisé comme cache. Imaginons que notre application génère quelque chose à la volée, le donne aux utilisateurs et le fasse pendant longtemps. Par conséquent, l'application, par exemple, le génère et le donne aux utilisateurs, et en même temps le stocke quelque part, de sorte que la prochaine fois que l'utilisateur viendra pour la même chose, il sera plus rapide de le donner immédiatement généré. Un répertoire vide peut être demandé à Kubernetes pour qu'il soit créé en mémoire. Et ainsi, vos caches peuvent généralement fonctionner à une vitesse fulgurante – en termes de vitesse d’accès au disque. Autrement dit, vous avez un répertoire vide en mémoire, dans le système d'exploitation, il est stocké en mémoire, mais pour vous, pour l'utilisateur à l'intérieur du pod, cela ressemble simplement à un répertoire local. Vous n'avez pas besoin de l'application pour enseigner spécifiquement la magie. Vous prenez et placez directement votre fichier dans un répertoire, mais, en fait, en mémoire sur le système d'exploitation. C’est également une fonctionnalité très pratique en termes de Kubernetes.

Quels problèmes Minio a-t-il ? Le principal problème avec Minio est que pour que cette chose fonctionne, elle doit être exécutée quelque part et il doit y avoir une sorte de système de fichiers, c'est-à-dire un stockage. Et ici, nous rencontrons les mêmes problèmes que Ceph. Autrement dit, Minio doit stocker ses fichiers quelque part. C'est simplement une interface HTTP pour vos fichiers. De plus, les fonctionnalités sont nettement moins bonnes que celles du S3 d'Amazon. Auparavant, il n'était pas en mesure d'autoriser correctement l'utilisateur. Maintenant, pour autant que je sache, il peut déjà créer des buckets avec des autorisations différentes, mais encore une fois, il me semble que le principal problème est, pour ainsi dire, le système de stockage sous-jacent au minimum.

Comment le répertoire vide en mémoire affecte-t-il les limites ? N'affecte en rien les limites. Il réside dans la mémoire de l'hôte, et non dans la mémoire de votre conteneur. Autrement dit, votre conteneur ne voit pas le répertoire vide en mémoire comme faisant partie de sa mémoire occupée. L'hôte le voit. Par conséquent, oui, du point de vue de Kubernetes, lorsque vous commencez à l'utiliser, il serait bon de comprendre que vous consacrez une partie de votre mémoire à un répertoire vide. Et par conséquent, comprenez que la mémoire peut s'épuiser non seulement à cause des applications, mais aussi parce que quelqu'un écrit dans ces répertoires vides.

Nativeité du cloud

Et le dernier sous-thème est ce qu'est Cloudnative. Pourquoi est-ce nécessaire ? Cloudnativeness et ainsi de suite.

Autrement dit, les applications capables et écrites pour fonctionner dans une infrastructure cloud moderne. Mais, en fait, Cloudnative a un autre aspect. Qu'il ne s'agit pas seulement d'une application qui prend en compte toutes les exigences d'une infrastructure cloud moderne, mais qui sait également comment travailler avec cette infrastructure cloud moderne, profiter des avantages et des inconvénients du fait qu'elle fonctionne dans ces cloud. N'allez pas trop loin et travaillez dans le cloud, mais profitez des avantages du travail dans le cloud.

Conditions requises pour développer une application dans Kubernetes

Prenons simplement Kubernetes comme exemple. Votre application s'exécute dans Kubernetes. Votre application peut toujours, ou plutôt les administrateurs de votre application, peuvent toujours créer un compte de service. C'est-à-dire un compte d'autorisation dans Kubernetes lui-même sur son serveur. Ajoutez-y quelques droits dont nous avons besoin. Et vous pouvez accéder à Kubernetes depuis votre application. Que pouvez-vous faire de cette façon ? Par exemple, à partir de l'application, recevez des données sur l'emplacement de vos autres applications, d'autres instances similaires, et regroupez-les d'une manière ou d'une autre au-dessus de Kubernetes, si nécessaire.

Encore une fois, nous avons littéralement eu un cas récemment. Nous avons un contrôleur qui surveille la file d'attente. Et lorsque de nouvelles tâches apparaissent dans cette file d'attente, elles sont envoyées à Kubernetes - et à l'intérieur de Kubernetes, elles créent un nouveau pod. Donne à ce pod une nouvelle tâche et dans le cadre de ce pod, le pod exécute la tâche, envoie une réponse au contrôleur lui-même, et le contrôleur fait ensuite quelque chose avec ces informations. Par exemple, il ajoute une base de données. Autrement dit, c'est encore une fois un avantage du fait que notre application fonctionne dans Kubernetes. Nous pouvons utiliser la fonctionnalité Kubernetes intégrée elle-même afin d'étendre et de rendre les fonctionnalités de notre application plus pratiques. Autrement dit, ne cachez pas une sorte de magie sur la façon de lancer une application, comment lancer un travailleur. Dans Kubernetes, vous envoyez simplement une requête dans l'application si l'application est écrite en Python.

Il en va de même si l’on va au-delà de Kubernetes. Notre Kubernetes fonctionne quelque part - c'est bien si c'est dans une sorte de cloud. Encore une fois, nous pouvons utiliser, et même devrions, je crois, utiliser les capacités du cloud lui-même dans lequel nous opérons. Des choses élémentaires que nous offre le cloud. L'équilibrage, c'est-à-dire que nous pouvons créer des équilibreurs cloud et les utiliser. C’est un avantage direct de ce que nous pouvons utiliser. Parce que l'équilibrage du cloud, premièrement, nous enlève tout simplement bêtement la responsabilité de son fonctionnement et de sa configuration. De plus, c'est très pratique, car Kubernetes standard peut s'intégrer aux cloud.

Il en va de même pour la mise à l'échelle. Kubernetes standard peut s'intégrer aux fournisseurs de cloud. Sait comprendre que si le cluster manque de nœuds, c'est-à-dire que l'espace des nœuds est épuisé, vous devez alors en ajouter - Kubernetes lui-même ajoutera de nouveaux nœuds à votre cluster et commencera à lancer des pods dessus. Autrement dit, lorsque votre charge arrive, le nombre de foyers commence à augmenter. Lorsque les nœuds du cluster sont à court de ces pods, Kubernetes lance de nouveaux nœuds et, par conséquent, le nombre de pods peut encore augmenter. Et c'est très pratique. Il s’agit d’une opportunité directe de faire évoluer le cluster à la volée. Pas très rapide, dans le sens où ce n’est pas une seconde, c’est plutôt une minute pour ajouter de nouveaux nœuds.

Mais d’après mon expérience, encore une fois, c’est la chose la plus cool que j’ai jamais vue. Lorsque le cluster Cloudnative a été mis à l'échelle en fonction de l'heure de la journée. Il s’agissait d’un service backend utilisé par les personnes du back-office. Autrement dit, ils viennent travailler à 9 heures du matin, commencent à se connecter au système et, par conséquent, le cluster Cloudnative, où tout fonctionne, commence à gonfler, en lançant de nouveaux pods afin que tous ceux qui viennent travailler puissent travailler avec l'application. Lorsqu'ils quittent le travail à 8h ou 6h, les clusters Kubernetes remarquent que plus personne n'utilise l'application et commencent à rétrécir. Des économies allant jusqu'à 30 pour cent sont garanties. Cela fonctionnait en Amazonie à cette époque ; à cette époque, personne en Russie ne pouvait le faire aussi bien.

Je vais vous le dire clairement, les économies sont de 30 % simplement parce que nous utilisons Kubernetes et profitons des capacités du cloud. Cela peut désormais être fait en Russie. Je ne ferai de publicité à personne, bien sûr, mais disons simplement qu'il existe des fournisseurs qui peuvent le faire, en le fournissant dès la sortie de la boîte avec un bouton.

Il y a un dernier point sur lequel je voudrais également attirer votre attention. Pour que votre application, votre infrastructure soit Cloudnative, il est logique de commencer enfin à adapter l'approche appelée Infrastructure as a Code. Autrement dit, cela signifie que votre application, ou plutôt votre infrastructure, est nécessaire exactement de la même manière que le code Décrivez votre application, votre logique métier sous forme de code. Et travaillez-le sous forme de code, c'est-à-dire testez-le, déployez-le, stockez-le dans git, appliquez-lui CICD.

Et c'est exactement ce qui vous permet, d'une part, de toujours garder le contrôle sur votre infrastructure, de toujours comprendre dans quel état elle se trouve. Deuxièmement, évitez les opérations manuelles qui provoquent des erreurs. Troisièmement, évitez simplement ce qu’on appelle le turnover, lorsque vous devez constamment effectuer les mêmes tâches manuelles. Quatrièmement, cela vous permet de récupérer beaucoup plus rapidement en cas de panne. En Russie, chaque fois que j'en parle, il y a toujours un grand nombre de gens qui disent : "Oui, c'est clair, mais vous avez des approches, bref, il n'y a rien à arranger." Mais c'est vrai. Si quelque chose est cassé dans votre infrastructure, alors du point de vue de l'approche Cloudnative et du point de vue de l'Infrastructure as a Code, plutôt que de le réparer, d'aller sur le serveur, de déterminer ce qui est cassé et de le réparer, c'est plus facile pour supprimer le serveur et le créer à nouveau. Et je ferai restaurer tout cela.

Toutes ces questions sont abordées plus en détail à Cours vidéo Kubernetes : Junior, Basic, Mega. En suivant le lien, vous pourrez vous familiariser avec le programme et les conditions. Ce qui est pratique, c'est que vous pouvez maîtriser Kubernetes en étudiant à domicile ou en travaillant 1 à 2 heures par jour.

Source: habr.com

Ajouter un commentaire