Como o Docker é diferente de uma máquina virtual?

Eu continuo relendo a documentação do Docker para tentar entender a diferença entre o Docker e uma VM completa. Como ele consegue fornecer um sistema de arquivos completo, ambiente de rede isolado, etc. sem ser tão pesado?

Por que a implantação de software em uma imagem do Docker (se esse é o termo correto) é mais fácil do que simplesmente implantar em um ambiente de produção consistente?

    O Docker usava originalmente o LinuX Containers (LXC), mas depois mudou para o runC (anteriormente conhecido como libcontainer ), que é executado no mesmo sistema operacional do seu host. Isso permite que ele compartilhe muitos resources do sistema operacional do host. Além disso, ele usa um sistema de arquivos em camadas ( AuFS ) e gerencia a rede.

    O AuFS é um sistema de arquivos em camadas, portanto, você pode ter uma parte somente de leitura e uma parte de gravação que são mescladas. Pode-se ter as partes comuns do sistema operacional como somente leitura (e compartilhadas entre todos os seus contêineres) e, então, fornecer a cada contêiner sua própria assembly para gravação.

    Então, digamos que você tenha uma imagem de contêiner de 1 GB; Se você quiser usar uma VM completa, precisará ter 1 GB vezes x número de VMs desejadas. Com o Docker e o AuFS, você pode compartilhar a maior parte do 1 GB entre todos os contêineres e, se tiver 1.000 contêineres, ainda poderá ter pouco mais de 1 GB de espaço para o sistema operacional de contêineres (supondo que todos estejam executando a mesma imagem do sistema operacional) .

    Um sistema virtualizado completo obtém seu próprio conjunto de resources alocados a ele e faz um compartilhamento mínimo. Você obtém mais isolamento, mas é muito mais pesado (requer mais resources). Com o Docker, você obtém menos isolamento, mas os contêineres são leves (exigem menos resources). Assim, você pode facilmente executar milhares de contêineres em um host e nem piscará. Tente fazer isso com o Xen e, a menos que você tenha um host realmente grande, não acho que seja possível.

    Um sistema virtualizado completo geralmente demora alguns minutos para ser iniciado, enquanto os contêineres Docker / LXC / runC demoram segundos e, frequentemente, até menos de um segundo.

    Existem prós e contras para cada tipo de sistema virtualizado. Se você quiser isolamento total com resources garantidos, uma VM completa é o caminho a percorrer. Se você quer apenas isolar os processos uns dos outros e deseja executar uma tonelada deles em um host de tamanho razoável, então o Docker / LXC / runC parece ser o caminho a percorrer.

    Para mais informações, confira este conjunto de posts que explicam como funciona o LXC.

    Por que a implantação de software em uma imagem de encaixe (se esse é o termo correto) é mais fácil do que simplesmente implantar em um ambiente de produção consistente?

    Implantar um ambiente de produção consistente é mais fácil de falar do que fazer. Mesmo se você usar ferramentas como Chef e Puppet , sempre haverá atualizações do SO e outras coisas que mudam entre hosts e ambientes.

    O Docker permite que você instale o sistema operacional em uma imagem compartilhada e facilita a implantação em outros hosts do Docker. Localmente, dev, qa, prod, etc .: toda a mesma imagem. Claro que você pode fazer isso com outras ferramentas, mas não tão fácil ou rápido.

    Isso é ótimo para testes; digamos que você tenha milhares de testes que precisam se conectar a um database, e cada teste precisa de uma cópia original do database e fará alterações nos dados. A abordagem clássica para isso é redefinir o database após cada teste com código personalizado ou com ferramentas como o Flyway – isso pode consumir muito tempo e significa que os testes devem ser executados em série. No entanto, com o Docker, você poderia criar uma imagem do database e executar uma instância por teste e, em seguida, executar todos os testes em paralelo, já que todos eles estarão sendo executados no mesmo instantâneo do database. Como os testes estão sendo executados em paralelo e em contêineres Docker, eles podem rodar todos na mesma checkbox ao mesmo tempo e devem terminar muito mais rápido. Tente fazer isso com uma VM completa.

    De comentários …

    Interessante! Eu suponho que ainda estou confuso com a noção de “instantâneo” do sistema operacional. Como se faz isso sem, bem, fazer uma imagem do sistema operacional?

    Bem, vamos ver se eu posso explicar. Você começa com uma imagem de base e, em seguida, faz as alterações e confirma essas alterações usando a janela de encaixe e cria uma imagem. Esta imagem contém apenas as diferenças da base. Quando você quer rodar sua imagem, você também precisa da base, e ela coloca sua imagem sobre a base usando um sistema de arquivos em camadas: como mencionado acima, o Docker usa o AUFS. O AUFS mescla as diferentes camadas e você obtém o que deseja; você só precisa executá-lo. Você pode continuar adicionando mais e mais imagens (camadas) e continuará salvando os diffs. Como o Docker geralmente constrói em cima de imagens prontas de um registro , você raramente precisa “capturar instantaneamente” todo o sistema operacional.

    Boas respostas. Apenas para obter uma representação da imagem do container vs VM, dê uma olhada no abaixo.

    insira a descrição da imagem aqui

    Fonte: https://www.docker.com/what-container#/package_software

    Pode ser útil entender como a virtualização e os contêineres funcionam em baixo nível. Isso vai esclarecer muitas coisas.

    Nota: estou simplificando um pouco na descrição abaixo. Veja as referências para mais informações.

    Como a virtualização funciona em baixo nível?

    Nesse caso, o gerenciador de MV assume o anel da CPU 0 (ou o “modo raiz” em CPUs mais recentes) e intercepta todas as chamadas privilegiadas feitas pelo sistema operacional convidado para criar a ilusão de que o sistema operacional convidado possui seu próprio hardware. Curiosidade: Antes de 1998, era impossível conseguir isso na arquitetura x86, porque não havia como fazer esse tipo de interceptação. O pessoal da VMWare foi o primeiro que teve a idéia de rewrite os bytes executáveis ​​na memory para chamadas privilegiadas do sistema operacional convidado para conseguir isso.

    O efeito líquido é que a virtualização permite que você execute dois sistemas operacionais completamente diferentes no mesmo hardware. Cada sistema operacional convidado passa por todo o processo de bootstrapping, carregamento do kernel, etc. Você pode ter segurança muito rígida, por exemplo, o sistema operacional convidado não pode obter access total ao sistema operacional host ou a outros convidados e bagunçar as coisas.

    Como os contêineres funcionam em baixo nível?

    Por volta de 2006 , pessoas incluindo alguns dos funcionários do Google implementaram um novo recurso de nível de kernel chamado namespaces (no entanto, a idéia existia muito antes no FreeBSD ). Uma function do sistema operacional é permitir o compartilhamento de resources globais, como rede e disco, nos processos. E se esses resources globais fossem agrupados em namespaces para que eles sejam visíveis apenas para os processos executados no mesmo namespace? Digamos que você consiga um pedaço de disco e coloque-o no espaço de nomes X e, em seguida, os processos em execução no namespace Y não podem ver ou acessá-lo. Da mesma forma, os processos no namespace X não podem acessar nada na memory alocada para o namespace Y. É claro que os processos no X não podem ver ou falar com processos no namespace Y. Isso fornece virtualização e isolamento para resources globais. É assim que o docker funciona: Cada contêiner é executado em seu próprio namespace, mas usa exatamente o mesmo kernel que todos os outros contêineres. O isolamento acontece porque o kernel conhece o namespace que foi atribuído ao processo e, durante as chamadas de API, garante que o processo possa acessar apenas resources em seu próprio namespace.

    As limitações de contêineres vs VM devem ser óbvias agora: você não pode executar sistemas operacionais completamente diferentes em contêineres como em VMs. No entanto, você pode executar diferentes distros do Linux, porque eles compartilham o mesmo kernel. O nível de isolamento não é tão forte quanto na VM. Na verdade, havia uma maneira de o contêiner “guest” assumir o host nas implementações iniciais. Além disso, você pode ver que quando você carrega um novo contêiner, toda a nova cópia do sistema operacional não inicia como na VM. Todos os contêineres compartilham o mesmo kernel . É por isso que os contêineres são leves. Além disso, ao contrário da VM, você não precisa pré-alocar partes significativas de memory para os contêineres porque não estamos executando uma nova cópia do sistema operacional. Isso permite executar milhares de contêineres em um sistema operacional durante o uso do sandbox, o que pode não ser possível se estivéssemos executando uma cópia separada do sistema operacional em sua própria VM.

    Eu gosto da resposta de Ken Cochrane.

    Mas eu quero adicionar mais pontos de vista, não abordados em detalhes aqui. Na minha opinião Docker também difere em todo o processo. Em contraste com as VMs, o Docker não é (apenas) sobre o compartilhamento ideal de resources de hardware, além disso, fornece um “sistema” para o aplicativo de empacotamento (preferível, mas não obrigatório, como um conjunto de microsserviços).

    Para mim, isso se encheckbox na lacuna entre as ferramentas orientadas ao desenvolvedor como rpm, pacotes Debian , Maven , npm + Git de um lado e ferramentas ops como Puppet , VMware, Xen, o nome dele …

    Por que a implantação de software em uma imagem de encaixe (se esse é o termo correto) é mais fácil do que simplesmente implantar em um ambiente de produção consistente?

    Sua pergunta pressupõe um ambiente de produção consistente. Mas como mantê-lo consistente? Considere uma quantidade (> 10) de servidores e aplicativos, estágios no pipeline.

    Para manter isso em sincronia, você começará a usar algo como Puppet, Chef ou seus próprios scripts de provisionamento, regras não publicadas e / ou muita documentação … Em teoria, os servidores podem ser executados indefinidamente e mantidos completamente consistentes e atualizados. A prática falha em gerenciar completamente a configuração de um servidor, portanto, há um escopo considerável para desvio de configuração e alterações inesperadas nos servidores em execução.

    Portanto, há um padrão conhecido para evitar isso, o chamado servidor imutável . Mas o padrão de servidor imutável não era amado. Principalmente por causa das limitações das VMs que foram usadas antes do Docker. Lidar com várias imagens grandes de gigabytes, movendo essas imagens grandes, apenas para alterar alguns campos na aplicação, foi muito, muito trabalhoso. Compreensível…

    Com um ecossistema Docker, você nunca precisará mover gigabytes em “pequenas alterações” (obrigado aufs e Registry) e não precisa se preocupar em perder desempenho empacotando aplicativos em um contêiner Docker em tempo de execução. Você não precisa se preocupar com versões dessa imagem.

    E, finalmente, você poderá até mesmo reproduzir ambientes de produção complexos, mesmo em seu laptop com Linux (não me ligue se não funcionar no seu caso;))

    E, claro, você pode iniciar contêineres do Docker em VMs (é uma boa ideia). Reduza seu provisionamento de servidor no nível da VM. Todos os itens acima podem ser gerenciados pelo Docker.

    PS Enquanto isso, o Docker usa sua própria implementação “libcontainer” em vez de LXC. Mas o LXC ainda é utilizável.

    O Docker não é uma metodologia de virtualização. Ele se baseia em outras ferramentas que realmente implementam a virtualização baseada em contêiner ou a virtualização em nível de sistema operacional. Para isso, o Docker estava inicialmente usando o driver LXC, depois foi movido para o libcontainer, que agora é renomeado como runc. O Docker se concentra principalmente na automação da implantação de aplicativos dentro de contêineres de aplicativos. Os contêineres de aplicativos são projetados para empacotar e executar um único serviço, enquanto os contêineres do sistema são projetados para executar vários processos, como máquinas virtuais. Portanto, o Docker é considerado uma ferramenta de gerenciamento de contêineres ou de implementação de aplicativos em sistemas contêineres.

    Para saber como é diferente de outras virtualizações, vamos passar pela virtualização e seus tipos. Então, seria mais fácil entender qual é a diferença lá.

    Virtualização

    Em sua forma concebida, foi considerado um método de dividir logicamente mainframes para permitir que múltiplos aplicativos sejam executados simultaneamente. No entanto, o cenário mudou drasticamente quando as empresas e as comunidades de código aberto puderam fornecer um método para lidar com as instruções privilegiadas de uma forma ou de outra e permitir que vários sistemas operacionais fossem executados simultaneamente em um único sistema baseado em x86.

    Hipervisor

    O hipervisor lida com a criação do ambiente virtual no qual as máquinas virtuais convidadas operam. Ele supervisiona os sistemas convidados e garante que os resources sejam alocados aos convidados conforme necessário. O hipervisor fica entre a máquina física e as máquinas virtuais e fornece serviços de virtualização para as máquinas virtuais. Para perceber isso, ele intercepta as operações do sistema operacional convidado nas máquinas virtuais e emula a operação no sistema operacional da máquina host.

    O rápido desenvolvimento das tecnologias de virtualização, principalmente na nuvem, levou o uso da virtualização ainda mais, permitindo a criação de vários servidores virtuais em um único servidor físico com a ajuda de hipervisores, como Xen, VMware Player, KVM, etc. incorporação de suporte de hardware em processadores de commodity, como Intel VT e AMD-V.

    Tipos de Virtualização

    O método de virtualização pode ser categorizado com base em como ele imita o hardware para um sistema operacional convidado e emula o ambiente operacional convidado. Primeiramente, existem três tipos de virtualização:

    • Emulação
    • Paravirtualização
    • Virtualização baseada em contêiner

    Emulação

    A emulação, também conhecida como virtualização completa, executa o kernel do sistema operacional da máquina virtual totalmente em software. O hipervisor usado nesse tipo é conhecido como hipervisor Tipo 2. Ele é instalado na parte superior do sistema operacional host, que é responsável por traduzir o código do kernel do sistema operacional convidado para as instruções do software. A tradução é feita inteiramente em software e não requer nenhum envolvimento de hardware. A emulação possibilita a execução de qualquer sistema operacional não modificado que suporte o ambiente emulado. A desvantagem desse tipo de virtualização é a sobrecarga de resources adicionais do sistema que leva a uma redução no desempenho em comparação com outros tipos de virtualização.

    Emulação

    Exemplos nesta categoria incluem o VMware Player, o VirtualBox, o QEMU, o Bochs, o Parallels, etc.

    Paravirtualização

    A paravirtualização, também conhecida como hipervisor Tipo 1, é executada diretamente no hardware, ou “bare-metal”, e fornece serviços de virtualização diretamente para as máquinas virtuais executadas nela. Ele ajuda o sistema operacional, o hardware virtualizado e o hardware real a colaborar para alcançar o desempenho ideal. Esses hipervisores geralmente têm uma pegada pequena e não requerem resources extensos.

    Exemplos nesta categoria incluem Xen, KVM, etc.

    Paravirtualização

    Virtualização baseada em contêiner

    A virtualização baseada em contêiner, também conhecida como virtualização no nível do sistema operacional, permite várias execuções isoladas em um único kernel do sistema operacional. Tem o melhor desempenho e densidade possíveis e apresenta gerenciamento dynamic de resources. O ambiente de execução virtual isolado fornecido por esse tipo de virtualização é chamado de contêiner e pode ser visto como um grupo de processos rastreado.

    Virtualização baseada em contêiner

    O conceito de um contêiner é possibilitado pelo recurso namespaces adicionado ao kernel do Linux versão 2.6.24. O contêiner adiciona seu ID a cada processo e adiciona novas verificações de controle de access a todas as chamadas do sistema. Ele é acessado pela chamada de sistema clone () que permite criar instâncias separadas de namespaces globais anteriores.

    Os namespaces podem ser usados ​​de muitas maneiras diferentes, mas a abordagem mais comum é criar um contêiner isolado que não tenha visibilidade ou access a objects fora do contêiner. Os processos em execução dentro do contêiner parecem estar sendo executados em um sistema Linux normal, embora estejam compartilhando o kernel subjacente com processos localizados em outros namespaces, o mesmo para outros tipos de objects. Por exemplo, ao usar namespaces, o usuário raiz dentro do contêiner não é tratado como raiz fora do contêiner, adicionando segurança adicional.

    O subsistema Linux Control Groups (cgroups), o próximo componente principal para habilitar a virtualização baseada em contêiner, é usado para agrupar processos e gerenciar seu consumo agregado de resources. É comumente usado para limitar a memory e o consumo de CPU dos contêineres. Como um sistema Linux conteinerizado tem apenas um kernel e o kernel tem visibilidade total dos contêineres, existe apenas um nível de alocação e agendamento de resources.

    Várias ferramentas de gerenciamento estão disponíveis para containers Linux, incluindo LXC, LXD, systemd-nspawn, lmctfy, Warden, Linux-VServer, OpenVZ, Docker, etc.

    Contêineres vs máquinas virtuais

    Ao contrário de uma máquina virtual, um contêiner não precisa inicializar o kernel do sistema operacional, portanto, os contêineres podem ser criados em menos de um segundo. Esse recurso torna a virtualização baseada em contêiner única e desejável do que outras abordagens de virtualização.

    Como a virtualização baseada em contêiner adiciona pouca ou nenhuma sobrecarga à máquina host, a virtualização baseada em contêiner tem desempenho quase nativo.

    Para virtualização baseada em contêiner, nenhum software adicional é necessário, ao contrário de outras virtualizações.

    Todos os contêineres em uma máquina host compartilham o planejador da máquina host, economizando a necessidade de resources extras.

    Os estados de contêiner (imagens Docker ou LXC) são pequenos em comparação com as imagens de máquinas virtuais, portanto, as imagens de contêiner são fáceis de distribuir.

    O gerenciamento de resources em contêineres é obtido por meio de cgroups. O Cgroups não permite que os contêineres consumam mais resources do que os alocados para eles. No entanto, a partir de agora, todos os resources da máquina host são visíveis em máquinas virtuais, mas não podem ser usados. Isso pode ser feito executando top ou htop em containers e host machine ao mesmo tempo. A saída em todos os ambientes será semelhante.

    Através deste post, vamos desenhar algumas linhas de diferenças entre VMs e LXCs. Vamos primeiro defini-los.

    VM :

    Uma máquina virtual emula um ambiente de computação física, mas solicitações de CPU, memory, disco rígido, rede e outros resources de hardware são gerenciados por uma camada de virtualização que traduz essas solicitações para o hardware físico subjacente.

    Nesse contexto, a VM é chamada como o convidado, enquanto o ambiente em que é executado é chamado de host.

    LXC s:

    Os contêineres Linux (LXC) são resources no nível do sistema operacional que possibilitam a execução de vários contêineres isolados do Linux, em um host de controle (o host LXC). Os contêineres Linux servem como uma alternativa leve às VMs, pois não exigem a visualização dos hipervisores. Virtualbox, KVM, Xen, etc.

    Agora, a menos que você tenha sido drogado por Alan (Zach Galifianakis – da série Hangover) e tenha estado em Vegas no último ano, você estará bem ciente do tremendo surto de interesse pela tecnologia de containers Linux, e se eu for específico, um container O projeto que criou um burburinho em todo o mundo nos últimos meses é – Docker levando a algumas opiniões ecoando que os ambientes de computação em nuvem devem abandonar as máquinas virtuais (VMs) e substituí-las por contêineres devido à menor sobrecarga e desempenho potencialmente melhor.

    Mas a grande questão é, é possível ?, será sensato?

    uma. Os LXCs são definidos para uma instância do Linux. Pode ser de diferentes tipos de Linux (por exemplo, um container Ubuntu em um host CentOS, mas ainda é Linux.) Da mesma forma, contêineres baseados em Windows têm escopo para uma instância do Windows agora, se olharmos para VMs, eles têm um escopo bem mais amplo hipervisores você não está limitado a sistemas operacionais Linux ou Windows.

    b. Os LXCs têm baixos custos indiretos e apresentam melhor desempenho em comparação às VMs. Ferramentas viz. O Docker, criado com base na tecnologia LXC, forneceu aos desenvolvedores uma plataforma para executar seus aplicativos e, ao mesmo tempo, capacitou as pessoas da área de operações com uma ferramenta que permitiria a implantação do mesmo contêiner em servidores de produção ou data centers. Ele tenta fazer a experiência entre um desenvolvedor executando um aplicativo, inicializando e testando um aplicativo e uma pessoa de operações implementando esse aplicativo sem problemas, porque é nesse ponto que reside toda a fricção e o objective do DevOps é decompor esses silos.

    Portanto, a melhor abordagem é que os provedores de infraestrutura em nuvem defendam o uso adequado das VMs e do LXC, pois cada um deles é adequado para lidar com cargas de trabalho e cenários específicos.

    Abandonar VMs não é prático a partir de agora. Portanto, as VMs e os LXCs têm sua própria existência e importância individuais.

    A maioria das respostas aqui fala sobre máquinas virtuais. Eu vou dar uma resposta de uma linha para esta questão que me ajudou mais nos últimos dois anos usando o Docker. É isso:

    O Docker é apenas uma maneira sofisticada de executar um processo, não uma máquina virtual.

    Agora, deixe-me explicar um pouco mais sobre o que isso significa. Máquinas virtuais são sua própria fera. Eu sinto que explicar o que é o Docker ajudará você a entender isso mais do que explicar o que é uma máquina virtual. Especialmente porque há muitas respostas bem aqui dizendo exatamente o que alguém quer dizer quando diz “máquina virtual”. Assim…

    Um contêiner do Docker é apenas um processo (e seus filhos) que é compartimentalizado usando cgroups dentro do kernel do sistema host do restante dos processos. Você pode realmente ver seus processos contêineres do Docker executando ps aux no host. Por exemplo, iniciar o apache2 “em um contêiner” está iniciando o apache2 como um processo especial no host. Ele foi compartimentado de outros processos na máquina. É importante observar que seus contêineres não existem fora do tempo de vida do seu processo em contêiner. Quando seu processo morre, seu contêiner morre. Isso é porque o Docker substitui o pid 1 dentro do seu contêiner com o seu aplicativo ( pid 1 é normalmente o sistema init). Este último ponto sobre o pid 1 é muito importante.

    No que diz respeito ao sistema de arquivos usado por cada um desses processos de contêiner, o Docker usa imagens suportadas pelo UnionFS , que é o que você está baixando quando você faz um docker pull ubuntu . Cada “imagem” é apenas uma série de camadas e metadados relacionados. O conceito de camadas é muito importante aqui. Cada camada é apenas uma mudança da camada abaixo dela. Por exemplo, quando você exclui um arquivo no Dockerfile durante a criação de um contêiner do Docker, na verdade você está apenas criando uma camada na parte superior da última camada que diz “esse arquivo foi excluído”. Aliás, é por isso que você pode excluir um arquivo grande do seu sistema de arquivos, mas a imagem ainda ocupa a mesma quantidade de espaço em disco. O arquivo ainda está lá, nas camadas abaixo do atual. As camadas em si são apenas pacotes de arquivos. Você pode testar isso com o docker save --output /tmp/ubuntu.tar ubuntu e depois cd /tmp && tar xvf ubuntu.tar . Então você pode dar uma olhada ao redor. Todos esses diretórios que parecem hashes longos são, na verdade, as camadas individuais. Cada um contém arquivos ( layer.tar ) e metadados ( json ) com informações sobre essa camada em particular. Essas camadas apenas descrevem mudanças no sistema de arquivos que são salvas como uma camada “em cima de” seu estado original. Ao ler os dados “atuais”, o sistema de arquivos lê os dados como se estivessem olhando apenas para as camadas superiores de alterações. É por isso que o arquivo parece ser excluído, mesmo que ele ainda exista em camadas “anteriores”, porque o sistema de arquivos está apenas olhando para as camadas mais superiores. Isso permite que contêineres completamente diferentes compartilhem suas camadas do sistema de arquivos, mesmo que algumas mudanças significativas tenham ocorrido no sistema de arquivos nas camadas mais superiores de cada contêiner. Isso pode poupar muito espaço em disco quando seus contêineres compartilham suas camadas de imagem de base. No entanto, quando você monta diretórios e arquivos do sistema host em seu contêiner por meio de volumes, esses volumes “ignoram” o UnionFS, portanto, as alterações não são armazenadas em camadas.

    A rede no Docker é obtida usando uma ponte ethernet (chamada docker0 no host) e interfaces virtuais para cada contêiner no host. Ele cria uma sub-rede virtual no docker0 para que seus contêineres se comuniquem “entre”. Há muitas opções de rede aqui, incluindo a criação de sub-redes personalizadas para seus contêineres e a capacidade de “compartilhar” a pilha de rede do host para que seu contêiner acesse diretamente.

    O Docker está se movendo muito rápido. Sua documentação é uma das melhores documentações que já vi. Geralmente é bem escrito, conciso e preciso. Eu recomendo que você verifique a documentação disponível para mais informações, e confie na documentação sobre qualquer outra coisa que você leia online, incluindo o Stack Overflow. Se você tiver perguntas específicas, eu recomendo juntar-se ao #docker no IRC da Freenode e perguntar lá (você pode até usar o webchat da Freenode para isso!).

    O Docker encapsula um aplicativo com todas as suas dependencies.

    Um virtualizador encapsula um sistema operacional que pode executar qualquer aplicativo que possa executar normalmente em uma máquina bare-metal.

    Ambos são muito diferentes. O Docker é leve e usa o LXC / libcontainer (que depende do namespace e dos cgroups do kernel) e não possui emulação de máquina / hardware, como hypervisor, KVM. Xen que são pesados.

    O Docker e o LXC significam mais para isolamento de contêineres, contêineres e resources. Ele usa a API clone do sistema operacional host (atualmente apenas kernel Linux) que fornece namespaces para IPC, NS (assembly), rede, PID, UTS, etc.

    E quanto a memory, E / S, CPU, etc.? Isso é controlado usando cgroups, onde você pode criar grupos com determinados resources (CPU, memory, etc.), especificação / restrição e colocar seus processos lá. No topo do LXC, o Docker fornece um back-end de armazenamento ( http://www.projectatomic.io/docs/filesystems/ ), por exemplo, o sistema de arquivos de assembly union, no qual você pode adicionar camadas e compartilhar camadas entre diferentes namespaces de assembly.

    Este é um recurso poderoso em que as imagens de base são normalmente somente leitura e somente quando o contêiner modifica algo na camada, ele escreve algo na partição de leitura / gravação (também conhecido como copy on write). Ele também fornece muitos outros wrappers, como registro e version control de imagens.

    Com o LXC normal, você precisa vir com alguns rootfs ou compartilhar os rootfs e quando compartilhados, e as alterações são refletidas em outros contêineres. Devido a muitos desses resources adicionais, o Docker é mais popular que o LXC. O LXC é popular em ambientes incorporados para implementar a segurança em torno de processos expostos a entidades externas, como rede e interface do usuário. O Docker é popular no ambiente de multilocação em nuvem, no qual é esperado um ambiente de produção consistente.

    Uma VM normal (por exemplo, VirtualBox e VMware) usa um hipervisor e as tecnologias relacionadas têm firmware dedicado que se torna a primeira camada do primeiro sistema operacional (sistema operacional host ou sistema operacional convidado 0) ou um software executado no sistema operacional host para fornecer emulação de hardware, como CPU, USB / acessórios, memory, rede, etc., para os sistemas operacionais convidados. As VMs ainda são (a partir de 2015) populares em ambientes multi-tenant de alta segurança.

    O Docker / LXC pode quase ser executado em qualquer hardware barato (menos de 1 GB de memory também está OK, desde que você tenha um kernel mais novo), enquanto as VMs normais precisam de pelo menos 2 GB de memory, etc., para fazer qualquer coisa significativa com ele . Mas o suporte do Docker no sistema operacional host não está disponível no sistema operacional, como o Windows (a partir de novembro de 2014), onde os tipos de VMs podem ser executados em Windows, Linux e Macs.

    Aqui está uma foto do docker / rightscale: Aqui está uma foto de rightscale

    1. Leve

    Esta é provavelmente a primeira impressão para muitos aprendizes do docker.

    Primeiro, as imagens do docker geralmente são menores que as imagens da VM, facilitam a criação, a cópia e o compartilhamento.

    Second, Docker containers can start in several milliseconds, while VM starts in seconds.

    2. Layered File System

    This is another key feature of Docker. Images have layers, and different images can share layers, make it even more space-saving and faster to build.

    If all containers use Ubuntu as their base images, not every image has its own file system, but share the same underline ubuntu files, and only differs in their own application data.

    3. Shared OS Kernel

    Think of containers as processes!

    All containers running on a host is indeed a bunch of processes with different file systems. They share the same OS kernel, only encapsulates system library and dependencies.

    This is good for most cases(no extra OS kernel maintains) but can be a problem if strict isolations are necessary between containers.

    Why it matters?

    All these seem like improvements, not revolution. Well, quantitative accumulation leads to qualitative transformation .

    Think about application deployment. If we want to deploy a new software(service) or upgrade one, it is better to change the config files and processes instead of creating a new VM. Because Creating a VM with updated service, testing it(share between Dev & QA), deploying to production takes hours, even days. If anything goes wrong, you got to start again, wasting even more time. So, use configuration management tool(puppet, saltstack, chef etc.) to install new software, download new files is preferred.

    When it comes to docker, it’s impossible to use a newly created docker container to replace the old one. Maintainance is much easier!Building a new image, share it with QA, testing it, deploying it only takes minutes(if everything is automated), hours in the worst case. This is called immutable infrastructure : do not maintain(upgrade) software, create a new one instead.

    It transforms how services are delivered. We want applications, but have to maintain VMs(which is a pain and has little to do with our applications). Docker makes you focus on applications and smooths everything.

    Docker, basically containers, supports OS virtualization ie your application feels that it has a complete instance of an OS whereas VM supports hardware virtualization . You feel like it is a physical machine in which you can boot any OS.

    In Docker, the containers running share the host OS kernel, whereas in VMs they have their own OS files. The environment (the OS) in which you develop an application would be same when you deploy it to various serving environments, such as “testing” or “production”.

    For example, if you develop a web server that runs on port 4000, when you deploy it to your “testing” environment, that port is already used by some other program, so it stops working. In containers there are layers; all the changes you have made to the OS would be saved in one or more layers and those layers would be part of image, so wherever the image goes the dependencies would be present as well.

    In the example shown below, the host machine has three VMs. In order to provide the applications in the VMs complete isolation, they each have their own copies of OS files, libraries and application code, along with a full in-memory instance of an OS. Without Containers Whereas the figure below shows the same scenario with containers. Here, containers simply share the host operating system, including the kernel and libraries, so they don’t need to boot an OS, load libraries or pay a private memory cost for those files. The only incremental space they take is any memory and disk space necessary for the application to run in the container. While the application’s environment feels like a dedicated OS, the application deploys just like it would onto a dedicated host. The containerized application starts in seconds and many more instances of the application can fit onto the machine than in the VM case. insira a descrição da imagem aqui

    Source: https://azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/

    In relation to:-

    “Why is deploying software to a docker image easier than simply deploying to a consistent production environment ?”

    Most software is deployed to many environments, typically a minimum of three of the following:

    1. Individual developer PC(s)
    2. Shared developer environment
    3. Individual tester PC(s)
    4. Shared test environment
    5. QA environment
    6. UAT environment
    7. Load / performance testing
    8. Live staging
    9. Produção
    10. Archive

    There are also the following factors to consider:

    • Developers, and indeed testers, will all have either subtlely or vastly different PC configurations, by the very nature of the job
    • Developers can often develop on PCs beyond the control of corporate or business standardisation rules (eg freelancers who develop on their own machines (often remotely) or contributors to open source projects who are not ’employed’ or ‘contracted’ to configure their PCs a certain way)
    • Some environments will consist of a fixed number of multiple machines in a load balanced configuration
    • Many production environments will have cloud-based servers dynamically (or ‘elastically’) created and destroyed depending on traffic levels

    As you can see the extrapolated total number of servers for an organisation is rarely in single figures, is very often in triple figures and can easily be significantly higher still.

    This all means that creating consistent environments in the first place is hard enough just because of sheer volume (even in a green field scenario), but keeping them consistent is all but impossible given the high number of servers, addition of new servers (dynamically or manually), automatic updates from o/s vendors, anti-virus vendors, browser vendors and the like, manual software installs or configuration changes performed by developers or server technicians, etc. Let me repeat that – it’s virtually (no pun intended) impossible to keep environments consistent (okay, for the purist, it can be done, but it involves a huge amount of time, effort and discipline, which is precisely why VMs and containers (eg Docker) were devised in the first place).

    So think of your question more like this “Given the extreme difficulty of keeping all environments consistent, is it easier to deploying software to a docker image, even when taking the learning curve into account ?” . I think you’ll find the answer will invariably be “yes” – but there’s only one way to find out, post this new question on Stack Overflow.

    There are three different setups that providing a stack to run an application on (This will help us to recognize what a container is and what makes it so much powerful than other solutions):

     1) Traditional Servers(bare metal) 2) Virtual machines (VMs) 3) Containers 

    1) Traditional server stack consist of a physical server that runs an operating system and your application.

    Vantagens:

    • Utilization of raw resources

    • Isolamento

    Desvantagens:

    • Very slow deployment time
    • Caro
    • Wasted resources
    • Difficult to scale
    • Difficult to migrate
    • Complex configuration

    2) The VM stack consist of a physical server which runs an operating system and a hypervisor that manages your virtual machine, shared resources, and networking interface. Each Vm runs a Guest Operating System, an application or set of applications.

    Vantagens:

    • Good use of resources
    • Easy to scale
    • Easy to backup and migrate
    • Cost efficiency
    • Flexibility

    Desvantagens:

    • Resource allocation is problematic
    • Vendor lockin
    • Complex configuration

    3) The Container Setup , the key difference with other stack is container-based virtualization uses the kernel of the host OS to rum multiple isolated guest instances. These guest instances are called as containers. The host can be either a physical server or VM.

    Vantagens:

    • Isolamento
    • Lightweight
    • Resource effective
    • Easy to migrate
    • Segurança
    • Low overhead
    • Mirror production and development environment

    Desvantagens:

    • Same Architecture
    • Resource heavy apps
    • Networking and security issues.

    By comparing the container setup with its predecessors, we can conclude that containerization is the fastest, most resource effective, and most secure setup we know to date. Containers are isolated instances that run your application. Docker spin up the container in a way, layers get run time memory with default storage drivers(Overlay drivers) those run within seconds and copy-on-write layer created on top of it once we commit into the container, that powers the execution of containers. In case of VM’s that will take around a minute to load everything into the virtualize environment. These lightweight instances can be replaced, rebuild, and moved around easily. This allows us to mirror the production and development environment and is tremendous help in CI/CD processes. The advantages containers can provide are so compelling that they’re definitely here to stay.

    There are many answers which explain more detailed on the differences, but here is my very brief explanation.

    One important difference is that VMs use a separate kernel to run the OS . That’s the reason it is heavy and takes time to boot, consuming more system resources.

    In Docker, the containers share the kernel with the host; hence it is lightweight and can start and stop quickly.

    In Virtualization, the resources are allocated in the beginning of set up and hence the resources are not fully utilized when the virtual machine is idle during many of the times. In Docker, the containers are not allocated with fixed amount of hardware resources and is free to use the resources depending on the requirements and hence it is highly scalable.

    Docker uses UNION File system .. Docker uses a copy-on-write technology to reduce the memory space consumed by containers. Read more here

    With a virtual machine , we have a server, we have a host operating system on that server, and then we have a hypervisor. And then running on top of that hypervisor, we have any number of guest operating systems with an application and its dependent binaries, and libraries on that server. It brings a whole guest operating system with it. It’s quite heavyweight. Also there’s a limit to how much you can actually put on each physical machine.

    Digite a descrição da imagem aqui

    Docker containers on the other hand, are slightly different. We have the server. We have the host operating system. But instead a hypervisor , we have the Docker engine , in this case. In this case, we’re not bringing a whole guest operating system with us. We’re bringing a very thin layer of the operating system , and the container can talk down into the host OS in order to get to the kernel functionality there. And that allows us to have a very lightweight container.

    All it has in there is the application code and any binaries and libraries that it requires. And those binaries and libraries can actually be shared across different containers if you want them to be as well. And what this enables us to do, is a number of things. They have much faster startup time . You can’t stand up a single VM in a few seconds like that. And equally, taking them down as quickly.. so we can scale up and down very quickly and we’ll look at that later on.

    Digite a descrição da imagem aqui

    Every container thinks that it’s running on its own copy of the operating system. It’s got its own file system, own registry, etc. which is a kind of a lie. It’s actually being virtualized.

    I have used Docker in production environments and staging very much. When you get used to it you will find it very powerful for building a multi container and isolated environments.

    Docker has been developed based on LXC (Linux Container) and works perfectly in many Linux distributions, especially Ubuntu.

    Docker containers are isolated environments. You can see it when you issue the top command in a Docker container that has been created from a Docker image.

    Besides that, they are very light-weight and flexible thanks to the dockerFile configuration.

    For example, you can create a Docker image and configure a DockerFile and tell that for example when it is running then wget ‘this’, apt-get ‘that’, run ‘some shell script’, setting environment variables and so on.

    In micro-services projects and architecture Docker is a very viable asset. You can achieve scalability, resiliency and elasticity with Docker, Docker swarm, Kubernetes and Docker Compose.

    Another important issue regarding Docker is Docker Hub and its community. For example, I implemented an ecosystem for monitoring kafka using Prometheus, Grafana, Prometheus-JMX-Exporter, and Dokcer.

    For doing that I downloaded configured Docker containers for zookeeper, kafka, Prometheus, Grafana and jmx-collector then mounted my own configuration for some of them using yml files or for others I changed some files and configuration in the Docker container and I build a whole system for monitoring kafka using multi-container Dockers on a single machine with isolation and scalability and resiliency that this architecture can be easily moved into multiple servers.

    Besides the Docker Hub site there is another site called quay.io that you can use to have your own Docker images dashboard there and pull/push to/from it. You can even import Docker images from Docker Hub to quay then running them from quay on your own machine.

    Note: Learning Docker in the first place seems complex and hard, but when you get used to it then you can not work without it.

    I remember the first days of working with Docker when I issued the wrong commands or removing my containers and all of data and configurations mistakenly.

    This is how Docker introduces itself:

    Docker is the company driving the container movement and the only container platform provider to address every application across the hybrid cloud. Today’s businesses are under pressure to digitally transform but are constrained by existing applications and infrastructure while rationalizing an increasingly diverse portfolio of clouds, datacenters and application architectures. Docker enables true independence between applications and infrastructure and developers and IT ops to unlock their potential and creates a model for better collaboration and innovation.

    So Docker is container based, meaning you have images and containers which can be run on your current machine. It’s not including the operating system like VM s, but like a pack of different working packs like Java, Tomcat, etc.

    If you understand containers, you get what Docker is and how it’s different from VM s…

    So, what’s a container?

    A container image is a lightweight, stand-alone, executable package of a piece of software that includes everything needed to run it: code, runtime, system tools, system libraries, settings. Available for both Linux and Windows based apps, containerized software will always run the same, regardless of the environment. Containers isolate software from its surroundings, for example differences between development and staging environments and help reduce conflicts between teams running different software on the same infrastructure.

    Docker

    So as you see in the image below, each container has a separate pack and running on a single machine share that machine’s operating system… They are secure and easy to ship…

    There are a lot of nice technical answers here that clearly discuss the differences between VMs and containers as well as the origins of Docker.

    For me the fundamental difference between VMs and Docker is how you manage the promotion of your application.

    With VMs you promote your application and its dependencies from one VM to the next DEV to UAT to PRD.

    1. Often these VM’s will have different patches and libraries.
    2. It is not uncommon for multiple applications to share a VM. This requires managing configuration and dependencies for all the applications.
    3. Backout requires undoing changes in the VM. Or restoring it if possible.

    With Docker the idea is that you bundle up your application inside its own container along with the libraries it needs and then promote the whole container as a single unit.

    1. Except for the kernel the patches and libraries are identical.
    2. As a general rule there is only one application per container which simplifies configuration.
    3. Backout consists of stopping and deleting the container.

    So at the most fundamental level with VMs you promote the application and its dependencies as discrete components whereas with Docker you promote everything in one hit.

    And yes there are issues with containers including managing them although tools like Kubernetes or Docker Swarm greatly simplify the task.

    Difference between how apps in VM use cpu vs containers

    Source: Kubernetes in Action.