Uma opção: criar um ELB para cada cliente e, em seguida, atribuir determinados contêineres a cada ELB.
[1] link
Estou jogando com o Amazon ECS (um reempacotamento do Docker) e estou descobrindo que há um recurso do Docker que o ECS parece não oferecer. Ou seja, gostaria de ter vários contêineres em execução em uma instância e ter solicitações entrando no mapa do endereço IP 1 para o contêiner 1 e as solicitações que chegam ao endereço IP 2 são mapeadas para o contêiner 2, etc.
No Docker, a vinculação de um contêiner a um endereço IP específico é feita por meio de:
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 elásticos. Ao configurar um contêiner como parte de uma definição de tarefa, é possível mapear portas do host para portas de contêiner. No entanto, ao contrário 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 todos os itens acima?
Analisei a documentação do AWS CLI, bem como o AWS SDK for Java. Eu posso ver que a CLI pode retornar um array 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 a mesma informação. No entanto, esta informação parece ser apenas de saída, em resposta a um pedido. Não consigo encontrar uma maneira de fornecer essas informações de ligação ao ECS.
O motivo pelo qual desejo fazer isso é que desejo configurar VMs completamente diferentes para diferentes grupos, 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 FTP e SSH.
Obrigado.
Uma opção: criar um ELB para cada cliente e, em seguida, atribuir determinados contêineres a cada ELB.
[1] link
Aqui está uma maneira lógica e real de fazer isso. Parece muito complicado, mas você pode realmente 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, associado a um grupo-alvo para cada serviço. E então você cria apenas 1 Elastic Load Balancer.
Balanceadores de carga elásticos baseados em aplicativos podem rotear solicitações com base no caminho solicitado. Usando os grupos de destino, você pode rotear solicitações que chegam em 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 quiser, e usando o recurso de proxy reverso do nginx você pode rotear seus IPs para os caminhos do seu ELB, o (s) recipiente (s) 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;
}
}
É claro que, se você realmente estiver ouvindo IPs, poderá omitir a linha server_name
e apenas ouvir as interfaces correspondentes.
Na verdade, isso é melhor do que atribuir um IP estático por contêiner, porque ele permite que você tenha clusters de máquinas docker, nas quais as solicitações são balanceadas sobre esse cluster para cada um de seus "IPs". Recriar 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, pois não permitirá que você use FTP e SSH, eu diria que você nunca deve usar o Docker para fazer isso, e você 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.
Você não pode acessar o próprio container, mas pode tornar uma instância do EC2 dedicada a um contêiner específico. Então, onde você precisa acessar esse serviço, é possível referenciar o host do EC2 que está executando o contêiner.
Embora você ainda esteja falando diretamente com uma instância do EC2, é possível controlar o IP do contêiner (indiretamente) como faria na instância do EC2. Isso evita a dor de cabeça de executar os serviços no "bare metal", permitindo gerenciar e configurar facilmente o serviço e a configuração nele.