Eu tenho um DNS curinga configurado para que todas as solicitações da web para um domínio personalizado (* .foo) sejam mapeadas para o endereço IP do host Docker. Se eu tiver vários contêineres executando instâncias do Apache (ou Nginx), cada contêiner mapeia a porta do Apache (80) para alguma porta de entrada externa.
O que eu gostaria de fazer é fazer uma solicitação para container-1.foo, que já está mapeado para o endereço IP correto (do host Docker) por meio do meu servidor DNS personalizado, mas proxy da solicitação da porta 80 padrão para o Docker externo correto porta de modo que a instância correta do Apache do contêiner especificado seja capaz de responder com base no domínio personalizado. Da mesma forma, container-2.foo procuraria o apache de um segundo container e assim por diante.
Existe uma solução pré-construída para isso, minha melhor aposta é executar um proxy Nginx no host Docker ou devo escrever um proxy node.js com potencial para gerenciar contêineres Docker (iniciar / parar / reconstruir via web ), ou ...? Quais opções eu tenho que tornariam o uso dos contêineres do Docker mais parecido com um evento natural e não algo com portas estranhas e malabarismo de contêiner?
Respostas:
Esta resposta pode demorar um pouco, mas o que você precisa é de um proxy reverso automático. Usei duas soluções para isso:
Com o tempo, minha preferência é usar o Traefik. Principalmente porque é bem documentado e mantido, e vem com mais recursos (balanceamento de carga com diferentes estratégias e prioridades, verificações de saúde, disjuntores, certificados SSL automáticos com ACME / Let's Encrypt, ...).
Usando jwilder / nginx-proxy
Ao executar um contêiner do Docker , a imagem nginx-proxy do Docker de Jason Wilder , você obtém um servidor nginx configurado como um proxy reverso para seus outros contêineres sem configuração para manter.
Basta executar seus outros contêineres com a
VIRTUAL_HOST
variável de ambiente e o nginx-proxy descobrirá seu ip: port e atualizará a configuração do nginx para você.Digamos que seu DNS esteja configurado para
*.test.local
mapear o endereço IP de seu host Docker e, em seguida, basta iniciar os seguintes contêineres para obter uma demonstração rápida em execução:# start the reverse proxy docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy # start a first container for http://tutum.test.local docker run -d -e "VIRTUAL_HOST=tutum.test.local" tutum/hello-world # start a second container for http://deis.test.local docker run -d -e "VIRTUAL_HOST=deis.test.local" deis/helloworld
Usando Traefik
Ao executar um contêiner Traefik , você obtém um servidor proxy reverso configurado que reconfigurará suas regras de encaminhamento de acordo com os rótulos do docker encontrados em seus contêineres.
Digamos que seu DNS esteja configurado para
*.test.local
mapear o endereço IP de seu host Docker e, em seguida, basta iniciar os seguintes contêineres para obter uma demonstração rápida em execução:# start the reverse proxy docker run --rm -it -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock traefik:1.7 --docker # start a first container for http://tutum.test.local docker run -d -l "traefik.frontend.rule=Host:tutum.test.local" tutum/hello-world # start a second container for http://deis.test.local docker run -d -l "traefik.frontend.rule=Host:deis.test.local" deis/helloworld
fonte
-v /var/run/docker.sock:/tmp/docker.sock
É uma solução perigosa? O contêiner deste proxy nginx tem acesso ao daemon do host do docker? Isso pode ser uma possível falha de segurança?/var/run/docker.sock
também não é uma garantia de que o host docker não pode ser explorado a partir de um contêiner. A segurança do Docker é um assunto à parte.Aqui estão duas respostas possíveis: (1) configurar portas diretamente com Docker e usar Nginx / Apache para fazer proxy dos vhosts, ou (2) usar Dokku para gerenciar portas e vhosts para você (que é como aprendi a fazer o Método 1).
Método 1a (atribuir portas diretamente com docker)
Etapa 1: configure nginx.conf ou Apache no host, com as atribuições de número de porta desejadas. Este servidor web, rodando no host, fará o proxy vhost. Não há nada de especial nisso em relação ao Docker - é uma hospedagem vhost normal. A parte especial vem a seguir, na Etapa 2, para fazer o Docker usar o número de porta do host correto.
Etapa 2: force as atribuições de número de porta no Docker com "-p" para definir os mapeamentos de porta do Docker e "-e" para definir variáveis de ambiente personalizadas no Docker, da seguinte maneira:
port=12345 # <-- the vhost port setting used in nginx/apache IMAGE=myapps/container-1 id=$(docker run -d -p :$port -e PORT=$port $IMAGE) # -p :$port will establish a mapping of 12345->12345 from outside docker to # inside of docker. # Then, the application must observe the PORT environment variable # to launch itself on that port; This is set by -e PORT=$port. # Additional goodies: echo $id # <-- the running id of your container echo $id > /app/files/CONTAINER # <-- remember Docker id for this instance docker ps # <-- check that the app is running docker logs $id # <-- look at the output of the running instance docker kill $id # <-- to kill the app
Método 1b Porta de aplicativo codificada
... se seu aplicativo usa uma porta codificada, por exemplo a porta 5000 (ou seja, não pode ser configurada por meio da variável de ambiente PORT, como no Método 1a), então ela pode ser codificada por meio do Docker como este:
publicPort=12345 id=$(docker run -d -p $publicPort:5000 $IMAGE) # -p $publicPort:5000 will map port 12345 outside of Docker to port 5000 inside # of Docker. Therefore, nginx/apache must be configured to vhost proxy to 12345, # and the application within Docker must be listening on 5000.
Método 2 (deixe Dokku descobrir as portas)
No momento, uma boa opção para gerenciar vhosts do Docker é o Dokku . Uma opção futura pode ser usar Flynn , mas no momento Flynn está apenas começando e ainda não está pronto. Portanto, vamos com o Dokku por enquanto: Após seguir as instruções de instalação do Dokku, para um único domínio, habilite o vhosts criando o arquivo "VHOST":
echo yourdomain.com > /home/git/VHOST # in your case: echo foo > /home/git/VHOST
Agora, quando um aplicativo é enviado via SSH para Dokku (consulte os documentos do Dokku para saber como fazer isso), o Dokku vai olhar para o arquivo VHOST e para o aplicativo enviado (digamos que você tenha enviado "container-1"), ele irá gerar o seguinte arquivo:
E terá o seguinte conteúdo:
Quando o servidor for reinicializado, o Dokku garantirá que o Docker inicie o aplicativo com a porta mapeada para sua porta inicialmente implantada (49162 aqui), em vez de receber outra porta aleatoriamente. Para alcançar essa atribuição determinística, o Dokku salva a porta inicialmente atribuída
/home/git/container-1/PORT
e na próxima inicialização, ele define oPORT
ambiente com esse valor e também mapeia as atribuições de porta do Docker para ser esta porta no lado do host e no lado do aplicativo. Isso se opõe ao primeiro lançamento, quando Dokku irá definirPORT=5000
e então descobrir qualquer porta aleatória que o Dokku mapeie no lado VPS para 5000 no lado do aplicativo. É redondo (e pode até mudar no futuro), mas funciona!O modo como o VHOST funciona, por baixo do capô, é: ao fazer um push git do aplicativo via SSH, o Dokku executará ganchos que residem no
/var/lib/dokku/plugins/nginx-vhosts
. Esses ganchos também estão localizados no código-fonte do Dokku aqui e são responsáveis por gravar osnginx.conf
arquivos com as configurações corretas de vhost. Se você não tiver esse diretório/var/lib/dokku
, tente executardokku plugins-install
.fonte
Com o docker, você deseja que os ips internos permaneçam normais (por exemplo, 80) e descubra como conectar as portas aleatórias.
Uma maneira de lidar com eles é com um proxy reverso como o hipache. Aponte seu DNS para ele e, em seguida, você pode reconfigurar o proxy conforme seus contêineres sobem e descem. Dê uma olhada em http://txt.fliglio.com/2013/09/protyping-web-stuff-with-docker/ para ver como isso pode funcionar.
Se você estiver procurando por algo mais robusto, pode dar uma olhada em "descoberta de serviço". (uma olhada na descoberta de serviço com docker: http://txt.fliglio.com/2013/12/service-discovery-with-docker-docker-links-and-beyond/ )
fonte