Ansible, Terraform, Docker, Consul, Nomad in den Wolken (Alexey Vakhov, Uchi.ru)

Dieser Artikel ist eine Abschrift des Videoberichts von Alexei Vakhov aus Uchi.ru "Clouds in the Clouds"


Uchi.ru - eine Online-Plattform für die Schulbildung, mehr als 2 Millionen Schüler, wir lösen regelmäßig interaktive Klassen. Alle unsere Projekte werden vollständig in öffentlichen Clouds gehostet. 100% der Anwendungen werden in Containern ausgeführt, angefangen bei den kleinsten für den internen Gebrauch bis hin zu großen Produktionen für 1-k-Anfragen pro Sekunde. Zufällig haben wir 15 isolierte Docker-Cluster (nicht Kubernetes, sic!) In fünf Cloud-Anbietern. Eintausendfünfhundert Benutzeranwendungen, deren Anzahl ständig wächst.


Ich werde ganz bestimmte Dinge sagen: Wie wir auf Container umgestiegen sind, wie wir die Infrastruktur verwaltet haben, welche Probleme wir hatten, was funktionierte und was nicht.


Während des Berichts werden wir diskutieren:


  • Motivation der Technologieauswahl und Business-Features
  • Tools: Ansible, Terraform, Docker, Github Flow, Konsul, Nomad, Prometheus, Shaman - Web-Interface für Nomad.
  • Verwenden der Clusterföderation zum Verwalten der verteilten Infrastruktur
  • NoOps-Rollouts, Testumgebungen, Anwendungsdiagramme (Entwickler nehmen fast alle Änderungen selbst vor)
  • Unterhaltsame Geschichten aus der Praxis


Wen kümmert's, frage ich unter der Katze.


Ich heiße Alexey Vakhov. Ich arbeite als technischer Direktor in der Firma Uchi.ru. Wir werden in öffentlichen Clouds gehostet. Wir verwenden Terraform, Ansible aktiv. Seitdem haben wir komplett auf Docker umgestellt. Sehr zufrieden Wie zufrieden, wie zufrieden wir sind, werde ich erzählen.



Firma Uchi.ru beschäftigt sich mit der Herstellung von Produkten für die Schulbildung. Wir haben eine zentrale Plattform, auf der Kinder interaktive Aufgaben zu verschiedenen Themen in Russland, in Brasilien und in den USA lösen. Wir veranstalten Online-Wettbewerbe, Wettbewerbe, Vereine, Camps. Jedes Jahr wächst diese Aktivität.



Aus technischer Sicht ist dies der klassische Web-Stack (Ruby, Python, NodeJS, Nginx, Redis, ELK, PostgreSQL). Das Hauptmerkmal, dass viele Anwendungen. Anwendungen werden weltweit gehostet. Jeden Tag gibt es Rollouts in der Produktion.


Das zweite Merkmal ist, dass sich unsere Schemata sehr oft ändern. Bitten Sie um eine neue Anwendung, stoppen Sie die alte und fügen Sie cron für Hintergrundjobs hinzu. Alle 2 Wochen gibt es eine neue Olympiade - dies ist eine neue Anwendung. All dies muss begleitet, überwacht und gesichert werden. Daher ist die Umgebung superdynamisch. Dynamik ist unsere Hauptschwierigkeit.



Unsere Arbeitseinheit ist ein Spielplatz. In Bezug auf Cloud-Anbieter ist dies Project. Unsere Website ist eine vollständig isolierte Einheit mit API und privatem Subnetz. Wenn wir in das Land einreisen, suchen wir nach lokalen Cloud-Anbietern. Nicht überall ist Google und Amazon. Manchmal gibt es keine API für den Cloud-Anbieter. Außerhalb veröffentlichen wir VPN und HTTP, HTTPS auf Balancer. Alle anderen Dienste kommunizieren innerhalb der Cloud.



Unter jeder Site haben wir unser eigenes Ansible-Repository erstellt. Im Repository befinden sich hosts.yml, Playbook, Rollen und 3 geheime Ordner, über die ich weiter sprechen werde. Dies ist eine Terraform, Bereitstellung, Routing. Wir sind Fans der Standardisierung. Unser Repository sollte immer "site ansible-name" heißen. Wir standardisieren jeden Dateinamen und die interne Struktur. Dies ist sehr wichtig für die weitere Automatisierung.



Terraform vor anderthalb Jahren eingerichtet, also benutzen wir es. Terraform ohne Module, ohne Dateistruktur (flache Struktur wird verwendet). Terraform-Dateistruktur: 1 Server - 1 Datei, Netzwerkkonfiguration und andere Einstellungen. Mit terraform beschreiben wir Server, Festplatten, Domänen, S3-Buckets, Netzwerke usw. Terraform bereitet das Eisen vollständig vor.



Terraform erstellt einen Server und dann rollt diese Server von ansibl. Da wir überall die gleiche Version des Betriebssystems verwenden, haben wir alle die Rollen von Grund auf neu geschrieben. Zugelassene Rollen für alle Betriebssysteme, die nirgendwo funktionieren, werden normalerweise im Internet veröffentlicht. Wir nahmen alle Ansible-Rollen an und ließen nur das zurück, was wir brauchen. Standardisierte Ansible-Rollen. Wir haben 6 grundlegende Spielbücher. Beim Starten von Ansible wird eine Standardliste der Software installiert: OpenVPN, PostgreSQL, Nginx, Docker. Kubernetes verwenden wir nicht.



Wir verwenden Consul + Nomad. Dies sind sehr einfache Programme. Führen Sie auf jedem Server 2 in Golang geschriebene Programme aus. Consul ist für die Service Discovery, die Statusprüfung und die Speicherung der Schlüsselwerte verantwortlich. Nomad ist für die Planung und den Rollout verantwortlich. Nomad startet Container, bietet Rollouts an, einschließlich Rollup-Update für die Gesundheitsprüfung, ermöglicht das Ausführen von Sidecar-Containern. Cluster ist einfach zu erweitern oder umgekehrt. Nomad unterstützt verteiltes Cron.



Nachdem wir die Site betreten haben, führt Ansible ein Playbook aus, das sich im Bereitstellungsverzeichnis befindet. Ein Playbook in diesem Verzeichnis ist für die Installation der Software im Docker-Cluster verantwortlich, die von Administratoren verwendet wird. Installierte Prometheus, Grafana und geheime Software-Schamane.


Shaman ist ein Web-Dashboard für Nomaden. Nomad ist ein Low-Level, und ich möchte es Entwicklern nicht wirklich erlauben. In Shaman sehen wir eine Liste von Anwendungen. Entwickler geben eine Schaltfläche für die Anwendungsbereitstellung aus. Entwickler können Konfigurationen ändern: Hinzufügen von Containern, Umgebungsvariablen, Starten von Diensten.



Die letzte Komponente der Site ist das Routing. Das Routing wird in unserem K / V-Lager des Konsuls gespeichert, das heißt, es gibt eine Menge zwischen Upstream, Service, URL und so weiter. Bei jedem Balancer dreht sich die Consul-Vorlage, wodurch die Nginx-Konfiguration generiert und neu geladen wird. Sehr zuverlässig, wir hatten nie ein Problem damit. Der Chip eines solchen Schemas ist, dass der Verkehr den Standard-Nginx akzeptiert und Sie immer sehen können, welche Config erzeugt wurde, und wie der Standard-Nginx arbeitet.



Somit besteht jeder Standort aus 5 Schichten. Mit der Hilfe von terraform richten wir die Hardware ein. Ansible führen wir die Grundeinrichtung der Server durch, richten einen Docker-Cluster ein. Bereitstellungsrollen-Systemsoftware. Das Routing leitet den Verkehr innerhalb der Site. Anwendungen enthält Benutzeranwendungen und Administratoranwendungen.


Wir haben diese Layer seit geraumer Zeit debuggt, damit sie so identisch wie möglich sind. Provision Routing stimmt zu 100% zwischen den Standorten überein. Für Entwickler ist daher jede Plattform genau gleich.


Wenn IT-Experten von Projekt zu Projekt wechseln, landen sie in einer völlig typischen Umgebung. In Ansible konnten wir keine identischen Firewall- und VPN-Einstellungen für verschiedene Cloud-Anbieter vornehmen. Mit dem Netzwerk arbeiten alle Cloud-Anbieter unterschiedlich. Terraform unterscheidet sich, da es spezifische Konstruktionen für jeden Cloud-Anbieter enthält.



Wir haben 14 Produktionsstätten. Es stellt sich die Frage: wie man mit ihnen umgeht? Wir haben die 15. Masterplattform gemacht, in die wir nur Admins einlassen. Es funktioniert nach dem Verbandsschema.


Die Idee wurde von prometheus übernommen. In prometheus gibt es ein Regime, wenn wir an jedem Standort prometheus installieren. Prometheus veröffentlichen wir außerhalb der HTTPS-Basisauthentifizierung. Prometheus-Meister sammelt nur die erforderlichen Metriken, die entfernt wurden. Dadurch ist es möglich, Anwendungsmetriken in verschiedenen Clouds zu vergleichen, um die am häufigsten heruntergeladenen oder entladenen Anwendungen zu finden. Die zentrale Benachrichtigung (Alerting) durchläuft den Prometheus-Master für Admins. Entwickler erhalten Warnungen von lokalen Prometheus.



Der Schamane ist auf dieselbe Weise konfiguriert. Administratoren können die Bereitstellung über die Hauptwebsite durchführen und auf einer beliebigen Site über eine einzige Schnittstelle konfigurieren. Eine ausreichend große Klasse von Aufgaben wird gelöst, ohne diese Master-Site zu verlassen.



Ich erzähle Ihnen, wie wir zu Docker gewechselt sind. Dieser Prozess ist sehr langsam. Wir sind um 10 Monate umgezogen. Im Sommer 2017 hatten wir 0 Produktionscontainer. Im April 2018 haben wir unsere neueste Anwendung in der Produktion dokumentiert und ausgerollt.



Wir sind aus der Welt des Rubins auf Schienen. Früher gab es 99% der Ruby on Rails-Anwendungen. Rails rollt durch Capistrano. Technisch funktioniert Capistrano folgendermaßen: Der Entwickler führt cap deploy ein, capistrano erfasst alle Anwendungsserver über ssh, ruft die neueste Version des Codes ab, sammelt Ressourcen und migriert die Datenbank. Capistrano stellt eine Verknüpfung zu der neuen Version des Codes her und sendet ein USR2-Signal an die Webanwendung. Bei diesem Signal empfängt der Webserver einen neuen Code.



Der letzte Schritt im Docker wird nicht so gemacht. Im Andockfenster müssen Sie den alten Container anhalten, den neuen Container anheben. Dann stellt sich die Frage: Wie wechselt man den Verkehr? In der bewölkten Welt ist hierfür die Service Discovery verantwortlich.



Daher haben wir jedem Standort einen Konsul hinzugefügt. Konsul wurde hinzugefügt, weil sie Terraform verwendeten. Wir haben alle Nginx-Konfigurationen in die Konsul-Vorlage eingepackt. Formal das Gleiche, aber wir waren bereits bereit, den Verkehr innerhalb der Standorte dynamisch zu steuern.



Als Nächstes haben wir ein Rubin-Skript geschrieben, das ein Bild auf einem der Server sammelte, es in die Registrierung einlegte, dann in ssh zu jedem Server ging, neue aufnahm, die alten Container anhielt und beim Konsul registrierte. Die Entwickler führten auch weiterhin Cap-Implementierungen ein, aber die Dienste liefen bereits im Docker.


Ich erinnere mich, dass es zwei Versionen des Skripts gab, die zweite erwies sich als ziemlich fortgeschritten, es gab ein laufendes Update, als eine kleine Anzahl von Containern stoppte, neue Container angehoben wurden und die Konsul-Helfchieks warteten.



Dann erkannten sie, dass dies eine Sackgasse ist. Das Skript wurde auf 600 Zeilen erweitert. Der nächste Schritt ist die manuelle Planung, wir haben Nomad ersetzt. Versteckt sich vor den Entwicklerdetails der Arbeit. Das heißt, sie hießen immer noch cap deploy, aber innen war eine völlig andere Technologie.



Am Ende haben wir die Bereitstellung auf die Benutzeroberfläche verlagert und den Zugriff auf die Server weggenommen.


Im Prinzip war ein solcher Übergang sicherlich lang, aber wir haben ein Problem vermieden, das ich einige Male getroffen habe.


Es gibt eine Art veraltetes Stack, System oder ähnliches. Khachinnaya schon gerade in Lumpen. Die Entwicklung einer neuen Version beginnt. Nach ein paar Monaten oder einigen Jahren, je nach Unternehmensgröße, wurde in der neuen Version weniger als die Hälfte der erforderlichen Funktionalität implementiert, und die alte Version stieß noch immer in der Vergangenheit. Und das Neue wurde auch sehr erbe. Und es ist Zeit, eine neue, dritte Version von Grund auf zu starten. Im Allgemeinen ist dies ein endloser Prozess.


Daher verschieben wir immer den gesamten Stapel. In kleinen Schritten krumm, mit Krücken, aber ganz. Wir können beispielsweise die Docker-Engine nicht an einem Standort aktualisieren. Es ist notwendig, überall zu aktualisieren, da ein Wunsch besteht.



Ausrollen Alle Dockeranweisungen rollen 10 Nginx-Container oder 10 Redis-Container zum Docker aus. Dies ist ein schlechtes Beispiel, da die Bilder bereits gesammelt wurden und die Bilder hell sind. Wir haben unsere Schienenanwendungen in Docker gepackt. Die Größe der Docker-Images betrug 2-3 Gigabyte. Sie rollen nicht so schnell aus.



Das zweite Problem kam aus dem Hipster Web. Hipster Web ist immer Github Flow. Im Jahr 2011 gab es einen Meilenstein, den Github Flow regelt, sodass die gesamte Bahn rollt. Wie sieht es aus? Die Hauptbranche ist immer Produktion. Beim Hinzufügen einer neuen Funktion erstellen wir eine Verzweigung. Beim Zusammenführen führen wir eine Code-Überprüfung durch, führen Tests durch und verbessern die Staging-Umgebung. Geschäft sieht Inszenierungsumgebung aus. Wenn alles erfolgreich ist, wird der Zweig zum Master X zusammengeführt und in der Produktion ausgeführt.


Es hat perfekt auf Capistrano funktioniert, weil es dafür geschaffen wurde. Docker verkauft uns immer Pipeline. Gesammelter Behälter Der Behälter kann an den Entwickler oder Tester übergeben und in die Produktion überführt werden. Aber im Moment der Verschmelzung im Mastercode ist das anders. Alle Docker-Images, die vom Feature-Zweig erfasst wurden, werden nicht vom Master erfasst.



Wie sind wir fertig Wir sammeln ein Bild und legen es in die lokale Docker-Registry. Danach erledigen wir den Rest der Operationen: Migrationen in der Produktion.



Um dieses Bild schnell zusammenzustellen, verwenden wir Docker-in-Docker. Im Internet schreibt jeder, dass dies ein Anti-Muster ist, es kreshitsya. Wir hatten nichts davon. Wie viele arbeiteten schon mit ihm, hatte nie Probleme. Wir leiten das Verzeichnis / var / lib / docker über den beständigen Datenträger an den Hauptserver weiter. Alle Zwischenbilder befinden sich auf dem Hauptserver. Erstellen Sie innerhalb weniger Minuten ein neues Bild.



Für jede Anwendung erstellen wir eine lokale interne Docker-Registrierung und unser eigenes Build-Volume. Weil das Andockfenster alle Schichten auf der Festplatte speichert und schwer zu reinigen ist. Nun kennen wir die Festplattenauslastung jeder lokalen Docker-Registry. Wir wissen, wie viel Datenträger benötigt wird. Sie können Benachrichtigungen über eine zentrale Grafana erhalten und bereinigen. Während wir ihre Hände reinigen. Aber wir werden es automatisieren.



Noch eine Sache. Docker-Bild gesammelt Jetzt muss dieses Image auf Servern erweitert werden. Wenn Sie ein großes Docker-Image kopieren, wird das Netzwerk nicht unterstützt. In der Cloud haben wir 1 Gbit / s. Ein globales Plug-In tritt in der Cloud auf. Jetzt stellen wir ein Docker-Image auf 4 schweren Produktionsservern bereit. Die Grafik zeigt, dass die Festplatte auf einem Server-Pack gearbeitet hat. Dann wird das zweite Serverpaket bereitgestellt. Unten ist der Recyclingkanal zu sehen. Ungefähr 1 Gbit / s ziehen wir fast aus. Mehr wird dort nicht besonders beschleunigt.



Meine Lieblingsproduktion ist Südafrika. Es gibt ein sehr teures und langsames Bügeleisen. Viermal so teuer wie in Russland. Es gibt sehr schlechtes Internet. Internet-Modem-Ebene, aber nicht fehlerhaft. Dort rollen wir innerhalb von 40 Minuten Anwendungen aus und berücksichtigen dabei Tyunig-Caches und Timeout-Einstellungen.



Das letzte Problem, das mich beunruhigte, bevor der Hafenarbeiter Kontakt aufnahm, war die Ladung. In der Tat ist die Last die gleiche wie ohne Docker mit identischem Bügeleisen. Die einzige Nuance, die wir hatten, war nur ein Punkt. Wenn von der Docker-Engine Protokolle über den integrierten fluentd-Treiber abgerufen werden, beginnt der interne Puffer bei einer Last von etwa 1000 U / s zu flüchten und die Anforderungen werden langsamer. Wir haben in Sidecar-Containern Abholzen durchgeführt. In Nomad wird dies als Protokollversender bezeichnet. Neben dem großen Container der Anwendung befindet sich ein kleiner Container. Die einzige Aufgabe für ihn, Protokolle zu erstellen und an ein zentrales Repository zu senden.



Was waren die Probleme / Lösungen / Herausforderungen? Ich habe versucht zu analysieren, was die Aufgabe war. Die Merkmale unserer Probleme sind:


  • viele unabhängige Anwendungen
  • ständige Änderungen an der Infrastrukturkarte
  • Github-Fluss und große Docker-Bilder


Unsere Lösungen


  • Föderation von Dockerclustern. In Sachen Umgang schwer. Aber Docker ist gut in Bezug auf die Einführung von Business-Funktionalität in der Produktion. Wir arbeiten mit personenbezogenen Daten und sind in jedem Land zertifiziert. In einem isolierten Bereich ist eine solche Zertifizierung leicht zu bestehen. Bei der Zertifizierung stellen sich alle Fragen: Wo werden Sie gehostet, wie ist Ihr Cloud-Anbieter, wo speichern Sie persönliche Daten, wo sichern Sie sich an, wer Zugriff auf die Daten hat. Wenn alles isoliert ist, ist der Kreis der Verdächtigen viel einfacher zu beschreiben und zu folgen.
  • Orchestrierung Es ist klar, dass kubernetes. Er ist überall. Ich möchte jedoch sagen, dass Consul + Nomad eine ziemlich produktive Lösung ist.
  • Erstellen Sie Bilder. Schnelles Sammeln von Bildern in Docker-in-Docker.
  • Bei Verwendung des Docker ist es auch möglich, eine Last von 1000 Rps zu halten.

Entwicklungsrichtungsvektor


Nun ist eines der größten Probleme die nicht synchronisierten Softwareversionen auf den Websites. Zuvor haben wir den Server von Hand eingerichtet. Dann wurden wir Devops-Ingenieure. Konfigurieren Sie nun den Server mit ansible. Jetzt haben wir vollständige Vereinheitlichung, Standardisierung. Führen Sie das übliche Denken in den Kopf ein. Wir können PostgreSQL-Hände auf dem Server nicht reparieren. Wenn Sie eine Feinabstimmung auf genau einem Server benötigen, überlegen wir, wie Sie diese Einstellung überall erweitern können. Wenn dies nicht standardisiert ist, werden Zoo-Einstellungen festgelegt.


Ich freue mich sehr und freue mich, dass wir eine wirklich sehr angenehme Infrastruktur kostenlos aus der Box bekommen.



Sie können mich auf Facebook hinzufügen. Wenn wir etwas Gutes Neues tun, werde ich darüber schreiben.


Fragen:


Was ist der Vorteil von Consul Template gegenüber Ansible Template zum Beispiel für das Setzen von Firewall-Regeln und anderen Dingen?


Antwort: Jetzt haben wir Datenverkehr von externen Balancer direkt zu den Containern. Es gibt keine Zwischenschicht. Dort wird eine Config erstellt, die die IP-Adressen und Ports des Clusters weiterleitet. Wir haben auch alle Abgleicheinstellungen in K / V in Consul. Wir haben die Idee, den Routern über eine sichere Schnittstelle Routing-Einstellungen zu geben, damit sie nichts kaputt machen.


Frage: Zur Homogenität aller Standorte. Gibt es wirklich keine Anfragen von Unternehmen oder von Entwicklern, die auf dieser Site etwas anderes als Standard implementieren müssen? Zum Beispiel Tarantool mit Kassandra.


Antwort: Es passiert, aber es ist eine sehr große Rarität. Dadurch erkennen wir ein internes separates Artefakt. Es gibt ein solches Problem, aber es kommt selten vor.


Frage: Die Lösung des Zustellungsproblems besteht in der Verwendung einer privaten Docker-Registrierung an jedem Standort. Von dort können Sie schnell Docker-Images abrufen.


Antwort: Trotzdem bleibt die Bereitstellung im Netzwerk, da wir das Docker-Image auf den 15 Servern gleichzeitig zerlegen. Wir laufen ins Netz. Innerhalb des Netzwerks 1 Gbit / s.


F: Stehen so viele Docker-Container auf demselben Technologie-Stack?


Antwort: Ruby, Python, NodeJS.


Frage: Wie oft testen oder prüfen Sie Ihre Docker-Images auf Updates? Wie lösen Sie Update-Probleme, zum Beispiel wenn glibc, openssl in allen Dockern behoben werden muss?


Antwort: Wenn Sie einen solchen Fehler oder eine solche Schwachstelle finden, setzen wir uns eine Woche lang hin und beheben sie. Wenn Sie ein Rollout durchführen müssen, können wir die gesamte Cloud (alle Anwendungen) von Grund auf durch den Verbund ausrollen. Wir können alle grünen Schaltflächen für die Anwendungsbereitstellung durchklicken und zum Tee trinken gehen.


Frage: Werden Sie Ihren Schamanen in Open Source freigeben?


Antwort: Andrew hier (zeigt auf eine Person aus dem Publikum) verspricht uns, im Herbst einen Schamanen auszulegen. Aber dort müssen Sie die Unterstützung für kubernetes hinzufügen. Opensource sollte immer besser sein.


Jetzt auch beliebt: