Amazon ECS
Le service d'orchestration de conteneurs entièrement géré d'AWS qui vous permet de déployer, gérer et mettre à l'échelle des applications conteneurisées avec facilité.
Qu'est-ce qu'Amazon ECS ?
Imaginez que vous deviez gérer un grand nombre de colis identiques, qui doivent être transportés, surveillés et livrés à différents endroits. Au lieu de gérer chaque colis manuellement, vous utiliseriez un système logistique sophistiqué.
Amazon ECS (Elastic Container Service) est ce système logistique, mais pour les applications informatiques modernes. Il permet de gérer des "conteneurs" - des paquets standardisés contenant une application et tout ce dont elle a besoin pour fonctionner.
Pourquoi est-ce important ?
Simplicité
ECS simplifie le déploiement, la gestion et la mise à l'échelle d'applications conteneurisées, sans avoir à gérer l'infrastructure sous-jacente.
Flexibilité
Permet d'exécuter des applications dans des environnements isolés et standardisés, qui peuvent tourner de manière identique du développement à la production.
En résumé, Amazon ECS permet aux entreprises de moderniser leurs applications en utilisant des conteneurs, ce qui leur permet de les déployer plus rapidement, de les faire évoluer plus facilement et de les exécuter de manière plus cohérente, quel que soit l'environnement.
Fonctionnement technique
Amazon ECS (Elastic Container Service) est un service d'orchestration de conteneurs hautement évolutif et performant qui prend en charge les conteneurs Docker. Il vous permet d'exécuter et de gérer facilement des conteneurs sur un cluster d'instances
EC2 ou sans serveur avec AWS Fargate.
Les concepts fondamentaux
Architecture d'ECS
L'architecture d'ECS comprend plusieurs composants clés:
- Cluster : Un regroupement logique d'instances EC2 ou de tâches Fargate
- Task Definition : Un "blueprint" qui définit les conteneurs à exécuter ensemble
- Task : Une instance d'une Task Definition en cours d'exécution
- Service : Configuration qui maintient un nombre spécifié de tâches en cours d'exécution
- Container Instance : Une instance EC2 exécutant l'agent ECS (non applicable pour Fargate)
- Agent ECS : Logiciel qui permet aux instances de se connecter au cluster
Task Definition
La Task Definition est un fichier JSON qui décrit un ou plusieurs conteneurs qui forment votre application:
{
"family": "webapp",
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "webapp",
"image": "123456789012.dkr.ecr.eu-west-1.amazonaws.com/my-webapp:latest",
"essential": true,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80,
"protocol": "tcp"
}
],
"environment": [
{
"name": "NODE_ENV",
"value": "production"
},
{
"name": "DATABASE_URL",
"value": "postgres://user:password@db-host:5432/mydb"
}
],
"secrets": [
{
"name": "API_KEY",
"valueFrom": "arn:aws:ssm:eu-west-1:123456789012:parameter/myapp/api_key"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-group": "/ecs/webapp",
"awslogs-region": "eu-west-1",
"awslogs-stream-prefix": "ecs"
}
},
"healthCheck": {
"command": ["CMD-SHELL", "curl -f http://localhost/health || exit 1"],
"interval": 30,
"timeout": 5,
"retries": 3,
"startPeriod": 60
},
"memory": 512,
"cpu": 256
},
{
"name": "nginx",
"image": "nginx:latest",
"essential": true,
"portMappings": [
{
"containerPort": 443,
"hostPort": 443,
"protocol": "tcp"
}
],
"links": ["webapp"],
"memory": 256,
"cpu": 128
}
],
"requiresCompatibilities": ["FARGATE"],
"cpu": "512",
"memory": "1024",
"tags": [
{
"key": "Environment",
"value": "Production"
},
{
"key": "Application",
"value": "WebApp"
}
]
}
Configuration de service
La définition de service vous permet de maintenir un nombre spécifié de tâches en cours d'exécution simultanément:
{
"cluster": "production-cluster",
"serviceName": "webapp-service",
"taskDefinition": "webapp:3",
"desiredCount": 3,
"launchType": "FARGATE",
"platformVersion": "LATEST",
"deploymentConfiguration": {
"maximumPercent": 200,
"minimumHealthyPercent": 100,
"deploymentCircuitBreaker": {
"enable": true,
"rollback": true
}
},
"networkConfiguration": {
"awsvpcConfiguration": {
"subnets": [
"subnet-12345678",
"subnet-87654321"
],
"securityGroups": [
"sg-12345678"
],
"assignPublicIp": "ENABLED"
}
},
"loadBalancers": [
{
"targetGroupArn": "arn:aws:elasticloadbalancing:eu-west-1:123456789012:targetgroup/webapp-target-group/1234567890abcdef",
"containerName": "webapp",
"containerPort": 80
}
],
"serviceRegistries": [
{
"registryArn": "arn:aws:servicediscovery:eu-west-1:123456789012:service/srv-1234567890abcdef"
}
],
"enableECSManagedTags": true,
"propagateTags": "SERVICE",
"tags": [
{
"key": "Environment",
"value": "Production"
}
],
"schedulingStrategy": "REPLICA",
"placementConstraints": [],
"placementStrategy": [
{
"type": "spread",
"field": "attribute:ecs.availability-zone"
}
]
}
Auto Scaling
Vous pouvez configurer l'Auto Scaling pour ajuster automatiquement le nombre de tâches en fonction de métriques comme l'utilisation du CPU:
# Configuration d'Auto Scaling pour ECS avec AWS CLI
# 1. Créer une politique de dimensionnement pour le service ECS
aws application-autoscaling put-scaling-policy \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/production-cluster/webapp-service \
--policy-name cpu-tracking-scaling-policy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration '{
"TargetValue": 70.0,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ECSServiceAverageCPUUtilization"
},
"ScaleOutCooldown": 60,
"ScaleInCooldown": 60,
"DisableScaleIn": false
}'
# 2. Définir la capacité minimale et maximale
aws application-autoscaling register-scalable-target \
--service-namespace ecs \
--scalable-dimension ecs:service:DesiredCount \
--resource-id service/production-cluster/webapp-service \
--min-capacity 2 \
--max-capacity 10
# 3. Créer une alarme CloudWatch pour les métriques personnalisées
aws cloudwatch put-metric-alarm \
--alarm-name HighRequestCount \
--metric-name RequestCount \
--namespace AWS/ApplicationELB \
--statistic Sum \
--period 60 \
--threshold 1000 \
--comparison-operator GreaterThanThreshold \
--evaluation-periods 2 \
--alarm-actions arn:aws:autoscaling:eu-west-1:123456789012:scalingPolicy:policy-id \
--dimensions Name=LoadBalancer,Value=app/my-alb/1234567890abcdef Name=TargetGroup,Value=targetgroup/webapp-target-group/1234567890abcdef
Déploiement avec
CloudFormation
Voici un exemple de template CloudFormation pour déployer une application sur ECS avec Fargate:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Stack ECS avec Fargate, ALB et Auto Scaling'
Parameters:
EnvironmentName:
Type: String
Default: production
Description: Nom de l'environnement
ContainerImage:
Type: String
Description: URI de l'image container (ex: 123456789012.dkr.ecr.eu-west-1.amazonaws.com/webapp:latest)
ContainerPort:
Type: Number
Default: 80
Description: Port exposé par le container
DesiredCount:
Type: Number
Default: 2
Description: Nombre souhaité de tâches dans le service
Resources:
# Cluster ECS
ECSCluster:
Type: AWS::ECS::Cluster
Properties:
ClusterName: !Sub '${EnvironmentName}-cluster'
CapacityProviders:
- FARGATE
- FARGATE_SPOT
DefaultCapacityProviderStrategy:
- CapacityProvider: FARGATE
Weight: 1
Tags:
- Key: Environment
Value: !Ref EnvironmentName
# Définition de tâche ECS
TaskDefinition:
Type: AWS::ECS::TaskDefinition
Properties:
Family: !Sub '${EnvironmentName}-webapp'
NetworkMode: awsvpc
RequiresCompatibilities:
- FARGATE
ExecutionRoleArn: !GetAtt ECSTaskExecutionRole.Arn
TaskRoleArn: !GetAtt ECSTaskRole.Arn
Cpu: '256'
Memory: '512'
ContainerDefinitions:
- Name: webapp
Image: !Ref ContainerImage
Essential: true
PortMappings:
- ContainerPort: !Ref ContainerPort
HostPort: !Ref ContainerPort
Protocol: tcp
LogConfiguration:
LogDriver: awslogs
Options:
awslogs-group: !Ref CloudWatchLogsGroup
awslogs-region: !Ref AWS::Region
awslogs-stream-prefix: ecs
Environment:
- Name: ENVIRONMENT
Value: !Ref EnvironmentName
Tags:
- Key: Environment
Value: !Ref EnvironmentName
# Service ECS
ECSService:
Type: AWS::ECS::Service
DependsOn: ALBListener
Properties:
ServiceName: !Sub '${EnvironmentName}-webapp-service'
Cluster: !Ref ECSCluster
TaskDefinition: !Ref TaskDefinition
DesiredCount: !Ref DesiredCount
LaunchType: FARGATE
PlatformVersion: LATEST
DeploymentConfiguration:
MaximumPercent: 200
MinimumHealthyPercent: 100
DeploymentCircuitBreaker:
Enable: true
Rollback: true
NetworkConfiguration:
AwsvpcConfiguration:
Subnets: !Ref Subnets
SecurityGroups:
- !Ref ContainerSecurityGroup
AssignPublicIp: ENABLED
LoadBalancers:
- TargetGroupArn: !Ref TargetGroup
ContainerName: webapp
ContainerPort: !Ref ContainerPort
ServiceRegistries:
- RegistryArn: !GetAtt ServiceDiscoveryService.Arn
Tags:
- Key: Environment
Value: !Ref EnvironmentName
# Groupe de sécurité pour les conteneurs
ContainerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Contrôle l'accès aux conteneurs ECS
VpcId: !Ref VpcId
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref ContainerPort
ToPort: !Ref ContainerPort
SourceSecurityGroupId: !Ref ALBSecurityGroup
# Application Load Balancer
ApplicationLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub '${EnvironmentName}-alb'
Subnets: !Ref Subnets
SecurityGroups:
- !Ref ALBSecurityGroup
Tags:
- Key: Environment
Value: !Ref EnvironmentName
# Groupe cible ALB
TargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckPath: /health
HealthCheckIntervalSeconds: 30
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
UnhealthyThresholdCount: 3
Port: !Ref ContainerPort
Protocol: HTTP
TargetType: ip
VpcId: !Ref VpcId
Tags:
- Key: Environment
Value: !Ref EnvironmentName
# Écouteur ALB
ALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
LoadBalancerArn: !Ref ApplicationLoadBalancer
Port: 80
Protocol: HTTP
DefaultActions:
- Type: forward
TargetGroupArn: !Ref TargetGroup
# Auto Scaling
ScalableTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 10
MinCapacity: 2
ResourceId: !Sub 'service/${ECSCluster}/${ECSService.Name}'
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs
RoleARN: !Sub 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService'
ScalingPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub '${EnvironmentName}-target-tracking-scaling'
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref ScalableTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: ECSServiceAverageCPUUtilization
TargetValue: 70.0
ScaleInCooldown: 60
ScaleOutCooldown: 60
# Service Discovery
ServiceDiscoveryNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Name: !Sub '${EnvironmentName}.local'
Vpc: !Ref VpcId
ServiceDiscoveryService:
Type: AWS::ServiceDiscovery::Service
Properties:
Name: webapp
DnsConfig:
NamespaceId: !Ref ServiceDiscoveryNamespace
DnsRecords:
- Type: A
TTL: 60
HealthCheckCustomConfig:
FailureThreshold: 1
# Groupe de logs CloudWatch
CloudWatchLogsGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub '/ecs/${EnvironmentName}-webapp'
RetentionInDays: 30
# Rôles IAM
ECSTaskExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'
ECSTaskRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess'
- 'arn:aws:iam::aws:policy/AmazonDynamoDBReadOnlyAccess'
# Paramètres requis
Parameters:
VpcId:
Type: AWS::EC2::VPC::Id
Description: ID du VPC où déployer le service ECS
Subnets:
Type: List<AWS::EC2::Subnet::Id>
Description: Liste des sous-réseaux pour déployer le service ECS
ALBSecurityGroup:
Type: AWS::EC2::SecurityGroup::Id
Description: Groupe de sécurité pour l'ALB
Outputs:
ClusterName:
Description: Nom du cluster ECS
Value: !Ref ECSCluster
ServiceName:
Description: Nom du service ECS
Value: !GetAtt ECSService.Name
LoadBalancerDNS:
Description: DNS public de l'Application Load Balancer
Value: !GetAtt ApplicationLoadBalancer.DNSName
ServiceDiscoveryNamespace:
Description: Namespace Service Discovery
Value: !Ref ServiceDiscoveryNamespace
ServiceUrl:
Description: URL pour accéder à l'application
Value: !Sub 'http://${ApplicationLoadBalancer.DNSName}'
Modes de lancement
EC2 Launch Type : Exécute vos conteneurs sur des instances EC2 que vous gérez dans votre cluster ECS. Vous êtes responsable de la gestion de la capacité et de la configuration des instances.
- Fargate Launch Type : Option sans serveur où AWS gère l'infrastructure sous-jacente. Vous ne vous occupez que de la définition des tâches et des services, sans vous soucier des VM.
- External Launch Type : Permet d'enregistrer et de gérer des instances externes dans votre cluster ECS, comme des serveurs on-premises.
Fonctionnalités avancées
- Déploiements bleu/vert : Avec
AWS CodeDeploy, vous pouvez effectuer des déploiements avec zéro temps d'arrêt
- Service Discovery : Intégration avec AWS Cloud Map pour découvrir automatiquement les services
- Secrets et Configuration : Intégration avec AWS Secrets Manager et Parameter Store pour gérer les secrets et la configuration
- Persistent Storage : Support pour
Amazon S3 et Amazon EFS, ce qui permet aux conteneurs de partager un système de fichiers persistant
- Networking avancé : Support pour plusieurs types de réseaux, y compris awsvpc, bridge, host et none
- GPU Support : Capacité à exécuter des conteneurs qui utilisent des GPU pour des charges de travail comme le machine learning
Cas d'usage
Architectures microservices
ECS est idéal pour déployer des applications basées sur des microservices, où chaque service peut être développé, déployé et mis à l'échelle indépendamment.
Applications web et e-commerce
Les applications e-commerce et web peuvent bénéficier de l'évolutivité d'ECS, qui peut augmenter ou diminuer la capacité en fonction du trafic et de la demande.
Traitement par lots et tâches planifiées
ECS permet d'exécuter des tâches ponctuelles pour le traitement par lots, les migrations de données ou les tâches de nettoyage, avec la possibilité de les planifier.
Intégration continue et déploiement continu (CI/CD)
ECS s'intègre avec AWS CodePipeline et CodeBuild pour automatiser la construction, les tests et le déploiement d'applications conteneurisées. Il est également possible d'utiliser
GitHub Actions pour les déploiements.
Industries qui utilisent Amazon ECS
Amazon ECS est utilisé dans de nombreux secteurs pour déployer et gérer des applications modernes: