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.
fonte
aws ecs describe-container-instances
parece não ajudar. Eles realmente querem pressioná-lo a usar um ELB, o que para o nosso caso é meio idiota.Respostas:
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
fonte
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/1
ao contêiner 1,elb-domain.com/2
ao 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.
Obviamente, se você estiver ouvindo IPs, poderá omitir a
server_name
linha 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.
fonte
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.
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.
fonte