Amazon ECS (Docker): liaison du conteneur à une adresse IP spécifique

24

Je joue avec Amazon ECS (un reconditionnement de Docker) et je trouve qu'il n'y a qu'une capacité Docker que ECS ne semble pas fournir. À savoir, je voudrais que plusieurs conteneurs s'exécutent dans une instance, et que les demandes entrant dans l'adresse IP 1 mappent vers le conteneur 1, et les demandes venant vers l'adresse IP 2 mappent vers le conteneur 2, etc.

Dans Docker, la liaison d'un conteneur à une adresse IP spécifique se fait via:

docker run -p myHostIPAddr:80:8080 imageName command

Cependant, dans Amazon ECS, il ne semble pas y avoir de moyen de le faire.

J'ai configuré une instance EC2 avec plusieurs adresses IP Elastic. Lors de la configuration d'un conteneur dans le cadre d'une définition de tâche, il est possible de mapper des ports hôtes à des ports conteneurs. Cependant, contrairement à Docker, ECS ne fournit aucun moyen de spécifier l'adresse IP de l'hôte dans le cadre du mappage.

Une autre torsion est que je voudrais que les requêtes sortantes du conteneur N aient l'adresse IP externe du conteneur N.

Existe-t-il un moyen de faire tout ce qui précède?

J'ai parcouru la documentation de l'AWS CLI, ainsi que le kit AWS SDK pour Java. Je peux voir que la CLI peut renvoyer un tableau networkBindings contenant des éléments comme celui-ci:

{
  "bindIP": "0.0.0.0", 
  "containerPort": 8021, 
  "hostPort": 8021
},

et le SDK Java possède une classe nommée NetworkBinding qui représente les mêmes informations. Cependant, ces informations semblent être uniquement en sortie, en réponse à une demande. Je ne trouve aucun moyen de fournir ces informations de liaison à ECS.

La raison pour laquelle je veux le faire est que je veux configurer des machines virtuelles complètement différentes pour différentes circonscriptions, en utilisant différents conteneurs potentiellement sur la même instance EC2. Chaque machine virtuelle aurait son propre serveur Web (y compris des certificats SSL distincts), ainsi que son propre service FTP et SSH.

Merci.

Mark R
la source
J'ai le même problème avec notre flux de travail. aws ecs describe-container-instancesne semble pas aider. Ils semblent vraiment vouloir vous pousser à utiliser un ELB, ce qui dans notre cas est un peu stupide.
four43
Il semble y avoir une façon de le faire maintenant (T4 2017): stackoverflow.com/a/46577872/6309
VonC

Réponses:

4

Une option: créer un ELB pour chaque client, puis affecter certains conteneurs à chaque ELB.

[1] http://docs.aws.amazon.com/AmazonECS/latest/developerguide/service-load-balancing.html

Adam Keck
la source
13
Ca-ching! 18 dollars par mois pour un ELB. Maintenant, qui veut des microservices avec ECS? aws.amazon.com/elasticloadbalancing/pricing
Noeuds
1
@Knots, nous avons eu le même problème. Ensuite, nous sommes passés à Lambda + API Gateway et notre coût est tombé à 10 cents.
grepe
Vous pouvez désormais utiliser un seul ALB (au lieu des ELB classiques) pour tous vos services au lieu de 1 par service. Ils doivent être sur des noms d'hôtes différents ou sur des chemins différents sur un nom d'hôte.
AJ Brown
4

Voici une façon réelle et logique de le faire. Cela semble trop compliqué, mais vous pouvez réellement l'implémenter en quelques minutes, et cela fonctionne. Je le mets en œuvre en ce moment même.

Vous créez une tâche pour chaque conteneur et vous créez un service pour chaque tâche, couplé à un groupe cible pour chaque service. Et puis vous créez juste 1 Elastic Load Balancer.

Les équilibreurs de charge élastiques basés sur l'application peuvent acheminer les demandes en fonction du chemin demandé. À l'aide des groupes cibles, vous pouvez acheminer les demandes provenant elb-domain.com/1du conteneur 1, elb-domain.com/2du conteneur 2, etc.

Vous n'êtes plus qu'à un pas. Créez un serveur proxy inverse.

Dans mon cas, nous utilisons nginx, vous pouvez donc créer un serveur nginx avec autant d'adresses IP que vous le souhaitez, et en utilisant la fonction de proxy inverse de nginx, vous pouvez router vos adresses IP vers les chemins de votre ELB, qui les acheminent en conséquence vers le conteneur approprié (s). Voici un exemple si vous utilisez des domaines.

server {
    server_name domain1.com;
    listen 80;
    access_log /var/log/nginx/access.log vhost;
    location / {
        proxy_pass http://elb-domain.com/1;
    }
}

Bien sûr, si vous écoutez réellement des adresses IP, vous pouvez omettre la server_nameligne et simplement écouter les interfaces correspondantes.

C'est en fait mieux que d'attribuer une IP statique par conteneur car cela vous permet d'avoir des clusters de machines docker où les demandes sont équilibrées sur ce cluster pour chacune de vos "IP". La recréation d'une machine n'affecte pas l'IP statique et vous n'avez pas à refaire beaucoup de configuration.

Bien que cela ne réponde pas entièrement à votre question car cela ne vous permettra pas d'utiliser FTP et SSH, je dirais que vous ne devriez jamais utiliser Docker pour le faire, et vous devriez plutôt utiliser des serveurs cloud. Si vous utilisez Docker, au lieu de mettre à jour le serveur via FTP ou SSH, vous devez mettre à jour le conteneur lui-même. Cependant, pour HTTP et HTTPS, cette méthode fonctionne parfaitement.

TheNavigat
la source
1

Vous ne pouvez pas accéder au conteneur lui-même, mais vous pouvez créer une instance EC2 dédiée à un conteneur spécifique. Ensuite, là où vous devez accéder à ce service, vous pouvez référencer l'hôte EC2 exécutant le conteneur.

  • Créez un cluster dédié pour vos services avec cette exigence
  • Créez une instance EC2 optimisée AMI en utilisant votre type d'instance préféré
    • Assurez-vous d'affecter cette instance au cluster ci-dessus à l'aide de l'option UserData comme décrit dans ce guide.
  • Créer une définition de tâche avec NetworkMode défini sur "pont" (identique à votre bureau)
  • Créez une définition de service avec:
    • LaunchType défini sur EC2
    • Cluster défini sur le cluster que vous avez créé ci-dessus
    • Définition de tâche définie sur la définition de tâche que vous avez créée ci-dessus
  • Attribuez des groupes de sécurité à l'instance EC2 comme vous le feriez autrement.

Bien que vous parliez toujours directement à une instance EC2, vous pouvez contrôler (indirectement) l'IP du conteneur comme vous le feriez pour l'instance EC2. Cela vous évite le casse-tête de l'exécution des services sur le "bare metal" vous permettant de gérer et de configurer plus facilement le service et la configuration qui s'y trouve.

Patrick Twohig
la source