Como saber se você precisa do Docker em vez de uma VM? É necessário determinar o que exatamente você deseja isolar. Se precisar isolar um sistema com recursos garantidos e hardware virtual, a escolha deve recair sobre a VM. Se o objetivo é isolar aplicativos em execução como processos separados do sistema, você precisará do Docker.
Qual é a diferença entre contêineres Docker e VMs?
Máquina Virtual (VM) é um computador virtual com todos os dispositivos virtuais e um disco rígido virtual, no qual é instalada uma nova OS independente, juntamente com drivers de dispositivo virtuais, gerenciamento de memória e outros componentes. Ou seja, obtemos uma abstração de hardware físico que permite executar vários computadores virtuais em um único computador.
Uma VM instalada pode ocupar espaço no disco rígido do computador de diferentes maneiras:
- espaço fixo no disco rígido, o que permite acesso mais rápido ao disco rígido virtual e evita a fragmentação do arquivo;
- alocação dinâmica de memória. À medida que novos aplicativos são instalados, a memória será alocada dinamicamente para eles, até atingir o volume máximo permitido.
Quanto maior máquinas virtuais no servidor, mais espaço eles ocupam e também exigem manutenção constante do ambiente necessário para o funcionamento do seu aplicativo.
Docker é um software para criar aplicativos baseados em contêineres. Contêineres e máquinas virtuais têm vantagens semelhantes, mas funcionam de maneiras diferentes. Os contêineres ocupam menos espaço, pois reutilizam mais recursos compartilhados do sistema host do que as VMs, pois, ao contrário das VMs, proporcionam virtualização a nível de OS, e não de hardware. Essa abordagem garante menor consumo de memória, implantação rápida e escalabilidade mais fácil.
O contêiner oferece um mecanismo de encapsulamento de aplicativos mais eficiente, fornecendo as interfaces necessárias do sistema host. Essa capacidade permite que os contêineres compartilhem o núcleo do sistema, onde cada contêiner opera como um processo separado do sistema operacional principal, possuindo seu próprio conjunto de áreas de memória (seu próprio espaço de endereçamento virtual). Como o espaço de endereçamento virtual de cada contêiner é independente, os dados pertencentes a diferentes áreas de memória não podem ser alterados.
O sistema operacional nativo para Docker é o Linux (o Docker também pode ser usado no Windows e no MacOS), aproveitando suas principais vantagens que permitem organizar a separação do núcleo. A execução de contêineres Docker no Windows ocorrerá dentro de uma máquina virtual com o sistema operacional Linux, uma vez que os contêineres compartilham o sistema operacional do host, sendo que o Linux é o sistema operacional principal para eles.
Como funciona um contêiner?
O contêiner — é uma abstração em nível de aplicação que combina código e dependências. Os contêineres sempre são criados a partir de imagens, adicionando uma camada superior gravável e inicializando vários parâmetros. Como o contêiner possui sua própria camada para gravação e todas as alterações são salvas nessa camada, vários contêineres podem compartilhar o acesso a uma mesma imagem base.
Cada contêiner pode ser configurado através de um arquivo no projeto docker-compose, incluído na solução principal — docker-compose.yml. Nele, é possível definir diferentes parâmetros, como o nome do contêiner, portas, identificadores, limites de recursos e dependências entre outros contêineres. Se o nome do contêiner não for especificado nas configurações, o Docker criará um novo contêiner a cada vez, atribuindo-lhe um nome aleatório.
Quando um contêiner é iniciado a partir de uma imagem, o Docker monta o sistema de arquivos para leitura e gravação sobre quaisquer camadas inferiores. É aqui que todos os processos que desejamos que nosso contêiner Docker execute ocorrerão.
Quando o Docker inicia um contêiner pela primeira vez, a camada inicial de leitura-gravação está vazia. Quando ocorrem alterações, elas são aplicadas a essa camada; por exemplo, se você quiser alterar um arquivo, esse arquivo será copiado da camada somente leitura inferior para a camada de leitura e gravação.
A versão do arquivo que está disponível apenas para leitura ainda existirá, mas agora estará oculta sob uma cópia. Volumes são usados para armazenar dados, independentemente do ciclo de vida do container. Os volumes são inicializados quando o container é criado.
Como a imagem está relacionada ao container?
Modelo — é o elemento principal para cada container. A imagem é criada a partir de um Dockerfile adicionado ao projeto e representa um conjunto de sistemas de arquivos (camadas) empilhadas umas sobre as outras e agrupadas, disponíveis apenas para leitura; o número máximo de camadas é 127.
No fundo de cada imagem, há uma imagem base, que é especificada pelo comando FROM — o ponto de entrada ao construir a imagem Dockerfile. Cada camada é uma camada somente leitura e é representada por um comando que modifica o sistema de arquivos registrado no Dockerfile.
Para combinar essas camadas em uma única imagem, o Docker usa o Advanced multi layered Union file system (AuFS é baseado no UnionFS), permitindo que diferentes arquivos e diretórios de diferentes camadas de arquivos se sobreponham de forma transparente, criando um sistema de arquivos coeso.
As camadas contêm metadados que permitem armazenar informações complementares sobre cada camada durante a execução e construção. Cada camada contém um link para a próxima camada; se uma camada não tiver um link, significa que é a camada superior da imagem.
O Dockerfile pode conter comandos como:
- FROM — ponto de entrada ao construir a imagem;
- MAINTAINER — nome do proprietário da imagem;
- RUN — executa um comando durante a construção da imagem;
- ADD — copia um arquivo do host para a nova imagem, se um URL de arquivo for especificado, o Docker fará o download para o diretório designado;
- ENV — variáveis de ambiente;
- CMD — inicia a criação de um novo container com base na imagem;
- ENTRYPOINT — comando executado ao iniciar o container.
- WORKDIR — diretório de trabalho para a execução do comando CMD.
- USER — define o UID para o container criado a partir da imagem.
- VOLUME — monta um diretório do host no container.
- EXPOSE — conjunto de portas que são escutadas dentro do container.
Como funciona o UnionFS?
UnionFS — sistema de arquivos empilhado de serviço (FS) para Linux e FreeBSD. Este FS implementa o mecanismo de cópia ao gravar (Copy-On-Write, COW). A unidade de trabalho do UnionFS é uma camada, cada camada deve ser vista como um sistema de arquivos completo separado, com uma hierarquia de diretórios a partir da raiz. O UnionFS cria um ponto de montagem unificado para outros sistemas de arquivos e permite que arquivos e diretórios de diferentes sistemas de arquivos (chamados de ramos) sejam unidos em um único sistema de arquivos coeso de forma transparente para o usuário.
O conteúdo de diretórios com caminhos iguais será exibido junto em um único diretório unificado (em um único espaço de nomes) do sistema de arquivos resultante.
O UnionFS une as camadas seguindo os seguintes princípios:
- uma das camadas se torna a camada de nível superior, a segunda e as subsequentes tornam-se camadas de nível inferior;
- os objetos das camadas estão disponíveis ao usuário de "cima para baixo", ou seja, se o objeto solicitado estiver na camada "superior", ele é retornado, independentemente da existência de um objeto com esse nome na camada "inferior"; caso contrário, retorna-se o objeto da camada "inferior"; se o objeto solicitado não estiver em nenhuma das camadas, retorna-se o erro "Arquivo ou diretório não encontrado";
- a camada de trabalho é a "superior", ou seja, todas as ações do usuário para modificar dados refletem-se apenas na camada de nível superior, sem afetar o conteúdo das camadas inferiores.
O Docker é a tecnologia mais comum usada para containers em aplicativos. Tornou-se o padrão nesta área, construindo-se com base em cgroups e namespaces, que são fornecidos pelo núcleo do Linux.
O Docker nos permite implantar aplicações rapidamente e utilizar o sistema de arquivos da maneira mais eficiente possível, dividindo o núcleo do SO entre todos os containers, funcionando como processos separados do SO.
Fonte: habr.com
