Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Ich heiße Viktor Jagofarov und bin der technische Entwicklungsleiter des Kubernetes-Platforms bei DomKlick im Ops-Team (Betrieb). Ich möchte über die Struktur unserer Dev Ops-Prozesse, die Besonderheiten des Betriebs eines der größten k8s-Cluster in Russland sowie über die DevOps/SRE-Praktiken berichten, die unser Team anwendet.

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Ops-Team

Momentan besteht unser Ops-Team aus 15 Personen. Drei von ihnen sind für das Büro verantwortlich, zwei arbeiten in einer anderen Zeitzone und sind auch nachts verfügbar. So ist immer jemand aus dem Ops-Team am Monitor und bereit, auf Vorfälle jeder Komplexität zu reagieren. Wir haben keinen Nachtdienst, was unser psychisches Wohlbefinden erhält und allen ermöglicht, gut zu schlafen und ihre Freizeit nicht nur am Computer zu verbringen.

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Die Kompetenzen sind vielfältig: Netzwerkspezialisten, DBA, ELK-Stack-Experten, Kubernetes-Admins/Entwickler, Monitoring- und Virtualisierungsspezialisten, Hardware-Spezialisten usw. Alle sind vereint durch eins — jeder kann in gewissem Maße jeden ersetzen: zum Beispiel neue Knoten in das k8s-Cluster einfügen, PostgreSQL aktualisieren, einen CI/CD-Pipeline + Ansible schreiben, etwas auf Python/Bash/Go automatisieren oder Hardware im Rechenzentrum anschließen. Starke Kompetenzen in einem Bereich hindern nicht daran, in einen anderen Bereich zu wechseln und sich dort weiterzuentwickeln. Zum Beispiel habe ich in dem Unternehmen als PostgreSQL-Spezialist angefangen und jetzt liegt mein Hauptverantwortungsbereich bei Kubernetes-Clustern. In unserem Team wird persönliches Wachstum stets gefördert, und der Teamgeist ist stark ausgeprägt.

Übrigens, wir sind auf der Suche nach neuen Talenten. Die Anforderungen an die Kandidaten sind ziemlich standardisiert. Für mich persönlich ist es wichtig, dass die Person ins Team passt, konfliktscheu ist, aber auch in der Lage ist, ihre Meinung zu vertreten, bereit ist, sich weiterzuentwickeln und keine Angst hat, Neues auszuprobieren und eigene Ideen einzubringen. Zudem sind Kenntnisse in Skriptprogrammiersprachen, grundlegendes Wissen über Linux und Englisch erforderlich. Englisch ist notwendig, damit die Person im Falle eines Problems schnell eine Lösung über Google finden kann, und zwar in 10 Sekunden, nicht in 10 Minuten. Fachleute mit tiefem Wissen über Linux sind derzeit sehr schwer zu finden: Lustig, aber zwei von drei Kandidaten können nicht auf die Frage „Was ist Load Average? Woraus setzt es sich zusammen?“ antworten, und die Frage „Wie sammle ich einen Core-Dump aus einem C-Programm?“ wird als etwas Aussergewöhnliches betrachtet… oder aus der Welt der Supermenschen… oder Dinosaurier. Damit müssen wir leben, da Menschen oft andere Kompetenzen viel stärker entwickelt haben, und „Linux“ werden wir ihnen beibringen. Die Antwort auf die Frage „Warum muss ein DevOps-Ingenieur das alles in der modernen Welt der Clouds wissen?“ würde den Rahmen dieses Artikels sprengen, aber in drei Worten: es ist alles notwendig.

Team Tools

Das Team Tools spielt eine wesentliche Rolle in der Automatisierung. Ihre Hauptaufgabe ist die Erstellung benutzerfreundlicher grafischer und CLI-Tools für Entwickler. Zum Beispiel ermöglicht unser internes Tool Confer mit nur wenigen Mausklicks, eine Anwendung in Kubernetes bereitzustellen, ihre Ressourcen zu konfigurieren, Schlüssel aus dem Vault und so weiter. Früher hatten wir Jenkins + Helm 2, aber wir mussten ein eigenes Tool entwickeln, um Copy-Paste zu vermeiden und Einheitlichkeit im Software-Lebenszyklus zu schaffen.

Das Team Ops schreibt keine Pipelines für Entwickler, kann sie aber bei allen Fragen zur Erstellung beraten (manche verwenden immer noch Helm 3).

DevOps

Was DevOps angeht, sehen wir es so:

Die Dev-Teams schreiben Code und setzen diesen über Confer in dev -> qa/stage -> prod um. Die Verantwortung dafür, dass der Code nicht ruckelt und keine Fehler produziert, liegt bei den Dev- und Ops-Teams. Tagsüber sollte zuerst der diensthabende Mitarbeiter des Ops-Teams auf Vorfälle mit seiner Anwendung reagieren, und abends sowie nachts sollte der diensthabende Administrator (Ops) den diensthabenden Entwickler wecken, wenn er sicher weiß, dass das Problem nicht in der Infrastruktur liegt. Alle Metriken und Alarme im Monitoring erscheinen automatisch oder halbautomatisch.

Der Verantwortungsbereich von Ops beginnt mit dem Rollout der Anwendung in die Produktion, aber die Verantwortung von Dev endet damit nicht — wir arbeiten gemeinsam und sitzen im gleichen Boot.

Entwickler beraten die Administratoren, wenn Hilfe beim Schreiben des Administrationsmikrosystems benötigt wird (zum Beispiel Go-Backend + HTML5), und die Administratoren beraten die Entwickler bei Infrastrukturfragen oder Fragen zu k8s.

Übrigens haben wir überhaupt kein Monolith, nur Mikrodienste. Ihre Anzahl schwankt derzeit zwischen 900 und 1000 im Produktions-k8s-Cluster, wenn man nach der Anzahl misst. deploymentsDie Anzahl der Pods schwankt zwischen 1700 und 2000. Momentan gibt es etwa 2000 Pods im Produktionscluster.

Ich kann die genauen Zahlen nicht nennen, da wir nicht benötigte Mikrodienste beobachten und sie halbautomatisch entfernen. Dabei hilft uns useless-operator, was Ressourcen und Geld erheblich spart.

Ressourcenverwaltung

Überwachung

Ein Grundpfeiler beim Betrieb eines großen Clusters ist ein gut aufgebautes und informatives Monitoring. Wir haben bisher keine universelle Lösung gefunden, die 100 % aller Anforderungen an das Monitoring abdeckt, daher erstellen wir regelmäßig verschiedene kundenspezifische Lösungen in diesem Bereich.

  • ZabbixDas gute alte Monitoring, das in erster Linie dafür gedacht ist, den allgemeinen Zustand der Infrastruktur zu überwachen. Es sagt uns, wann ein Knoten aufgrund von CPU, Speicher, Festplatten, Netzwerk usw. ausfällt. Nichts Übernatürliches, aber wir haben auch ein separates DaemonSet mit Agenten, mit denen wir zum Beispiel den Zustand von DNS im Cluster überwachen: wir suchen nach störenden Pods von coredns und überprüfen die Erreichbarkeit externer Hosts. Man könnte sich fragen, warum wir uns dafür die Mühe machen, aber bei großen Datenmengen ist diese Komponente ein ernsthafter Ausfallpunkt. Ich habe bereits beschrieben., wie ich mit der DNS-Leistung im Cluster gekämpft habe.
  • Prometheus Operator. Eine Reihe verschiedener Exporteure gibt einen großen Überblick über alle Komponenten des Clusters. Anschließend visualisieren wir all dies auf großen Dashboards in Grafana und verwenden alertmanager für Benachrichtigungen.

Ein weiteres nützliches Werkzeug für uns war list-ingress. Wir haben es geschrieben, nachdem wir mehrmals mit der Situation konfrontiert waren, dass ein Team mit seinen Ingress-Pfaden das andere Team überlagert hat, was zu 50x-Fehlern führte. Jetzt überprüfen die Entwickler vor der Bereitstellung in die Produktion, dass niemand betroffen wird, und für mein Team ist es ein gutes Werkzeug zur ersten Diagnose von Ingress-Problemen. Es ist lustig, dass es ursprünglich für Administratoren geschrieben wurde und ziemlich „stümperhaft“ aussah, aber nachdem das Tool bei den Entwicklungsteams beliebt wurde, hat es sich stark gewandelt und sieht nicht mehr aus wie „der Admin hat ein Web-Interface für Admins gemacht“. Bald werden wir dieses Tool nicht mehr verwenden und solche Situationen werden bereits vor dem Rollout der Pipeline validiert.

Die Ressourcen der Teams im „Kube“

Bevor wir mit den Beispielen beginnen, ist es wichtig zu erklären, wie wir die Ressourcenverteilung für Mikroservices.

verstehen können, welche Teams und in welchen Mengen ihre Ressourcen (CPU, RAM, lokaler SSD) verwenden, weisen wir jedem Team seinen eigenen Namespace im „Kube“ zu und begrenzen dessen maximale Möglichkeiten in Bezug auf CPU, RAM und Speicher, nachdem wir die Bedürfnisse der Teams besprochen haben. Entsprechend wird ein Team im Allgemeinen nicht den gesamten Cluster für die Bereitstellung blockieren, indem es sich tausende Kerne und Terabytes von RAM sichert. Die Zugriffsrechte im Namespace werden über AD (wir verwenden RBAC) vergeben. Namespaces und deren Limits werden über Pull-Requests in das GIT-Repository hinzugefügt, und anschließend wird alles automatisch über die Ansible-Pipeline ausgerollt.

Beispiel für die Zuweisung von Ressourcen an ein Team:

namespaces:

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

Requests und Limits

Im „Kube“ Request — das ist die Menge an garantiert reservierten Ressourcen für Pod (eine oder mehrere Docker-Container) im Cluster. Limit – das ist der nicht garantierte Höchstwert. Oft sieht man in Grafiken, dass ein Team sich für alle ihre Anwendungen zu viele Requests gesetzt hat und keine Anwendung mehr in den „Kube“ bereitstellen kann, da alle Requests in ihrem Namespace bereits „verbraucht“ sind.

Der richtige Weg aus einer solchen Situation: die tatsächliche Ressourcennutzung beobachten und mit der angeforderten Menge (Request) vergleichen.

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet
Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Auf den obigen Screenshots ist zu sehen, dass die „angeforderten“ (Requested) CPUs der tatsächlichen Anzahl von Threads angenähert werden, während die Limits die Anzahl der tatsächlichen CPU-Threads überschreiten können =)

Lassen Sie uns nun einen Namespace (ich habe den Namespace kube-system gewählt – den Systemnamespace für die Komponenten von „Kube“) im Detail betrachten und das Verhältnis von tatsächlich verwendetem CPU-Zeit und Speicher zu den angeforderten Ressourcen analysieren:

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Es ist offensichtlich, dass viel mehr Speicher und CPU für systemnahe Dienste reserviert ist, als tatsächlich genutzt wird. Im Falle von kube-system ist dies jedoch gerechtfertigt: es kam vor, dass der Nginx Ingress Controller oder nodelocaldns in Spitzenzeiten die CPU auslasteten und viel RAM beanspruchten, daher ist ein solcher Puffer hier sinnvoll. Außerdem können wir uns nicht auf die Grafiken der letzten 3 Stunden verlassen: Es wäre wünschenswert, historische Metriken über einen längeren Zeitraum zu sehen.

Ein System von "Empfehlungen" wurde entwickelt. Beispielsweise kann man hier sehen, welche Ressourcen besser „Limits“ (maximale erlaubte Obergrenze) angehoben werden sollten, um „Throttling“ zu vermeiden: der Moment, wenn bereits CPU oder Speicher in dem ihm zugewiesenen Zeitquantum verbraucht wurden und darauf warten, "entfroren" zu werden:

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Und hier sind Pods, die ihre Ansprüche zügeln sollten:

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Über Throttling + Über das Monitoring von Ressourcen könnte man nicht nur einen Artikel schreiben, daher stellt gerne Fragen in den Kommentaren. In wenigen Worten kann ich sagen, dass die Automatisierung solcher Metriken eine ziemlich komplizierte Aufgabe ist und viel Zeit sowie Geschicklichkeit mit „Window“-Funktionen und „CTEs“ in Prometheus / VictoriaMetrics erfordert (diese Begriffe sind in Anführungszeichen gesetzt, da es in PromQL kaum etwas Vergleichbares gibt und man aufwändige Abfragen, die mehrere Bildschirme füllen, konstruieren und optimieren muss).

Insgesamt haben Entwickler Werkzeuge zum Monitoring ihrer Namespaces in „Kube“, und sie können selbst entscheiden, wo und wann bei welchen Anwendungen Ressourcen „verknappen“ werden können, während andere Pods die gesamte CPU für die ganze Nacht abbekommen können.

Methodologien

Im Unternehmen, wie es derzeit modern, halten wir uns an DevOps- und SRE-Praxis. Wenn das Unternehmen 1000 Mikrodienste hat, etwa 350 Entwickler und 15 Administratoren für die gesamte Infrastruktur, muss man „modern“ sein: hinter all diesen „Buzzwords“ verbirgt sich ein dringender Bedarf an Automatisierung aller Prozesse, und Admins sollten kein Flaschenhals im Prozess sein.

Als Ops bieten wir verschiedene Metriken und Dashboards für Entwickler an, die mit der Reaktionsgeschwindigkeit der Dienste und deren Fehlern zusammenhängen.

Wir verwenden solche Methodologien wie: RED, USE und Golden Signals, indem wir sie zusammenführen. Wir versuchen, die Anzahl der Dashboards zu minimieren, sodass auf einen Blick klar ist, welcher Dienst gerade degradiert (zum Beispiel Antwortcodes pro Sekunde, Antwortzeiten im 99. Perzentil) usw. Sobald neue Metriken für die allgemeinen Dashboards benötigt werden, zeichnen wir sie sofort und fügen sie hinzu.

Ich habe seit einem Monat keine Diagramme mehr erstellt. Das ist wahrscheinlich ein gutes Zeichen: Das bedeutet, dass die meisten "Wünsche" bereits umgesetzt wurden. Früher habe ich wenigstens einmal am Tag ein neues Diagramm gezeichnet.

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet

Das Ergebnis ist wertvoll, weil die Entwickler nun ziemlich selten zu den Admins mit Fragen kommen wie "Wo kann ich eine bestimmte Metrik einsehen?"

Einführung Service Mesh steht vor der Tür und wird allen das Leben erheblich erleichtern. Die Kollegen aus dem Tools-Bereich sind bereits nahe daran, das abstrakte „Istio für gesunde Menschen“ einzuführen: Der Lebenszyklus jeder HTTP(s)-Anfrage wird im Monitoring sichtbar sein, und es wird immer möglich sein zu verstehen, „an welchem Punkt alles kaputt gegangen ist“ bei der Interaktion zwischen Diensten (und nicht nur). Abonnieren Sie die Neuigkeiten des Unternehmens Hub von DomClick. =)

Unterstützung der Kubernetes-Infrastruktur

Historisch gesehen verwenden wir eine gepatchte Version Kubespray — Ansible-Rolle zum Bereitstellen, Erweitern und Aktualisieren von Kubernetes. Irgendwann wurde die Unterstützung für non-kubeadm-Installationen aus dem Hauptzweig entfernt, und ein Übergangsprozess zu kubeadm wurde nicht vorgeschlagen. Infolgedessen hat die Firma Southbridge ihren Fork erstellt (mit Unterstützung für kubeadm und schnellem Fix von kritischen Problemen).

Der Prozess der Aktualisierung aller k8s-Cluster sieht folgendermaßen aus:

  • Wir nehmen Kubespray von Southbridge, vergleichen mit unserem Branch, mergen.
  • Wir rollen das Update aus in Stress-„Kube“.
  • Wir rollen das Update auf eine Node aus (in Ansible heißt das „serial: 1“) in Dev-„Kube“.
  • Aktualisieren Prod am Samstagabend eine Node für eine Node.

In Zukunft haben wir geplant, Kubespray durch etwas Schnelleres zu ersetzen und auf kubeadm.

Wir haben insgesamt drei „Kubes“: Stress, Dev und Prod. Wir planen, einen weiteren zu starten (Hot Standby) Prod-„Kube“ im zweiten Rechenzentrum. Stress und Dev leben in „Virtuellen Maschinen“ (oVirt für Stress und VMWare Cloud für Dev). Prod-„Kube“ läuft auf „nacktem Metall“: es sind identische Nodes mit 32 CPU-Threads, 64-128 GB RAM und 300 GB SSD RAID 10 — insgesamt sind es 50 Stück. Drei „dünne“ Nodes sind für „Meister“ Prod-„Kubes“ reserviert: 16 GB RAM, 12 CPU-Threads.

Für die Produktion ziehen wir es vor, „nacktes Metall“ zu verwenden und vermeiden unnötige Schichten wie OpenStack: wir brauchen keine „lautstarken Nachbarn“ und CPU Steal Time. Und die Komplexität der Verwaltung steigt nahezu doppelt, wenn es sich um In-House OpenStack handelt.

Für die CI/CD von «Kubovye» und anderen Infrastrukturkomponenten verwenden wir einen separaten GIT-Server, Helm 3 (wir sind ziemlich schmerzhaft von Helm 2 umgestiegen, sind aber sehr erfreut über die Option atomic), Jenkins, Ansible und Docker. Wir lieben Feature-Branches und das Deployment in verschiedene Umgebungen aus einem einzigen Repository.

Fazit

Kubernetes bei DomClick: wie man ruhig schlafen kann, während man einen Cluster mit 1000 Microservices verwaltet
So sieht der DevOps-Prozess bei der Firma DomClick aus Sicht eines Betriebstechnikers allgemein aus. Der Artikel ist weniger technisch geworden, als ich erwartet hatte: Daher, folgen Sie den Neuigkeiten von DomClick auf Habr: Es wird mehr „hardcore“ Artikel über Kubernetes und nicht nur das geben.

Quelle: habr.com

60GB SSD 8Gb DDR4