Docker-Orchestrierung mit Amazon ECS – das Tutorial

© Shutterstock / furtseff
Container auf dem eigenen Rechner zu starten, ist dank Docker kein Problem mehr. Was aber, wenn man seine Container auch in Produktion laufen lassen will? Womöglich sogar in der Cloud? Eine Möglichkeit, Container zu orchestrieren ist Amazon ECS. Dieser Artikel zeigt unterschiedliche Wege, wie sich ein ECS-Cluster erstellen lässt und ein Service darauf laufen kann.
Der EC2 Container Service (ECS) ist ein skalierbarer Containermanagementservice von AWS, der Docker-Container unterstützt und es erlaubt, Anwendungen auf einem verwalteten Cluster von EC2 Instances zu betreiben. Die Basis eines ECS-Clusters bilden eine oder mehrere Containerinstanzen. Der Name ist etwas unglücklich gewählt, da es eigentlich keine Container sind, sondern EC2-Instanzen mit einem angepassten Amazon AMI, auf dem Docker installiert ist und ein ECS-Agent als Container läuft.
Der große Vorteil im Vergleich zu Docker Swarm oder Kubernetes besteht darin, dass keine dedizierten Containerinstanzen nötig sind, auf denen der Cluster State gespeichert werden muss. Dieser wird von AWS verwaltet, und die Containerinstanzen bekommen die benötigten Informationen via API. Allerdings steckt hinter ECS kein fully managed Service – der Entwickler muss sich selbst um sein Cluster kümmern. Auto Scaling, Monitoring, Logging und Node Draining muss er erledigen. Glücklicherweise sind die meisten Tools und Services bereits vorhanden, und es gilt, sie nur noch zusammenzustecken. In einem Cluster lassen sich sowohl Tasks als auch Services starten. Tasks werden nur einmalig gestartet, wohingegen ein Service dafür sorgt, dass immer eine bestimmte Anzahl an Tasks läuft. Der Service kümmert sich auch darum, dass Tasks automatisch am Load Balancer an- bzw. abgemeldet werden. Um ein ECS-Cluster zu erstellen und Services darauf zu starten, bietet AWS vier verschiedene Möglichkeiten an.
AWS Console
Auch wenn der Name zuerst etwas anderes vermuten lässt, verbirgt sich hinter der AWS Console nichts anderes als ein Web-UI. Hiermit lassen sich der gesamte AWS-Account sowie die dazugehörigen Dienste verwalten. In der Navigation kann der Anwender zu jedem einzelnen Dienst wechseln, den er damit konfigurieren kann. Um ein ECS-Cluster zu erstellen, wechselt der Nutzer zum EC2 Container Service, klickt auf Cluster erstellen und lässt sich vom Assistenten führen (Abb. 1). Nach der Eingabe der wichtigsten Parameter dauert es nur wenige Minuten, bis das Cluster zur Verfügung steht.
Bevor der ECS-Service erstellt werden, kann fehlt allerdings noch eine Taskdefinition. Hier werden unter anderem das Docker Image und die Parameter angegeben, mit denen der Container gestartet werden soll. In der Clusterübersicht kann nun der ECS-Service erstellt werden. Die soeben erstellte Taskdefinition steht auch als Auswahl zur Verfügung.
Lesen Sie auch: Grundkurs Docker: Eine praktische Einführung in die Welt der Container
Die AWS Console eignet sich besonders für den ersten Kontakt mit ECS. Das UI ist übersichtlich gestaltet und kaschiert viel der dahinterliegenden Komplexität. Beim Service lassen sich sowohl Auto Scaling als auch der Load Balancer konfigurieren, und für Task Placement sind bereits typische Vorlagen vorhanden (Abb. 2). Für den produktiven Betrieb empfiehlt sich ein solches hand-rolled Cluster allerdings nicht unbedingt, da die Konfiguration nicht gespeichert bzw. versioniert ist und sich das Set-up nicht automatisieren lässt.
AWS CLI
Um AWS auch programmatisch nutzen zu können, bietet er nicht nur diverse SDKs, sondern auch das CLI (Command Line Interface) an. Ähnlich wie im Web-UI lässt sich jeder Dienst über ein eigenes Subcommand verwalten. Sämtliche API-Aufrufe lassen sich per Kommandozeile ausführen.
Cluster
Ein ECS-Cluster besteht aus mehreren Ressourcen, z. B. Launch Configuration, Security Group, Auto Scaling Group usw., die jeweils mit einem eigenen Kommando angelegt werden müssen (Listing 1). Manchmal muss der Anwender Abhängigkeiten berücksichtigen, da IDs einer erzeugten Ressource als Parameter beim Anlegen anderer Ressourcen benötigt werden. Das folgende Script zeigt, welche Kommandos mindestens erforderlich sind. Es setzt voraus, dass ein VPC bereits existiert.
aws ecs create-cluster --cluster-name ecs-demo-awscli aws ec2 create-security-group --group-name ecs-demo-awscli-sg --description "ecs demo awscli" --vpc-id vpc-1a2b3c4d aws autoscaling create-launch-configuration \ --launch-configuration-name ecs-demo-awscli-launchconfig \ --key-name mykey \ --image-id ami-c74127b4 \ --instance-type t2.micro \ --iam-instance-profile ecsInstanceRole \ --security-groups sg-1a2b3c4d \ --user-data file://ecs-demo-awscli-userdata.txt aws autoscaling create-auto-scaling-group \ --auto-scaling-group-name ecs-demo-awscli-asg \ --launch-configuration-name ecs-demo-awscli-launchconfig \ --min-size 1 --max-size 3 \ --vpc-zone-identifier subnet-1a2b3c4d
Service
Um einen Service zu erstellen, ist zuerst eine Taskdefinition nötig, die sich mit folgendem Kommando registrieren lässt:
aws ecs register-task-definition --cli-input-json file://./taskdefinition.json
Anschließend lässt sich der Service erstellen:
aws ecs create-service --service-name ecs-demo-service --cli-input-json file://service.json
Bei beiden Aufrufen ist die eigentliche Konfiguration als lokale JSON-Datei abgespeichert, was für deutlich mehr Übersicher bzgl. der Kommandos sorgt. (Diese Dateien sind AWS-spezifisch und haben nichts mit dem Dockerfile oder Docker Compose gemeinsam.)
Vor- und Nachteile
Obwohl sich mit dem CLI ein Cluster automatisiert anlegen lässt, erweist sich diese Methode doch als sehr umständlich. Bereits beim Erstellen braucht es mehrere Kommandos, die in der richtigen Reihenfolge ausgeführt werden müssen. Beim Aktualisieren müsste der Programmierer bei jeder Ressource anhand des Namens prüfen, ob sie schon existiert und gegebenenfalls aktualisieren statt erstellen. Um diese Komplexität zu vereinfachen, existiert zusätzlich zum AWS CLI noch das ECS CLI.
ECS CLI
Das ECS CLI [1] bietet, wie der Name schon sagt, ECS-relevante Befehle an. Der Vorteil dabei ist, dass mehrere API-Aufrufe, die normalerweise nötig sind, um ein ECS-Cluster zu erstellen, durch einen einzelnen Befehl ersetzt werden. Zusätzlich ist es möglich, einen ECS-Service automatisch auf Basis des Docker-Compose-Formats zu erstellen.
Cluster
Mit configure übermittelt der Entwickler dem CLI einmalig, welches Cluster er verwenden will (auch wenn es noch nicht existiert), und mit up wird anschließend das Cluster erzeugt:
ecs-cli configure --cluster ecs-demo-ecscli --region eu-west-1
ecs-cli up --keypair mykey --capability-iam --size 2
Mittels Parametern lässt sich das Cluster konfigurieren (z. B. InstanceType oder Anzahlinstanzen), allerdings ist die Auswahl eingeschränkt, da zu viele zu Verwirrung führten. Ein wichtiger Teil, der mit dem ECS CLI nicht angelegt wird, ist Auto Scaling. Ähnlich wie in der AWS Console, kommt auch hier im Hintergrund CloudFormation zum Einsatz, um das Cluster zu erstellen.
Service
Normalerweise verlangt ECS die Erstellung einer Service- und Taskdefinition, um einen Container zu starten. Viele der benötigten Informationen sind oftmals schon in docker-compose.yaml konfiguriert, um seine Anwendung lokal laufen zu lassen. Eine eigene Taskdefinition fühlt sich dabei wie eine Kopie an. Hierbei hilft das ECS CLI, da mit compose automatisch aus docker-compose.yaml eine Taskdefinition generiert und ein ECS-Service gestartet wird.
ecs-cli compose --file docker-compose.yaml service up
Vor- und Nachteile
Einfacher als mit dem ECS CLI lässt sich kein Cluster in der Kommandozeile erstellen. Gerade beim Entwickeln, um schnell etwas auszuprobieren, oder ein Proof of Concept zu erstellen, erweist sich das ECS CLI als ideal. Für den produktiven Betrieb eignet es sich nicht, da einige Einstellungen nicht unterstützt werden und mit dem AWS CLI zusätzlich konfiguriert werden müssten.
CloudFormation
CloudFormation ist ein Service von AWS, um Infrastructure as Code [2] zu betreiben. Dazu wird der gewünschte Zielzustand aller benötigten Ressourcen im YAML- (oder JSON-)Format beschrieben. CloudFormation kümmert sich anschließend darum, diesen Zielzustand zu erreichen. Fehlende Ressourcen werden dabei automatisch erstellt, geänderte aktualisiert und nicht mehr benötigte gelöscht. Ressourcen werden dabei über ihre Namen, die automatisch von CloudFormation generiert werden, identifiziert.
Cluster
Es gibt bereits gute CloudFormation-Templates, z. B. AWS Labs [3] oder Cloudonout [4], die ein Entwickler als Grundlage für ein eigenes Cluster verwenden kann. Durch Parameter lassen sich die wichtigsten Einstellungen, wie der EC2 Instance Type, konfigurieren. Mithilfe des Templates wird in CloudFormation ein sogenannter Stack erzeugt. Dieser Stack lässt sich sowohl über die AWS Console als auch das CLI anlegen. Änderungen am Template oder den Parametern werden als Stack-Update an CloudFormation übermittelt. Dabei darf sich der Name des Stacks nicht ändern.
aws cloudformation create-stack \
--stack-name ecs-demo-cloudformation \
--capabilities CAPABILITY_IAM \
--parameters ParameterKey=KeyName,ParameterValue=mykey \
--template-body file://stack.yaml
Service
Für einen Service erscheint es sinnvoll, ein separates CloudFormation-Template zu erstellen und den Namen des Clusters aus dem anderen Stack zu importieren. Listing 2 zeigt ein Template, das die minimalste Konfiguration enthält.
AWSTemplateFormatVersion: '2010-09-09' Parameters: DesiredInstances: Description: How many instances of this task should run? Type: Number Default: 2 Resources: Service: Type: AWS::ECS::Service Properties: Cluster: !ImportValue 'ParentECSStack-ClusterName' Role: 'ecsServiceRole' DesiredCount: !Ref DesiredInstances TaskDefinition: !Ref TaskDefinition TaskDefinition: Type: AWS::ECS::TaskDefinition Properties: Family: nginx ContainerDefinitions: - Name: nginx Essential: true Image: nginx Memory: 128 PortMappings: - ContainerPort: 80
Vor- und Nachteile
Beim ersten Mal können die oftmals langen CloudFormation-Templates sehr unübersichtlich und kompliziert wirken. Wer sich allerdings erst einmal daran gewöhnt hat, möchte es gar nicht mehr hergeben. Einfach definieren, was man will: CloudFormation kümmert sich um den Rest, und die gesamte Konfiguration kann versioniert im VCS abgelegt werden. Ein kleiner Wermutstropfen dabei besteht darin, dass es meist etwas dauert, bis neue Features (von ECS) auch in CloudFormation unterstützt werden.
AWS Console | AWS CLI | ECS CLI | CloudFormation | |
Einfach zu starten | ja | nein | ja | nein |
Automatisierung | nein | ja | ja | ja |
Infrastructure as Code | nein | nein | teilweise | ja |
Auto Scaling | ja | ja | nein | ja |
Load Balancer | ja | ja | teilweise | ja |
Task Placement | ja | ja | nein | ja |
Tabelle 1: Deployment-Optionen beim ECS-Cluster
AWS Console | AWS CLI | ECS CLI | CloudFormation | |
Einfach zu starten | ja | nein | ja | nein |
Automatisierung | nein | ja | ja | ja |
Infrastructure as Code | nein | nein | nein | ja |
Auto Scaling | ja | ja | nein | ja |
Tabelle 2: Deployment-Optionen beim ECS-Service
Fazit
Der Start mit ECS ist schnell erledigt. Ob mithilfe der Weboberfläche, der Konsole oder CloudFormation dauert es im Idealfall nur wenige Minuten, ein Cluster zu erstellen und seine erste Anwendung zu deployen. Spannend wird es bei der Frage, wie sich Container hinter einem Load Balancer betreiben lassen, und was man tun muss, um sowohl das ECS-Cluster als auch ECS-Services automatisch zu skalieren (Tabelle 1 und Tabelle 2). Das passiert beispielsweise, wenn Containerinstanzen aktualisiert werden müssen.
LESEN SIE AUCH:
10 kreative Wege, Docker Images zu bauen: Dockerfile & Docker Commit
[1] ECS CLI: https://github.com/aws/amazon-ecs-cli
[2] Infrastructure as Code: https://martinfowler.com/bliki/InfrastructureAsCode.html
[3] AWS Labs: https://github.com/awslabs/ecs-refarch-cloudformation/
[4] Cloudonout: http://templates.cloudonaut.io/en/stable/ecs/
Hinterlasse einen Kommentar