Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Je m'appelle Viktor Yagofarov et je développe la plateforme Kubernetes chez DomClick en tant que responsable du développement technique au sein de l'équipe Ops (opération). Je voudrais parler de la structure de nos processus Dev <-> Ops, des caractéristiques de l'exploitation de l'un des plus grands clusters k8s en Russie, ainsi que des pratiques DevOps/SRE que notre équipe applique.

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Équipe des opérations

L'équipe Ops compte actuellement 15 personnes. Trois d'entre eux sont responsables du bureau, deux travaillent dans un fuseau horaire différent et sont disponibles, y compris la nuit. Ainsi, quelqu'un des Ops est toujours aux commandes et prêt à répondre à un incident de toute complexité. Nous n'avons pas de travail de nuit, ce qui préserve notre psychisme et donne à chacun la possibilité de dormir suffisamment et de passer du temps libre, pas seulement devant l'ordinateur.

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Chacun a des compétences différentes : réseauteurs, administrateurs de bases de données, spécialistes de la pile ELK, administrateurs/développeurs Kubernetes, surveillance, virtualisation, spécialistes du matériel, etc. Une chose unit tout le monde : tout le monde peut remplacer n'importe lequel d'entre nous dans une certaine mesure : par exemple, introduire de nouveaux nœuds dans le cluster k8s, mettre à jour PostgreSQL, écrire un pipeline CI/CD + Ansible, automatiser quelque chose dans Python/Bash/Go, connecter du matériel à Centre de données. De solides compétences dans n'importe quel domaine ne vous empêchent pas de changer la direction de votre activité et de commencer à vous améliorer dans un autre domaine. Par exemple, j'ai rejoint une entreprise en tant que spécialiste PostgreSQL, et désormais mon principal domaine de responsabilité concerne les clusters Kubernetes. Dans l’équipe, toute hauteur est la bienvenue et le sens de l’effet de levier est très développé.

Au fait, nous chassons. Les exigences pour les candidats sont assez standards. Personnellement, il est important pour moi qu'une personne s'intègre dans l'équipe, ne soit pas en conflit, mais sache aussi défendre son point de vue, veuille se développer et n'ait pas peur de faire quelque chose de nouveau et propose ses idées. Aussi, des compétences en programmation dans les langages de script, une connaissance des bases de Linux et de l'anglais sont requises. L'anglais est nécessaire simplement pour qu'une personne, en cas de fakap, puisse rechercher sur Google la solution au problème en 10 secondes, et non en 10 minutes. Il est désormais très difficile de trouver des spécialistes ayant une connaissance approfondie de Linux : c'est drôle, mais deux candidats sur trois ne peuvent pas répondre à la question « Qu'est-ce que la charge moyenne ? De quoi est-il fait ? », et la question « Comment assembler un core dump à partir d'un programme C » est considérée comme quelque chose du monde des surhumains... ou des dinosaures. Nous devons l'accepter, car généralement les gens ont d'autres compétences très développées, mais nous enseignerons Linux. La réponse à la question « pourquoi un ingénieur DevOps a-t-il besoin de savoir tout cela dans le monde moderne des cloud » devra rester en dehors du cadre de l'article, mais en trois mots : tout cela est nécessaire.

Outils d'équipe

L'équipe Outils joue un rôle important dans l'automatisation. Leur tâche principale est de créer des outils graphiques et CLI pratiques pour les développeurs. Par exemple, notre Confer de développement interne vous permet de déployer littéralement une application sur Kubernetes en quelques clics de souris, de configurer ses ressources, ses clés depuis le coffre-fort, etc. Auparavant, il y avait Jenkins + Helm 2, mais j'ai dû développer mon propre outil pour éliminer le copier-coller et uniformiser le cycle de vie des logiciels.

L'équipe Ops n'écrit pas de pipelines pour les développeurs, mais peut les conseiller sur tout problème lié à leur rédaction (certaines personnes disposent toujours de Helm 3).

DevOps

Quant au DevOps, nous le voyons ainsi :

Les équipes de développement écrivent le code, le déploient via Confer to dev -> qa/stage -> prod. La responsabilité de s'assurer que le code ne ralentit pas et ne contient pas d'erreurs incombe aux équipes Dev et Ops. Le jour, la personne de garde de l'équipe Ops doit tout d'abord répondre à un incident avec son application, et le soir et la nuit, l'administrateur de garde (Ops) doit réveiller le développeur de garde s'il sait pour sûr que le problème ne vient pas de l'infrastructure. Toutes les métriques et alertes de surveillance apparaissent automatiquement ou semi-automatiquement.

Le domaine de responsabilité des Ops commence à partir du moment où l'application est déployée en production, mais la responsabilité du Dev ne s'arrête pas là - nous faisons la même chose et sommes dans le même bateau.

Les développeurs conseillent les administrateurs s'ils ont besoin d'aide pour écrire un microservice d'administration (par exemple, Go backend + HTML5), et les administrateurs conseillent les développeurs sur tout problème d'infrastructure ou lié aux k8.

Soit dit en passant, nous n’avons pas du tout de monolithe, seulement des microservices. Leur nombre oscille jusqu'à présent entre 900 et 1000 8 dans le cluster prod kXNUMXs, si on le mesure en nombre. déploiements. Le nombre de pods oscille entre 1700 2000 et 2000 XNUMX. Il y a actuellement environ XNUMX XNUMX pods dans le cluster prod.

Je ne peux pas donner de chiffres exacts, car nous surveillons les microservices inutiles et les supprimons de manière semi-automatique. K8s nous aide à garder une trace des entités inutiles opérateur inutile, ce qui permet d'économiser beaucoup de ressources et d'argent.

La gestion des ressources

Surveillance

Un suivi bien structuré et informatif devient la pierre angulaire du fonctionnement d’un grand cluster. Nous n'avons pas encore trouvé de solution universelle qui couvrirait 100 % de tous les besoins de surveillance, c'est pourquoi nous créons périodiquement différentes solutions personnalisées dans cet environnement.

  • Zabbix. Bon vieux monitoring, qui vise avant tout à suivre l’état général des infrastructures. Il nous indique quand un nœud meurt en termes de traitement, de mémoire, de disques, de réseau, etc. Rien de surnaturel, mais nous avons aussi un DaemonSet d'agents séparé, à l'aide duquel, par exemple, nous surveillons l'état du DNS dans le cluster : nous recherchons des pods coredns stupides, nous vérifions la disponibilité des hôtes externes. Il semblerait que pourquoi s'embêter avec cela, mais avec de gros volumes de trafic, ce composant est un sérieux point d'échec. J'ai déjà décrit, comment j'ai eu du mal avec les performances DNS dans un cluster.
  • Opérateur Prometheus. Un ensemble de différents exportateurs donne un large aperçu de toutes les composantes du cluster. Ensuite, nous visualisons tout cela sur de grands tableaux de bord dans Grafana et utilisons alertmanager pour les alertes.

Un autre outil utile pour nous était entrée de liste. Nous l'avons écrit après avoir rencontré à plusieurs reprises une situation dans laquelle une équipe chevauchait les chemins d'entrée d'une autre équipe, ce qui entraînait des erreurs 50x. Désormais, avant de déployer en production, les développeurs vérifient que personne ne sera affecté, et pour mon équipe, c'est un bon outil pour le diagnostic initial des problèmes avec Ingresses. C'est drôle qu'au début, il ait été écrit pour les administrateurs et que cela ait l'air plutôt « maladroit », mais après que les équipes de développement soient tombées amoureuses de l'outil, cela a beaucoup changé et a commencé à ne plus ressembler à « un administrateur ayant créé un visage Web pour les administrateurs ». » Bientôt, nous abandonnerons cet outil et de telles situations seront validées avant même le déploiement du pipeline.

Ressources d'équipe dans le Cube

Avant de passer aux exemples, il convient d’expliquer comment nous allouons les ressources pour microservices.

Pour comprendre quelles équipes et dans quelles quantités utilisent leurs ressources (processeur, mémoire, SSD local), on attribue le sien à chaque commande namespace dans le « Cube » et limiter ses capacités maximales en termes de processeur, de mémoire et de disque, après avoir discuté au préalable des besoins des équipes. En conséquence, une seule commande, en général, ne bloquera pas le déploiement de l'ensemble du cluster, allouant des milliers de cœurs et de téraoctets de mémoire. L'accès à l'espace de noms est accordé via AD (nous utilisons RBAC). Les espaces de noms et leurs limites sont ajoutés via une pull request au référentiel GIT, puis tout est automatiquement déployé via le pipeline Ansible.

Un exemple d'allocation de ressources à une équipe :

namespaces:

  chat-team:
    pods: 23
    limits:
      cpu: 11
      memory: 20Gi
    requests:
      cpu: 11
      memory: 20Gi

Demandes et limites

En cubes" Demande est le nombre de ressources réservées garanties pour nacelle (un ou plusieurs conteneurs Docker) dans un cluster. La limite est un maximum non garanti. Vous pouvez souvent voir sur les graphiques comment une équipe s'est fixée trop de requêtes pour toutes ses applications et ne peut pas déployer l'application sur le « Cube », puisque toutes les requêtes sous son espace de noms ont déjà été « dépensées ».

La bonne façon de sortir de cette situation est d'examiner la consommation réelle des ressources et de la comparer avec le montant demandé (Demande).

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices
Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Dans les captures d'écran ci-dessus, vous pouvez voir que les processeurs « demandés » correspondent au nombre réel de threads et que les limites peuvent dépasser le nombre réel de threads CPU =)

Examinons maintenant un espace de noms en détail (j'ai choisi l'espace de noms kube-system - l'espace de noms système pour les composants du « Cube » lui-même) et voyons le rapport entre le temps processeur et la mémoire réellement utilisés et celui demandé :

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Il est évident que beaucoup plus de mémoire et de CPU sont réservées aux services système que ce qui est réellement utilisé. Dans le cas du système kube, cela est justifié : il arrive que le contrôleur d'entrée nginx ou les nodelocaldns à leur apogée frappent le CPU et consomment beaucoup de RAM, donc ici une telle réserve est justifiée. De plus, nous ne pouvons pas nous fier aux graphiques des 3 dernières heures : il est souhaitable de voir des métriques historiques sur une longue période de temps.

Un système de « recommandations » a été développé. Par exemple, vous pouvez voir ici quelles ressources feraient mieux d'augmenter les « limites » (la barre supérieure autorisée) afin que la « limitation » ne se produise pas : le moment où une ressource a déjà utilisé du CPU ou de la mémoire dans la tranche de temps impartie et attend qu'il soit « dégelé » :

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Et voici les gousses qui devraient freiner leur appétit :

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Sur étranglement + suivi des ressources, vous pouvez écrire plus d'un article, alors posez des questions dans les commentaires. En quelques mots, je peux dire que la tâche d'automatisation de telles métriques est très difficile et demande beaucoup de temps et d'équilibre avec les fonctions « fenêtre » et « CTE » Prometheus / VictoriaMetrics (ces termes sont entre guillemets, puisqu'il y a presque rien de tel dans PromQL, et il faut diviser les requêtes effrayantes en plusieurs écrans de texte et les optimiser).

En conséquence, les développeurs disposent d'outils pour surveiller leurs espaces de noms dans Cube, et ils peuvent choisir eux-mêmes où et à quelle heure quelles applications peuvent voir leurs ressources « coupées » et quels serveurs peuvent recevoir l'intégralité du processeur toute la nuit.

Méthodologies

Dans l'entreprise telle qu'elle est aujourd'hui à la mode, nous adhérons à DevOps- et SRE-praticien Lorsqu'une entreprise dispose de 1000 microservices, d'environ 350 développeurs et 15 administrateurs pour toute l'infrastructure, il faut « être à la mode » : derrière tous ces « mots de passe », il y a un besoin urgent d'automatiser tout et tout le monde, et les administrateurs ne doivent pas être un goulot d'étranglement. dans les processus.

En tant qu'Ops, nous fournissons diverses mesures et tableaux de bord aux développeurs liés aux taux de réponse et aux erreurs des services.

Nous utilisons des méthodologies telles que : RED, UTILISATION и Signaux dorésen les combinant ensemble. Nous essayons de minimiser le nombre de tableaux de bord afin qu'en un coup d'œil, il soit clair quel service est actuellement en train de se dégrader (par exemple, codes de réponse par seconde, temps de réponse au 99e centile), etc. Dès que de nouvelles métriques deviennent nécessaires pour les tableaux de bord généraux, nous les dessinons et les ajoutons immédiatement.

Je n'ai pas dessiné de graphiques depuis un mois. C’est probablement un bon signe : cela signifie que la plupart des « désirs » ont déjà été réalisés. Il m'est arrivé que pendant la semaine, je dessinais un nouveau graphique au moins une fois par jour.

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices

Le résultat qui en résulte est précieux, car désormais, les développeurs s'adressent très rarement aux administrateurs pour leur demander « où consulter une sorte de métrique ».

Mise en œuvre Maillage de services approche à grands pas et devrait rendre la vie beaucoup plus facile à tout le monde, les collègues de Tools sont déjà sur le point d'implémenter l'abstrait « Istio d'une personne en bonne santé » : le cycle de vie de chaque requête HTTP(s) sera visible dans la surveillance, et il il sera toujours possible de comprendre « à quel moment tout s'est cassé » lors de l'interaction interservices (et pas seulement). Abonnez-vous aux actualités du hub DomClick. =)

Prise en charge de l'infrastructure Kubernetes

Historiquement, nous utilisons la version patchée Kubespray — Rôle Ansible pour le déploiement, l'extension et la mise à jour de Kubernetes. À un moment donné, la prise en charge des installations autres que Kubeadm a été supprimée de la branche principale et le processus de passage à Kubeadm n'a pas été proposé. En conséquence, la société Southbridge a créé son propre fork (avec le support de Kubeadm et une solution rapide aux problèmes critiques).

Le processus de mise à jour de tous les clusters k8s ressemble à ceci :

  • prendre Kubespray de Southbridge, consultez notre fil de discussion, Merjim.
  • Nous déployons la mise à jour pour Stress- "Cube".
  • Nous déployons la mise à jour un nœud à la fois (dans Ansible, c'est « série : 1 ») dans dev- "Cube".
  • Nous mettons à jour Prod le samedi soir, un nœud à la fois.

Il est prévu de le remplacer à l'avenir Kubespray pour quelque chose de plus rapide et allez à Kubeadm.

Au total, nous avons trois « Cubes » : Stress, Dev et Prod. Nous prévoyons d'en lancer un autre (pose chaude) Prod-« Cube » dans le deuxième centre de données. Stress и dev vivre dans des « machines virtuelles » (oVirt for Stress et VMWare cloud for Dev). Prod- "Cube" vit sur du "bare metal" : ce sont des nœuds identiques avec 32 threads CPU, 64-128 Go de mémoire et 300 Go SSD RAID 10 - il y en a 50 au total. Trois nœuds « fins » sont dédiés aux « maîtres » Prod- « Cuba » : 16 Go de mémoire, 12 threads CPU.

Pour les ventes, nous préférons utiliser du « bare metal » et éviter les couches inutiles comme Pile ouverte: nous n'avons pas besoin de "voisins bruyants" et de CPU voler du temps. Et la complexité de l'administration double environ dans le cas d'OpenStack interne.

Pour CI/CD « Cubic » et d'autres composants d'infrastructure, nous utilisons un serveur GIT distinct, Helm 3 (ce fut une transition plutôt pénible depuis Helm 2, mais nous sommes très satisfaits des options atomique), Jenkins, Ansible et Docker. Nous aimons les branches de fonctionnalités et le déploiement dans différents environnements à partir d'un seul référentiel.

Conclusion

Kubernetes chez DomClick : comment dormir serein en gérant un cluster de 1000 microservices
Voilà, en termes généraux, à quoi ressemble le processus DevOps chez DomClick du point de vue d'un ingénieur opérationnel. L'article s'est avéré moins technique que prévu : suivez donc l'actualité DomClick sur Habré : il y aura plus d'articles « hardcore » sur Kubernetes et bien plus encore.

Source: habr.com

Ajouter un commentaire