A tecnologia de container Linux é, na verdade, um conjunto de capacidades que permitem o isolamento e contenção de aplicações. Apesar da recente exposição do termo, essa é uma tecnologia que vem sendo aprimorada desde o UNIX, com o chroot, ou do BSD, com o Jails.
Ao contrário da tecnologia de virtualização que encapsula um sistema operacional completo em cima de um hardware virtual para usar como casulo para aplicações, containers usam de funcionalidades nativas do kernel Linux para garantir isolamento e contenção das aplicações:
- Namespaces: Permite criar uma abstração de um recurso de sistema global particular e fazê-lo aparecer como uma instância separada para processos dentro de um namespace. Conseqüentemente, vários containers podem usar o mesmo recurso simultaneamente sem criar um conflito.
- Control Groups (cgroups): Permite agrupar processos para fins de gerenciamento de recursos do sistema. Os Cgroups alocam o tempo da CPU, a memória do sistema, a largura de banda da rede ou combinações destes entre os grupos de tarefas definidos pelo usuário.
- SELinux: Fornece uma separação segura, pois impede que os processos raiz dentro do container interfiram com outros processos globais.
- Linux Capabilities: Permite a limitação dos privilégios disponíveis a processos que rodam como root em pequenos grupos de privilégios. Dese modo, um processo rodando com privilégios de root pode ser limitado a obter apenas as permissões mínimas que ele precisa para executar suas tarefas.
Entendendo essas funcionalidades, podemos perceber que containers são linux já que estão intimamente acoplados as features nativas do kernel do linux.
Apesar de ser uma tecnologia antiga, os containers ganharam mais popularidade hoje em dia principalmente pela sua portabilidade. Soluções como Docker ficaram realmente atrativas quando permitiram que um container pudesse ser compartilhado entre infraestruturas heterogêneas. Isso foi possível graças a criação do conceito de imagem, que será nosso próximo tópico nesse guia.
Apesar da grande quantidade de informações que dizem ser possível a portabilidade de containers entre diferentes sistemas operacionais, ela não é sempre obtida na prática. Existem situações que podem não funcionar conforme esperado quando executamos, por exemplo, um container com Ubuntu em um servidor hospedeiro rodando CentOS. Além disso, precisamos garantir que a mesma versão do Docker esteja rodando nos servidores e até mesmo o tempo de vida da imagem pode influenciar nesse equação. Vale sempre lembrar que, container é linux e sua execução depende das bibliotecas e principalmente do kernel do host.
Além do Docker, existem também outras soluções de containers no mercado:
Com o surgimento de novas tecnologias de containers e com uma grande demanda por parte do mercado por esse tipo de ferramenta, foi criado uma especificação que norteia e direciona como os containers e imagens devem ser executados/criados. A OCI (Open Container Iniciative) foi criada em 2015 e se propõe a criar uma padrão de mercado para runtime e images. Grandes empresas como Google, Red Hat, Intel e Amazon apoiam essa iniciativa.
Os containers são entidades efêmeras por natureza, baseadas em imagens imutáveis. Estas armazenam informações de metadados (informações e parâmetros) e os dados (executáveis, bibliotecas e arquivos) que serão usados com o container.
Como mecanismo de otimização, de espaço e de performance, essas imagens são construídas em camadas sobrepostas, também imutáveis. Dessa forma conseguimos aproveitar camadas comuns entre as diferentes imagens, poupando espaço de armazenamento e melhorando a performance.
Apesar da possibilidade de escrita de dados na última camada conforme mostrado no desenho acima, todos os dados são perdidos após a finalização do container.
Existem dois tipos de repositórios, ou registros, importantes para armazenamento das imagens de containers: registro local (ou storage local) e registros remotos (públicos/privados).
O storage local é um espaço de armazenamento especial que reside no mesmo host que executa os containers. Esse é usado para armazenas as imagens que serão usadas para executar containers nessa máquina, servindo como uma camada de cache. Esse é o primeiro repositório a ser consultado em busca de imagens.
Os registros remotos são servidores, públicos ou privados, responsáveis por compartilhar imagens construidas por entidades e/ou usuários. Estes registros podem permitir não só o acesso para download de imagens, mas também envio de imagens novas por usuários autenticados/autorizados. Dentre os mais famosos temos:
Geralmente os registros remotos são executados na porta 5000.