Enterprise-Restaurant-Computer

Jan 10 2023
vom CFA Enterprise Restaurant Compute Team Das letzte Mal, dass wir öffentlich über unsere Edge Kubernetes-Bereitstellung gesprochen haben, war im Sommer 2018. Seitdem haben wir eine kettenweite Bereitstellung abgeschlossen und sie fast 4 Jahre lang in Produktion betrieben.

vom CFA Enterprise Restaurant Compute Team

Das letzte Mal, dass wir öffentlich über unsere Bereitstellung von Edge Kubernetes gesprochen haben, war im Sommer 2018.

Seitdem haben wir eine kettenweite Implementierung abgeschlossen und betreiben sie fast 4 Jahre lang in Produktion. Jedes Chick-fil-A-Restaurant verfügt über einen Edge Compute-Cluster, auf dem Kubernetes ausgeführt wird. Wir betreiben auch eine groß angelegte Cloud-Infrastruktur, um unsere Restaurantpräsenz zu unterstützen.

Wir haben mehrere unserer Restaurantsysteme integriert, um die Küchenproduktionsprozesse oder das Onboarding mobiler Zahlungsterminals zu unterstützen, die in unserem Drive Thru verwendet werden. Insgesamt sind in unseren Restaurants Zehntausende von Geräten im Einsatz, die aktiv Telemetriedaten von einer Vielzahl von Smart-Equipment-Geräten (Fritteusen, Grills usw.) bereitstellen.

Unser heutiges Ziel ist es, die Leser auf unseren aktuellen Stand zu bringen und zu teilen, was sich in den letzten 4 Jahren geändert hat. Es gibt noch viele aufregende Möglichkeiten für die Plattform am Horizont, aber wir verschieben das auf einen anderen Tag …

Wo wir aufgehört haben

Das Ziel der Restaurant Edge Compute-Plattform war es, in jedem Restaurant eine robuste Plattform zu schaffen, auf der unsere DevOps-Produktteams Anwendungen bereitstellen und verwalten konnten, um Bedienern und Teammitgliedern zu helfen, mit dem ständig wachsenden Geschäft Schritt zu halten, sei es in der Küche, der Lieferkette, oder in der direkten Kundenbetreuung.

Dies war ein ehrgeiziges Projekt und das erste, das in unserer Branche in großem Umfang eingesetzt wurde.

Bei der Recherche nach Tools und Komponenten für die Plattform stellten wir schnell fest, dass vorhandene Angebote auf Cloud- oder Rechenzentrumsbereitstellungen ausgerichtet waren. Die Komponenten wurden nicht für den Betrieb in ressourcenbeschränkten Umgebungen ohne zuverlässige Internetverbindungen oder für die Skalierung auf Tausende von aktiven Kubernetes-Clustern entwickelt. Selbst kommerzielle Tools, die im großen Maßstab funktionierten, hatten keine Lizenzmodelle, die über einige hundert Cluster hinaus funktionierten. Aus diesem Grund haben wir uns entschieden, viele der Komponenten selbst zu bauen und zu hosten.

Von Anfang an war das Ziel, eine auf Standards basierende Plattform aufzubauen und sich an gut verstandene Spezifikationen zu halten und sich an den Best Practices der Branche auszurichten.

Wie zu erwarten war, hielt sich unsere erste Veröffentlichung an unsere allgemeinen Designziele, war aber an den Rändern etwas rau (Wortspiel beabsichtigt). Wir haben einen MVP-Ansatz verwendet und Dinge im Feld eingesetzt, damit wir mit dem Lernen beginnen konnten.

Damals und heute

Wo haben wir angefangen und was hat sich im Laufe der Zeit verändert? Lassen Sie uns eintauchen.

Hardware

Wir haben uns entschieden, Intel NUCs für Verbraucher zu standardisieren. Die Bereitstellung eines Drei-Knoten-Clusters mit diesen NUCs ermöglichte uns ein hohes Maß an Zuverlässigkeit, Kapazität und architektonischer Flexibilität für die HA-Konfiguration in der Zukunft.

Wir haben bisher keine Änderungen an diesem Design vorgenommen und waren sehr zufrieden mit dieser Hardwareentscheidung für Verbraucher, obwohl wir bei unserer geplanten Aktualisierung wahrscheinlich mehr Rechen- und Speicherkapazität pro Knoten hinzufügen werden.

Betriebssystem

Für die erste Version landeten wir bei der Verwendung von Ubuntu als Basisbetriebssystem. Das Design sollte ein sehr einfaches, schnörkelloses Bild verwenden; nur ein paar Call-Home-Skripts, die automatisch beim ersten Start ausgeführt werden, um den Bereitstellungsprozess zu starten und den Knoten im Cluster zu konfigurieren.

Unser Designziel war von Anfang an, den Drop-Shipping von NUCS an Restaurants zu ermöglichen und zu erfordern, dass keine restaurantspezifischen Konfigurationen manuell vorgenommen werden müssen. Mit anderen Worten, die gesamte Bereitstellung erfolgt dynamisch und on-the-fly (aber es sind eine Reihe von Sicherheitsfunktionen eingebaut, die verhindern, dass bösartige Geräte einem Cluster beitreten und/oder mit unseren sicheren Cloud-Diensten kommunizieren).

Edge-Kommandant

Eine Sache, über die wir nie viel geteilt haben, ist ein Dienst namens Edge Commander (EC), der Teil unseres Bootstrapping- und Managementprozesses für Cluster ist.

Jeder Edge-Cluster-Knoten wird mit demselben Image erstellt, das eine Reihe von Festplattenpartitionen und einige raffinierte Tricks mit OverlayFS enthält , die es uns letztendlich ermöglichen, einige Daten langfristig zu speichern (z Möglichkeit, andere Partitionen auf dem Knoten aus der Ferne zu „löschen“, z. B. diejenige, auf der Kubernetes lebt.

Wie funktioniert es? Jeder Knoten meldet sich regelmäßig bei Edge Commander an und nimmt Arbeitsbefehle in Form von „Wischen“ an, wonach der Knoten zu seinem Basis-Image zurückkehrt und dann das neueste „Bootstrap-Skript“ anfordert. Es führt dann dieses Skript aus und tritt dem Restaurant-Cluster wieder bei (oder erstellt einen neuen, wenn alle Knoten gelöscht wurden und noch niemand sonst einen neuen Cluster erstellt hat). Auf diese Weise können wir Geräte aus der Ferne löschen und Kubernetes-Cluster auf Geräten erneut bereitstellen, um auf Produktionsprobleme zu reagieren oder K3s zu aktualisieren.

Dieser Dienst hat überraschend gut funktioniert, da er uns die Möglichkeit gibt, einen Knoten aus der Ferne zu löschen, aber es ist ziemlich beängstigend, da ein Fehler mit der Codebasis oder den Bootstrap-Skripten massive Auswirkungen auf unsere Tausenden von Clustern haben könnte.

Kubernetes

Wir wussten, dass wir Kubernetes standardisieren wollten, um unsere Plattform zu betreiben, und landeten schließlich bei der Open-Source- K3s - Implementierung von Rancher. K3s ist eine abgespeckte, spezifikationskonforme Version von Kubernetes und hat sich als sehr einfach einzurichten und skalierbar zu unterstützen erwiesen. Da wir nicht in der Cloud laufen, brauchen wir viele der Cloud-Service-Features nicht, die Kubernetes zu einem ziemlich großen Projekt machen. Wir versuchen, die Verwendung implementierungsspezifischer Funktionen zu vermeiden, um bei Bedarf in Zukunft ein einfaches Umschalten zu ermöglichen.

Wir sind sehr zufrieden mit dieser Entscheidung und haben keine Pläne, in naher Zukunft etwas zu ändern.

GitOps

Als wir unser erstes Plattform-Release erstellten, gab es keine großartigen Standardlösungen für einen GitOps-Agenten, der am Edge in einer Umgebung mit eingeschränkten Ressourcen ausgeführt werden konnte. Am Ende haben wir unseren eigenen Agenten namens „Vessel“ entwickelt, der ein Git-Repo (ein eindeutiges Repo für jeden Store) abfragt und alle angeforderten Änderungen auf den Cluster anwendet. Es war eine einfache Lösung, die sehr gut funktioniert hat.

Wir hosten auch unsere eigene Open Source GitLab-Instanz in unserem Cloud-K8S-Cluster. Wir hofften, nicht die Last des Hostens unseres eigenen Git-Servers auf uns nehmen zu müssen, aber wir konnten kein kostengünstiges Lizenzmodell für gehostete Lösungen finden, das mit Tausenden von Clients funktioniert, die alle paar Minuten abfragen.

Bereitstellungen

Für GitOps haben wir uns für ein einfaches Modell entschieden, bei dem jedem Standort ein eigenes Git-Repo zugewiesen wird, das wir „Atlas“ nennen. Neue Bereitstellungen in einem Restaurant erfordern lediglich das Zusammenführen der neuen Konfiguration im Master-Branch des Atlas. Bei diesem Ansatz gibt es Kompromisse für die Unternehmensverwaltung, aber er machte Bereitstellungen, die Sichtbarkeit des Bereitstellungsstatus und die Überwachung viel einfacher.

Erstes Release-Design

Hier ist ein einfaches Diagramm, das zeigt, wie unser ursprüngliches Release-Design aussah.

Unterstützung einer kettenweiten Bereitstellung

Eine der größten Herausforderungen, die wir gelöst haben, war die Umwandlung von einem funktionalen MVP in eine skalierbare, unterstützungsfähige Plattform, die von einem relativ kleinen Team gewartet werden konnte. Die Grundlagen der Plattform waren alle vorhanden, aber es gab noch manuelle Schritte, die in den Bereitstellungs- und Supportprozessen erforderlich waren, die angegangen werden mussten.

API-First-Strategie

Die erste Aufgabe bestand darin, alle manuellen Prozesse und Validierungsprüfungsschritte in Restful-APIs einzubetten. Wir haben eine umfassende API-Suite für jeden der Schritte erstellt und dann darauf Orchestrierungsebenen aufgebaut, um mit der Automatisierung der manuellen Prozesse zu beginnen.

Die Erstellung eines umfassenden und gut dokumentierten PostMan-Projekts ermöglichte es uns, die neuen APIs schnell zu nutzen und die Entwicklung einer Support-Team-Web-Benutzeroberfläche zu verzögern.

Wir nutzten OAuth, um einen granularen Zugriff auf die API-Suite bereitzustellen, mit dem wir bestimmte Funktionen einfach sperren konnten, während wir unseren Kunden nicht-invasive Status- und Berichtsendpunkte öffneten, was ein großer Gewinn war.

Engagiertes Rollout-Team

Wie haben wir in relativ kurzer Zeit so viele Geräte in der gesamten Kette eingeführt?

Unser zentrales Entwicklungsteam ist klein und verfügt nicht über die Kapazität, die Plattform (Edge/Cloud-Infrastruktur, Kerndienste, Client-SDK) zu unterstützen, neue Funktionen zu entwickeln und auch den kettenweiten Rollout durchzuführen.

Wir haben die drei NUCs vorab an alle Restaurants der gesamten Restaurantkette geliefert und vor der vollständigen Einführung installiert, sodass nur noch die Konfigurations- und Überprüfungsschritte übrig blieben. Nachdem unsere API-Suite eingerichtet war, stellten wir schnell ein halbtechnisches Support-Team zusammen, das sich mit der Einführung der Plattform, der Überwachung des Status und der Lösung einfacherer Support-Probleme befasste. Wir nutzten Pair-Support, Playbooks und eine Doc-Feedback-Schleife, um das Rollout-Team schnell aufzustocken – innerhalb weniger Wochen war das Team größtenteils autark und erreichte innerhalb weniger Monate eine kettenweite Einführung.

Wir mussten auch eine organisierte Struktur implementieren, um einen außergewöhnlichen Support für die Plattform zu bieten und gleichzeitig neue Fähigkeiten und Skalierungsmöglichkeiten zu entwickeln.

Unser Ziel ist es, dort zu automatisieren, wo es praktisch ist, und die verbleibende Supportarbeit so hoch wie möglich in der Supportkette zu verschieben. Dies entlastet unser technisches Personal, um die Plattform weiter zu erneuern und zu verbessern.

Wir haben dies durch eine Feedback-Schleife zwischen den First-Tier-Support- und Support-DevOps-Teams erreicht. Alle Probleme beginnen durch die erste Ebene. Wenn ein neues oder komplexes Problem auftritt, für dessen Lösung sie nicht gerüstet sind, wird es an das Support-DevOps-Team weitergeleitet. Die beiden Teams arbeiten zusammen, um das Problem zu lösen, während das Tier-1-Team Dokumentation und Playbooks aktualisiert, damit es das nächste ähnliche Vorkommnis bewältigen kann. Eine wöchentliche Support-Retrospektive hilft dabei, den Rückstand des Support-DevOps-Teams für Verbesserungen und Gelegenheiten zur automatischen Behebung zu füttern. Das Support-DevOps-Team beeinflusst auch den Rückstand des neuen Entwicklungsteams, um bei der Priorisierung neuer Tools oder Funktionen zur Verbesserung der Supportfähigkeit zu helfen.

Dieses Unterstützungsmodell ist sehr erfolgreich. Das First-Tier-Support-Team ist in der Lage, die überwiegende Mehrheit der auftretenden Warnungen zu lösen – oft bevor ein Problem in einem Restaurant überhaupt erkannt wird.

Überwachung und Autokorrektur

Mit über 2.500 aktiven K3s-Clustern mussten wir unsere Überwachungsprozesse verbessern, um Probleme mit den Clustern proaktiv zu identifizieren und zu beheben. Es wurde ein facettenreicher Ansatz entwickelt.

Synthetischer Client

Wir haben einen synthetischen Client eingerichtet, der als Container im Cluster ausgeführt wird, um unsere Kernplattformfunktionen zu testen und Probleme zu analysieren (Dienstprobleme, Datenlatenz usw.). Wenn Probleme entdeckt werden, meldet der Client unsere Cloud-Steuerungsebene über eine API, die das Support-Team benachrichtigt und automatisierte Behebungsprozesse auslöst.

Knoten-Herzschläge

Da der Kubernetes-Cluster selbstheilend ist, stellt ein Knotenausfall nicht unbedingt einen Ausfall dar, da Workloads automatisch zwischen anderen aktiven Knoten im Cluster neu verteilt werden.

Um Knotenausfälle zu erkennen, haben wir einfache „Heartbeat-Pods“ auf jedem Knoten im Cluster bereitgestellt. Diese Pods melden regelmäßig den Status (und ein paar Metadaten) an einen API-Endpunkt in der Cloud. Der Endpunkt wendet Logik an, die das Fehlen von Heartbeats verwendet, um eine Warnung an Supportmitarbeiter auszulösen und bei Bedarf automatische Behebungsprozesse zu starten.

Automatische Korrektur

Durch die Nutzung wöchentlicher Support-Retrospektiven entdeckten wir schnell Muster zwischen Fehlern, Validierung und Behebungsschritten. Da alle Support-Tools API-fähig waren, konnten wir auf den APIs Orchestrierungsabläufe aufbauen und die am häufigsten auftretenden Probleme automatisch beheben.

Ein einfaches Prozessbeispiel wäre eine Warnung zu einem ausgefallenen Knoten in einem funktionierenden Cluster. Das Produktionssupportteam a) validiert das Problem durch Aufrufen einer Standortzustands-API, b) ruft eine andere API auf, um den Knoten aus der Ferne neu zu erstellen, c) wartet darauf, dass der Knoten wieder online geht, und d) ruft die Zustands-API erneut auf, um den Knoten zu überprüfen kam zurück und trat dem Cluster erfolgreich bei. Wenn der Node nicht fehlerfrei zurückkam, wiederholten wir den Vorgang normalerweise einige Male und reichten dann schließlich ein Ticket bei unserem Anbieter ein, um den fehlerhaften Node per Hot Swap auszutauschen. Dieser Prozess war relativ einfach zu automatisieren und über die Warninfrastruktur, eine Orchestrierungsebene und die vorhandenen APIs auszulösen.

Das Hinzufügen einiger einfacher Abläufe zur automatischen Fehlerbehebung hat den Supportaufwand für das Team drastisch reduziert.

Neue Fähigkeiten

Während wir die Support-Infrastruktur iterativ verbesserten, entwickelte das Entwicklungsteam weiterhin neue Plattformfunktionen, um Self-Service und einfache Bereitstellung/Support zu fördern.

Bereitstellungs-Orchestrierung

Unser GitOps-Modell war einfach. Wir begannen damit, frühzeitig manuelle Änderungen vorzunehmen, schrieben aber sehr schnell ein minimalistisches Tool namens „Fleet“, mit dem wir eine Cluster-Konfigurationsänderung (Bereitstellung) vornehmen und auf mehrere Restaurants anwenden konnten. Das funktionierte, aber als die Plattform wuchs, brauchten wir eine bessere Möglichkeit für Verbraucher, ihre Bereitstellungen in der gesamten Kette zu orchestrieren und ihre bereitgestellten Versionen sowie Fehler und Erfolge bei der Bereitstellung zu sehen.

In unserer zweiten Iteration haben wir eine neue Deployment Orchestration API erstellt, um Teams bei der effektiven Verwaltung von Workload-Bereitstellungen zu unterstützen. Zusammen mit der API haben wir auf jedem Cluster einen passenden Feedback-Agent bereitgestellt, um Bereitstellungen und Status an die Cloud zu melden.

Wir haben dies auch verwendet, um die Erstellung von selbstverwalteten Canary-Bereitstellungsmustern zusammen mit automatischen kettenweiten Releases zu ermöglichen.

Als Ergebnis dieser Änderungen sind Teams in der Lage, Bereitstellungen fein abzustimmen und ihre Bereitstellungen zu beobachten, was zu einer höheren Zuverlässigkeit der Bereitstellungen führt.

Log-Exfiltration

In unseren frühen Bereitstellungsphasen ermöglichten wir internen DevOps-Produktteams den direkten Zugriff auf den K3s-Cluster des Restaurants, um den Status abzurufen, Protokolle abzurufen usw., wie sie es wünschten, um sie nahezu in Echtzeit zu haben. Wir hatten eine grundlegende Log-Exfiltrationsfunktion, aber Latenzprobleme und Netzwerküberlastungsprobleme in unterdurchschnittlichen Netzwerken machten die Verwendung sehr schwierig.

Da wir den Remote-Zugriff auf unsere Cluster minimieren wollten, gingen wir schnell zu einer zweiten Iteration über, in der wir API-Endpunkte bereitstellten, um die Entwickler vom Cluster zu trennen, aber den Abruf von Protokollen und Status bei Bedarf ermöglichten.

In unserer dritten Iterationsphase (wo wir uns heute befinden) haben wir eine robustere Log-Exfiltrationsfunktion hinzugefügt.

Um diese Funktion bereitzustellen, haben wir ein Open-Source-Projekt namens Vector genutzt , um Protokolle von den Edge-Clustern zu sammeln und an die Cloud weiterzuleiten. Wir haben eine gemeinsame Sammlung von Rechenprotokollen und einen Protokollierungsendpunkt für intelligente Geräte außerhalb des Clusters bereitgestellt, um auch den zentralisierten Protokollversand zu unterstützen.

Vector bietet Funktionen zum Filtern, Speichern und Weiterleiten sowie zum automatisierten Rotieren von Protokollen. Auf der Cloud-Seite richten wir einen weiteren Vector-Dienst ein, um die Protokolle von allen Edge-Instanzen zu sammeln, Regeln anzuwenden und die Protokolle an die verschiedenen Tools weiterzuleiten, die unsere internen Engineering-Teams verwenden (Data Dog, Grafana, CloudWatch usw.).

Dieser zentralisierte Ansatz ermöglichte die Priorisierung (oder Abschaltung) der Protokollierung in Zeiten geringer Bandbreite (z. B. wenn wir von Glasfaser zu einer Backup-LTE-Verbindung wechseln) sowie die Abstrahierung produzierender Clients vom nachgelagerten Protokollziel und seinen Verbrauchern.

Wir haben auch die benutzerdefinierte Funktion hinzugefügt, um die Protokollausgabe für eine begrenzte Zeit zu erhöhen, um die Fehlersuche / das Debugging des Produktionssupports in Echtzeit zu unterstützen.

Metriken und Dashboards

Wir haben auch die Möglichkeit hinzugefügt, Prometheus Remote Write zu nutzen, um Metriken von allen Restaurants zu sammeln und an eine zentral gehostete Grafana-Instanz in der Cloud weiterzuleiten. Jeder K3s-Cluster erfasst Metriken zu Zustand, Knoten und Hauptdienst-Workloads, aber wir bieten auch einen Kerndienst an, mit dem Kundenentwicklungsteams benutzerdefinierte Geschäftsmetriken in unserer Enterprise-Cloud-Instanz veröffentlichen können. Dieses Modell war ein großer Erfolg und hat die Sichtbarkeit der Plattform als Ganzes in unserer gesamten Infrastruktur erheblich verbessert.

Heute stellen wir eine Vielzahl von Grafana-Dashboards auf der Grundlage von Edge-Daten zur Verfügung und fangen gerade an, zusätzliche proaktive Überwachung und Alarmierung auf der Grundlage historischer Trends, Kapazitätsreserven usw. zu untersuchen.

Fazit

Heute sind unsere Restaurant Compute Platform und ihre unterstützenden Prozesse so ausgereift, dass wir mit relativ kleinen Entwicklungs- und Supportteams ein hohes Maß an Zuverlässigkeit und Kundensupport bieten können. Dies gibt uns einen großartigen Ort, um wichtige Dienste auszuführen, die uns helfen, geschäftliche Herausforderungen in unserem Restaurant zu lösen.

Was haben wir gelernt?

  • Es bedurfte einer Menge großartiger Technik und intelligenter Kompromisse, um mit einem kleinen Team eine geschäftskritische MVP-Edge-Compute-Plattform zu entwickeln.
  • Der Betrieb von mehr als 2.500 Kubernetes-Clustern (mit einem kleinen Team) ist harte Arbeit, aber ein API-First-Ansatz mit gerade ausreichender Automatisierung hat für uns hervorragend funktioniert.
  • Aus einer Cloud-First-Welt kommend, sind einige der größten Herausforderungen am Edge die Einschränkungen (Rechenkapazität, begrenzte Netzwerkbandbreite, Remotezugriff). Wir empfehlen, viel Zeit in das Erlernen Ihrer (und potenziellen) Einschränkungen zu investieren und zu überlegen, ob Sie sie beseitigen (was länger dauert und mehr Geld kostet) oder sie verwalten. Beispielsweise haben wir einige Beschränkungen der Netzwerkverwaltung umgangen, indem wir eine Reihe von benutzerdefinierten Diensten eingeführt haben, die hervorragend funktionierten, aber langfristige Verwaltungskosten verursachten.