Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Hallo zusammen! Ich bin Kirill, CTO bei Adapty. Der Großteil unserer Architektur lĂ€uft auf AWS, und heute werde ich erlĂ€utern, wie wir unsere Serverkosten um das Dreifache gesenkt haben, indem wir Spot-Instanzen in unserer Produktionsumgebung verwendet haben, sowie wie man ihre automatische Skalierung einrichtet. Zuerst gibt es einen Überblick, wie das funktioniert, gefolgt von einer detaillierten Anleitung zum Start.

Was sind Spot-Instanzen?

Spot- Instanzen sind Server anderer AWS-Nutzer, die derzeit ungenutzt sind und diese zu einem großen Rabatt verkaufen (Amazon gibt bis zu 90% an, nach unserer Erfahrung etwa 3x, variiert je nach Region, AZ und Instanztyp). Das Hauptunterscheidungsmerkmal zu regulĂ€ren Instanzen ist, dass sie jederzeit abgeschaltet werden können. Daher dachten wir lange, dass es in Ordnung sei, sie fĂŒr Entwicklungsumgebungen oder fĂŒr Berechnungsaufgaben zu verwenden, wobei die Zwischenergebnisse in S3 oder einer Datenbank gespeichert werden, aber nicht fĂŒr Produktionen. Es gibt Drittanbieter-Lösungen, die die Verwendung von Spot-Instanzen in Produktionen ermöglichen, aber in unserem Fall gibt es viele Probleme mit diesen, weshalb wir sie nicht implementiert haben. Der in diesem Artikel beschriebene Ansatz funktioniert vollstĂ€ndig innerhalb der StandardfunktionalitĂ€t von AWS, ohne zusĂ€tzliche Skripte, Cronjobs usw.

Im Folgenden werde ich einige Screenshots zeigen, die die Preisentwicklung von Spot-Instanzen verdeutlichen.

m5.large in der Region eu-west-1 (Irland). Der Preis ist ĂŒber einen Zeitraum von 3 Monaten ĂŒberwiegend stabil, derzeit liegt die Einsparung bei 2,9x.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

m5.large in der Region us-east-1 (N. Virginia). Der Preis Ă€ndert sich stĂ€ndig ĂŒber einen Zeitraum von 3 Monaten, gegenwĂ€rtig liegt die Einsparung zwischen 2,3x und 2,8x, je nach VerfĂŒgbarkeitszone.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

t3.small in der Region us-east-1 (N. Virginia). Der Preis ist ĂŒber einen Zeitraum von 3 Monaten stabil, aktuell liegt die Einsparung bei 3,4x.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Architektur des Dienstes

Die Grundarchitektur des Dienstes, ĂŒber den wir in diesem Artikel sprechen werden, ist im folgenden Diagramm dargestellt.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Application Load Balancer → EC2 Target Group → Elastic Container Service

Als Lastverteilung wird der Application Load Balancer (ALB) verwendet, der Anfragen an die EC2 Target Group (TG) weiterleitet. Die TG sorgt dafĂŒr, dass die Ports auf den Instanzen fĂŒr den ALB geöffnet werden und sie mit den Ports der Container des Elastic Container Service (ECS) verbunden sind. ECS ist das Pendant zu Kubernetes in AWS, das das Management von Docker-Containern ĂŒbernimmt.

Auf einer Instanz können mehrere Container mit denselben Ports ausgefĂŒhrt werden, weshalb wir diese nicht festlegen können. ECS teilt TG mit, dass es eine neue Aufgabe startet (in der Terminologie von Kubernetes wird dies als Pod bezeichnet), TG prĂŒft die verfĂŒgbaren Ports auf der Instanz und weist einen davon fĂŒr die gestartete Aufgabe zu. Außerdem ĂŒberprĂŒft TG regelmĂ€ĂŸig, ob die Instanz und die API darauf funktionieren, indem es Health Checks durchfĂŒhrt, und wenn es Probleme feststellt, hört es auf, Anfragen dorthin zu senden.

EC2 Auto Scaling Groups + ECS Capacity Providers

In dem obigen Diagramm wurde der Dienst EC2 Auto Scaling Groups (ASG) nicht dargestellt. Aus dem Namen kann man entnehmen, dass er fĂŒr das Skalieren der Instanzen verantwortlich ist. Bis vor kurzem gab es in AWS keine integrierte Möglichkeit, die Anzahl der von ECS gestarteten Maschinen zu verwalten. ECS erlaubte es, die Anzahl der Aufgaben basierend auf der CPU-Nutzung, RAM oder der Anzahl der Anfragen zu skalieren. Wenn jedoch alle freien Instanzen von Aufgaben belegt waren, wurden keine neuen Maschinen automatisch gestartet.

Das hat sich mit der EinfĂŒhrung von ECS Capacity Providers (ECS CP) geĂ€ndert. Jetzt kann jeder Dienst in ECS mit ASG verbunden werden, und wenn die Aufgaben nicht auf den laufenden Instanzen Platz finden, werden neue gestartet (aber innerhalb der festgelegten ASG-Grenzen). Das funktioniert auch umgekehrt: Wenn ECS CP ungenutzte Instanzen ohne Aufgaben sieht, gibt es ASG den Befehl, diese abzuschalten. ECS CP hat die Möglichkeit, einen Zielauslastungsprozentsatz fĂŒr die Instanzen anzugeben, damit immer eine bestimmte Anzahl von Maschinen frei bleibt, um die Aufgaben schnell zu skalieren, mehr dazu spĂ€ter.

EC2 Launch Templates

Der letzte Dienst, ĂŒber den ich sprechen werde, bevor ich in die detaillierte Beschreibung der Erstellung dieser Infrastruktur ĂŒbergehe, sind EC2 Launch Templates. Sie ermöglichen es, eine Vorlage zu erstellen, nach der alle Maschinen gestartet werden, um dies nicht jedes Mal von Grund auf neu zu tun. Hier kann man den Typ der zu startenden Maschine, die Sicherheitsgruppe, das Disk-Image und viele andere Parameter auswĂ€hlen. Außerdem kann man benutzerdefinierte Daten angeben, die auf alle gestarteten Instanzen ĂŒbertragen werden. In den benutzerdefinierten Daten können Skripte ausgefĂŒhrt werden, beispielsweise kann der Inhalt einer Datei bearbeitet werden. Konfiguration des ECS-Agenten.

Einer der wichtigsten Parameter in diesem Artikel ist die Konfiguration — ECS_ENABLE_SPOT_INSTANCE_DRAINING=true. Wenn diese Option aktiviert ist, wechselt ECS, sobald es ein Signal erhĂ€lt, dass der Spot-Instance zurĂŒckgenommen wird, alle Aufgaben, die darauf ausgefĂŒhrt werden, in den Status Draining. Es werden keine neuen Aufgaben auf diese Instanz zugewiesen, und wenn Aufgaben derzeit darauf ausgefĂŒhrt werden sollen, werden sie abgebrochen. Anfragen vom Load Balancer kommen ebenfalls nicht mehr an. Die Benachrichtigung ĂŒber das Entfernen der Instanz erfolgt 2 Minuten vor dem tatsĂ€chlichen Ereignis. Wenn Ihr Dienst also keine Aufgaben lĂ€nger als 2 Minuten ausfĂŒhrt und nichts auf der Festplatte speichert, können Sie Spot-Instanzen ohne Datenverlust nutzen.

BezĂŒglich der Festplatte – AWS hat kĂŒrzlich ermöglicht die Verwendung des Elastic File System (EFS) zusammen mit ECS. Mit diesem Schema ist selbst die Festplatte kein Hindernis, aber wir haben das nicht ausprobiert, da wir im Grunde keine Festplatte zur Speicherung des Status benötigen. StandardmĂ€ĂŸig werden nach Erhalt von SIGINT (das zum Zeitpunkt des Wechsels der Aufgabe in den Status Draining gesendet wird) alle aktiven Aufgaben nach 30 Sekunden gestoppt, selbst wenn sie nicht abgeschlossen sind. Diese Zeit kann mit dem Parameter ECS_CONTAINER_STOP_TIMEOUTgeĂ€ndert werden. Wichtig ist, ihn nicht auf mehr als 2 Minuten fĂŒr Spot-Maschinen zu setzen.

Erstellung des Dienstes

Wir gehen jetzt direkt zur Erstellung des beschriebenen Dienstes ĂŒber. Dabei werde ich einige nĂŒtzliche Punkte beschreiben, die oben nicht erwĂ€hnt wurden. Insgesamt handelt es sich um eine Schritt-fĂŒr-Schritt-Anleitung, aber ich werde sehr grundlegende oder sehr spezifische FĂ€lle nicht behandeln. Alle Aktionen werden ĂŒber die visuelle AWS-Konsole ausgefĂŒhrt, können aber auch programmgesteuert mit CloudFormation oder Terraform reproduziert werden. Bei Adapty verwenden wir Terraform.

EC2 Launch Template

In diesem Dienst wird eine Konfiguration fĂŒr die Maschinen erstellt, die verwendet werden. Die Verwaltung der Vorlagen erfolgt im Abschnitt EC2 -> Instances -> Launch templates.

Amazon Machine Image (AMI) – wir geben das Disk-Image an, mit dem alle Instanzen gestartet werden. FĂŒr ECS sollte in den meisten FĂ€llen das von Amazon optimierte Image verwendet werden. Es wird regelmĂ€ĂŸig aktualisiert und enthĂ€lt alles, was fĂŒr den Betrieb von ECS erforderlich ist. Um die aktuelle ID des Images zu erfahren, gehen wir auf die Seite Amazon ECS-optimized AMIs, wĂ€hlen die verwendete Region aus und kopieren die AMI-ID dafĂŒr. Zum Beispiel, fĂŒr die Region us-east-1 ist zu dem Zeitpunkt, zu dem dieser Artikel geschrieben wurde, die aktuelle ID – ami-00c7c1cf5bdc913ed. Diese ID muss in den Punkt Specify a custom value eingefĂŒgt werden.

Instanztyp — der Typ der Instanz wird angegeben. WĂ€hlen Sie den, der am besten zu Ihrer Aufgabe passt.

SchlĂŒsselpaar (Login) — das Zertifikat, mit dem eine Verbindung zur Instanz ĂŒber SSH hergestellt werden kann, falls erforderlich.

Netzwerkeinstellungen — die Netzparameter werden angegeben. Netzwerktechnologie in den meisten FĂ€llen sollte es sich um ein Virtual Private Cloud (VPC) handeln. Sicherheitsgruppen — Sicherheitsgruppen fĂŒr Ihre Instanzen. Da wir einen Load Balancer vor den Instanzen verwenden werden, empfehle ich, hier eine Gruppe anzugeben, die eingehende Verbindungen nur vom Load Balancer zulĂ€sst. Das bedeutet, dass Sie 2 Sicherheitsgruppen haben werden: eine fĂŒr den Load Balancer, die eingehende (Inbound) Verbindungen von ĂŒberall ĂŒber die Ports 80 (http) und 443 (https) erlaubt, und eine zweite fĂŒr die Maschinen, die eingehende Verbindungen ĂŒber alle Ports von der Gruppe des Load Balancers erlaubt. Ausgehende (Outbound) Verbindungen in beiden Gruppen mĂŒssen ĂŒber das TCP-Protokoll auf alle Ports zu allen Adressen geöffnet sein. Es ist möglich, die Ports und Adressen fĂŒr ausgehende Verbindungen einzuschrĂ€nken, aber dann mĂŒssen Sie stĂ€ndig ĂŒberwachen, dass Sie nicht versuchen, auf einen geschlossenen Port zuzugreifen.

Speicher (Volumen) — die Plattenparameter fĂŒr die Maschinen werden angegeben. Der Plattenumfang darf nicht kleiner sein als der, der in der AMI angegeben ist, fĂŒr ECS-Optimierte — 30 GiB.

Erweiterte Details — zusĂ€tzliche Parameter werden angegeben.

Kaufoption — ob wir Spot-Instanzen kaufen möchten. Wir möchten das, aber hier werden wir dieses KontrollkĂ€stchen nicht aktivieren, wir konfigurieren es in der Auto Scaling Group, dort gibt es mehr Optionen.

IAM-Instanzprofil — die Rolle angeben, mit der die Instanzen gestartet werden. Damit die Instanzen in ECS funktionieren, benötigen sie Rechte, die normalerweise in der Rolle ecsInstanceRoleliegen. In einigen FĂ€llen kann sie erstellt werden, falls sie nicht existiert, dann hier Anleitung finden Sie Informationen, wie das geht. Nach der Erstellung geben wir sie im Template an.
Danach folgen viele Parameter, die in der Regel auf den Standardwerten belassen werden können, aber jeder von ihnen hat eine verstÀndliche Beschreibung. Ich aktiviere immer die Parameter EBS-optimierte Instanz und T2/T3 Unlimited, wenn verwendet werden. burstable Instanzen.

Benutzerdaten — die Benutzerdaten werden angegeben. Wir werden die Datei /etc/ecs/ecs.configbearbeiten, in der die Konfiguration des ECS-Agenten gespeichert ist.
Ein Beispiel, wie die Benutzerdaten aussehen können:

#!/bin/bash
echo ECS_CLUSTER=DemoApiClusterProd >> /etc/ecs/ecs.config
echo ECS_ENABLE_SPOT_INSTANCE_DRAINING=true >> /etc/ecs/ecs.config
echo ECS_CONTAINER_STOP_TIMEOUT=1m >> /etc/ecs/ecs.config
echo ECS_ENGINE_AUTH_TYPE=docker >> /etc/ecs/ecs.config
echo "ECS_ENGINE_AUTH_DATA={"registry.gitlab.com":{"username":"username","password":"password"}}" >> /etc/ecs/ecs.config

ECS_CLUSTER=DemoApiClusterProd — Der Parameter gibt an, dass die Instanz zu einem Cluster mit dem angegebenen Namen gehört, d.h. dieses Cluster kann seine Aufgaben auf diesem Server hosten. Wir haben bisher noch keinen Cluster erstellt, werden jedoch beim Erstellen diesen Namen verwenden.

ECS_ENABLE_SPOT_INSTANCE_DRAINING=true — Der Parameter gibt an, dass alle Aufgaben auf der Spot-Instanz beim Empfang des Abschaltsignals in den Status Draining versetzt werden sollen.

ECS_CONTAINER_STOP_TIMEOUT=1m — Der Parameter gibt an, dass nach Empfang des SIGINT-Signals alle Aufgaben 1 Minute Zeit haben, bevor sie beendet werden.

ECS_ENGINE_AUTH_TYPE=docker — Der Parameter gibt an, dass das Docker-Schema als Authentifizierungsmechanismus verwendet wird.

ECS_ENGINE_AUTH_DATA=... — Verbindungseinstellungen zu einem privaten Container-Registry, in dem Ihre Docker-Images gespeichert werden. Wenn es öffentlich ist, mĂŒssen keine Angaben gemacht werden.

Im Rahmen dieses Artikels werde ich ein öffentliches Bild aus dem Docker Hub verwenden, daher sind keine Angaben nötig. ECS_ENGINE_AUTH_TYPE und ECS_ENGINE_AUTH_DATA sind nicht erforderlich.

NĂŒtzliche Informationen: Es wird empfohlen, AMIs regelmĂ€ĂŸig zu aktualisieren, da neue Versionen Docker, Linux, ECS-Agenten usw. aktualisieren. Um dies nicht zu vergessen, können Sie Benachrichtigungen einstellen ĂŒber neue Versionen. Sie können Benachrichtigungen per E-Mail erhalten und manuell aktualisieren oder eine Lambda-Funktion schreiben, die automatisch eine neue Version des Launch Templates mit dem aktualisierten AMI erstellt.

EC2 Auto Scaling Gruppe

Die Auto Scaling Gruppe ist verantwortlich fĂŒr das Starten und Skalieren von Instanzen. Die Verwaltung der Gruppen erfolgt im Bereich EC2 -> Auto Scaling -> Auto Scaling Gruppen.

Launch-Vorlage — WĂ€hlen Sie die im vorherigen Schritt erstellte Vorlage aus. Die Version bleibt auf der Standard-Einstellung.

Kaufoptionen und Instanztypen — Geben Sie die Instanztypen fĂŒr das Cluster an. Adhere to launch template verwendet den Instanztyp aus der Launch-Vorlage. Combine purchase options and instance types ermöglicht eine flexible Konfiguration der Instanztypen. Wir werden dies verwenden.

Optionale On-Demand-Basis — Die Anzahl der normalen, nicht-Spot-Instanzen, die immer laufen werden.

On-Demand-Prozentsatz ĂŒber der Basis — Das prozentuale VerhĂ€ltnis von normalen und Spot-Instanzen; 50-50 wird gleichmĂ€ĂŸig verteilen, 20-80 bedeutet, dass auf jede normale Instanz 4 Spot-Instanzen hochgefahren werden. Im Rahmen dieses Beispiels werde ich 50-50 angeben, aber in der RealitĂ€t machen wir hĂ€ufig 20-80, in einigen FĂ€llen 0-100.

Instanztypen — hier können zusĂ€tzliche Instanztypen angegeben werden, die im Cluster verwendet werden. Wir haben das nie genutzt, weil ich den Sinn dieser Geschichte nicht ganz verstehe. Vielleicht liegt es an den Limits fĂŒr bestimmte Instanztypen, aber diese lassen sich leicht ĂŒber den Support erhöhen. Wenn Sie eine Anwendung kennen, wĂŒrde ich mich freuen, in den Kommentaren darĂŒber zu lesen)

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Netzwerk — Netzwerkeinstellungen, Sie wĂ€hlen VPC und Subnetze fĂŒr die Maschinen aus, in den meisten FĂ€llen sollten alle verfĂŒgbaren Subnetze ausgewĂ€hlt werden.

Lastverteilung — Einstellungen fĂŒr den Load Balancer, aber das werden wir separat machen, hier rĂŒhren wir nichts an. Health Checks werden ebenfalls spĂ€ter eingerichtet.

GruppengrĂ¶ĂŸe — wir geben die Limits fĂŒr die Anzahl der Maschinen im Cluster und die gewĂŒnschte Anzahl der Maschinen beim Start an. Die Anzahl der Maschinen im Cluster wird nie kleiner sein als die minimal angegebene und nie grĂ¶ĂŸer als die maximale, selbst wenn das Scaling nach Metriken erfolgen sollte.

Scaling-Richtlinien — Skalierungseinstellungen, aber wir werden die Skalierung basierend auf den laufenden ECS-Tasks vornehmen, daher werden wir die Skalierung spĂ€ter einstellen.

Instanz-Skalierungsschutz — Schutz von Instanzen vor Löschung beim Downscaling. Wir aktivieren dies, damit ASG die Maschine, auf der aktive Tasks laufen, nicht löscht. Der Schutz wird fĂŒr Instanzen ohne Tasks von der ECS Capacity Provider deaktiviert.

Tags hinzufĂŒgen — Sie können Tags fĂŒr Instanzen angeben (dafĂŒr muss das KontrollkĂ€stchen 'Neue Instanzen taggen' aktiviert sein). Ich empfehle, das Tag 'Name' anzugeben, sodass alle Instanzen, die innerhalb der Gruppe gestartet werden, denselben Namen haben, was die Anzeige in der Konsole erleichtert.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Nach der Erstellung der Gruppe öffnen Sie diese und gehen Sie zu den erweiterten Konfigurationen, warum bei der Erstellung in der Konsole nicht alle Optionen sichtbar sind.

Beendigungsrichtlinien — Regeln, die beim Löschen von Instanzen berĂŒcksichtigt werden. Sie werden in der Reihenfolge angewendet. Wir verwenden normalerweise solche wie auf dem Bild unten. Zuerst werden die Instanzen mit dem Ă€ltesten Launch Template gelöscht (zum Beispiel, wenn wir das AMI aktualisiert haben, wurde eine neue Version erstellt, aber alle Instanzen wurden rechtzeitig darauf umgestellt). Dann werden die Instanzen ausgewĂ€hlt, die dem nĂ€chsten Abrechnungszeitpunkt am nĂ€chsten sind. Und weiter werden die Ă€ltesten nach dem Startdatum ausgewĂ€hlt.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

NĂŒtzliche Informationen: um alle Maschinen im Cluster zu aktualisieren, ist es sinnvoll, Instanz-Refresh. Wenn Sie dies mit der Lambda-Funktion aus dem vorherigen Schritt kombinieren, erhalten Sie ein vollstĂ€ndig automatisiertes Update-System fĂŒr Instanzen. Vor der Aktualisierung aller Maschinen mĂŒssen Sie den Schutz vor dem Skalieren von Instanzen fĂŒr alle Instanzen in der Gruppe deaktivieren. Dies bezieht sich auf den Schutz der Maschinen selbst, diesen Schritt fĂŒhren Sie im Tab fĂŒr das Instantenmanagement durch.

Application Load Balancer und EC2 Zielgruppe

Der Lastenausgleich wird im Bereich EC2 → Load Balancing → Load Balancers erstellt. Wir werden den Application Load Balancer verwenden. Einen Vergleich verschiedener Arten von Lastenausgleich finden Sie auf der Service-Seite.

Listener — es macht Sinn, die Ports 80 und 443 zu erstellen und eine Weiterleitung von 80 nach 443 mit spĂ€teren Regeln des Lastenausgleichs einzurichten.

VerfĂŒgbarkeitszonen — in den meisten FĂ€llen wĂ€hlen wir alle VerfĂŒgbarkeitszonen aus.

Sicherheitseinstellungen konfigurieren — hier wird das SSL-Zertifikat fĂŒr den Lastenausgleich angegeben, die bequemste Option ist es, ein Zertifikat in ACM zu erstellen. Um die Unterschiede zu der Sicherheitsrichtlinie können Sie auf lesen, Sie können die standardmĂ€ĂŸig ausgewĂ€hlte Option belassen, DokumentationELBSecurityPolicy-2016-08 . Nach der Erstellung des Lastenausgleichs sehen Sie dessenDNS-Namen , fĂŒr den Sie einen CNAME fĂŒr Ihre Domain einrichten mĂŒssen. So sieht es beispielsweise in Cloudflare aus.— erstellen oder wĂ€hlen Sie eine Sicherheitsgruppe fĂŒr den Lastenausgleich, weitere Einzelheiten dazu finden Sie etwas weiter oben im Abschnitt EC2 Launch Template → Netzwerkeinstellungen.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Security Group Zielgruppe

— erstellen Sie eine Gruppe, die fĂŒr das Routing von Anfragen vom Lastenausgleich zu den Maschinen verantwortlich ist und deren VerfĂŒgbarkeit ĂŒberprĂŒft, um sie bei Problemen zu ersetzen. Typ der Zielgruppe muss Instance sein, beliebig, wenn Sie HTTPS fĂŒr die Kommunikation zwischen dem Lastenausgleich und den Instanzen verwenden, mĂŒssen Sie das Zertifikat auf diesen hochladen. In diesem Beispiel werden wir dies nicht tun, sondern einfach Port 80 belassen. Protokoll und Port — Parameter zur ÜberprĂŒfung der DienstverfĂŒgbarkeit. In einem echten Dienst sollte dies eine separate Anfrage sein, die wichtige Teile der GeschĂ€ftsanwendung implementiert. In diesem Beispiel lasse ich die Standardeinstellungen. Danach können Sie das Anfragenintervall, die ZeitĂŒberschreitung, die Codes fĂŒr erfolgreiche Antworten usw. auswĂ€hlen. In unserem Beispiel geben wir die Erfolgs-Codes 200-399 an, da das Docker-Image, das verwendet wird, den Code 304 zurĂŒckgibt.

Health Checks Ziele registrieren

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

— hier wĂ€hlen Sie die Maschinen fĂŒr die Gruppe aus, aber in unserem Fall wird dies von ECS erledigt, daher ĂŒberspringen wir diesen Schritt einfach. : auf Ebene des Lastenausgleichs können Sie Protokolle aktivieren, die in S3 an einem bestimmten Ort gespeichert werden.

NĂŒtzliche InformationenAuf der Ebene des Load Balancers können Protokolle aktiviert werden, die in S3 gespeichert werden. im SVG-Konturformat festgelegt wird.. Von dort aus können sie in externe Dienstleistungen fĂŒr Analysen exportiert werden, oder man kann SQL-Abfragen direkt auf die Daten in S3 mit Athena. Das ist praktisch und funktioniert ohne zusĂ€tzlichen Code. Ich empfehle außerdem, die Protokolldaten aus dem S3-Bucket nach Ablauf eines bestimmten Zeitraums zu löschen.

ECS Task Definition

In den vorherigen Schritten haben wir alles in Bezug auf die Infrastruktur des Dienstes erstellt, nun kommen wir zur Beschreibung der Container, die wir starten werden. Dies erfolgt im Abschnitt ECS → Task Definitions.

KompatibilitĂ€tstyp des Startvorgangs — wĂ€hlen Sie EC2.

IAM-Rolle fĂŒr die TaskausfĂŒhrung — wĂ€hlen Sie ecsTaskExecutionRole. Mit ihr werden Protokolle geschrieben, der Zugang zu geheimen Variablen gewĂ€hrt usw.

Im Abschnitt Container Definitions klicken wir auf Add Container.

Bild — Link zum Image mit dem Code des Projekts, in diesem Beispiel werde ich ein öffentliches Image von Docker Hub verwenden bitnami/node-example:0.0.1.

Speicherlimits — Limits fĂŒr den Speicher des Containers. Harter Limit — harter Limit, wenn der Container den angegebenen Wert ĂŒberschreitet, wird der Befehl docker kill ausgefĂŒhrt, der Container stirbt sofort. Weicher Limit — weicher Limit, der Container kann den angegebenen Wert ĂŒberschreiten, aber bei der Platzierung von Tasks auf den Maschinen wird dieser Parameter berĂŒcksichtigt. Wenn beispielsweise auf der Maschine 4 GiB RAM vorhanden sind und das weiche Limit des Containers 2048 MiB betrĂ€gt, können auf dieser Maschine maximal 2 Tasks mit diesem Container gestartet werden. TatsĂ€chlich sind 4 GiB RAM etwas weniger als 4096 MiB, das kann man auf der Registerkarte ECS Instances im Cluster sehen. Das weiche Limit darf nicht grĂ¶ĂŸer sein als das harte Limit. Wichtig zu verstehen ist, dass, wenn in einem Task mehrere Container vorhanden sind, deren Limits addiert werden.

Portzuordnungen — bei Host-Port geben wir 0 an, das bedeutet, dass der Port dynamisch zugewiesen wird, er wird von der Target Group ĂŒberwacht. Container-Port — der Port, an dem Ihre Anwendung lĂ€uft, wird oft im AusfĂŒhrungsbefehl festgelegt oder im Code Ihrer Anwendung, Dockerfile usw. zugewiesen. FĂŒr unser Beispiel verwenden wir 3000, weil er in der Dockerfile verwendeten Abbildung angegeben ist.

Health Check — Parameter zur ÜberprĂŒfung der FunktionsfĂ€higkeit des Containers, nicht zu verwechseln mit dem, der in der Target Group konfiguriert ist.

Umgebung — Umgebungsparameter. CPU-Einheiten — sieht Ă€hnlich aus wie Memory-Limits, nur fĂŒr die CPU. Jedes CPU-Kern entspricht 1024 Einheiten, daher können bei einem Server mit einer dual-core CPU und einem Wert von 512 fĂŒr den Container insgesamt 4 Aufgaben mit diesem Container gestartet werden. CPU-Einheiten sind immer an die Anzahl der Kerne gebunden, es kann nicht leicht weniger wie bei dem Speicher sein.

Befehl — Befehl zum Starten eines Dienstes innerhalb des Containers, alle Parameter werden durch ein Komma angegeben. Dies kann gunicorn, npm usw. sein. Wenn nicht angegeben, wird der Wert der CMD-Direktive aus der Dockerfile verwendet. Wir geben an npm,start.

Umgebungsvariablen — Umgebungsvariablen des Containers. Dies können sowohl einfache Textdaten als auch geheime Variablen aus Secrets Manager oder Parameter Store.

Speicherung und Protokollierung — hier konfigurieren wir die Protokollierung in den CloudWatch Logs (AWS-Dienst fĂŒr Protokolle). Dazu genĂŒgt es, das KĂ€stchen Auto-configure CloudWatch Logs zu aktivieren. Nach dem Erstellen der Task-Definition wird automatisch eine Log-Gruppe in CloudWatch erstellt. StandardmĂ€ĂŸig werden die Protokolle dort unbegrenzt gespeichert; ich empfehle, den Aufbewahrungszeitraum von Never Expire auf den gewĂŒnschten Zeitraum zu Ă€ndern. Dies geschieht in den CloudWatch Log-Gruppen, man muss auf den aktuellen Zeitraum klicken und einen neuen auswĂ€hlen.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

ECS-Cluster und ECS-KapazitÀtsprovider

Wir gehen zum Abschnitt ECS → Clusters, um einen Cluster zu erstellen. Als Vorlage wĂ€hlen wir EC2 Linux + Networking.

Clustername — sehr wichtig, hier das gleiche Name wie im Launch Template im Parameter ECS_CLUSTER, in unserem Fall — DemoApiClusterProd. Wir aktivieren das KĂ€stchen Create an empty cluster. Optional kann Container Insights aktiviert werden, um die Metriken der Dienste in CloudWatch zu sehen. Wenn Sie alles richtig gemacht haben, sehen Sie im Abschnitt ECS Instances die Maschinen, die in der Auto Scaling-Gruppe erstellt wurden.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Wechseln Sie zur Registerkarte KapazitÀtsanbieter und wir erstellen einen neuen. Ich erinnere daran, dass dieser benötigt wird, um die Erstellung und das Ausschalten von Maschinen abhÀngig von der Anzahl der laufenden ECS-Aufgaben zu verwalten. Es ist wichtig zu beachten, dass der Anbieter nur an eine Gruppe gebunden werden kann.

Auto Scaling-Gruppe — wir wĂ€hlen die zuvor erstellte Gruppe.

Verwaltetes Scaling — aktivieren, damit der Anbieter den Dienst skalieren kann.

ZielkapazitĂ€t % — welcher Prozentsatz der Maschinenlast durch Aufgaben benötigt wird. Wenn 100% angegeben wird, sind alle Maschinen immer mit laufenden Aufgaben beschĂ€ftigt. Wenn 50% angegeben wird, sind immer die HĂ€lfte der Maschinen frei. In diesem Fall werden bei einem plötzlichen Anstieg der Last die neuen Aufgaben sofort auf die freien Maschinen verteilt, ohne auf die Bereitstellung von Instanzen warten zu mĂŒssen.

Verwalteter KĂŒndigungsschutz — aktivieren, dieser Parameter erlaubt dem Anbieter, den Schutz von Instanzen vor der Löschung zu entfernen. Dies geschieht, wenn auf der Maschine keine aktiven Aufgaben vorhanden sind und ermöglicht ZielkapazitĂ€ts %.

ECS-Dienst und Skalierungseinstellungen

Letzter Schritt :) Um einen Dienst zu erstellen, muss man in den zuvor erstellten Cluster auf den Tab Dienste gehen.

Starttyp — man muss auf ‚Wechseln zu KapazitĂ€tsanbieterstrategie‘ klicken und den zuvor erstellten Anbieter auswĂ€hlen.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Aufgabenbeschreibung — wĂ€hlen Sie die zuvor erstellte Aufgabenbeschreibung und deren Revision aus.

Service name — um Verwirrung zu vermeiden, geben wir immer dieselbe an wie die Aufgabenbeschreibung.

Diensttyp — immer Replica.

Anzahl der Aufgaben — die gewĂŒnschte Anzahl aktiver Aufgaben im Dienst. Dieses Parameter wird durch die Skalierung gesteuert, muss aber dennoch angegeben werden.

Minimaler gesunder Prozentsatz und Maximaler Prozentsatz — bestimmen das Verhalten der Aufgaben beim Deployment. Die Standardwerte von 100 und 200 bedeuten, dass sich die Anzahl der Aufgaben wĂ€hrend des Deployments verdoppeln wird, bevor sie wieder auf das gewĂŒnschte Niveau zurĂŒckkehrt. Wenn Sie 1 Aufgabe haben, min=0 und max=100, wird die Aufgabe beim Deployment beendet und danach wird eine neue gestartet, es wird also eine Ausfallzeit geben. Wenn 1 Aufgabe aktiv ist, min=50, max=150, findet das Deployment nicht statt, da man die 1 Aufgabe nicht halbieren oder um eineinhalb erhöhen kann.

Deploymenttyp — wir lassen Rolling update.

Platzierungsvorlagen — Regeln fĂŒr die Platzierung von Aufgaben auf Maschinen. StandardmĂ€ĂŸig ist AZ Balanced Spread festgelegt – das bedeutet, dass jede neue Aufgabe auf eine neue Instanz gesetzt wird, bis alle Maschinen in allen VerfĂŒgbarkeitszonen gestartet sind. Normalerweise verwenden wir BinPack – CPU und Spread – AZ, wobei die Aufgaben so nah wie möglich auf eine Maschine nach CPU platziert werden. Bei Bedarf wird eine neue Maschine in einer neuen VerfĂŒgbarkeitszone erstellt.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Typ des Lastenausgleichs — wir wĂ€hlen den Application Load Balancer.

IAM-Rolle fĂŒr den Dienst — wir wĂ€hlen ecsServiceRole.

Name des Lastenausgleichs — wir wĂ€hlen den zuvor erstellten Lastenausgleich aus.

GesundheitsprĂŒfungs-Gnadenfrist — Pause vor der DurchfĂŒhrung von GesundheitsprĂŒfungen nach dem Rollout neuer Aufgaben, wir setzen normalerweise 60 Sekunden.

Container zum Lastenausgleich — im Punkt ‚Zielgruppename‘ wĂ€hlen wir die zuvor erstellte Gruppe aus, und alles wird automatisch ausgefĂŒllt.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

Automatische Skalierung des Dienstes — Parameter zur Skalierung des Dienstes. Wir wĂ€hlen ‚Dienst-Automatisierungskalierung konfigurieren, um die gewĂŒnschte Anzahl Ihres Dienstes anzupassen‘. Wir geben die minimale und maximale Anzahl von Aufgaben bei der Skalierung an.

IAM-Rolle fĂŒr die automatische Skalierung des Dienstes — wir wĂ€hlen AWSServiceRoleForApplicationAutoScaling_ECSService.

Automatische Skalierungsrichtlinien fĂŒr Aufgaben — Regeln zum Skalieren. Es gibt 2 Typen:

  1. Zielverfolgung — Verfolgung einer Zielmetrik (Nutzung von CPU/RAM oder die Anzahl der Anfragen fĂŒr jede Aufgabe). Zum Beispiel, wir möchten, dass die durchschnittliche CPU-Auslastung 85% betrĂ€gt. Wenn sie darĂŒber steigt, werden neue Aufgaben hinzugefĂŒgt, bis sie den Zielwert erreicht. Liegt die Auslastung darunter, werden Aufgaben abgebaut, es sei denn, die Downsizing-Skalierungsschutz ist aktiviert (Skalierung nach unten deaktivieren).
  2. Step-Skalierung — Reaktion auf ein beliebiges Ereignis. Hier können Sie die Reaktion auf jedes Ereignis (CloudWatch Alarm) festlegen. Wenn es passiert, können Sie eine bestimmte Anzahl von Aufgaben hinzufĂŒgen oder entfernen, oder eine genaue Anzahl von Aufgaben angeben.

Ein Dienst kann mehrere Skalierungsregeln haben, was nĂŒtzlich sein kann. Es ist wichtig, darauf zu achten, dass sie sich nicht gegenseitig behindern.

Fazit

Wenn Sie die Anweisungen befolgt und dasselbe Docker-Image verwendet haben, sollte Ihr Dienst diese Seite zurĂŒckgeben.

Erstellung einer skalierbaren API auf Spot-Instanzen von AWS

  1. Wir haben eine Vorlage erstellt, nach der alle Maschinen im Dienst gestartet werden. Wir haben auch gelernt, Maschinen bei Änderungen an der Vorlage zu aktualisieren.
  2. Wir haben die Verarbeitung des Stoppsignals fĂŒr Spot-Instanzen eingerichtet, daher werden innerhalb einer Minute nach Erhalt alle aktiven Aufgaben von der Maschine entfernt, sodass nichts verloren geht und nichts unterbrochen wird.
  3. Wir haben einen Load Balancer eingerichtet, um die Last gleichmĂ€ĂŸig auf die Maschinen zu verteilen.
  4. Wir haben einen Dienst eingerichtet, der auf Spot-Instanzen lÀuft, wodurch die Maschinenkosten um etwa das Dreifache gesenkt werden.
  5. Wir haben das automatische Skalieren in beide Richtungen eingerichtet, um Lastspitzen zu bewĂ€ltigen, aber gleichzeitig nicht fĂŒr Leerlaufzeiten zu zahlen.
  6. Wir verwenden einen Capacity Provider, damit die Anwendung die Infrastruktur (Maschinen) verwaltet und nicht umgekehrt.
  7. Wir sind großartig.

Wenn Sie vorhersehbare Laststeigerungen haben, z.B. wenn Sie in einem großen E-Mail-Newsletter werben, können Sie die Skalierung nach Zeitplan.

Außerdem können Sie die Skalierung basierend auf Daten aus verschiedenen Teilen Ihres Systems durchfĂŒhren. Zum Beispiel haben wir die Funktion Versand von individuellen Rabattangeboten Nutzern der mobilen Anwendung. Manchmal wird die Kampagne an ĂŒber 1 Million Personen versendet. Nach einem solchen Versand beobachten wir immer einen deutlichen Anstieg der Anfragen an die API, da viele Benutzer gleichzeitig die Anwendung aufrufen. Wenn wir also sehen, dass die Anzahl der Warteschlangen fĂŒr das Versenden von Promo-Push-Benachrichtigungen deutlich ĂŒber den Standardwerten liegt, können wir sofort mehrere zusĂ€tzliche Maschinen und Aufgaben starten, um auf die Last vorbereitet zu sein.

Ich wĂŒrde mich freuen, wenn ihr in den Kommentaren interessante AnwendungsfĂ€lle fĂŒr Spot-Instanzen und ECS oder etwas zum Thema Skalierung erzĂ€hlt.

Bald erscheinen Artikel darĂŒber, wie wir tausende analytischer Events pro Sekunde auf einem ĂŒberwiegend serverless Stack (mit Finanzen) verarbeiten und wie das Deployment von Services mit GitLab CI und Terraform Cloud funktioniert.

Folgt uns, es wird interessant!

Nur registrierte Benutzer können an der Umfrage teilnehmen. Bitte einloggen.

Verwendet ihr Spot-Instanzen in der Produktion?

  • 22,2%Ja6

  • 66,7%Nein18

  • 11,1%Ich habe von ihnen in einem Artikel erfahren und plane, sie zu nutzen.

27 Benutzer haben abgestimmt. 5 Benutzer haben sich enthalten.

Quelle: habr.com

60GB SSD 8Gb DDR4