7 Práticas recomendadas para usar o Docker em produção

A adoção do Docker aumenta rapidamente e muitos estão familiarizados com ele, mas nem todos estão usando de acordo com as melhores práticas, sendo assim, siga adiante e fique por dentro das dicas!👌

A princípio, por quê usar as Melhores Práticas?
Com elas você consegue:

✅ melhorar a segurança;
✅ otimizar o tamanho da imagem;
✅ aproveitar alguns dos recursos úteis do Docker;
✅ escrever arquivos Docker mais limpos e fáceis de manter

Vamos lá?

1️⃣ Boa Prática:

Use uma imagem oficial e verificada do Docker como imagem base, sempre que disponível.

Digamos que você esteja desenvolvendo um aplicativo Node.js e queira construí-lo e executá-lo como uma imagem do Docker.

Em vez de pegar uma imagem base do sistema operacional inteiro e depois instalar node.js, npm e quaisquer outras ferramentas que você precise para seu aplicativo, use a imagem oficial do node para seu aplicativo.

Melhorias:

  • Dockerfile mais limpo;
  • Imagem oficial e verificada, já construída com as melhores práticas.

2️⃣ Boa Prática

Use versões de imagem específicas do Docker

Ok, então selecionamos a imagem base, mas agora quando construímos nossa imagem de aplicativos a partir deste Dockerfile, ela sempre usará a tag mais recente da imagem do node.

Agora, por que isso é um problema?
❌ – você pode obter uma versão de imagem diferente da versão anterior;
❌ – a nova versão da imagem pode quebrar coisas;
❌ – a última tag é imprevisível, causando um comportamento inesperado.

Portanto, em vez de uma tag de imagem mais recente aleatória, você deseja corrigir a versão e, assim como implantar seu próprio aplicativo com uma versão específica, deseja usar a imagem oficial com uma versão específica.
E a regra aqui é: quanto mais específico melhor

Melhorias:

  • Transparência para saber exatamente qual versão da imagem base você está usando.

3️⃣ Boas Práticas

Use imagens oficiais de tamanho pequeno

Ao escolher uma imagem Node.js, você verá que na verdade existem várias imagens oficiais. Não apenas com diferentes números de versão, mas também com diferentes distribuições de sistemas operacionais.

Então a pergunta é: Qual você escolhe e por que é importante?

1) Tamanho da imagem
❌ Bem, se a imagem for baseada em uma distribuição de sistema operacional completa como Ubuntu ou Centos, você terá várias ferramentas já empacotadas na imagem. Portanto, o tamanho da imagem será maior , mas você não precisa da maioria dessas ferramentas nas imagens do seu aplicativo.

✅ Em contraste, ter imagens menores significa que você precisa de menos espaço de armazenamento no repositório de imagens, bem como em um servidor de implantação e, claro, você pode transferir as imagens mais rapidamente ao puxá-las ou enviá-las do repositório.

2) Problema de segurança
❌ Além disso, com muitas ferramentas instaladas no interior, é preciso considerar o aspecto de segurança. Porque essas imagens de base geralmente contêm centenas de vulnerabilidades conhecidas e basicamente criam uma superfície de ataque maior para a imagem do seu aplicativo.

Dessa forma, você basicamente acaba introduzindo problemas de segurança desnecessários desde o início à sua imagem!

✅ Em comparação, usando imagens menores com distribuições de SO mais enxutas, que apenas agrupam o sistema necessário ferramentas e bibliotecas, você também está minimizando a superfície de ataque e garantindo a criação de imagens mais seguras .

Portanto, a melhor prática aqui seria selecionar uma imagem com uma versão específica com base em uma distribuição de sistema operacional mais enxuta, como a alpine, por exemplo:

Alpine tem tudo que você precisa para iniciar sua aplicação em um container, mas é muito mais leve. E para a maioria das imagens que você vê em um Docker Hub, você verá uma tag de versão com distribuição alpina dentro.

É uma das imagens de base mais comuns e populares para contêineres do Docker.

4️⃣ Boas Práticas

Otimize o cache para camadas de imagem ao criar uma imagem

Então, o que são camadas de imagem e o que significa cache e camada de imagem? 樂

1) O que são Camadas de Imagem?
Uma imagem do Docker é criada com base em um Dockerfile.
E em um Dockerfile cada comando ou instrução cria uma camada de imagem :
Então quando usamos uma imagem base do node alpine como no exemplo acima ele já possui camadas, pois já foi construído usando seu próprio Dockerfile. Além disso, em nosso Dockerfile, temos alguns outros comandos em que cada um adicionará uma nova camada a esta imagem.

2) E quanto ao cache?
Cada camada será armazenada em cache pelo Docker.
Portanto, quando você reconstruir sua imagem, se seu Dockerfile não tiver sido alterado, o Docker usará apenas as camadas em cache para construir a imagem.

Vantagens das camadas de imagem em cache:
✅ – Construção de imagem mais rápida;
✅ – Puxar e empurrar mais rápido de novas versões de imagem.
Se eu puxar uma nova versão de imagem do mesmo aplicativo e digamos que 2 novas camadas foram adicionadas na nova versão: Apenas as camadas recém-adicionadas serão baixadas, o restante já está armazenado em cache localmente pelo Docker.

3) Otimize o Cache
Então, para otimizar o cache, você precisa saber que:
Uma vez que uma camada é alterada, todas as camadas seguintes ou posteriores também precisam ser recriadas . Em outras palavras: quando você altera o conteúdo de uma linha no Dockerfile, os caches de todas as linhas ou camadas a seguir serão bloqueados e invalidados.

Portanto, a regra aqui e a melhor prática é:
Ordene seus comandos no Dockerfile dos comandos que mudam menos aos mais frequentes para aproveitar o armazenamento em cache e, dessa forma, otimizar a rapidez com que a imagem é criada.

5️⃣ Boas Práticas

Use o arquivo .dockerignore

Agora, geralmente, quando construímos a imagem, não precisamos de tudo que temos no projeto para executar o aplicativo dentro dele. Nós não precisamos das pastas geradas automaticamente , como a pasta build ou outra só em tempo de construção, não precisamos do arquivo readme e etc.

Então, como excluímos esse conteúdo de acabar na imagem do nosso aplicativo? Usando um arquivo .dockerignore

É bem direto. Basicamente, criamos este arquivo .dockerignore e listamos todos os arquivos e pastas que queremos que sejam ignorados e, ao construir a imagem, o Docker examinará o conteúdo e ignorará qualquer coisa especificada nele.

Melhorias:

  • Tamanho de imagem reduzido

6️⃣ Boas Práticas

Use o usuário menos privilegiado

Agora, quando criamos esta imagem e eventualmente a executamos como um container, qual usuário do sistema operacional será usado para iniciar a aplicação dentro dela?
Por padrão, quando um Dockerfile não especifica um usuário, ele usa um usuário root. Mas, na realidade, não há motivo para executar contêineres com privilégios de root.

❌ Isso basicamente introduz um problema de segurança, pois quando o contêiner é iniciado no host, ele potencialmente terá acesso root no host do Docker.
Portanto, executar um aplicativo dentro do contêiner com um usuário root tornará mais fácil para um invasor escalar privilégios no host e basicamente obter o host subjacente e seus processos, não apenas o próprio contêiner. Especialmente se o aplicativo dentro do contêiner for vulnerável à exploração.

✅ Para evitar isso, a melhor prática é simplesmente criar um usuário dedicado e um grupo dedicado na imagem do Docker para executar a aplicação e também executar a aplicação dentro do container com aquele usuário. Você pode usar uma diretiva chamada USER com o nome de usuário e, em seguida, iniciar o aplicativo convenientemente.

7️⃣ Boas Práticas

Analise suas imagens em busca de vulnerabilidades de segurança

Por fim, como você garante e valida a imagem que cria tem poucas ou nenhuma vulnerabilidade de segurança?

Uma vez que você criar a imagem , verifique vulnerabilidades de segurança usando o comando docker scan.

Em segundo plano, o Docker realmente usa um serviço chamado snyk para fazer a verificação de vulnerabilidades das imagens. A verificação usa um banco de dados de vulnerabilidades, que é atualizado constantemente.

Exemplo de saída do comando docker scan :

Você vê:
1) o tipo de vulnerabilidade
2) um URL para mais informações
3) qual versão da biblioteca relevante realmente corrige essa vulnerabilidade . Assim, você pode atualizar suas bibliotecas para se livrar desses problemas.

Automatize o scan
Além de verificar suas imagens manualmente com o comando docker scan em uma CLI, você também pode configurar o Docker Hub para verificar as imagens automaticamente , quando elas forem enviadas para o repositório. E é claro que você pode integrar essa verificação em seu pipeline de CI/CD ao criar suas imagens do Docker.

Portanto, estas são 7 práticas recomendadas de produção que você pode aplicar hoje para tornar suas imagens do Docker mais enxutas e seguras.

Esperamos que seja útil você que leu até aqui!😉

Comentários