Por que devemos (não) carregar o equilíbrio entre vários hosts em um cluster do Docker Swarm?

1

Temos três hosts em um cluster enxame e temos um aplicativo da web implantado nesse cluster. O aplicativo da web será executado em apenas 1 host a qualquer momento. Se um host morre, o aplicativo da web será movido para outro host.

O Docker cuidará de rotear sua solicitação para o aplicativo da Web, independentemente de qual host sua solicitação tenha atingido.

Para garantir que sempre chegaremos a um host em funcionamento, apesar de usar o Nginx está na frente. Nós criamos um host virtual no Nginx que procuraria solicitações para o enxame Docker.

Temos duas abordagens para isso.

Nós simplesmente enviamos as solicitações "round robin" pelos hosts.

Esta é uma abordagem simples. Nós usaríamos o Nginx para fazer serviços quando eles falharem. No entanto, mesmo que o Nginx tenha um erro 500 do host 1, pode ser que o aplicativo da Web tenha retornado o erro 500 do host 3. O Nginx incorretamente pensaria que o serviço falha no host 1 e retira o serviço desse host.

B. Nós direcionaríamos todos os pedidos para o líder do enxame.

Não usamos o Nginx para balancear a carga entre os hosts. Nós simplesmente enviamos todas as solicitações para o líder do Docker Swarm (através de vários scripts nós configuramos o Nginx para fazer isso). Dessa forma, não estamos fazendo balanceamento de carga "duplo" (Nginx e Docker Swarm) - mas todo o tráfego passa apenas pelo líder do Docker Swarm.

Por um lado, a solução A é simples e fácil de entender, mas também pode adicionar complexidade em termos de balanceamento de carga dupla. A segunda solução pode ser mais complicada no sentido de ser menos padronizada, mas também pode manter as coisas mais fáceis de entender.

Qual abordagem devemos, de uma perspectiva puramente técnica, preferir?

    
por sbrattla 23.01.2017 / 11:58

1 resposta

1

Acho que isso é um comentário sobre a opção 1.

Estou vendo isso também e pelo que posso dizer em Docker Swarm > 1.12 tudo o que você precisa fazer é criar um proxy reverso para o serviço / site. O que eu fiz na minha prova de conceito é, 1) criar duas redes de sobreposição, uma para uma rede proxy que será voltada para o exterior e uma para a minha rede de serviço que é interna apenas 2) implantada 3 réplicas do serviço anexando-a ao sobreposição de serviço e a rede de sobreposição de proxy (- proxy de rede - rede my-service). Finalmente, eu levantei um proxy reverso nginx que está vinculado ao meu alias corporativo, que aceitará conexões de entrada nas portas 80 e 443.

sudo docker service create --name proxy \ 
-p 80:80 \
-p 443:443 \
--network proxy \
--mount type=volume,source=reverse-proxy,target=/etc/nginx/conf.d,volume-driver=azurefile \
--mount type=volume,source=ssl,target=/etc/nginx/ssl,volume-driver=azurefile \
nginx

As montagens estão simplesmente lá, então não preciso copiar arquivos para cada host. Essa montagem está apontando para uma conta de armazenamento de arquivos do Azure que torna a criação de mais contêineres muito mais fácil de manter.

O proxy reverso é assim:

location /my-service/ {
    proxy_read_timeout 900;                
    proxy_pass http://my-service/;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

link é um registro DNS interno para enxame que sempre aponta para um VIP onde meu serviço é hospedado, seja ele de 1 nó ou 1.000 nós. Pelo que posso dizer, cada serviço que você implanta recebe seu próprio intervalo de sub-rede e os nós mestres rastreiam onde os contêineres estão sendo executados e manipulam o roteamento para você.

Atualmente, temos vários A-records apontando para os diferentes IPs de host e que usam round robin, mas podemos mover isso do DNS gerenciado do Windows Server para o Azure Traffic Manager para obter mais controle.

    
por 30.01.2017 / 21:00