Amazon ECS (Docker): vinculando contêiner a um endereço IP específico


24

Estou brincando com o Amazon ECS (uma reembalagem do Docker) e descobrindo que há um recurso do Docker que o ECS parece não fornecer. Ou seja, eu gostaria de ter vários contêineres em execução em uma instância e ter solicitações chegando no endereço IP 1 mapeadas para o contêiner 1 e solicitações chegando no endereço IP 2 mapeadas no contêiner 2, etc.

No Docker, a ligação de um contêiner a um endereço IP específico é feita via:

docker run -p myHostIPAddr:80:8080 imageName command

No entanto, no Amazon ECS, não parece haver uma maneira de fazer isso.

Eu configurei uma instância do EC2 com vários endereços IP Elastic. Ao configurar um contêiner como parte de uma definição de tarefa, é possível mapear as portas do host para as portas do contêiner. No entanto, diferentemente do Docker, o ECS não fornece uma maneira de especificar o endereço IP do host como parte do mapeamento.

Uma reviravolta adicional é que eu gostaria que as solicitações de saída do contêiner N tivessem o endereço IP externo do contêiner N.

Existe uma maneira de fazer tudo isso?

Examinei a documentação da CLI da AWS, bem como o SDK da AWS para Java. Eu posso ver que a CLI pode retornar uma matriz networkBindings contendo elementos como este:

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

e o Java SDK tem uma classe chamada NetworkBinding que representa as mesmas informações. No entanto, essas informações parecem ser apenas de saída, em resposta a uma solicitação. Não consigo encontrar uma maneira de fornecer essas informações vinculativas ao ECS.

A razão pela qual desejo fazer isso é que desejo configurar VMs completamente diferentes para diferentes constituintes, usando diferentes contêineres potencialmente na mesma instância do EC2. Cada VM teria seu próprio servidor da Web (incluindo certificados SSL distintos), bem como seu próprio serviço de FTP e SSH.

Obrigado.


Estou tendo o mesmo problema com nosso fluxo de trabalho. aws ecs describe-container-instancesparece não ajudar. Eles realmente querem pressioná-lo a usar um ELB, o que para o nosso caso é meio idiota.
four43

Parece haver uma maneira de fazê-lo agora (Q4 2017): stackoverflow.com/a/46577872/6309
VonC

Respostas:


4

Uma opção: Crie um ELB para cada cliente e atribua determinados contêineres a cada ELB.

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


13
Ca-ching! 18 dólares por mês por um ELB. Agora, quem quer microsserviços com ECS? aws.amazon.com/elasticloadbalancing/pricing
Knots

1
@ Nós tivemos o mesmo problema. Depois, mudamos para o Lambda + API Gateway e nosso custo caiu para 10 centavos.
grepe

Agora você pode usar um único ALB (em vez de ELBs clássicos) para todos os seus serviços, em vez de 1 por serviço. Eles precisam estar em nomes de host diferentes ou caminhos diferentes em um nome de host.
AJ Brown

4

Aqui está uma maneira lógica e real de fazer isso. Parece muito complicado, mas você pode implementá-lo em questão de minutos e funciona. Na verdade, estou implementando isso enquanto falamos.

Você cria uma tarefa para cada contêiner e cria um serviço para cada tarefa, juntamente com um grupo de destino para cada serviço. E então você cria apenas 1 Elastic Load Balancer.

Os balanceadores de carga elásticos baseados em aplicativo podem rotear solicitações com base no caminho solicitado. Usando os grupos de destino, você pode rotear solicitações que chegam elb-domain.com/1ao contêiner 1, elb-domain.com/2ao contêiner 2, etc.

Agora você está a apenas um passo de distância. Crie um servidor proxy reverso.

No meu caso, estamos usando o nginx, para que você possa criar um servidor nginx com quantos IPs desejar e, usando o recurso de proxy reverso do nginx, você pode rotear seus IPs para os caminhos do seu ELB, que os encaminha para o contêiner correto (s) Aqui está um exemplo se você estiver usando domínios.

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

Obviamente, se você estiver ouvindo IPs, poderá omitir a server_namelinha e apenas ouvir as interfaces correspondentes.

Na verdade, é melhor do que atribuir um IP estático por contêiner, pois permite que você tenha clusters de máquinas docker nas quais as solicitações são equilibradas sobre esse cluster para cada um dos seus "IPs". A recriação de uma máquina não afeta o IP estático e você não precisa refazer muita configuração.

Embora isso não responda totalmente à sua pergunta porque não permitirá que você use FTP e SSH, eu argumentaria que você nunca deve usar o Docker para fazer isso e, em vez disso, deve usar servidores em nuvem. Se você estiver usando o Docker, em vez de atualizar o servidor usando FTP ou SSH, atualize o próprio contêiner. No entanto, para HTTP e HTTPS, esse método funciona perfeitamente.


1

Você não pode acessar o contêiner em si, mas pode criar uma instância do EC2 dedicada a um contêiner específico. Então, onde você precisa acessar esse serviço, pode fazer referência ao host EC2 executando o contêiner.

  • Crie um cluster dedicado para seus serviços com este requisito
  • Crie uma instância do EC2 otimizada para AMI usando seu tipo de instância preferido
    • Certifique-se de atribuir essa instância ao cluster acima usando a opção UserData, conforme descrito nesse guia.
  • Crie uma TaskDefinition com o NetworkMode definido como "ponte" (igual à sua área de trabalho)
  • Crie uma definição de serviço com:
    • LaunchType definido como EC2
    • Conjunto de clusters para o cluster que você criou acima
    • Definição de tarefa definida para a definição de tarefa que você criou acima
  • Atribua quaisquer grupos de segurança à instância do EC2 como faria de outra forma.

Embora você ainda esteja falando diretamente com uma instância do EC2, você pode controlar o IP do contêiner (indiretamente) como faria com a instância do EC2. Isso evita a dor de cabeça da execução dos serviços no "bare metal", permitindo que você gerencie e configure com mais facilidade o serviço e a configuração nele.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.