Você já criou suas primeiras imagens, mas algo não ficou bom e teve muito trabalho? Periódicas atualizações fizeram com que gastasse um tempo não previsto para atualizar imagens?! Deseja criar imagens mas não sabe como criar imagens de forma eficiente e de acordo com as melhores práticas. Esse post é para você.

Você pode encontrar imagens para os mais variados tipos de serviços e produtos, desde load balancers até blogs, bancos de dados SQL e NoSQL até Log. A maioria delas preza por alguns aspectos que são considerados boas práticas na criação de imagens, entenda como nesse post.

Imagens

A criação de imagens é feita com o comando Docker Build. O build necessita de um DockerFile. Se você ainda não viu um DockerFile, siga esse exemplo abaixo:

Vamos tentar traduzir:

Nas minhas buscas pelo google, hub e github, não me recordo de sequer um DockerFile que não seguisse a seguinte estrutura:

  1. Definir imagem base (obrigatório).
  2. Instalar dependências.
  3. Instalar software ou ferramenta (via ap-get, via download ou via download e build).
  4. Executar algum tipo de limpeza para garantir que a imagem será o mais enxuta possível.
  5. Expor as portas em que o serviço ou app opera.
  6. Definir o comando de inicialização.

Embora haja esse padrãozinho, ainda há algumas coisas que você precisa saber sobre imagens.

Build X Image Layers

Ao realizar um build de DockerFile, cada instrução do DockerFile gerará, imediatamente após sua execução, uma nova image layer. Uma imagem, nada mais é que um conjunto de image layers sobrepostos. Esse design facilita a construção de novas imagens a partir de outras, reduzindo e otimizando a indexação, tráfego de rede, economizando o tempo de build e processamento durante a criação de imagens. Esse desenho simples, mas não simplista, é extremamente robusto e é a base da arquitetura de imagens do Docker.

Segregação de Comandos afins

Um DockerFile contém diversas instruções a serem executadas durante o build, vimos isso no tópico acima, mas você pode ter considerado meramente ilustrativo, se enganou. O isolamento de cada uma das image layers pode afetar seu build, principalmente se separar as execuções comandos que manipulem memória ou cache, como no caso do APT do debian e suas variações. Nunca separe APT-GET UPDATE de APT-GET INSTALL, pois em uma recompilação que parta do APT-GET INSTALL, não podemos garantir que o APT-GET UPATE tenha sido persistido na image layer, pois ele prioritariamente utiliza memória e provavelmente sua image layer foi criada antes da infraestrutura conseguir persistir esses dados. Como você pode imaginar, a execução do APT-GET INSTALL sem um devido APT-GET UPDATE pode simplesmente falhar, ou pior, instalar uma versão antiga de um determinado pacote.

EntryPoint.sh

EntryPoint.sh é um padrão super simples de ser implementado, ele consiste em ter um arquivo de inicialização que determina quais steps são necessários para a inicialização do seu container. O DockerFile pode criar esse arquivo, caso ele seja bem simples, ou você adiciona-o usando o comando COPY ou ADD no seu DockerFile. No arquivo EntryPoint.sh geralmente vemos comandos de preparação de ambiente, como cópias de arquivos, aplicação de configurações baseadas nas variáveis de ambiente, e etc. Geralmente colocamos o script de inicialização na imagem, já que utilizar infraestrutura de inicialização de serviços não é comum. Uma das coisas que mais me chamaram a atenção, são cópias de arquivos-padrão para Data Volumes, tema que vou abordar em Data Volumes e Default Volume Content, tópicos a seguir. Antes que me esqueça, o EntryPoint.sh é corriqueiramente utilizado no parâmetro EntryPoint do DockerFile.

Nos repositórios do Docker no github, vemos alguns DockerFiles bem interessantes, e podemos ver as diferenças entre o EntryPoint.sh do WordPress e do Redis. Ainda não entendi o motivo deles usarem o nome docker-entrypoint.sh enquanto a maioria dos DockerFiles não produzidos por eles possui o nome de EntryPoint.sh.

Imutabilidade

Imagens devem gerar containers imutáveis, isso significa que para fazer atualizações, ou modificações, é aconselhável que faça modificações no DockerFile para gerar uma nova versão da imagem. Você sempre terá acesso ao container para executar comandos após sua criação, mas essa não é uma boa prática. Executar comandos no container diretamente, é o mesmo que modificar arquivos em produção, sem versionamento.

Data Volumes (User Data)

Enquanto a imutabilidade diz para não realizar modificações no container, criando containers stateless, em algum momento você se deparará com cenários que a evolução da utilização da aplicação ou serviço gerará arquivos que não podem ser perdidos com um update de container. Podem ser dados do usuário, ou atualizações automáticas das aplicações, novos plugins, arquivos de configurações, novos temas, ou simplesmente um novo dado em um banco de dados (sql ou nosql) containerizado. São dados que representam a utilização ou evolução da aplicação em questão. Para esses cenários, devemos ter uma estratégia bem definida para que possamos realizar modificações duradouras. Os DATA VOLUMES, para o Docker são pontos de montagem que estão no host e são compartilhados entre host e containers. Cada container pode ter um ou vários desses pontos de montagem, e é bem interessante usá-los para o tipo de conteúdo que não pode ser perdido.

É uma boa prática criar containers sem estado, que pois sua portabilidade não dependerá do estado adicional, apenas do container.

Default Volume Content

Supondo que um Data Volume deva conter configurações, é interessante que você forneça uma configuração padrão, ou um arcabouço de configuração, para facilitar o trabalho de quem utiliza seu container, além de reduzir o atrito na implantação. No tópico EntryPoint.sh falamos do que um EntryPoint.sh pode fazer, umas das atividades extremamente relevantes em imagens profissionais, é analisar um determinado diretório, para tomar a decisão de copiar arquivos-padrão para lá. Isso é muito útil quando esses diretórios fazem parte de um Data Volume, um ponto de montagem para o seu container.

Lightweight Containers

No post DockerFile – Ubuntu + SSH + WebMin como criar uma imagem que fere praticamente todas as boas práticas. Mas qual o motivo?

  1. Imagens devem atender a uma única necessidade, pois assim facilita a manutenção, evolução, gestão e distribuição.
  2. Containers destinados a uma única finalidade podem depender de outros containers, que por sua vez podem ser trocados, por containers criados com imagens diferentes do mesmo produto ou serviço, seja por evolução, ou por configurações mais completas, ou por produtos similares de outras comunidades ou mesmo fabricantes. É o que acontece caso queira migrar do Memcached para o Redis. Bastaria criar um novo container Redis, dropar o Container Mamecached, e reapontar seus consumidores.

Então para que eu criaria um container “gordo”?

A resposta é simples, para fazer testes, das mais variadas naturezas:

  • Desde compreender como o Docker interfere no seu ambiente.
  • Compreender diferenças entre containers SO’s completos e containers.
  • Analisar os impactos de instalações em detalhes.

Does not expose mystique port

Os containers por padrão, recebem IP’s virtuais, isso significa que seu container pode utilizar todas1 as portas possíveis, sem entrar em conflito com nenhum outro container. A preocupação com alocação de portas é responsabilidade de quem vai criar um container, não de quem cria imagens. Cada imagem deve utilizar a porta padrão da ferramenta ou produto. Não complique! HTTP utiliza porta 80 e 443, Redis, RabbitMQ, MySQL/MariaDB, entre outros, utilizam portas específicas, não invente.

Agradecimentos

Obrigado a você que leu até aqui, se gostou, curta o post, assine, compartilhe com os amigos e colegas de trabalho. Essa semana será dedicada ao Docker, portanto teremos muito a falar nesse tema.

Observações

1) Somente portas do sistema são excepcionais.

 

hangout-docker-2016-03-04

Save The Date

Nessa sexta-feira, dia 4/Mar/2016!

Nessa semana vamos bater um papo no Canal.Net do Youtube, vamos falar sobre Docker, Containers, mostrar alguns exemplos e falar muito sobre tudo o que você quer saber sobre Docker. Se já tiver perguntas, podem mandar!

Comente, compartilhe, curta!

Logo abaixo desse texto você encontra os Posts Relacionados, e botões de compartilhamento, em seguida a sessão de comentários!

Gostou? Então aproveite para curtir, compartilhar e enviar comentários, dúvidas ou sugestões.

Conheça o Grupo Arquitetura de Softwate | .NET: Facebook e Telegram
Luiz Carlos Faria: Site, Youtube, Facebook, Twitter, Telegram, Linkedin e Email