fbpx
Kubernetes em C#, seria possível?
Publicado em: quinta-feira, 14 de jan de 2021

Você já pensou em criar seu próprio Kubernetes em C#? Hoje eu vou mostrar como você pode dar os primeiros passos nessa direção.

Introdução

O Docker, assim como o Containerd possuem API´s. Essas API´s permitem que você lide com containers da forma que bem entender.

Você tanto pode criar containers, dropar containers, reiniciar containers e fazer o que que quiser. Os recursos estão disponíveis para todos nós.

Um ponto importante em comum é que essas API´s são gRPC. E essa é uma característica que habilita qualquer linguagem que suporte gRPC a operar e gerenciar tanto o docker quanto o containerd.

No passado eu já mostrei como usei a API do Docker para subir bancos de dados MySQL, Oracle, Postgres e SQL Server, dinamicamente, para poder lidar com testes integrados. Isso foi detalhado em Underwater – Construindo Libraries .NET Standard Profissionais.

E vale lembrar que a API gRPC dessas soluções não são API´s alternativas. gRPC é usado para a comunicação entre Kubernetes e diversos de seus componentes, assim como é usado para falar com Docker via DockerShim e com Containerd. Outro ponto legal é que o Docker fala com o containerd via gRPC também.

Sobre esse assunto, que tal olhar arquivos *.PROTO no repositório do Kubernetes.

Disclaimers

Que esse post não sirva de incentivo para a criação de gambiarras nessa direção, a intenção aqui é mostrar uma oportunidade de usar a API do Docker para fazer algumas coisas interessantes.

A ideia de criar seu próprio Kubernetes é meramente ilustrativa.

Como usar a API gRPC do Docker?

Você vai precisar instalar o pacote Docker.DotNet (Nuget, GitHub).

var dockerClientConfiguration = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine"));
var client = dockerClientConfiguration.CreateClient();

Esse endereço “npipe://./pipe/docker_engine” só funciona se seu projeto estiver rodando no Windows e com o Docker Desktop instalado e funcionando. Já no Linux o endereço é “unix:///var/run/docker.sock” e está disponível para todos os processos que rodem sob contas que sejam do grupo Docker. Isso geralmente, mas não sempre, inclui o usuário root.

Aliás esse docker.sock dá o poder de um container controlar o host inteiro, na medida que dá total acesso à API de Containers do Docker.

Mas para nossa alegria, isso só está acessível se você expor para o container usando o -v /var/run/docker.sock:/var/run/docker.sock em um docker run.

Sobe segurança

Essa é uma questão super importante sobre segurança em containers:

Expor o docker.sock para um container dá a ele poderes ilimitados.

Dá para baixar uma imagem maliciosa de um registry inseguro, assumir o controle do host. Dá até para instalar um minerador de bitcoin ou uma infra inteira de vpn para a dark web.

O que quero dizer é que dar esse acesso é algo que pode ser feito, mas só e somente se você confia na imagem do container que está subindo. Como nesse caso é você mesmo então ok. Mas fique atento a quais containers pedem esse tipo de acesso, só entregue o docker.sock para os containers de imagens que você confia.

Voltando ao Docker Client

Como baixar uma imagem

É assim que baixamos uma imagem. Usando o Create Image e o FromImage como parâmetro.

dockerClient.Images.CreateImageAsync(new ImagesCreateParameters() { FromImage = "NomeImagem:Tag" }, null, logManager);

Como criar um container

Essa abaixo é a criação de um RabbitMQ, por exemplo.

CreateContainerResponse response = await this.dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters()
            {
                Image = "rabbitmq:3.8-management",
                Hostname = "masterclass-rabbitmq",
                Env = new List<string>() {
                    "RABBITMQ_DEFAULT_USER=mc",
                    "RABBITMQ_DEFAULT_PASS=mc2",
                    "RABBITMQ_DEFAULT_VHOST=main"
                },
               
                HostConfig = new HostConfig()
                {
                    PortBindings = new Dictionary<string, IList<PortBinding>>()
                    {
                        { "5672", new List<PortBinding>(){ new PortBinding() { HostIP = "0.0.0.0", HostPort = "5672/tcp" }  } },
                        { "15672", new List<PortBinding>(){ new PortBinding() { HostIP = "0.0.0.0", HostPort = "15672/tcp" }  } }
                    }
                },
                ExposedPorts = new Dictionary<string, EmptyStruct>() {
                    { "5672", default },
                    { "15672", default }
                }
            });

Como Iniciar um container

Criar o container não faz ele iniciar, você precisa iniciá-lo chamando um segundo método.

await this.dockerClient.Containers.StartContainerAsync(response.ID, new ContainerStartParameters() { });

Agora sim temos a chance de ver um container no ar, criado programaticamente.

Mas o que está disponível?

Tudo! Dá para criar containers, criar serviços, configurações, deployments e muito mais. Como é a interface default, ela suporta tudo do Docker!!

Não é incrível?

Pra que?

Aí você me pergunta: Qual a utilidade disso?

Você nunca ouviu alguém dizendo que ficaria muito feliz se pudesse testar a aplicação em conjunto com outras coisas? Eu já mostrei como subo Oracle, SQL Server, Postregres e MySQL para validar uma implementação de uma library. Esse é o poder. Fora isso, você tem a oportunidade de criar projetos que criam containers dinamicamente.

Seja para resolver um problema ou rodar uma rotina. Até uma rotina agendada.

O céu é o limite! Enjoy!

Mas e aí, Kubernetes em C#, afinal seria possível?

Possível sim, perfeitamente possível, no entanto a força do Kubernetes está no standard, na autonomia e na direção que o projeto e a comunidade deram para o projeto. São variáveis que extrapolam o código. Aliás, vale lembrar para quem ficou pilhado com a ideia que não basta saber operar o docker para construir o Kubernetes. É buraco é beeeeeeemmmm maior!

0 comentários

Enviar um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

[docker de a a z]

Lives

Fique de olho nas lives

Fique de olho nas lives no meu canal do Youtube, no Canal .NET e nos Grupos do Facebook e Instagram.

Aceleradores

Existem diversas formas de viabilizar o suporte ao teu projeto. Seja com os treinamentos, consultoria, mentorias em grupo.