1 Punkte von GN⁺ 5 시간 전 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Auf Slacks Datenplattform betreiben mehr als 700 SSH-basierte Operatoren zentrale Datenpipelines wie tägliche Suchindexierung und Analyse-Workloads; für alle Jobs war ein direkter SSH-Zugriff auf produktive AWS-EMR-Cluster erforderlich, was eine große Angriffsfläche schuf
  • Diese SSH-Abhängigkeit war nicht nur ein Sicherheitsrisiko, sondern auch ein zentrales Hindernis für die Infrastrukturmodernisierung, darunter Spark on Kubernetes, der Wechsel zu EMR on EKS und der Abschluss der Whitecastle-Initiative
  • Als Lösung nutzte Slack die YARN Distributed Shell, um selbst beliebige Shell-Befehle in YARN-Containern ausführen zu können, und bündelte alle Job-Submissions über das eigene REST-Gateway Quarry
  • Mehr als 700 Jobs wurden ohne Downtime über 8 Datenregionen hinweg migriert, die vollständige Abschaffung von SSH wurde in drei Quartalen erreicht
  • Das Ergebnis: kleinere Angriffsfläche, höhere Job-Zuverlässigkeit, bessere Sichtbarkeit sowie die Grundlage für den Abschluss von Whitecastle und die nächste Infrastruktur-Generation wie Spark on Kubernetes

Hintergrund: Entstehung einer SSH-basierten Datenplattform

  • Die um 2017 aufgebaute Slack-Datenplattform entschied sich für SSH als direktesten Weg, damit Airflow Jobs auf EMR-Clustern ausführen konnte
    • Verbindung zum EMR-Master-Node per SSHOperator, anschließend Ausführung von Befehlen wie spark-submit
  • Danach entwickelten Teams für verschiedene Einsatzzwecke (nicht nur Spark, sondern auch MapReduce, AWS CLI und benutzerdefinierte Python-Skripte) eigene maßgeschneiderte SSH-basierte Operatoren
  • Das Ergebnis war eine Ansammlung von mehr als 700 SSH-basierten Jobs in der Produktion

Die tatsächlichen Kosten des SSH-Ansatzes

  • Potenzielle Sicherheitsrisiken

    • Direkter SSH-Zugriff auf Compute-Cluster vergrößerte die Angriffsfläche
    • Verteilung und Rotation von Schlüsseln über Orchestrierungs-Worker hinweg erhöhten den operativen Aufwand
    • Für granulare Audits war eine Korrelation von Logs aus mehreren Systemen nötig
    • Zugriffssteuerung wurde durch dedizierte Security Groups und benutzerdefinierte Konfigurationen komplexer
  • Operative Probleme

    • Jobs wurden nicht verteilt, sondern direkt auf dem EMR-Master-Node ausgeführt, was zu Ressourcenkonkurrenz führte
    • Bei Neustarts von Kubernetes-Pods brachen SSH-Verbindungen ab und Jobs scheiterten
    • Lang laufende Jobs liefen nach Verbindungsabbrüchen weiter und wurden zu Zombie-Prozessen
    • Bei Verbindungsabbrüchen ließ sich nicht zuverlässig feststellen, ob ein Job erfolgreich oder fehlgeschlagen war
  • Blocker für die Modernisierung

    • Kein Einstieg in Spark on Kubernetes und EMR on EKS (zuerst musste die SSH-Abhängigkeit entfernt werden)
    • Der letzte EMR-Cluster im Hauptkonto konnte nicht in ein Child-Account verschoben werden, wodurch die Whitecastle-Initiative unvollständig blieb
      • Whitecastle ist Slacks Initiative, AWS-Infrastruktur in Child-Accounts zu verlagern, um Sicherheit und Netzwerkisolation zu verbessern
    • Eine angemessene Job-Überwachung und Sichtbarkeit ließ sich nicht umsetzen
  • Beispiel aus der Praxis — das Search-Infrastructure-Team

    • Eine Pipeline zum Erstellen täglicher Solr-Suchindizes aus Daten im Terabyte-Bereich, zentral für Slacks Suchfunktion
    • Aufgrund der SSH-basierten Job-Submissions war sie allen oben genannten Zuverlässigkeitsproblemen ausgesetzt

Grundidee von REST-basierter Job-Submission

  • Die grundlegenden Grenzen von SSH

    • SSH-Verbindungen sind zustandsbehaftete Direktverbindungen; wenn sie etwa durch einen Pod-Neustart abbrechen, laufen Befehle weiter, schlagen fehl oder hinterlassen verwaiste Prozesse
    • Es gibt kein verlässliches Mittel, sich erneut zu verbinden und den Status zu prüfen
  • Die REST-Alternative

    • Moderne Compute-Engines wie YARN, Trino und Snowflake unterstützen Job-Submission per HTTP API
      • POST einer Job-Anfrage → Rückgabe einer Job-ID
      • GET des Job-Status → Prüfung auf laufend/abgeschlossen/fehlgeschlagen
      • DELETE eines Jobs → sauberes Abbrechen
    • Der Job-Lebenszyklus wird serverseitig verwaltet; auch wenn der Client neu startet, läuft der Job weiter und sein Status bleibt abrufbar
  • Rolle und Grenzen von YARN

    • Für Hadoop-Workloads (MapReduce, Spark, Hive) ist YARN Ressourcenmanager und stellt zugleich eine REST API bereit
    • Für mehr als 300 CLI-basierte Jobs, die beliebige Shell-Befehle wie aws s3 sync oder hadoop distcp ausführen, gab es jedoch keine sofort nutzbare REST API
    • Der Schlüssel zur Lösung war die YARN Distributed Shell

Der Durchbruch: YARN Distributed Shell

  • Für Spark existiert die Livy-REST-API, für Hive HiveServer2, daher war die Migration dort relativ einfach
  • Dagegen waren MapReduce-Jobs und mehr als 300 CLI-basierte Jobs schwierig, weil keine direkt nutzbare REST API vorhanden war
  • Anforderungen

    • Eine einfache REST-basierte Lösung, die natürlich zur Architektur passt
    • Nutzung bestehender Authentifizierungs- und Autorisierungsmechanismen (keine eigene Sicherheitsschicht nötig)
    • Einsatz eines Open-Source-Protokolls (Standard-YARN-API) statt einer proprietären Lösung
    • Minimale Komplexität, um Aufbau und Betrieb einer eigenen Job-Ausführungsinfrastruktur zu vermeiden
  • Geprüfte und verworfene Ansätze

    • Aufbau eines eigenen Wrapper-Service für Remote-Befehlsausführung
    • Einsatz von Remote-Execution-Frameworks wie Ansible oder Salt
    • Einen neuen Job-Typ in YARN von Grund auf ergänzen
    • Alle Optionen erwiesen sich wegen übermäßiger Komplexität, eigener Sicherheitslogik und neuer Abhängigkeiten als ungeeignet
  • Entdeckung der YARN Distributed Shell

    • Mit org.apache.hadoop.yarn.applications.distributedshell.ApplicationMaster lassen sich beliebige Shell-Skripte in YARN-Containern ausführen
    • Diese Funktion ist bereits in YARN enthalten, nutzt dieselbe REST API und erfordert keine eigene Sicherheitsschicht
  • Funktionsweise

    • 1. Kommando-Skript nach S3 hochladen (z. B. aws s3 sync /tmp/data/ s3://bucket/output/)
    • 2. Mit Distributed-Shell-Konfiguration an YARN übergeben
      • application-type wird auf MAPREDUCE gesetzt; in am-container-spec stehen Umgebungsvariablen wie DISTRIBUTEDSHELLSCRIPTLOCATION, DISTRIBUTEDSHELLSCRIPTLEN und DISTRIBUTEDSHELLSCRIPTTIMESTAMP
    • 3. YARN weist einen Container zu, lädt das Skript herunter und führt es aus
      • YARN verwaltet Ressourcenlimits wie Speicher und vCores, Container-Isolation, Retries und Fehlertoleranz, sauberes Abbrechen sowie Logging über die YARN-UI
  • Durch diese Entscheidung konnten nicht nur Hadoop-Workloads, sondern auch aws s3 sync, hadoop distcp und benutzerdefinierte Python-Skripte vollständig in YARN-Containern ausgeführt werden

Die Lösung: Quarry

  • Quarry ist Slacks REST-basiertes Gateway für Job-Submission, das Jobs an mehrere Compute-Engines wie EMR/YARN, Trino und Snowflake sendet
  • Es hatte bereits Authentifizierung, Zuverlässigkeit und Sichtbarkeit gelöst und passte damit genau zur Abschaffung von SSH
  • Funktionen von Quarry

    • Authentifizierung: Service-zu-Service-Tokens statt SSH-Schlüsseln
    • Job-Submission: Versand an YARN, Trino und Snowflake per REST API
    • Statusverfolgung: serverseitiges Monitoring des Job-Status
    • Lebenszyklusverwaltung: sauberes Abbrechen und Aufräumen über die REST API
    • Sichtbarkeit: strukturierte Logs, Metriken und Tracing für alle Job-Submissions
  • Architekturänderung

    • Vorher: Airflow → SSH Connection → EMR Master Node → Execute Command
    • Nachher: Airflow → Quarry REST API → YARN ResourceManager → EMR Container
    • Airflow-Operatoren senden statt einer SSH-Verbindung HTTP-Anfragen an Quarry; Quarry submitttet an YARN und pollt den Status
    • Auch bei Neustarts von Airflow-Pods bleiben Jobs bestehen, da Quarry die Verbindung serverseitig verwaltet
  • Stärken von Quarry

    • Durch die Unterstützung der YARN Distributed Shell wurde es zu einem universellen Gateway für Job-Submission
    • Spark-Jobs, Hive-Abfragen und Shell-Skripte laufen alle über dieselbe REST API
    • SSH-Credentials und direkter Cluster-Zugriff entfallen vollständig; verwendet werden nur REST-Aufrufe mit Authentifizierung und serverseitigem Job-Tracking

Der Weg der Migration

  • Bei mehr als 700 Produktionsjobs über 8 unabhängige Datenregionen hinweg, jeweils mit unterschiedlichen Netzwerkkonfigurationen und Anforderungen an Datensouveränität sowie unterbrechungsfreien kritischen Workloads wie der Suchindexierung, war ein systematischer Plan nötig
  • Schrittweiser Ansatz

    • Phase 1 – Proof of Concept (PoC): Validierung des Quarry-Ansatzes mit Pilotjobs, Entwicklung des ersten Quarry-Operators und Tests in der Dev-Umgebung
    • Phase 2 – Sicherheitsprüfung: Zusammenarbeit mit dem Security-Team, um einen Plan zur Entfernung von Credentials zu erstellen und zu validieren, dass der REST-basierte Ansatz die Sicherheitsanforderungen erfüllt
    • Phase 3 – OKR-getriebene Umsetzung: Als Key Result definiert, um Management-Sichtbarkeit zu schaffen; in dieser Phase wurde der 80-%-Migrationsmeilenstein erreicht
    • Phase 4 – Massenmigration: Mehrere Teams wie Search Infrastructure, Data Engineering & Analytics und ML Services migrierten die verbleibenden Workloads parallel über alle Regionen
    • Phase 5 – Abschlussarbeiten: Abschluss fehlender DAGs, Stilllegung aller Legacy-SSH-Operatoren und Erreichen von 100 %
  • Migrationszahlen

    • Mehr als 700 Jobs über 7 Operator-Typen hinweg migriert
    • Einführung in 8 unabhängigen Datenregionen mit koordiniertem Rollout
    • 5 Teams wechselten auf die neuen Operatoren
    • Keine Unterbrechung geschäftskritischer Services
    • Vom ersten Pilot bis zur vollständigen SSH-Abschaffung in drei Quartalen abgeschlossen

Herausforderungen während der Migration

  • Challenge 1 — Ausfälle durch Virtual Memory Check

    • Bei der Migration eines Datenexport-DAGs schlug ein Job, der unter SSH problemlos lief, plötzlich wegen eines vmem-Check-Fehlers fehl
    • Ursache: Unter SSH lief der Job direkt auf dem Master-Node und umging damit die Ressourcenlimits von YARN; Quarry submitttet den Job korrekt an YARN, wodurch Container verworfen werden, die das virtuelle Speicherlimit überschreiten
    • Lösung: Deaktivierung des vmem-Checks clusterweit gemäß AWS-Best Practices — "yarn.nodemanager.vmem-check-enabled": "false"
      • Das entspricht der AWS-Empfehlung, da Linux-Virtual-Memory-Accounting unzuverlässig ist und physische Speicherlimits ausreichen
    • Lehre: SSH hatte viele Probleme verdeckt; beim Wechsel zu korrekter YARN-Submission muss man mit bislang unsichtbaren Ressourcenlimit-Problemen rechnen und gründlich in Dev testen
  • Challenge 2 — Netzwerkisolation und EKM-Konnektivität

    • Als ein Dev-Search-Infrastructure-Job von einem Dev-Cluster auf einen Staging-Analytics-Cluster migriert wurde, kam es zu Timeouts bei der EKM- (Enterprise Key Management) Verbindung
    • Fehler: Unable to execute HTTP request: Connect to sts.amazonaws.com:443 failed: connect timed out
    • Ursache: Der ursprüngliche Cluster hatte Netzwerk-Routing zum Key-Management-Endpunkt; der stärker segmentierte Staging-Analytics-Cluster hatte diese Konnektivität nicht, wodurch eine in der Job-Konfiguration nicht sichtbare Abhängigkeit von der Netzwerktopologie offengelegt wurde
    • Lösung: Verlagerung der Search-Infrastructure-Workloads auf einen Dev-ETL-Cluster mit Routing zu Dev-Services; Jobs, die den produktiven Hive-Katalog benötigten, blieben in Staging; zusätzlich wurde der Dev-ETL-Cluster skaliert, um die zusätzliche Last aufzunehmen
    • Lehre: Netzwerktopologie ist entscheidend; vor der Entscheidung, welcher Job auf welchem Cluster läuft, müssen Netzwerksegmentierung und Account-Grenzen verstanden werden
  • Challenge 3 — Komplexität durch mehrere Regionen

    • Wegen Anforderungen an Datensouveränität liefen EMR-Cluster in 8 unabhängigen Datenregionen; die Abschaffung von SSH war damit faktisch 8 parallele Migrationen
    • Komplexitätsfaktoren

      • Konfigurationsmanagement: Regionale Quarry-Konfigurationen, Cluster-Endpunkte und Regeln für Netzwerk-Routing waren nötig
      • Testaufwand: Jede Codeänderung musste in allen 8 Regionen validiert werden
      • Sequenzielle Ausrollung: Keine gleichzeitige Auslieferung möglich, sondern schrittweise pro Region
      • Regionalspezifische Probleme: Unterschiede bei Netzwerkkonfigurationen, Datensouveränitätsregeln und Cluster-Versionen
    • Vorgehensweise

      • Validierung in einer einzelnen Pilotregion (meist in den USA)
      • Dokumentation regionsspezifischer Konfigurationsanforderungen
      • Aufbau eines regionsbewussten Quarry-Operators
      • Schrittweiser Rollout mit Übernahme der Lernpunkte pro Region
      • Getrennte Nachverfolgung des Migrationsfortschritts je Region
    • Lehre: Multi-Region-Infrastruktur ist nicht einfach nur N-mal größer, sondern durch regionsspezifische Ausfallmodi N-mal schwieriger; für regionenübergreifende Koordination und Debugging pro Region muss ausreichend Zeit eingeplant werden

Ergebnisse

  • 100 % SSH-Abschaffung erreicht; alle Produktionsjobs wurden auf REST-basierte Submission über Quarry umgestellt
  • Sicherheitsergebnisse

    • SSH-Zugriff auf produktive EMR-Cluster wurde in allen 8 unabhängigen Datenregionen entfernt, wodurch die Angriffsfläche deutlich schrumpfte
    • Die Verteilung von SSH-Schlüsseln wurde durch Service-zu-Service-Token-Authentifizierung ersetzt, und REST-API-Logging ermöglichte ordnungsgemäße Audit-Trails
    • Alle Job-Submissions verfügen über strukturierte Logs über Quarry
    • Der letzte EMR-Cluster im AWS-Hauptkonto wurde in ein Child-Account verschoben, womit die Whitecastle-Initiative abgeschlossen wurde
    • Der Wegfall spezieller Security Groups und komplexer Berechtigungsverwaltung vereinfachte Compliance
  • Operative Verbesserungen

    • Ressourcenwettbewerb auf dem Master-Node entfiel; alle Nicht-Hadoop-Jobs laufen nun in verteilten YARN-Containern mit passender Ressourcenzuteilung
    • Jobs überstehen Neustarts von Client-Kubernetes-Pods, was die Zuverlässigkeit deutlich erhöht; Zombie-Prozesse verschwanden, sauberes Beenden ist über die REST API möglich
    • Die Quarry-API liefert strukturierte Job-Statusdaten, Logs und Metriken, sodass der gesamte Lebenszyklus verfolgt und mit YARN-Container-Logs gezielt debuggt werden kann
  • Grundlage für die Zukunft

    • Durch das Ende der SSH-Abhängigkeit wurde die Migration zu Spark on Kubernetes möglich
    • Die REST-basierte Architektur ist mit Cloud-Native-Praktiken kompatibel
    • Gegenüber komplexen SSH-Setups ist der Quarry-Operator einfacher und leichter zu warten, was das Onboarding von Teams erleichtert
    • Airflow wurde von den Details der EMR-Infrastruktur entkoppelt
    • Alle Job-Submissions wurden auf Quarry standardisiert, was künftige Änderungen vereinfacht
  • Zwei Jahre produktiver Betrieb nach Abschluss bestätigten die Architekturentscheidung: Sicherheit, operative Stabilität und Infrastrukturflexibilität wurden gleichermaßen verbessert

Gewonnene Erkenntnisse

  • Was gut funktioniert hat

    • Schrittweise Migration: Sequenzieller Rollout von Dev → GovDev/CommDev → Prod sowie die Migration nach Operator-Typen ermöglichten Lernen in Etappen
    • Starke Team-Zusammenarbeit: Bereichsübergreifende Kooperation zwischen Search, Analytics, Data Engineering, ML und Marketing mit schnellen Code-Reviews und Kommunikation über gemeinsame Kanäle
    • Analysegestützte Fortschrittsverfolgung: Aufbau eines Dashboards zum Migrationsfortschritt über alle Regionen sowie Identifikation verbleibender SSH-basierter Aufgaben per Airflow-Datenbankabfragen
  • Was man beim nächsten Mal anders machen würde

    • Netzwerktopologie früher erfassen: Probleme mit Netzwerkisolation wie bei der EKM-Konnektivität wurden erst spät entdeckt; Account-Grenzen und Netzwerk-Routing im Rahmen von Whitecastle sollten vor der Clustermigration dokumentiert werden
    • Tests auf Ressourcenlimits früher durchführen: Das vmem-Check-Problem trat spät auf; bereits in der Pilotphase sollten YARN-Ressourcenlimit-Tests im Vergleich zu SSH enthalten sein
    • Frühzeitigere Kommunikation über Operator-Einschränkungen: Als in der Endphase die Nutzung neuer SSHOperator-Jobs eingeschränkt wurde, bemerkten einige Teams das nicht; eine breitere Vorabinformation an alle Airflow-Nutzer wäre nötig gewesen
  • Best Practices für Migrationen in großem Maßstab

    • Monitoring vor der Migration aufbauen: Frühzeitig ein Dashboard bereitstellen, um verbleibende Arbeiten jederzeit sichtbar zu haben, und Airflow-DB-Abfragen nutzen
    • Tests in mehreren Umgebungen: In Dev, CommDev und GovDev testen, um umgebungsspezifische Probleme vor der Produktion zu erkennen, besonders durch Tests über Account-Grenzen hinweg zur frühzeitigen Erkennung von Netzwerkisolationsproblemen
    • Schrittweise Abschaffung von Operatoren: Operatoren wie CrunchExecOperator und S3SyncOperator einen nach dem anderen stilllegen; jede Phase als eigenes Mini-Projekt mit Tests und Validierung behandeln — langsamer, aber deutlich risikoärmer

Noch keine Kommentare.

Noch keine Kommentare.