In den Jahren des Bestehens von Pinterest haben 300 Millionen Nutzer des Dienstes mehr als 200 Milliarden Pins auf mehr als 4 Milliarden Boards erstellt. Um dieser Armee von Benutzern und einer umfangreichen Inhaltsbasis zu dienen, hat das Portal Tausende von Diensten entwickelt, die von Mikrodiensten reichen, die von mehreren CPUs verarbeitet werden können, bis hin zu riesigen Monolithen, die sich auf einer ganzen Flotte virtueller Maschinen drehen. Und dann kam der Moment, in dem die Augen des Unternehmens auf k8s fielen. Wie sah der "Würfel" für "Interesse" aus? Dies erfahren Sie in unserer Übersetzung des neuesten Pinterest-Blogposts .
Also Hunderte Millionen Benutzer und Hunderte Milliarden Pins. Um dieser Armee von Benutzern und einer umfangreichen Inhaltsbasis zu dienen, haben wir Tausende von Diensten entwickelt, die von Mikrodiensten reichen, die von mehreren CPUs verwaltet werden können, bis zu riesigen Monolithen, die sich auf einer ganzen Flotte virtueller Maschinen drehen. Darüber hinaus verfügen wir über eine Vielzahl von Frameworks, für die möglicherweise auch CPU-Ressourcen, Speicher oder Zugriff auf E / A erforderlich sind.
Zur Unterstützung dieses Werkzeugzoos steht das Entwicklungsteam vor einer Reihe von Herausforderungen:
- Ingenieure haben keine einheitliche Möglichkeit, eine Arbeitsumgebung auszuführen. Staatenlose Dienste, Stateful Services und Projekte, die sich in der aktiven Entwicklung befinden, basieren auf völlig unterschiedlichen Technologiepaketen. Dies führte zur Schaffung eines vollständigen Schulungskurses für Ingenieure und erschwert die Arbeit unseres Infrastrukturteams erheblich.
- Entwickler mit einer eigenen Flotte virtueller Maschinen stellen eine enorme Belastung für interne Administratoren dar. Infolgedessen dauern einfache Vorgänge wie das Aktualisieren des Betriebssystems oder des AMI Wochen und Monate. Dies führt zu einer Erhöhung der Arbeitsbelastung in scheinbar absolut alltäglichen Situationen.
- Schwierigkeiten bei der Erstellung globaler Infrastrukturmanagement-Tools zusätzlich zu vorhandenen Lösungen. Die Situation wird durch die Tatsache kompliziert, dass es nicht einfach ist, die Besitzer virtueller Maschinen zu finden. Das heißt, wir wissen nicht, ob es sicher ist, diese Kapazitäten für die Arbeit in anderen Teilen unserer Infrastruktur zu extrahieren.
Container-Orchestrierungssysteme sind eine Möglichkeit, das Workload-Management zu vereinheitlichen. Sie eröffnen Ihnen die Möglichkeit, die Entwicklungsgeschwindigkeit zu erhöhen und das Infrastrukturmanagement zu vereinfachen, da alle am Projekt beteiligten Ressourcen von einem zentralen System verwaltet werden.
Abbildung 1: Infrastrukturprioritäten (Zuverlässigkeit, Entwicklerproduktivität und Effizienz).Das Team der Cloud Management Platform auf Pinterest hat K8s 2017 getroffen. Bis zum ersten Halbjahr 2017 haben wir die meisten unserer Produktionsanlagen dokumentiert, einschließlich der API und aller unserer Webserver. Danach haben wir die verschiedenen Systeme der Orchestrierung von Containerlösungen sorgfältig bewertet, Cluster erstellt und mit ihnen gearbeitet. Bis Ende 2017 haben wir uns für Kubernetes entschieden. Es war flexibel genug und wurde in der Entwicklergemeinschaft weitgehend unterstützt.
Bisher haben wir unsere eigenen Kops-basierten Cluster-Bootstrap-Tools erstellt und auf vorhandene Infrastrukturkomponenten wie Netzwerk, Sicherheit, Metriken, Protokollierung, Identitätsmanagement und Datenverkehr von Kubernetes migriert. Wir haben auch ein Workload-Modellierungssystem für unsere Ressource implementiert, dessen Komplexität den Entwicklern verborgen bleibt. Jetzt konzentrieren wir uns darauf, die Stabilität des Clusters, seine Skalierung und die Verbindung neuer Clients sicherzustellen.
Kubernetes: Pinterest's Way
Der Einstieg in Kubernetes auf Pinterest als Plattform, die unsere Ingenieure lieben werden, ist überwältigend.
Als großes Unternehmen haben wir stark in Infrastruktur-Tools investiert. Beispiele hierfür sind Sicherheitstools, die Zertifikate verarbeiten und Schlüssel verteilen, Verkehrssteuerungskomponenten, Service Discovery-Systeme, Sichtbarkeit und das Senden von Protokollen und Metriken. All dies wurde aus einem Grund gesammelt: Wir gingen den normalen Weg des Versuchs und Irrtums und wollten deshalb all diese Wirtschaft in die neue Infrastruktur auf Kubernetes integrieren, anstatt das alte Fahrrad auf einer neuen Plattform neu zu erfinden. Dieser Ansatz vereinfachte im Allgemeinen die Migration, da die gesamte Anwendungsunterstützung bereits vorhanden ist und nicht von Grund auf neu erstellt werden muss.
Andererseits reichen die Lastprognosemodelle in Kubernetes selbst (z. B. Bereitstellung, Jobs und Daemon-Kits) für unser Projekt nicht aus. Diese Usability-Probleme sind ein großes Hindernis für den Wechsel zu Kubernetes. Wir haben beispielsweise gehört, dass sich Serviceentwickler über eine fehlende oder falsche Anmeldeeinstellung beschwert haben. Wir haben auch festgestellt, dass Template-Engines nicht ordnungsgemäß verwendet wurden, als Hunderte von Kopien mit derselben Spezifikation und Aufgabe erstellt wurden, was zu Albtraumproblemen beim Debuggen führte.
Es war auch sehr schwierig, verschiedene Versionen im selben Cluster zu unterstützen. Stellen Sie sich die Komplexität des Kundensupports vor, wenn Sie sofort in vielen Versionen derselben Laufzeit mit all ihren Problemen, Fehlern und Updates arbeiten müssen.
Benutzerdefinierte Ressourcen und Controller von Pinterest
Um die Bereitstellung von Kubernetes für unsere Ingenieure zu vereinfachen sowie die Infrastruktur zu vereinfachen und zu beschleunigen, haben wir unsere eigenen benutzerdefinierten Ressourcendefinitionen (CRD) entwickelt.
CRDs bieten die folgenden Funktionen:
- Kombinieren Sie verschiedene native Kubernetes-Ressourcen, damit sie als einzelne Last funktionieren. Die PinterestService-Ressource enthält beispielsweise eine Bereitstellung, einen Anmeldedienst und eine Konfigurationszuordnung. Dadurch können sich Entwickler keine Gedanken über das Einrichten von DNS machen.
- Implementieren Sie die erforderliche Anwendungsunterstützung. Der Benutzer sollte sich nur auf die Containerspezifikation gemäß seiner Geschäftslogik konzentrieren, während der CRD-Controller alle erforderlichen Init-Container, Umgebungsvariablen und Pod-Spezifikationen implementiert. Dies bietet Entwicklern ein grundlegend anderes Maß an Komfort.
- CRD-Controller verwalten auch den Lebenszyklus ihrer eigenen Ressourcen und erhöhen die Verfügbarkeit von Debugging. Dies umfasst die Vereinbarung der gewünschten und tatsächlichen Spezifikationen, die Aktualisierung des CRD-Status sowie die Pflege von Ereignisprotokollen und mehr. Ohne CRD wären Entwickler gezwungen, eine große Anzahl von Ressourcen zu verwalten, was die Wahrscheinlichkeit eines Fehlers nur erhöhen würde.
Hier ist ein Beispiel für PinterestService und die interne Ressource, die von unserem Controller gesteuert wird:

Wie Sie oben sehen können, müssen wir zur Unterstützung eines benutzerdefinierten Containers einen Initialisierungscontainer und mehrere Add-Ons integrieren, um Sicherheit, Sichtbarkeit und Arbeit mit dem Netzwerkverkehr zu gewährleisten. Darüber hinaus haben wir Konfigurationszuordnungsvorlagen erstellt und die Unterstützung für PVC-Vorlagen für Stapeljobs implementiert sowie eine Vielzahl von Umgebungsvariablen verfolgt, um die Identifizierung, den Ressourcenverbrauch und die Speicherbereinigung zu verfolgen.
Es ist kaum vorstellbar, dass Entwickler diese Konfigurationsdateien ohne CRD-Unterstützung manuell schreiben möchten, ganz zu schweigen von der weiteren Unterstützung und dem Debuggen von Konfigurationen.
Bereitstellung von Workflow-Anwendungen

Die obige Abbildung zeigt, wie eine benutzerdefinierte Pinterest-Ressource in einem Kubernetes-Cluster bereitgestellt wird:
- Entwickler interagieren mit unserem Kubernetes-Cluster über die CLI und die Benutzeroberfläche.
- CLI / UI-Tools extrahieren die YAML-Dateien für die Workflowkonfiguration und andere Assembly-Eigenschaften (gleiche Versionskennung) aus Artifactory und senden sie dann an den Job Submission Service. Dieser Schritt stellt sicher, dass nur Produktionsversionen an den Cluster geliefert werden.
- JSS ist das Tor zu verschiedenen Plattformen, einschließlich Kubernetes. Hier findet die Benutzerauthentifizierung, Kontingentausstellung und teilweise Überprüfung unserer CRD-Konfiguration statt.
- Nach Überprüfung der CRD auf der JSS-Seite werden die Informationen an die k8s-Plattform-API gesendet.
- Unser CRD-Controller überwacht Ereignisse auf allen Benutzerressourcen. Es konvertiert CR in native k8s-Ressourcen, fügt die erforderlichen Module hinzu, legt die entsprechenden Umgebungsvariablen fest und führt andere Hilfsarbeiten aus, wodurch Containerbenutzeranwendungen eine ausreichende Infrastrukturunterstützung garantiert werden.
- Anschließend überträgt der CRD-Controller die empfangenen Daten an die Kubernetes-API, damit sie vom Scheduler verarbeitet und in Betrieb genommen werden.
Hinweis : Diese Workflow-Bereitstellung vor der Veröffentlichung wurde für die ersten Benutzer der neuen k8s-Plattform erstellt. Wir sind gerade dabei, diesen Prozess abzuschließen, um ihn vollständig in unser neues CI / CD zu integrieren. Dies bedeutet, dass wir nicht alles über Kubernetes erzählen können. Wir freuen uns darauf, unsere Erfahrungen zu teilen und dem Team in unserem nächsten Blog-Beitrag „Aufbau einer CI / CD-Plattform für Pinterest“ über diese Fortschritte zu berichten.
Arten von speziellen Ressourcen
Basierend auf den spezifischen Anforderungen von Pinterest haben wir die folgenden CRDs entwickelt, die für eine Vielzahl von Workflows geeignet sind:
- PinterestService ist ein langjähriger zustandsloser Dienst. Viele unserer Hauptsysteme basieren auf einer Reihe solcher Dienste.
- PinterestJobSet modelliert Batch-Jobs mit vollem Zyklus. Pinterest hat ein gemeinsames Szenario, nach dem mehrere Aufgaben dieselben Container parallel und unabhängig von anderen ähnlichen Prozessen ausführen.
- PinterestCronJob wird häufig in Verbindung mit kleinen periodischen Belastungen verwendet. Dies ist eine native Cron-Shell mit Pinterest-Unterstützungsmechanismen, die für Sicherheit, Datenverkehr, Protokolle und Metriken verantwortlich sind.
- PinterestDaemon enthält die Infrastruktur von Daemon. Diese Familie wächst weiter, da wir unsere Cluster stärker unterstützen.
- PinterestTrainingJob erstreckt sich auf Tensorflow- und Pytorch-Prozesse und bietet den gleichen Grad an Online-Unterstützung wie alle anderen CRDs. Da Pinterest Tensorflow und andere maschinelle Lernsysteme aktiv nutzt, hatten wir einen Grund, eine separate CRD um sie herum zu erstellen.
Wir arbeiten auch an PinterestStatefulSet, das in Kürze für Data Warehouses und andere Stateful-Systeme angepasst wird.
Laufzeitunterstützung
Wenn das Anwendungsmodul in Kubernetes ausgeführt wird, erhält es automatisch ein Zertifikat, um sich selbst zu identifizieren. Dieses Zertifikat wird verwendet, um auf den geheimen Speicher zuzugreifen oder über mTLS mit anderen Diensten zu kommunizieren. In der Zwischenzeit laden der Konfigurator für die Containerinitialisierung und der Daemon alle erforderlichen Abhängigkeiten herunter, bevor die Containeranwendung gestartet wird. Wenn alles fertig ist, registrieren der Beiwagenverkehr und der Daemon die IP-Adresse des Moduls in unserem Zookeeper, damit Kunden sie finden können. All dies funktioniert, da das Netzwerkmodul vor dem Start der Anwendung konfiguriert wurde.
Im Folgenden finden Sie typische Beispiele für die Unterstützung von Laufzeit-Workloads. Für andere Arten von Workloads ist möglicherweise eine etwas andere Unterstützung erforderlich, die jedoch alle als virtuelle Maschinen auf Sidecar-Pod-, Knoten- oder Daemon-Ebene dargestellt werden. Wir stellen sicher, dass all dies im Rahmen der Verwaltungsinfrastruktur bereitgestellt und zwischen den Anwendungen koordiniert wird, was letztendlich die Belastung in Bezug auf technische Arbeit und Kundenunterstützung erheblich reduziert.
Testen und Qualitätssicherung
Wir haben eine End-to-End-Testpipeline auf der vorhandenen Kubernetes-Testinfrastruktur zusammengestellt. Diese Tests gelten für alle unsere Cluster. Unsere Pipeline hat viele Änderungen durchlaufen, bevor sie Teil des Produktclusters wurde.
Zusätzlich zu den Testsystemen verfügen wir über Überwachungs- und Warnsysteme, die den Status der Systemkomponenten, den Ressourcenverbrauch und andere wichtige Indikatoren ständig überwachen und uns nur dann benachrichtigen, wenn ein menschliches Eingreifen erforderlich ist.
Alternativen
Wir haben uns einige Alternativen zu benutzerdefinierten Ressourcen angesehen, z. B. Mutationszugriffscontroller und Vorlagensysteme. Alle sind jedoch mit ernsthaften Schwierigkeiten bei der Arbeit behaftet, weshalb wir uns für den Weg der CRD entschieden haben.
Ein Mutationstoleranz-Controller wurde verwendet, um Sidecars, eine Umgebungsvariable und andere Laufzeitunterstützung einzugeben. Dennoch sah er sich verschiedenen Problemen gegenüber, beispielsweise der Ressourcenbindung und der Verwaltung ihres Lebenszyklus, wenn solche Probleme bei CRD nicht auftreten.
Hinweis: Vorlagensysteme wie Helmdiagramme werden häufig auch zum Ausführen von Anwendungen mit ähnlichen Konfigurationen verwendet. Unsere Produktionsanwendungen sind jedoch zu vielfältig, um sie mit Vorlagen zu verwalten. Während der kontinuierlichen Bereitstellung werden durch die Verwendung von Vorlagen zu viele Fehler generiert.
Zukünftige Arbeit
Jetzt haben wir es mit einer gemischten Belastung aller unserer Cluster zu tun. Um ähnliche Prozesse unterschiedlicher Typen und Größen zu unterstützen, arbeiten wir in folgenden Bereichen:
- Ein Cluster von Clustern verteilt große Anwendungen auf Cluster, um Skalierbarkeit und Stabilität zu gewährleisten.
- Gewährleistung der Stabilität, Skalierbarkeit und Sichtbarkeit des Clusters, um die Verbindung zwischen der Anwendung und ihrem SLA herzustellen.
- Ressourcen- und Kontingentverwaltung, damit Anwendungen nicht miteinander in Konflikt stehen und die Cluster-Skalierung von uns gesteuert wird.
- Neue CI / CD-Plattform zur Unterstützung und Bereitstellung von Anwendungen in Kubernetes.