Docker de baixo para cima: construindo imagens

Os contêineres do Docker estão em ascensão como uma prática recomendada para implantar e gerenciar sistemas distribuídos nativos da nuvem. Os contêineres são instâncias de imagens do Docker. Acontece que há muito para saber e entender sobre imagens.

Neste tutorial de duas partes, estou abordando as imagens do Docker em profundidade. Na primeira parte, discuti os princípios básicos, considerações de design e inspeção de imagens internas. Nesta parte, abordo a criação de suas próprias imagens, a solução de problemas e o trabalho com repositórios de imagens.

Quando você sair do outro lado, terá uma compreensão sólida do que são exatamente as imagens do Docker e como utilizá-las efetivamente em seus próprios aplicativos e sistemas.

Imagens de construção

Existem duas maneiras de construir imagens. Você pode modificar um contêiner existente e, em seguida, confirmá-lo como uma nova imagem ou pode escrever um Dockerfile e construí-lo em uma imagem. Analisaremos ambos e explicaremos os prós e os contras.

Compilações manuais

Com as compilações manuais, você trata seu contêiner como um computador normal. Você instala pacotes, escreve arquivos e, quando tudo está dito e feito, você o confirma e acaba com uma nova imagem que usa como modelo para criar muitos outros contêineres idênticos ou até mesmo basear outras imagens.

Vamos começar com a imagem alpine, que é uma imagem muito pequena e espartana baseada no Alpine Linux. Podemos executá-lo no modo interativo para entrar em um shell. Nosso objetivo é adicionar um arquivo chamado “yeah” que contenha o texto “it works!” para o diretório raiz e, em seguida, crie uma nova imagem chamada “yeah-alpine”.

Aqui vamos nós. Legal, já estamos no diretório raiz. Vamos ver o que há.

Qual editor está disponível? Sem vim, sem nano?

Ah bem. Queremos apenas criar um arquivo:

Saí do shell interativo e posso ver o contêiner chamado “vibrant_spenc” com docker ps --all. o --all sinalizador é importante porque o contêiner não está mais em execução.

Aqui, crio uma nova imagem do contêiner “vibrate_spence”. Eu adicionei a mensagem de commit “meu, meu, meu” para garantir.

Vamos dar uma olhada. Sim, há uma nova imagem, e em seu histórico você pode ver uma nova camada com o comentário “meu, meu, meu”.

Agora, para o teste real. Vamos deletar o container e criar um novo container a partir da imagem. O resultado esperado é que o sim arquivo estará presente no novo contêiner.

O que posso dizer? Sim, funciona!

Usando um Dockerfile

Criar imagens a partir de contêineres modificados é legal, mas não há responsabilidade. É difícil acompanhar as mudanças e saber quais foram as modificações específicas. A maneira disciplinada de criar imagens é construí-las usando um Dockerfile.

o Dockerfile é um arquivo de texto semelhante a um script de shell, mas suporta vários comandos. Cada comando que modifica o sistema de arquivos cria uma nova camada. Na primeira parte, discutimos a importância de dividir sua imagem em camadas adequadamente. o Dockerfile é um grande tópico por si só.

Aqui, vou apenas demonstrar alguns comandos para criar outra imagem, oh-sim-alpino, com base em um Dockerfile. Além de criar o famigerado sim arquivo, vamos também instalar o vim. A distribuição Alpine Linux usa um sistema de gerenciamento de pacotes chamado apk. Aqui está o Dockerfile:

A imagem base é alpina. Ele copia o sim arquivo do mesmo diretório do host onde o Dockerfile é (o caminho do contexto de construção). Então, ele corre apk update e instala o vim. Por fim, define o comando que é executado quando o contêiner é executado. Neste caso imprimirá na tela o conteúdo do sim Arquivo.

OK. Agora que sabemos no que estamos entrando, vamos construir essa coisa. o -t opção define o repositório. Eu não especifiquei uma tag, então será o padrão “mais recente”.

Parece bom. Vamos verificar se a imagem foi criada:

Observe como a instalação do vim e suas dependências aumentou o tamanho do contêiner de 4,8 MB da imagem alpina básica para 30,5 MB!

É tudo muito legal. Mas funciona?

Ah sim, funciona!

Caso você ainda esteja desconfiado, vamos entrar no contêiner e examinar o sim arquivo com nosso vim recém-instalado.

O Contexto de Construção e o .dockerignore Arquivo

Eu não contei a você, mas originalmente, quando tentei criar a imagem oh-yeah-alpine, ela ficou suspensa por vários minutos. O problema é que acabei de colocar o Dockerfile no meu diretório pessoal. Quando o Docker cria uma imagem, ele primeiro empacota todo o diretório onde o Dockerfile é (incluindo subdiretórios) e o torna disponível para comandos COPY no Dockerfile.

O Docker não está tentando ser inteligente e analisar seus comandos COPY. Apenas embala a coisa toda. Observe que o conteúdo de compilação não terminará em sua imagem, mas diminuirá a velocidade do comando de compilação se o contexto de compilação for desnecessariamente grande.

Neste caso, eu simplesmente copiei Dockerfile e sim em um subdiretório e executei o comando docker build nesse subdiretório. Mas às vezes você tem uma árvore de diretório complicada da qual deseja copiar subdiretórios e arquivos específicos e ignorar outros. Introduzir o .dockerignore Arquivo.

Este arquivo permite controlar exatamente o que vai para o contexto de construção. Meu truque favorito é primeiro excluir tudo e depois começar a incluir os pedaços de que preciso. Por exemplo, neste caso eu poderia criar o seguinte .dockerignore arquivo e manter Dockerfile e sim no meu diretório pessoal:

Não há necessidade de incluir o Dockerfile em si ou o .dockerignore arquivo no contexto de compilação.

Copiar x Montar

Copiar arquivos para a imagem às vezes é o que você precisa, mas em outros casos você pode querer que seus contêineres sejam mais dinâmicos e trabalhem com arquivos no host. É aqui que os volumes e montagens entram em jogo.

A montagem de diretórios de host é um jogo diferente. Os dados são de propriedade do host e não do contêiner. Os dados podem ser modificados quando o container é parado. O mesmo contêiner pode ser iniciado com diferentes diretórios de host montados.

Marcando Imagens

A marcação de imagens é muito importante se você desenvolver um sistema baseado em microsserviços e gerar muitas imagens que às vezes devem ser associadas umas às outras. Você pode adicionar quantas tags quiser a uma imagem.

Você já viu a tag padrão “mais recente”. Às vezes, faz sentido adicionar outras tags, como “tested”, “release-1.4” ou o git commit que corresponde à imagem.

Você pode marcar uma imagem durante uma construção ou posteriormente. Veja como adicionar uma tag a uma imagem existente. Observe que, embora seja chamado de tag, você também pode atribuir um novo repositório.

Você também pode desmarcar removendo uma imagem pelo nome da marca. Isso é um pouco assustador, porque se você remover a última tag acidentalmente, perderá a imagem. Mas se você construir imagens de um Dockerfilevocê pode apenas reconstruir a imagem.

Se eu tentar remover a última imagem marcada restante, recebo um erro porque ela é usada por um contêiner.

Mas se eu remover o recipiente…

Sim. Foi-se. Mas não se preocupe. Podemos reconstruí-lo:

Sim, está de volta. Dockerfile pela vitória!

Trabalhando com registros de imagem

As imagens são muito semelhantes em alguns aspectos aos repositórios git. Eles também são construídos a partir de um conjunto ordenado de commits. Você pode pensar em duas imagens que usam as mesmas imagens base como ramificações (embora não haja mesclagem ou rebase no Docker). Um registro de imagem é o equivalente a um serviço central de hospedagem git como o GitHub. Adivinha qual é o nome do registro de imagem oficial do Docker? Isso mesmo, Docker Hub.

Puxando Imagens

Quando você executa uma imagem, se ela não existir, o Docker tentará extraí-la de um de seus registros de imagem configurados. Por padrão, ele vai para o Docker Hub, mas você pode controlá-lo em seu ~/.docker/config.json Arquivo. Se você usar um registro diferente, poderá seguir as instruções, que geralmente envolvem o login usando suas credenciais.

Vamos deletar a imagem “hello-world” e puxá-la novamente usando o comando docker pull comando.

Foi-se. Vamos puxar agora.

O último hello-world foi substituído por uma versão mais recente.

Empurrando Imagens

Enviar imagens é um pouco mais complicado. Primeiro você precisa criar uma conta no Docker Hub (ou outro registro). Em seguida, você faz login. Em seguida, você precisa marcar a imagem que deseja enviar de acordo com o nome da sua conta (“g1g1” no meu caso).

Agora, posso enviar a imagem marcada g1g1/hello-world.

Conclusão

As imagens do Docker são os modelos para seus contêineres. Eles são projetados para serem eficientes e oferecer reutilização máxima usando um driver de armazenamento do sistema de arquivos em camadas.

O Docker fornece muitas ferramentas para listar, inspecionar, construir e marcar imagens. Você pode extrair e enviar imagens para registros de imagens como o Docker Hub para gerenciar e compartilhar facilmente suas imagens.

Deixe uma resposta