DevSecOps

10 nov, 2016

Executando Ngynx proxy no Docker para HTTP/2

Publicidade

Este é um write-up muito rápido sobre como eu tenho executado HTTP/2 no meu servidor nos últimos dois meses, apesar de ter um sistema operacional que não suporta OpenSSL 1.0.2.

Ele usa um container Docker para executar o Nginx, construído com a mais recente distribuição Alpine Linux. Isso tem um moderno OpenSSL embutido sem trabalho extra. Ele usa as mesmas configurações do Nginx do servidor host e usa um modo de ligação de rede que não requer que eu remapeie todas as portas usando iptables/haproxy/…

Um container docker nginx para HTTP/2

A maneira realmente rápida de começar é executar este comando.

$ docker run --name nginx-container --net="host" -v /etc/nginx/:/etc/nginx/ -v /etc/ssl/certs/:/etc/ssl/certs/ -v /etc/letsencrypt/:/etc/letsencrypt/ -v /var/log/nginx/:/var/log/nginx/ --restart=always -d nginx:1.11-alpine

Assim que executado, ele se mostrará como “nginx-container”:

$ docker ps
CONTAINER ID    IMAGE               COMMAND                  CREATED        STATUS
960ee2adb381    nginx:1.11-alpine   "nginx -g 'daemon off"   6 weeks ago    Up 2 weeks

E a razão pela qual estou fazendo isso em primeiro lugar: para fazer backup do HTTP/2 no Chrome depois que eles desativaram o suporte para NPN.

http2_via_docker_container_nginx

Executar um container Docker com esses argumentos faz algumas coisas que valem a pena apontar.

Host networking no Docker

Primeiro: –net=”host” diz ao Docker daemon para não usar uma rede local e ligar a uma porta aleatória (modo “bridge”), mas usar o mesmo modelo de rede que o host no qual ele está sendo executado. Isso significa que o container quer ligar na porta: 443 ou: 80, e o host (o servidor que executa o daemon Docker) irá tratá-lo assim.

O –net=”host” também torna mais fácil usar Nginx como um proxy reverso. Todas as minhas configurações geradas no meu servidor se parecem com isto:

location / {
  proxy_pass                          http://localhost:8080;
  proxy_set_header Host               $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  https;
  proxy_read_timeout                  60;
  proxy_connect_timeout               60;
  proxy_redirect                      off;
}

Em um container Docker padrão, localhost refere-se a esse container em si, ele não tem ideia do que está sendo executado no host na porta: 8080. O –net=”host” também permite que o container Docker comunique de volta ao host, conectando-se ao serviço Apache rodando na porta :8080 no meu caso (que não é executado em um container Docker).

Adicionando configurações locais ao container

Segundo: vários parâmetros “-v”: isso adiciona pontos de dados ao seu container do docker, compartilhados pelo host. Nesse caso, estou mapeando os diretórios /etc/nginx, /etc/ssl/certs, /etc/letsencrypt e /var/log/nginx para o container do docker.

Ele também me permite reutilizar meus certificados Let’s Encrypt  existentes e renovar a lógica, como atualizar as configurações no host e ler os containers.

Há um pequeno atrativo: uma mudança nos certificados SSL precisa de uma recarga do Nginx daemon, que agora significa uma recarga do container Docker.

Reinicie o container quando ele quebrar

Terceiro: –restart=always fará com que o container reinicie automaticamente, no caso de o Nginx daemon estar sendo executado dentro dele falhasse ou segfault.

Use a imagem Ngynx docker oficial

Quarto: -d nginx: 1.11-alpine usa o container oficial do Nginx, construído na distribuição Alpine.

A primeira vez que você executá-lo, ele vai baixar essa imagem do hub Docker e armazená-la localmente.

Gerenciamento de configuração no container

Ao vincular meus diretórios diretamente no host dentro do container, posso continuar usando o mesmo gerenciamento de configuração que venho utilizando há anos.

Por exemplo, minha configuração Puppet irá gravar arquivos em /etc/nginx. Porque eu mapeei isso no container Docker, aquele container obtém as configurações exatamente iguais.

Gerenciamento de configuração é essencialmente no host, tempo de execução, no container. Isso torna consideravelmente mais fácil implementar Docker se você puder reutilizar containers pré-fabricados e fornecê-lo com suas próprias configurações.

Os desafios com Docker

Claro, há muitos. Eu sei o que há nesse container? Não totalmente. Eu confio em quem fez aquele container? Apenas parcialmente. Quem atualiza o Nginx nesse contêiner quando ocorre uma vulnerabilidade crítica? Eu não tenho ideia.

É um salto de fé, para ser honesto – o tempo dirá se vale a pena.

***

Mattias Geniar faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: https://ma.ttias.be/run-nginx-proxy-docker-container-http2/.