Nós tivemos algumas conversas no passado sobre diferentes recursos do containerd, como ele foi projetado e alguns dos problemas que consertamos ao longo do caminho. Containerd é usado por Docker, Kubernetes CRI e alguns outros projetos, mas este é um post para pessoas que podem não saber o que o containerd realmente faz nessas plataformas. Gostaria de fazer mais posts sobre featureset e design do containerd no futuro, mas por agora vamos começar com o básico.
Eu acho que o ecossistema de contêiner pode ser confuso às vezes. Especialmente com a terminologia que usamos. O que é isso? Um tempo de execução. E isto? Um tempo de execução … containerd, como o nome indica, não contém “nerd” como alguns desejariam me “trollar”, é um daemon de contêiner. Ele foi originalmente construído como um ponto de integração para tempos de execução do OCI, como o runc, mas nos últimos seis meses adicionou muita funcionalidade para compará-lo com as necessidades de plataformas de contêineres modernas, como Docker e Kubernetes.
Uma vez que não há coisas como contêineres Linux no kernelspace, os contêineres são vários recursos do kernel vinculados. Quando você está construindo uma grande plataforma ou um sistema distribuído, você quer uma camada de abstração entre o seu código de gerenciamento e os syscalls e a fita adesiva dos recursos para executar um contêiner. É aí que o containerd vive. Ele fornece uma camada de cliente de tipos nas quais as plataformas podem ser construídas sem ter que descartar o nível do kernel. É muito melhor trabalhar com os tipos Container, Task e Snapshot do que gerenciar chamadas para clone() ou mount().
O Containerd foi projetado para ser usado por Docker e Kubernetes, bem como por qualquer outra plataforma de contêiner que deseje abstrair-se de syscalls ou funcionalidade específica do sistema operacional para executar contêineres em Linux, Windows, Solaris ou outros Sistemas Operacionais. Com esses usuários em mente, queríamos ter certeza de que containerd tem apenas o que eles precisam e nada que eles não precisem. Realmente isso é impossível, mas pelo menos é isso que almejamos. Coisas como a rede estão fora do escopo do containerd. A razão para isso é que, quando você está construindo um sistema distribuído, a rede é um aspecto muito central. Com o SDN e a descoberta de serviços hoje, a rede é muito mais específica da plataforma do que abstrair-se de chamadas netlink no linux. A maioria das novas redes de sobreposição são baseadas em rotas e exigem que as tabelas de roteamento sejam atualizadas sempre que um novo contêiner for criado ou excluído. Descoberta de serviço, DNS, etc., todos devem ser notificados dessas mudanças também. Seria um grande pedaço de código para poder suportar todas as diferentes interfaces de rede, ganchos e pontos de integração para suportar isso se adicionássemos rede a containerd. O que fizemos em vez disso foi optar por um sistema de eventos robusto dentro do containerd para que vários consumidores pudessem se inscrever nos eventos pelos quais se interessam. Nós também expomos uma API de tarefas que permite aos usuários criar uma tarefa em execução, ter a capacidade de adicionar interfaces ao espaço de nome da rede do contêiner e, em seguida, iniciar o processo do contêiner sem a necessidade de ganchos complexos em vários pontos do ciclo de vida de um contêiner.
Outra área que foi adicionada ao containerd nos últimos meses é um sistema completo de armazenamento e distribuição que suporta formatos de imagem OCI e Docker. Você tem um sistema completo de armazenamento de conteúdo endereçado na API containerd que funciona não apenas para imagens, mas também para metadados, pontos de controle e dados arbitrários anexados aos contêineres.
Nós também usamos o tempo para repensar como funcionam as “graphdrivers”. Estes são os sistemas de arquivos de nível de sobreposição ou de bloco que permitem que as imagens tenham camadas e que você execute compilações eficientes. As graphdrivers foram inicialmente escritas por Salomon e eu quando adicionamos suporte para devicemapper. O Docker só suportou AUFS naquele momento, então modelamos as graphdrivers após o sistema de arquivos de sobreposição. No entanto, fazer um sistema de arquivos em nível de bloco, como o devicemapper/lvm, atua como um sistema de arquivos de sobreposição que mostrou ser muito mais difícil de fazer a longo prazo. As interfaces tiveram que se expandir ao longo do tempo para suportar diferentes recursos do que pensávamos que originalmente seria necessário. Com containerd, usamos uma abordagem diferente, fazendo com que os sistemas de arquivos de sobreposição agissem como um instantâneo em vez de vice-versa. Isso foi muito mais fácil de fazer, já que os sistemas de arquivos de sobreposição proporcionam muito mais flexibilidade do que os sistemas de arquivos instantâneos, como BTRFS, ZFS e devicemapper, pois não possuem uma relação estrita pai e filho. Isso nos ajudou a construir uma interface menor para os instantâneos, enquanto ainda cumprem os requisitos necessários de coisas como um construtor, bem como reduz a quantidade de código necessário, tornando muito mais fácil manter a longo prazo.
Então, o que você realmente ganha usando containerd? Você obtém funcionalidades push e pull, bem como gerenciamento de imagens. Você obtém as APIs do ciclo de vida do contêiner para criar, executar e gerenciar contêineres e suas tarefas. Toda uma API dedicada ao gerenciamento de snapshot. Basicamente, tudo o que você precisa para construir uma plataforma de contêiner sem ter que lidar com os detalhes subjacentes do sistema operacional. Eu acho que a parte mais importante do containerd é ter uma API controlada e estável que terá correções de erros e patches de segurança suportados.
Saiba mais sobre containerd:
- Confira o Repositório GitHub do containerd;
- Junte-se ao canal Slack do containerd;
- Registre-se no Moby Summit LA ao lado da Open Source Summit da América do Norte;
- Registre-se para DockerCon Europa e DockerCon Moby Summit.
***
Este artigo é do Docker Core Engineering. A tradução do artigo foi feita pela Redação iMasters com autorização, e você pode acompanhar o artigo em inglês no link: https://blog.docker.com/2017/08/what-is-containerd-runtime/