Wie wir mit diesem einfachen Trick 500.000 USD DataTransfer-Kosten gespart haben
Im Zuge der stetigen Weiterentwicklung und Optimierung von OTTO wurde das Cost Optimization Service Team (COST) ins Leben gerufen. Ziel dieses Teams ist es, die Kostenkultur innerhalb des Unternehmens zu stärken und die Effizienz der Cloud-Nutzung signifikant zu verbessern. Eine für uns identifizierte und analysierte Maßnahme mit hohem Effizienzgrad ist die plattformweite Migration zu Dual-stack IPv6. Dadurch konnten wir die durch das AWS-NAT-Gateway verursachten Kosten stark reduzieren. In diesem Artikel beschreiben wir die Herleitung dieser Effizienzmaßnahme und die Umsetzung im Detail.
Das COST wurde Anfang 2023 mit dem Ziel gegründet, die Kostenkultur innerhalb von OTTO zu verbessern und die Effizienz der Cloud-Nutzung zu steigern. Wir haben drei Mitglieder, die sich aufgrund der folgenden Herausforderungen zusammengefunden haben:
Diesen Herausforderungen begegnen wir insbesondere mit einem Bottom-up-Approach und durch Wirkung direkt in den Teams. Kostenkultur wird hochgehoben und gelebt, indem öfter und mehr darüber gesprochen wird. Die Entwickler*innenteams werden direkt in diese Gespräche eingebunden und über mögliche Veränderungen an der Infrastruktur hingewiesen. Der Fokus liegt dabei auf der Erzeugung von Ersparnissen.
Die Teams arbeiten nach dem Prinzip „You built it, you run it“. Dementsprechend tragen sie die Verantwortung für den Betrieb, die Weiterentwicklung und Sicherheit, aber auch für die Kosten. Die Entscheidung für eine Architektur soll Kostenaspekte von vornherein berücksichtigen und Teil der Entscheidung sein.
Systeme, welche schon über mehrere Jahre laufen, und ein Blick auf den allgemeinen Betrieb zeigen Spuren der Vergangenheit in Form von technischer Schuld. Wenn der Fokus ausschließlich auf den Ausbau unserer Fähigkeiten gelegt wird, bleibt nicht genug Zeit, technische Schulden zu identifizieren und zu beheben. Es häufen sich ineffiziente Lösungen an, welche kumulieren und vermeidbare Kosten erzeugen. Nicht zuletzt werden Cloud-Services seit Jahren genutzt, obwohl nicht eindeutig klar und kommuniziert ist, wie sie funktionieren, warum sie genutzt werden (müssen), noch wie sie Kosten erzeugen. Unwissenheit lässt sich durch Aufklärung angehen.
Wir als COST analysieren datengetrieben genutzte Cloud-Services und bringen das Wissen zurück in die Teams. Dabei fallen technische Optimierungsmöglichkeiten heraus, welche von den Teams kostensparend und möglichst aufwandsarm implementiert werden können. Das Ziel ist es, Optimierungsmaßnahmen zu identifizieren und hinsichtlich Ersparnis und Aufwand einzuordnen.
Nicht zuletzt unterstützen wir die Entwickler*innenteams sowohl beim Aufbau des Wissens um die Cloud-Services, als auch bei der Identifikation von technischer Schuld bzw. deren Abbau. Wir testen vorab die technischen Maßnahmen in unserer eigenen Team-Umgebungen oder bei betroffenen Teams. Wir erzeugen Guides, welche den Entwickler*innenteams als Schritt-für-Schritt-Anleitung zur Verfügung gestellt werden, um Ersparnisse zu erzeugen. Hier wird eine Hands-On-Mentalität gelebt. Es fördert den Austausch und die Aktivität in den Teams an dem Thema zu arbeiten.
Somit spielt COST eine entscheidende Rolle dabei, OTTO auf dem Weg noch effizienter und kostenbewusster zu arbeiten, zu unterstützen.
Die Teams innerhalb von OTTO arbeiten autonom und betreiben ihre (Micro)-Services in der Regel innerhalb eines VPCs. Die VPCs bestehen aufgrund mehrerer genutzter Verfügbarkeitszonen aus mehreren öffentlichen und privaten Subnetzen und basieren bisher rein auf IPv4. Die Services der Teams liegen in privaten Subnetzen, d.h. sie bekommen keine öffentlichen IPv4 Adressen und müssen aus diesem Grund über das AWS-NAT-Gateway kommunizieren (siehe Abbildung).
Dieser Ansatz hat über die Jahre gut funktioniert und uns erlaubt, teamautonom und entkoppelt zu arbeiten und zu skalieren, allerdings nicht umsonst. Denn der Fakt, dass Teams untereinander von VPC zu VPC kommunizieren, führt zu hohen Kosten. Denn für die NAT-Funktionalitäten nutzen die Teams die von AWS bereitgestellten NAT-Gateways.
Für die Nutzung von NAT-Gateways sind zwei Kostenarten relevant: Zum einen werden sie auf Stundenbasis abgerechnet. Der hier weitaus wichtigere, denn größere Kostenblock ergibt sich aus den variablen Traffic-Kosten der NAT-Gateways, die für jedes über diesen Service übertragene GB in Rechnung gestellt werden. Diese Kosten sind im AWS Cost Explorer unter dem „Usage Type“ NatGateway-Bytes zu finden.
Aktuell (Stand Mai 2024) liegen diese Kosten bei 0,052 USD/GB in der Region Frankfurt. Allein im Jahr 2023 sind bei der Abteilung, die otto.de betreibt, in diesem Kostenblock Kosten in Höhe von ca. 79.000 USD/Monat entstanden! Wie bekommen wir diese Kosten unter Kontrolle? Das Geheimnis ist IPv6.
Lasst uns zuvor nochmal einen Schritt zurückgehen und rekapitulieren, warum wir überhaupt NAT-Gateways brauchen. Ein NAT-Gateway (Network Address Translation Gateway) fungiert als Vermittler zwischen einem privaten Netzwerk (VPC) und dem Internet. Es ermöglicht Hosts innerhalb des VPCs, das Internet zu nutzen, ohne dass jeder eine öffentliche IP-Adresse zugeordnet bekommt. Jeder Host in den privaten Subnetzen des VPCs hat eine private IP4-Adresse, die im Internet nicht routbar ist. Ein NAT-Gateway besitzt hingegen eine eindeutige öffentliche IP-Adresse.
Wenn ein Host aus dem privaten Subnetz eine Verbindung zum Internet herstellen möchte, sendet er seine Anfrage an das NAT-Gateway. Das NAT-Gateway nimmt die Anfrage entgegen und ersetzt die private IP4-Adresse des Rechners durch seine eigene öffentliche IP4-Adresse. Wenn das Internet auf die Anfrage antwortet, sendet es die Antwort an die öffentliche IP-Adresse des NAT-Gateways. Das Gateway empfängt die Antwort und leitet dann die Antwort an die entsprechende private IP4-Adresse im internen Netzwerk weiter.
Die Möglichkeit, einfach alle Hosts ins Public Subnetz zu lokalisieren und ihnen jeweils eine öffentliche IPv4-Adresse zu allokieren, kommt wegen potenziellen Sicherheitsbedenken nicht in Frage, denn so wäre jeder Host potenziell vom Internet aufrufbar. Ferner ist die Allokation öffentlicher IPv4-Adressen auch teuer, insbesondere, wenn man sich vor Augen hält, dass unsere Systeme horizontal skalieren, gerne auf dutzende, wenn nicht hunderte Instanzen – und das pro Team!
Neben dem AWS-NAT-Gateway gibt es aber auch noch die Möglichkeit, NAT-Gateways eigenständig zu hosten, was sogar unser Proxy-Team so konfiguriert hat. Damit verbunden entstehen andere Totalkosten, wie z.B. die Instanz- und Wartungskosten, sowie deutlich mehr Betriebsaufwand.
NAT ist aus der Not geboren, dass es bei IPv4 nur eine begrenzte Anzahl von zu verteilenden Adressen gibt. Es erlaubt das Verteilen von 2³² IP-Adressen. Eine Zahl, die mittlerweile aufgrund des rasanten Wachstums des Internets und der zunehmenden Zahl der angeschlossenen Geräte zu klein geworden ist. Wäre es nicht schön, wenn es diese Differenzierung zwischen öffentlichen und privaten IP-Adressen nicht gäbe?
Im Gegensatz dazu verwendet IPv6 128-Bit-Adressen und bietet damit einen weitaus größeren Adressraum: insgesamt gibt es 2¹²⁸ mögliche IPv6-Adressen – eine Zahl, die größer ist als die Anzahl an Sternen in der Galaxis! Aufgrund dieses größeren Adressraums muss nicht mehr zwischen öffentlichen und privaten IP-Adressen unterschieden werden. Somit wird kein NAT mehr benötigt.
So viel zur Theorie. Wie sieht eine Implementation aber in der Praxis aus? Die IPv6-Migration ist notorisch dafür, sich in die Länge zu ziehen. Das Protokoll ist zwar schon mehr als 20 Jahre alt, hat sich aber keineswegs schon überall durchgesetzt.
Zum Glück ist das Aufsetzen in AWS sehr einfach. AWS ermöglicht es, VPCs im Dual-stack-Modus aufzusetzen. Das bedeutet, dass sowohl IPv6 als auch IPv4 unterstützt werden. Und das funktioniert wie folgt:
Zuerst wird dem VPC ein global einzigartiger IPv6-CIDR-Block (::/56) zugewiesen (1). Dieser wird, genauso wie bei IPv4-only, in n Subnetze (private und public) untergliedert. Da es keine Differenzierung zwischen öffentlichen und privaten IP-Adressen in IPv6 gibt, sind dann nicht alle Subnetze im Endeffekt public? Nein, denn es kann nur Zugriff auf eine Instanz geben, wenn es eine Default-Route zwischen Instanz und dem Internet-Gateway gibt (3). Die Abstraktion der privaten Subnetze kann rekonstruiert werden, wenn ein sogenanntes Egress-only Internet Gateway ins VPC einhängt und bei den privaten Subnetzen als Default-Route gesetzt wird (2). Dieses Gateway garantiert, dass nur ausgehender Zugriff möglich ist, und kapselt so unsere Services wie gewollt. Wie in (6) zu sehen ist, gehen so IPv6-Requests direkt zum Egress-only Internet Gateway.
Dieses Setup in nur einem VPC eines Clients aufzusetzen, reicht leider nicht aus, um IPv6 zu nutzen, denn die aufgerufenen Server müssen ebenfalls IPv6 unterstützen.
Das Aufsetzen von Dual-stack beim Server stellt sich aber als trivial heraus, denn der AWS Application Load Balancer unterstützt Dual-stack nativ. Dem VPC muss lediglich ein IPv6-Adressraum zugewiesen, der ALB auf Dual-stack umgeschaltet, ein AAAA-Record angelegt werden und fertig ist die IPv6-Kommunikation. Somit ist der inter-team Traffic, welcher den Großteil unseres Traffic-Volumens ausmacht, IPv6-basiert. Ein positiver Nebeneffekt der Migration auf IPv6 ist, dass bei OTTO-externen IPv6-ready Servern und APIs ebenfalls die NAT-Gateways vermieden werden. Außerdem haben wir Dank des Dual-stack Ansatzes immer noch den Fallback auf IPv4, sollte ein Remote-Host noch kein IPv6 unterstützen.
Wir haben das monetäre Potenzial mit mindestens 500.000 USD pro Jahr für die Migration auf Dual-stack IPv6 beziffert. Um es zu heben, braucht es die Umstellung in allen unseren cross-funktionalen Teams. Innerhalb von acht Wochen konnten 75% unserer Teams vollständig migrieren und dadurch die täglichen Kosten um knapp 1.400 USD am Tag senken. Das antizipierte Potenzial werden wir überschreiten.
Unsere Erfahrung hat gezeigt, dass die meisten Teams mit nur ein bis zwei Entwickler*innen und innerhalb von ein bis zwei Tagen die Migration abschließen konnten. Außerdem konnten wir beobachten, dass einige Drittanbieter-Services, wie z.B. Confluent Kafka, noch kein IPv6 sprechen. Da hierüber ein Großteil unserer verbleibenden IPv4-Kommunikation gelöst wird , bleibt Potenzial liegen. Es ist daher notwendig auch unsere Service-Provider auf dieses Potenzial aufmerksam zu machen und eine Kommunikation über IPv6 auf ihrer Roadmap zu priorisieren. Sobald sie diese Fähigkeiten einbauen, können wir mit weiteren Ersparnissen rechnen.
Trotz der simplen Integration ist es wichtig, diese nach Abschluss auf den Traffic-Fluss hin zu überprüfen. Es kam u.a. vor, dass ein AAAA-Record doch nicht korrekt gesetzt wurde oder anwendungsspezifische Konfigurationen (z. B. die -Djava.net.preferIPv6Addresses=true Runtime Flag) noch nicht angewendet wurden. Ein weiteres, häufig aufgetretenes Fehlerbild war, dass vergessen wurde, Docker ebenfalls auf Dual-stack umzuschalten, z. B. durch --network host.
Die NAT-Gateway-Architektur erlaubt eine gewisse Sicherheit gegen Angriffe von außen. In den Überlegungen auf Dual-stack IPv6 umzustellen, haben wir sehr früh eine Sicherheitsanalyse angestrengt. Dank des Egress-only-Internet-Gateway wird eingehender Traffic, welcher nicht default geroutet ist, geblockt. Somit besteht ähnlich zur NAT-Architektur dieselbe Sicherheit, da die public IPv6-Adresse unbekannt bleibt.
Traffic macht in vielen Fällen einen der größten Kostenblöcke in der Nutzung von Cloud aus. Diesen Teil zu optimieren ist schwierig, da die technische Kommunikation notwendig ist und er sich nicht einfach ausschalten lässt. Die Kosten dafür lassen sich auch nicht pauschal durch leistungsstärkere Infrastruktur reduzieren.
Die Tatsache, dass der IPv4-Adressraum ausgereizt ist, macht die Notwendigkeit über IPv6 zu kommunizieren ebenfalls deutlich. Umso besser, dass wir innerhalb weniger Wochen den Großteil unserer Kommunikation auf IPv6 shiften konnten.
Die Abhängigkeit zu Services, welche noch nicht IPv6 sprechen können, wird sich in der Zukunft ebenfalls auflösen. Hier birgt sich also weiteres Potenzial die Traffic-Kosten weiter zu senken. Abgesehen von wenigen Edge-Cases ließ sich die Migration in der AWS aufwandsarm umsetzen. Durch den Austausch zwischen den Teams auf den Edge-Cases konnten diese in vielen Fällen ebenfalls erfolgreich umgesetzt werden.
Aufgrund der Server/Client-Abhängigkeit ist nicht in jedem Team ein positiver Effekt in den Kosten zu beobachten, aber definitiv organisationsweit und auf unserer AWS-Rechnung. Hier sparen wir schon heute jährlich mindestens 500.000 USD. Tendenz steigend. Das macht deutlich, wie effektiv Gemeinschaftsleistungen dieser Art und damit auch das Standardisieren von Technologie sein können.
Vielleicht kennt ihr auch eine? Wir suchen schon nach der nächsten.
Möchtest du Teil des Teams werden?
We have received your feedback.