Le Blog Amazon Web Services
Guide pour tester les Conteneurs localement avec l’Endpoint d’Amazon ECS Local et Docker Compose
Alors que de plus en plus d’entreprises adoptent les conteneurs, les développeurs ont besoin de moyens simples leur permettant de tester localement leurs applications conteneurisées avant de les déployer sur AWS. L’équipe AWS en charge des conteneurs a publié le premier outil dédié au développement local : Amazon ECS Local Container Endpoints. Il fait partie d’un projet open source conçu pour améliorer le processus de développement local pour Amazon Elastic Container Service (ECS) et AWS Fargate. Cet outil vous permet de simuler les endpoints V2 et V3 pour ECS Task Metadata et les rôles IAM pour les Tasks.
Dans ce post, nous allons vous montrer les scénarios de test suivants supportés par l’endpoint d’Amazon ECS local et Docker Compose :
- Tester un conteneur qui a besoin des identifiants pour interagir avec les Services d’AWS,
- Tester un conteneur qui utilise l’API Task Metadata,
- Tester une application multi-conteneur utilisant le mode réseau
awsvpc
ouhost
sur Docker pour Mac et Docker pour Windows (dans un environnement Linux), - Tester plusieurs applications conteneurisées à l’aide de la découverte de services locaux.
Installation et prérequis
Votre environnement local consiste en Docker, Docker Compose, et awslabs/amazon-ecs-local-container-endpoints. Vous avez besoin d’une installation locale de Docker Daemon, le Docker Command Line et Docker Compose, afin de suivre le scénario décrit dans ce post.
Une fois les prérequis installés, créez un fichier Docker Compose appelé docker-compose.yml
. Le fichier Compose définit les paramètres nécessaires pour l’exécution de votre application. Si vous n’avez jamais utilisé Docker Compose, consultez le tutoriel Getting Started with Compose tutorial. Cet exemple de fichier définit une application Web :
Assurez d’enregistrer votre ficher docker-compose.yml
: il est utilisé dans l’ensemble des scénarios.
Scénario 1 : Tester un conteneur qui a besoin des identifiants AWS pour interagir avec les Services d’AWS
Supposons que nous souhaitons tester localement un conteneur qui nécessite des identifiants d’AWS. Nous pouvons fournir ces identifiants en tant que variables d’environnement dans le conteneur, mais ce serait une mauvaise pratique en terme de sécurité. Au lieu de cela, nous pouvons utiliser l’endpoint d’Amazon ECS local en toute sécurité pour avoir accès aux identifiants dans un conteneur local.
Le fichier suivant de Docker Compose définit un conteneur qui utilisera les identifiants d’AWS. Ceci doit être utilisé avec le fichier docker-compose.yml
que vous avez créé dans la section prérequis. Nommez ce fichier docker-compose.override.yml
, (Docker Compose saura utiliser automatiquement les deux fichiers).
Votre fichier docker-compose.override.yml
devrait ressembler à ceci :
Afin de tester votre conteneur localement, exécute la commande: docker-compose up
Votre conteneur sera alors exécuté et utilisera des identifiants temporaires obtenues à partir de votre profil AWS par défaut pour votre AWS Command Line Interface.
REMARQUE: vous ne devez pas utiliser vos identifiants de production localement. Si vous fournissez à ecs-local-endpoints
un profil AWS d’accès à votre compte de production, votre application pourra alors accéder aux ressources de production / les modifier à partir de votre environnement local de test. Nous vous recommandons de créer des comptes distincts pour le développement et la production.
Comment ça marche ?
Dans cet exemple, nous avons créé un User Defined Docker Bridge Network qui permet à l’endpoint d’Amazon ECS local d’écouter sur l’adresse IP 169.254.170.2
. Nous avons également défini la variable d’environnement AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
dans notre conteneur d’applications. Les AWS SDK et AWS CLI sont tous conçus pour extraire les identifiants d’AWS par les requêtes HTTP à 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
. Lorsque les conteneurs sont exécutés en production sur ECS, l’agent ECS transmet les identifiants aux conteneurs via cet endpoint; c’est ainsi que les rôles IAM pour les tâches sont implémentés.
Gotchas : Points importants à prendre en compte lors de l’utilisation de l’endpoint d’Amazon ECS local et de Docker Compose
- Assurez-vous que chaque conteneur dans le réseau
credentials_network
a une adresse IP unique. Si vous ne le faites pas, Docker Compose peut à tort tenter d’attribuer169.254.170.2
(adresse IP du conteneur ecs-local-endpoints) à l’un des conteneurs de l’application. Cela empêchera votre projet Compose de démarrer, - Sous Windows, remplacez
$HOME/.aws/
dans la déclaration de volumes du conteneur d’endpoint par l’emplacement correct du répertoire de configuration de l’AWS CLI, comme indiqué dans la documentation, - Notez que le conteneur d’application est nommé ‘app’ dans les deux fichiers d’exemple. Vous devez vous assurer que les noms des conteneurs correspondent à votre
docker-compose.yml
etdocker-compose.override.yml
. Lorsque vous exécutez docker-compos up, les fichiers sont fusionnés. Lorsque les paramètres de chaque fichier pour chaque conteneur seront fusionnés, il est donc important d’utiliser des noms de conteneurs cohérents dans les deux fichiers.
Scénario 2 : Vérification des identifiants du rôle IAM de Task ECS
Le conteneur endpoint peut également fournir des identifiants à partir d’un rôle IAM; ceci vous permet de tester votre application localement à l’aide d’un rôle IAM pour son utilisation par les ‘Tasks’ au niveau d’ECS.
REMARQUE: vous ne devez pas utiliser votre rôle IAM de Task de production localement. Créez un rôle de test distinct, avec des permissions équivalentes pour tester vos ressources developpement.
Afin d’utiliser un rôle IAM de Task localement, vous devez modifier sa stratégie d’approbation. Commencez par obtenir l’ARN de l’utilisateur IAM défini par votre profil AWS CLI par défaut
(remplacez-le par un nom de profil différent si nécessaire) :
aws --profile default sts get-caller-identity
Ensuite modifiez votre rôle IAM de Task afin que sa stratégie d’approbation comprenne l’instruction suivante. Vous pouvez trouver des instructions pour modifier les rôles IAM dans la documentation IAM.
Pour utiliser votre rôle IAM de Task dans votre fichier de Docker Compose pour les tests locaux, modifiez simplement la valeur de la variable d’environnement URI AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
dans votre conteneur d’applications:
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI: "/role/<nom de votre role>"
Par exemple, si votre rôle IAM s’appelle ecs_task_role
, la variable d’environnement doit être "/role/ecs_task_role"
. C’est tout ce qu’il faut faire; le conteneur ecs-local-endpoints
fournira maintenant les identifiants obtenues en assumant le rôle de Task. Vous pouvez l’utiliser pour vérifier si les permissions de votre rôle IAM de Task sont suffisantes pour exécuter votre application.
Scénario 3 : Tester un conteneur qui utilise l’API Task Metadata
Les endpoints de Task Metadata sont très utiles. Ils permettent en effet à un conteneur d’ECS d’obtenir des informations sur lui-même au moment de l’exécution. Cela est utile pour de nombreux cas d’utilisation. Par exemple, il vous permet d’obtenir des mesures d’utilisation des ressources du conteneur, comme montré dans ce projet.
Avec l’endpoint d’Amazon ECS local, vous pouvez tester localement les applications qui utilisent les endpoints V2 ou V3 de l’API Task Metadata. Si vous souhaitez utiliser l’endpoint V2, le template Docker Compose affiché au début de cet article suffit. Si vous souhaitez utiliser la V3, ajoutez simplement une autre variable d’environnement à chacun conteneur d’application :
ECS_CONTAINER_METADATA_URI: "http://169.254.170.2/v3"
Cette variable d’environnement est définit par le V3 metadata spec.
Scénario 4 : Tester une application multi-conteneur en utilisant le mode réseau awsvpc
Jusqu’ici, tous nos exemples consistent à tester des conteneurs dans un mode réseau bridge
. Mais que se passe-t-il si vous avez une application qui utilise le mode réseau awsvpc. Pouvez-vous tester ces applications localement ?
Votre environnement de développement local n’aura pas d’Elastic Network Interfaces. Si votre Tâche Amazon ECS consiste en un seul conteneur, le mode réseau bridge
utilisé dans les exemples précédents suffira. Cependant, si votre application consiste en plusieurs conteneurs qui doivent communiquer entre elles, le mode réseau awsvpc
est considérablement différent par rapport au mode Bridge
. Comme indiqué dans la documentation d’AWS :
“les conteneurs qui appartiennent à la même tâche peuvent communiquer via l’interface localhost
.“
Ceci est l’un des bénéfices de l’awsvpc
, il facilite la communication inter-conteneurs. Afin de la simuler localement, nous avons besoin d’un approche différente :
- Si votre environnement de développement local est Linux, c’est plus simple. Vous pouvez tester vos conteneurs en utilisant le mode réseau
host
, qui permet aux conteneurs de communiquer via localhost. Consultez la documentation ECS Local Container Endpoints Project README pour les instructions de configurer les iptables pour que vos conteneurs puissent récupérer les identifiants et les meta-données, - Si vous développez dans un environnement de Windows ou Mac, l’option précédente ne fonctionnera pas. Docker ne supporte le mode réseau
host
que sous Linux. La section suivante décrit une solution permettant de simuler localementawsvpc
dans Docker pour Mac ou Docker pour Windows. Il se sert partiellement la simulation du mode réseauhost
, dans le sens où tous vos conteneurs peuvent communiquer entre eux via localhost (d’un point de vue des tests locaux,host
etawsvpc
sont fonctionnellement identiques, l’essentiel étant que tous les conteneurs partagent une seule interface réseau).
Dans ECS, awsvpc est implémenté en créant un conteneur, appelé « pause container« . On attache une ‘Elastic Network Interface (ENI)’ à ce conteneur, puis tous les autres conteneurs de votre Tâche Amazon ECS sont lancés dans le même namespace du réseau du « pause container ». Pour la simulation locale d’awsvpc
, une approche similaire sera utilisée.
Tout d’abord, créez un Dockerfile avec le contenu suivant pour le “pause container” local.
Ce Dockerfile définie une image de conteneur qui configure les iptables et se met en veille pour toujours. Les règles de routage transfère toutes les requêtes d’identifiants ou de metadata à la destination de 169.254.170.2:80 vers localhost:51679, 169.254.170.2:80 est le port de l’endpoint d’Amazon ECS local.
Construire l’image:
Maintenant, modifiez votre fichier docker-compose.override.yml
comme ci-dessous :
Quelques points importants à noter:
ECS_LOCAL_METADATA_PORT
est 51679; c’est le port qui a été utilisé dans les règles iptables du “pause container »,network_mode
est défini ainsicontainer:local-pause
pour tous les conteneurs, ce qui signifie qu’ils utiliseront la stack réseau du conteneur ‘local-pause’,ECS_CONTAINER_METADATA_URI
esthttp://169.254.170.2/v3/containers/app
. C’est important. En mode bridge, le conteneur d’endpoints local peut identifier le conteneur qui envoie la requête grace à son adresse IP dans la requête. Dans l’awsvpc
simulé, il ne fonctionnera pas car tous les conteneurs partagent la même adresse IP. Ainsi, le conteneur d’endpoint prend en compte le nom du conteneur dans l’URI de la demande afin qu’il puisse identifier le conteneur qui envoie la requête. Dans notre cas, le conteneur est nommé app, app est donc ajoutée à la variable d’environnement. Si vous copiez la configuration du conteneur app pour ajouter d’autres conteneurs à ce fichier de Docker compose, rassurez de mettre à jour la valeur deECS_CONTAINER_METADATA_URI
pour chaque nouveau conteneur,- Supprimez toutes les déclarations de port dans le fichier docker-compose.yml. Elles ne fonctionnent pas avec la configuration de network_mode que vous utiliserez. Le texte ci-dessous explique comment exposer les ports dans ce mode réseau
awsvpc
simulé.
Avant de lancer le docker-compose, vous avez besoin de lancer le conteneur local-pause
. Nous ne pouvons pas déclarer ce conteneur dans le fichier Docker Compose, car Compose ne supporte pas l’ordre de lancement de conteneurs. Le conteneur local-pause doit être lancé avant les autres. Vous pensez peut-être au paramètre depends_on
, mais ce paramètre détermine l’ordre de démarrage des conteneurs, ce n’est pas une solution robuste.
Un point clé à noter; tous les ports utilisés par vos conteneurs d’applications doivent être déclaré dans le conteneur de local-pause
. Vous ne pouvez pas définir des ports directement dans vos conteneurs d’applications car leur mode réseau est conteneur: local-pause
. C’est une limitation imposée par Docker.
Imaginez que vos conteneurs d’applications doivent exposer les ports 8080 et 3306 (remplacez-les par les ports réels utilisés par vos applications), exécutez le conteneur local-pause
avec la commande suivante : docker run -d -p 8080:8080 -p 3306:3306 --name local-pause --cap-add=NET_ADMIN local-pause
.
Ensuite, il suffit d’exécuter les fichiers de docker compose et vous aurez des conteneurs qui partagent une seule interface réseau et ont accès aux identifiants et aux metadata !
Scénario 5 : Tester plusieurs applications conteneurisées à l’aide de la découverte de services locaux
Jusqu’a présent, tous les exemples ont porté sur l’exécution d’une seule application conteneurisée localement. Mais que se passe-t-il si vous souhaitez tester plusieurs applications exécutées en tant que Tâches ECS (Task) distinctes en production ?
Docker Compose vous permet de configurer des alias DNS pour vos conteneurs. Ceci leur permet de communiquer entre eux utilisant un hostname.
Dans cet exemple, retournez au fichier docker-compose.override.yml
avec le mode de réseau bridge des scénarios 1 à 3. Voici un exemple de fichier docker-compose.override.yml
qui implémente un scénario simple. Il y a deux applications: frontend et backend. Frontend envoie des requêtes au backend.
Avec cette configuration, le conteneur frontend
peut trouver le conteneur backend
en adressant une requête à http://backend
.
Conclusion
Dans ce post, nous avons parcouru comment utiliser Docker Compose et awslabs/amazon-ecs-local-container-endpoints pour tester vos applications Amazon ECS et AWS Fargate localement avant leur déploiement.
Vous avez appris à :
- Créer les fichiers
docker-compose.yml
etdocker-compose.override.yml
. - Tester un conteneur localement avec des identifiants temporaires à partir d’un profil AWS CLI local.
- Tester un conteneur localement à l’aide des identifiants d’un rôle IAM de ECS Task.
- Tester un conteneur localement qui utilise le Task Metadata Endpoints,
- Simuler localement le mode réseau awsvpc,
- Utiliser la découverte du service Docker Compose pour tester localement plusieurs applications dépendantes.
Pour suivre les nouveautés du projet de développement local, vous pouvez vous rendre sur le site publique AWS Containers Roadmap sur GitHub. Informez l’équipe sur Github si vous avez des questions ou des commentaires !
Ce post a été rédigé par Wesley Pettit, Développeur Logiciel chez AWS, et traduit en français par Kun Song, Architecte de Solutions chez AWS France aidant les clients français à adopter le cloud AWS, LinkedIn.