Compreendendo o Docker

Há vários meses, estou usando o Docker para estruturar o processo de desenvolvimento/entrega de projetos web. Ofereço aos leitores do «HabrHabr» a tradução de um artigo introdutório sobre Docker — «Entendendo o Docker».

O que é Docker?

Docker é uma plataforma aberta para desenvolver, entregar e operar aplicativos. O Docker foi criado para facilitar a implantação dos seus aplicativos de forma mais rápida. Com o Docker, você pode separar seu aplicativo de sua infraestrutura e gerenciar a infraestrutura como um aplicativo controlado. O Docker ajuda a implantar seu código mais rapidamente, testar mais rapidamente, lançar aplicativos e reduzir o tempo entre escrever o código e executá-lo. O Docker faz isso por meio de uma plataforma leve de virtualização de contêineres, utilizando processos e utilitários que ajudam a gerenciar e implantar seus aplicativos.

Em sua essência, o Docker permite executar praticamente qualquer aplicativo, de forma segura e isolada em um contêiner. O isolamento seguro permite que você execute muitos contêineres simultaneamente em um único host. A leveza do contêiner, que é executado sem a sobrecarga adicional de um hipervisor, permite que você extraia mais do seu hardware.

A plataforma e as ferramentas de virtualização de contêineres podem ser úteis nas seguintes situações:

  • embalar seu aplicativo (e os componentes utilizados) em contêineres Docker;
  • distribuir e entregar esses contêineres para suas equipes para desenvolvimento e teste;
  • implantar esses contêineres em suas produções, tanto em data centers quanto em nuvens.

Para que posso usar o Docker?

Implantação rápida dos seus aplicativos

Docker é ideal para organizar o ciclo de desenvolvimento. O Docker permite que os desenvolvedores usem contêineres locais com aplicativos e serviços, o que, por sua vez, permite a integração com o processo de integração e entrega contínuas (continuous integration and deployment workflow).

Por exemplo, seus desenvolvedores escrevem código localmente e compartilham seu stack de desenvolvimento (conjunto de imagens Docker) com colegas. Quando estão prontos, enviam o código e os contêineres para um ambiente de teste e executam os testes necessários. A partir do ambiente de teste, eles podem enviar o código e as imagens para a produção.

Implantação e provisionamento mais fáceis

A plataforma baseada em contêineres Docker permite portabilidade fácil da sua carga de trabalho. Contêineres Docker podem ser executados em sua máquina local, tanto física quanto virtual, em um datacenter ou na nuvem.

A portabilidade e a leveza do Docker permitem que você gerencie sua carga de forma dinâmica com facilidade. Você pode usar o Docker para implantar ou desligar seu aplicativo ou serviços. A velocidade do Docker possibilita isso quase em tempo real.

Altas cargas e mais cargas úteis

Docker é leve e rápido. Ele oferece uma alternativa estável e econômica às máquinas virtuais baseadas em hipervisor. É especialmente útil em condições de alta carga, como ao criar sua própria nuvem ou plataforma como serviço (platform-as-service). Mas também é útil para aplicativos pequenos e médios, quando você deseja aproveitar melhor os recursos disponíveis.

Principais componentes do Docker

O Docker consiste em dois componentes principais:

  • Docker: plataforma de virtualização de código aberto;
  • Docker Hub: nossa plataforma como serviço para distribuição e gerenciamento de contêineres Docker.

Nota! O Docker é distribuído sob a licença Apache 2.0.

Arquitetura do Docker

O Docker utiliza uma arquitetura cliente-servidor. O cliente Docker se comunica com o daemon Docker, que assume a carga de criar, executar e distribuir seus contêineres. Ambos, cliente e servidor podem funcionar na mesma máquina, e você pode conectar o cliente a um daemon Docker remoto. O cliente e o servidor se comunicam através de um soquete ou por meio da API RESTful.

Compreendendo o Docker

Daemon Docker

Como mostrado no diagrama, o daemon é iniciado na máquina host. O usuário não interage diretamente com o servidor, mas utiliza o cliente para isso.

Cliente Docker

O cliente Docker, programa docker — é a principal interface com o Docker. Ele recebe comandos do usuário e interage com o daemon Docker.

Dentro do Docker

Para entender do que é feito o Docker, você precisa conhecer três componentes:

  • imagens (images)
  • registros (registries)
  • containers

Imagens

Uma imagem Docker é um modelo somente leitura. Por exemplo, uma imagem pode conter o sistema operacional Ubuntu com Apache e um aplicativo instalado. As imagens são usadas para criar contêineres. O Docker permite criar novas imagens facilmente, atualizar as existentes ou você pode baixar imagens criadas por outras pessoas. Imagens são um componente essencial do Docker.

Registro

O registro Docker armazena imagens. Existem registros públicos e privados, de onde você pode baixar ou carregar imagens. O registro público do Docker é Docker Hub. Ele contém uma enorme coleção de imagens. Como você sabe, as imagens podem ser criadas por você ou você pode usar imagens criadas por outros. Registros são um componente de distribuição.

Contêineres

Contêineres são semelhantes a diretórios. Dentro dos contêineres, está tudo o que é necessário para o funcionamento do aplicativo. Cada contêiner é criado a partir de uma imagem. Contêineres podem ser criados, iniciados, parados, movidos ou excluídos. Cada contêiner é isolado e fornece uma plataforma segura para o aplicativo. Contêineres são um componente operacional.

Como funciona o Docker?

Até agora, sabemos que:

  • podemos criar imagens que contêm nossos aplicativos;
  • podemos criar contêineres a partir de imagens para executar aplicativos;
  • podemos distribuir imagens através do Docker Hub ou de outro registro de imagens.

Vamos ver como esses componentes se combinam.

Como funciona uma imagem?

Já sabemos que uma imagem é um modelo somente leitura do qual um contêiner é criado. Cada imagem é composta por um conjunto de camadas. O Docker utiliza sistema de arquivos unificado para combinar essas camadas em uma única imagem. O sistema de arquivos unificado permite que arquivos e diretórios de diferentes sistemas de arquivos (ramificações diferentes) se sobreponham de forma transparente, criando um sistema de arquivos coeso.

Uma das razões pelas quais o Docker é leve é o uso dessas camadas. Quando você altera uma imagem, por exemplo, atualizando um aplicativo, uma nova camada é criada. Assim, sem substituir toda a imagem ou reconstruí-la, como pode ser necessário com uma máquina virtual, apenas a camada é adicionada ou atualizada. E você não precisa distribuir toda a nova imagem, apenas a atualização é enviada, o que facilita e acelera a distribuição de imagens.

Cada imagem é baseada em uma imagem base. Por exemplo, ubuntu, a imagem base do Ubuntu, ou fedora, a imagem base da distribuição Fedora. Você também pode usar imagens como base para criar novas imagens. Por exemplo, se você tem uma imagem apache, pode usá-la como imagem base para suas aplicações web.

Nota! O Docker normalmente obtém imagens do repositório Docker Hub.

As imagens do Docker podem ser criadas a partir dessas imagens base. Os passos de descrição para criar essas imagens chamamos de instruções. Cada instrução cria uma nova imagem ou camada. As instruções incluem as seguintes ações:

  • executar um comando
  • adicionar um arquivo ou diretório
  • criar uma variável de ambiente
  • indicar o que executar quando o contêiner desta imagem for iniciado

Essas instruções são armazenadas em um arquivo Dockerfile. O Docker lê isso Dockerfile, quando você cria a imagem, executa essas instruções e retorna a imagem final.

Como funciona o repositório docker?

Um repositório é um armazenamento de imagens Docker. Após criar a imagem, você pode publicá-la em um repositório público Docker Hub ou em seu repositório pessoal.

Com o cliente docker, você pode pesquisar imagens já publicadas e baixá-las para sua máquina com docker para criar contêineres.

O Docker Hub oferece repositórios de imagens públicos e privados. A pesquisa e o download de imagens de repositórios públicos estão disponíveis para todos. O conteúdo de repositórios privados não aparece nos resultados de busca. Somente você e seus usuários podem acessar essas imagens e criar contêineres a partir delas.

Como funciona um contêiner?

Um contêiner consiste em um sistema operacional, arquivos de usuário e metadados. Como sabemos, cada contêiner é criado a partir de uma imagem. Essa imagem informa ao Docker o que está no contêiner, qual processo iniciar quando o contêiner é iniciado e outros dados de configuração. A imagem do Docker é somente leitura. Quando o Docker inicia um contêiner, ele cria uma camada de leitura/gravação sobre a imagem (usando um sistema de arquivos union, como mencionado anteriormente), onde um aplicativo pode ser executado.

O que acontece quando um contêiner é iniciado?

Ou por meio de um programa docker, ou por meio da API RESTful, o cliente docker diz ao demônio docker para iniciar o contêiner.

$ sudo docker run -i -t ubuntu /bin/bash

Vamos analisar este comando. O cliente é iniciado com o comando docker, com a opção run, que indica que um novo contêiner será iniciado. Os requisitos mínimos para iniciar o contêiner são os seguintes atributos:

  • qual imagem usar para criar o contêiner. No nosso caso ubuntu
  • o comando que você deseja executar quando o contêiner for iniciado. No nosso caso /bin/bash

O que acontece por trás dos panos quando executamos esse comando?

O Docker, em sequência, faz o seguinte:

  • faz o download da imagem ubuntu: o Docker verifica se a imagem ubuntu está presente na máquina local e, se não estiver, faz o download dela de Docker Hub. Se a imagem já estiver disponível, utiliza-a para criar o contêiner;
  • cria o contêiner: quando a imagem é obtida, o Docker a utiliza para criar o contêiner;
  • inicializa o sistema de arquivos e monta o nível somente leitura: o contêiner é criado no sistema de arquivos e o nível somente leitura é adicionado à imagem;
  • inicializa a rede/pontes: cria uma interface de rede que permite ao Docker se comunicar com a máquina host;
  • Define o endereço IP: encontra e atribui o endereço;
  • Inicia o processo especificado: inicia seu aplicativo;
  • Processa e exibe a saída do seu aplicativo: conecta e registra a entrada padrão, saída e fluxo de erros do seu aplicativo, para que você possa monitorar como seu aplicativo está funcionando.

Agora você tem um contêiner funcionando. Você pode gerenciar seu contêiner, interagir com seu aplicativo. Quando decidir parar o aplicativo, exclua o contêiner.

Tecnologias utilizadas

O Docker é escrito em Go e utiliza alguns recursos do núcleo do Linux para implementar as funcionalidades mencionadas acima.

Espaços de nomes (namespaces)

O Docker utiliza a tecnologia namespaces para organizar espaços de trabalho isolados, que chamamos de contêineres. Quando iniciamos um contêiner, o Docker cria um conjunto de espaços de nomes para esse contêiner.

Isso cria um nível isolado, onde cada aspecto do contêiner é executado em seu próprio espaço de nomes e não tem acesso ao sistema externo.

Lista de alguns espaços de nomes que o Docker utiliza:

  • pid: para isolamento de processos;
  • net: para gerenciar interfaces de rede;
  • ipc: para gerenciar recursos IPC. (ICP: Comunicação Interprocessos);
  • mnt: para gerenciar pontos de montagem;
  • utc: para isolar o núcleo e controlar a geração de versões (UTC: sistema de tempo Unix).

Grupos de controle (control groups)

O Docker também utiliza a tecnologia cgroups ou grupos de controle. A chave para o funcionamento do aplicativo em isolamento é fornecer ao aplicativo apenas os recursos que você deseja disponibilizar. Isso garante que os contêineres sejam bons vizinhos. Os grupos de controle permitem dividir os recursos de hardware disponíveis e, se necessário, estabelecer limites e restrições. Por exemplo, limitar a quantidade de memória disponível para o contêiner.

Sistema de Arquivo Unificado

Sistema de Arquivo Unificado, ou UnionFS, é um sistema de arquivos que funciona criando camadas, tornando-o muito leve e rápido. O Docker utiliza o UnionFS para criar os blocos a partir dos quais o contêiner é construído. O Docker pode usar várias versões do UnionFS, incluindo: AUFS, btrfs, vfs e DeviceMapper.

Formatos de contêiner

O Docker combina esses componentes em uma embalagem que chamamos de formato de contêiner. O formato usado por padrão é chamado de libcontainer. O Docker também suporta o formato tradicional de contêineres no Linux por meio de LXC. No futuro, o Docker poderá suportar outros formatos de contêiner. Por exemplo, integrando-se com BSD Jails ou Solaris Zones.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster