Amazon Elastic Container Service, Teil 2 – Praxis ECS auf EC2-Cluster-Basis provisionieren

Autor / Redakteur: Dipl. -Ing. Thomas Drilling / Stephan Augsten

Docker-Image, Container, Cluster, Container-Definition, Cluster-Manager, Task-Definition, Task, Service-Definition und Services sind die essenziellen Konzepte von ECS. Schauen wir uns nun an, wie man aus diesen Zutaten eine cloudnative App backt.

Anbieter zum Thema

Sofern wir unser Container-Cluster richtig konfigurieren, zeigt das Dashboard der AWS Management Console den Service mit Statusinformation „Running“.
Sofern wir unser Container-Cluster richtig konfigurieren, zeigt das Dashboard der AWS Management Console den Service mit Statusinformation „Running“.
(Bild: Drilling / AWS Germany GmbH)

Provisioniert man ECS mit Hilfe des Einrichtungsassistenten in der AWS Management Console, werden die geschilderten Zusammenhänge sehr schön visualisiert:

Der Ersteinrichtichtungs-Assistent schlägt ein Fargate-basiertes Container-Cluster vor.
Der Ersteinrichtichtungs-Assistent schlägt ein Fargate-basiertes Container-Cluster vor.
(Bild: Drilling / AWS Germany GmbH)

Wir wollen allerdings nun eine App auf ECS schrittweise auf Basis eines EC2-Clusters provisionieren, statt im Wizard auf Fargate-Basis. Als Beispiel verwenden wir den Sinatra-Service (Sinatra ist eine populäre Ruby-On-Rails-Alternative) von „tongueroo“, der auf dem Docker Hub zu finden ist und nicht weiter tut, als „die elementare Frage des Lebens“ mit „42“ zu beantworten.

Die erste Herausforderung bestünde nun darin, das Image auf der Elastic Container Registry (ECR) bereitzustellen, was aus Sicherheitsgründen durchaus zu empfehlen wäre. Wir behandeln diesen Punkt im nächsten Teil und beschränken uns hier darauf, in der Task-Definition das Docker-Repo zu verwenden. Der prinzipielle Ablauf zum Bereitstellen einer App auf ECS wäre dann

  • 1. Erstellen des Clusters
  • 2. Erstellen einer Task-Definition
  • 3. Konfigurieren des Service
  • 4. Konfigurieren des Clusters
  • 5. Starten der Ressourcen

Erstellen des Clusters

AWS stellt drei verschiedene Cluster Templastes zur Verfügung.
AWS stellt drei verschiedene Cluster Templastes zur Verfügung.
(Bild: Drilling / AWS Germany GmbH)

Das Erstellen des Clusters in der Management-Console geht schnell von der Hand. Hier genügt im ECS-Dashboard im Abschnitt „Clusters“ ein Klick auf „Create Cluster“. AWS stellt hierzu drei verschiedene Templates „Networking only“, „EC2 Linux + Networking“ und „EC2 Windows + Networking“ bereit; wir entscheiden uns für die Linux-Variante.

Im Networking-Bereich lassen sich die Subnetze und Security-Gruppen zuordnen.
Im Networking-Bereich lassen sich die Subnetze und Security-Gruppen zuordnen.
(Bild: Drilling / AWS Germany GmbH)

Allerdings sollte man sich in der Praxis zunächst dem Thema Sicherheit widmen und neue Security-Groups für den Cluster erstellen, z. B. per Command Line Interface (CLI).

aws ec2 create-security-group --group-name ecs-sg --description ecs-sg

Andernfalls erstellt der Launch-Wizard passende Sicherheitsgruppen. In der Cluster-Konfiguration lassen sich dann die gewünschten, VPCs, Subnetze und Security-Groups verwenden.

Ist das Cluster erstellt, lässt es sich granularer konfigurieren.
Ist das Cluster erstellt, lässt es sich granularer konfigurieren.
(Bild: Drilling / AWS Germany GmbH)

Das Ergebnis lässt sich dann umgehend inspizieren und bei Bedarf weiter konfigurieren. Die GUI spendiert jeden der im ersten Teil beschriebenen Komponenten einen eigenen Tab: Services, Tasks, EC2 Instances, Metrics, Scheduled Tasks usw.

Es kann ein paar Minuten dauern, bis die Instanzen im Cluster registriert sind und im Tab „ECS Instances“ erscheinen. Für das Erstellen der Task-Definition stützen wir uns auf das erwähnte Sinatra-Docker-Image Tongueroo. Unter Praxisbedingungen würde man dies ggf. nun erst einmal lokal testen. Nun erstellen wir die Task-Definition direkt als JSON-File in einem beliebigen Editor:

{
   "family": "sinatra-hi",
   "containerDefinitions": [
   {
      "name": "web",
      "image": "tongueroo/sinatra:latest",
      "cpu": 256,
      "memoryReservation": 256,
      "portMappings": [
         {
            "containerPort": 4567,
            "protocol": "tcp"
         }
         ],
      "command": [
         "ruby", "hi.rb"
      ],
         "essential": true
      }
   ]
}

Ist die Task-Definition erstellt und registriert, taucht sie in der AWS Management Console auf.
Ist die Task-Definition erstellt und registriert, taucht sie in der AWS Management Console auf.
(Bild: Drilling / AWS Germany GmbH)

Dann registrieren wir die Task-Definition in ECS mit:

aws ecs register-task-definition --cli-input-json file://task-definition.json

Diese sollte dann auch in der AWS Console unter dem Punkt „Task Definitions“ auftauchen.

Konfiguration des Load Balancers.
Konfiguration des Load Balancers.
(Bild: Drilling / AWS Germany GmbH)

Nun erstellen wir den Load Balancer für unseren Service im gewünschten Subnet mit der passenden Security Group. Wir verwenden einen Advanced Load Balander (ALB) und müssen dazu eine Zielgruppe „target-group-ecs“ zum Registrieren der Instanzen festlegen. Als „Listener“ verwenden wir lediglich Port 80 zu Frontend und Backend. Das Registrieren der Instanzen im Load Balancer überspringen wir allerdings, da dies der Service-Scheduler erledigen wird.

Das Registrieren der Zielinstanzen übernimmt der Service Scheduler, deshalb tauchen Sie im Review-Bereich nicht mit auf.
Das Registrieren der Zielinstanzen übernimmt der Service Scheduler, deshalb tauchen Sie im Review-Bereich nicht mit auf.
(Bild: Drilling / AWS Germany GmbH)

Das Ergebnis lässt sich der Review-Seite des Load-Balancer-Assistenten entnehmen, die mit „Schritt 6“ gekennzeichnet ist und noch einmal sämtliche Details auflistet. Wie darin zu sehen ist, haben wir im Erstellungs-Assistenten für den Load Balancer eine Security Group erstellt, die Internetzugriff auf Port 80 erlaubt.

Die Security Group soll nur den eingehenden Traffic des Load Balancers entgegennehmen.
Die Security Group soll nur den eingehenden Traffic des Load Balancers entgegennehmen.
(Bild: Drilling / AWS Germany GmbH)

Jetzt müssen wir allerdings noch dafür sorgen, dass die Sicherheitsgruppe der beim Erstellen des ECS-Clusters erzeugten Instanzen ausschließlich Traffic vom Load Balancer akzeptiert. So ist denn auch gewährleistet, dass der gesamte ELB-Datenverkehr die Container-Instanz erreicht.

Auch für die nun noch fehlende Service-Definition kann man z. B. direkt eine JSON-Datei schreiben:

{
   "cluster": "ECS-Demo",
   "serviceName": "my-service",
   "taskDefinition": "sinatra-hi",
   "loadBalancers": [
      {
         "targetGroupArn": " arn:aws:elasticloadbalancing:eu-central-1:204730830381:targetgroup/target-group-ecs/826e2307393ebb98 ",
         "containerName": "web",
         "containerPort": 4567
      }
   ],
   "desiredCount": 1,
   "role": "myecsRole"
}

Task- und Service-Definitionen lassen sich per CLI oder in der AWS GUI erstellen.
Task- und Service-Definitionen lassen sich per CLI oder in der AWS GUI erstellen.
(Bild: Drilling / AWS Germany GmbH)

Diese registriert man dann wieder mit …

aws ecs create-service --cli-input-json file://ecs-service.json

… in ECS.

Selbstverständlich lassen sich Task- und Service-Definitionen aber auch in der GUI erstellen, wie im vorhergehenden Bild zu sehen ist. Ausgangspunkt hierfür ist eine bestehende Task-Definition. Bei markierter Task-Definition findet sich im „Actions“-Menü der Eintrag „Create Service“.

Die Netzwerk- und Security-Konfiguration in der Management Console weicht von unseren Werten ab.
Die Netzwerk- und Security-Konfiguration in der Management Console weicht von unseren Werten ab.
(Bild: Drilling / AWS Germany GmbH)

Achtung: In dieser Abbildung würde automatisch eine neue Target-Gruppe für den angegebenen Load Balancer erstellt, was nicht mehr exakt zum geschilderten Workflow passt. Es zeigt aber, wie einfach sich Service-Definitionen in der GUI erstellen lassen, auch wenn in diesem GUI-Beispiel IP-basierte Ziele erstellt werden.

Im Review-Bereich lassen sich sämtliche Einstellungen noch einmal prüfen und bei Bedarf editieren.
Im Review-Bereich lassen sich sämtliche Einstellungen noch einmal prüfen und bei Bedarf editieren.
(Bild: Drilling / AWS Germany GmbH)

Sind alle Angaben korrekt, wird der Service auch GUI-basiert problemlos erstellt.

Der neue Service sollte sich dann auch im Cluster-Dashboard wiederfinden und zwar zunächst im Status „Provisioning“ und kurze Zeit später mit dem Status „Ready“. Demnach sollten sich nach kurzer Zeit auch gesunde Ziele in der zugehörigen Target-Group wiederfinden.

Das Dashboard zeigt unseren Service samt Statusinformationen.
Das Dashboard zeigt unseren Service samt Statusinformationen.
(Bild: Drilling / AWS Germany GmbH)

Sollten die Ziele nicht gesund werden, muss man noch einmal überprüfen, ob die Sicherheitsgruppe (bei uns „EC2ContainerService-ECS-Demo“) den gesamten Datenverkehr von der Sicherheitsgruppe SG-LB erlaubt. Außerdem kann man überprüfen, bzw. sollte man bedenken, dass der Load Balancer nur fehlerfreie Ziele in den jeweils konfigurierten AZs erkennen und benutzen kann. Bei IP-basierte Zielen sähe das so aus.

Schließlich kann man sich per SSH auch auf die jeweiligen Container-Instanzen einloggen und prüfen, dass der laufende Docker-Prozess eine passende Antwort zurückgibt. Dies gelingt mit den Kommandos:

ssh ec2-18-185-86-248.eu-central-1.compute.amazonaws.comdocker ps

Über die GUI lassen sich Dienste und Tasks einfach stoppen.
Über die GUI lassen sich Dienste und Tasks einfach stoppen.
(Bild: Drilling / AWS Germany GmbH)

Stoppen lässt sich der Service dann jederzeit in der ECS-GUI, siehe die Schaltfläche oben rechts.

(ID:45994360)