Melhores práticas Kubernetes. Criando pequenos contêineres

Melhores práticas Kubernetes. Criando pequenos contêineres

O primeiro passo para implantar no Kubernetes é colocar seu aplicativo em um contêiner. Nesta série, vamos explorar como criar a imagem de um contêiner pequeno e seguro.
Com o Docker, a criação de imagens de contêiner nunca foi tão fácil. Especifique uma imagem base, adicione suas modificações e crie o contêiner.

Melhores práticas Kubernetes. Criando pequenos contêineres

Apesar de essa abordagem ser excelente para começar, usar imagens base padrão pode resultar em um funcionamento inseguro com imagens grandes e cheias de vulnerabilidades.

Além disso, a maioria das imagens no Docker utiliza Debian ou Ubuntu como imagem base, o que garante compatibilidade e fácil adaptação (o arquivo Docker ocupa apenas duas linhas de código), mas essas imagens base podem adicionar centenas de megabytes de carga extra ao seu contêiner. Por exemplo, um simples arquivo de aplicativo node.js Go chamado "hello-world" ocupa cerca de 700 megabytes, enquanto o tamanho do seu aplicativo em si é de apenas alguns megabytes.

Melhores práticas Kubernetes. Criando pequenos contêineres

Assim, toda essa carga extra representa um desperdício de espaço digital e uma excelente oportunidade para vulnerabilidades e falhas de segurança. Portanto, vamos explorar duas maneiras de reduzir o tamanho da imagem do contêiner.

A primeira é usar imagens base de tamanho pequeno, e a segunda é usar o padrão de projeto Builder Pattern. Utilizar imagens base menores é provavelmente a maneira mais simples de reduzir o tamanho do seu contêiner. É bem provável que a linguagem ou stack que você está usando forneça uma imagem original do aplicativo que é muito menor que a imagem padrão. Vamos dar uma olhada no nosso contêiner node.js.

Melhores práticas Kubernetes. Criando pequenos contêineres

Por padrão, o tamanho da imagem base node:8 no Docker é de 670 MB, enquanto o tamanho do node:8-alpine é de apenas 65 MB, ou seja, 10 vezes menor. Ao usar a menor imagem base Alpine, você reduz significativamente o tamanho do seu container. Alpine é uma distribuição Linux pequena e leve, muito popular entre os usuários do Docker, pois é compatível com muitos aplicativos, mantendo um tamanho reduzido dos containers. Diferente da imagem padrão do Docker 'node', 'node:alpine' remove muitos arquivos e programas desnecessários, apenas mantendo o que é preciso para executar seu aplicativo.

Para mudar para uma imagem base menor, basta atualizar o arquivo Docker para começar a usar a nova imagem base:

Melhores práticas Kubernetes. Criando pequenos contêineres

Agora, ao contrário da antiga imagem onbuild, você precisará copiar seu código para o container e instalar quaisquer dependências. No novo Dockerfile, o container começa a partir da imagem node:alpine, em seguida, cria um diretório para o código, instala as dependências usando o gerenciador de pacotes NPM e, por fim, executa o server.js.

Melhores práticas Kubernetes. Criando pequenos contêineres

Com essa atualização, você obtém um container 10 vezes menor. Se sua linguagem de programação ou stack não possui a funcionalidade de reduzir a imagem base, use o Alpine Linux. Isso também permitirá que você gerencie completamente o conteúdo do container. Usar imagens base pequenas é uma excelente maneira de criar rapidamente containers menores. Mas é possível alcançar uma redução ainda maior utilizando o Padrão Builder.

Melhores práticas Kubernetes. Criando pequenos contêineres

Em linguagens interpretadas, o código-fonte é primeiro passado para o interpretador, que o executa diretamente. Nas linguagens compiladas, o código-fonte é previamente transformado em código compilado. Durante esse processo, a compilação frequentemente utiliza ferramentas que na verdade não são necessárias para a execução do código. Isso significa que você pode remover completamente essas ferramentas do container final. Para isso, pode-se usar o Padrão Builder.

Melhores práticas Kubernetes. Criando pequenos contêineres

O código é criado no primeiro container e compilado. Em seguida, o código compilado é empacotado no container final sem os compiladores e ferramentas necessárias para compilar esse código. Vamos passar por esse processo com um aplicativo Go. Primeiramente, faremos a transição da imagem onbuild para o Alpine Linux.

Melhores práticas Kubernetes. Criando pequenos contêineres

No novo arquivo Docker, o contêiner começa com a imagem golang:alpine. Em seguida, ele cria um diretório para o código, copia o código-fonte, compila esse código e executa o aplicativo. Este contêiner é muito menor do que o contêiner onbuild, mas ainda contém o compilador e outras ferramentas Go que, na verdade, não precisamos. Portanto, vamos apenas extrair o programa compilado e colocá-lo em nosso próprio contêiner.

Melhores práticas Kubernetes. Criando pequenos contêineres

Você pode notar algo estranho neste arquivo Docker: ele contém duas linhas FROM. A primeira seção de 4 linhas se parece exatamente com o arquivo Docker anterior, exceto que usa a palavra-chave AS para dar um nome a essa etapa. Na próxima seção, há uma nova linha FROM que permite iniciar uma nova imagem, e em vez da imagem golang:alpine como base, vamos usar Raw alpine.

O Raw Alpine Linux não possui certificados SSL instalados, o que resultará em falhas na maioria das chamadas de API pelo protocolo HTTPS, então vamos instalar alguns certificados CA raiz.

E agora vem a parte mais interessante: para copiar o código compilado do primeiro contêiner para o segundo, você pode simplesmente usar o comando COPY localizado na 5ª linha da segunda seção. Ele copiará apenas um arquivo de aplicativo e não tocará nas ferramentas Go. O novo arquivo Docker de múltiplas etapas conterá uma imagem de contêiner que ocupa apenas 12 megabytes, enquanto a imagem de contêiner original tinha 700 megabytes, o que representa uma grande diferença!
Assim, usar imagens base pequenas e o Padrão Builder são ótimas maneiras de criar contêineres muito menores sem muito trabalho.
É possível que, dependendo da pilha do aplicativo, existam maneiras adicionais de reduzir o tamanho da imagem e do contêiner, mas será que contêineres pequenos realmente têm uma vantagem mensurável? Vamos considerar dois aspectos onde contêineres pequenos são extremamente eficazes – desempenho e segurança.

Para avaliar o aumento de desempenho, vamos considerar a duração do processo de criação de um contêiner, inserindo-o no registro (push) e a subsequente extração dele (pull). Você pode ver que um contêiner menor tem uma vantagem inegável em relação a um contêiner maior.

Melhores práticas Kubernetes. Criando pequenos contêineres

O Docker irá armazenar camadas em cache, por isso as compilações subsequentes serão realizadas muito rapidamente. No entanto, em muitos sistemas de CI utilizados para compilar e testar contêineres, as camadas não são armazenadas em cache, portanto há uma economia de tempo significativa. Como pode ser visto, o tempo de construção de um contêiner grande, dependendo da capacidade da sua máquina, varia de 34 a 54 segundos, enquanto o uso de um contêiner reduzido com o Builder Pattern leva de 23 a 28 segundos. Para operações desse tipo, o ganho de desempenho será de 40-50%. Portanto, apenas pense em quantas vezes você cria e testa seu código.

Depois que o contêiner é construído, você precisa inserir sua imagem (push container image) no registro de contêineres para depois utilizá-la em seu cluster Kubernetes. Recomendo o uso do Google Container Registry.

Melhores práticas Kubernetes. Criando pequenos contêineres

Ao usar o Google Container Registry (GCR), você paga apenas pelo armazenamento 'cru' e pela rede, sem taxas adicionais para gerenciamento de contêineres. É confidencial, seguro e muito rápido. O GCR utiliza várias técnicas para acelerar a operação pull. Como você vê, inserir a imagem do contêiner Docker Container Image ao usar go:onbuild, dependendo do desempenho do computador, levará de 15 a 48 segundos, enquanto a mesma operação com um contêiner menor levará de 14 a 16 segundos, e para máquinas menos potentes, a vantagem de velocidade da operação aumenta em 3 vezes. Para máquinas grandes, o tempo é aproximadamente o mesmo, pois o GCR utiliza um cache global para uma base comum de imagens, ou seja, você não precisa carregá-las. Em computadores de baixo desempenho, a CPU é um gargalo, portanto a vantagem de usar contêineres menores é muito mais perceptível.

Se você usar o GCR, recomendo fortemente aplicar o Google Container Builder (GCB) como parte do seu sistema de construção.

Melhores práticas Kubernetes. Criando pequenos contêineres

Como você pode ver, seu uso permite alcançar resultados muito melhores na redução do tempo da operação Build+Push do que mesmo em uma máquina eficiente – nesse caso, o processo de construção e envio de contêineres para o host é acelerado quase duas vezes. Além disso, a cada dia você recebe 120 minutos de construção gratuitamente, o que na maioria dos casos atende às necessidades de criação de contêineres.

Em seguida, vem a métrica de desempenho mais importante – a velocidade de extração ou download de contêineres Pull. E se você não se importa muito com o tempo gasto na operação push, a duração do processo pull afeta seriamente o desempenho geral do sistema. Suponha que você tenha um cluster de três nós e um deles falhe. Se você utilizar um sistema de gerenciamento, como o Google Kubernetes Engine, ele substituirá automaticamente o nó inoperante por um novo. No entanto, esse novo nó estará completamente vazio, e você precisará transferir todos os seus contêineres para que ele comece a funcionar. Se a operação pull demorar demais, todo esse tempo seu cluster funcionará com menor desempenho.

Existem muitos casos em que isso pode acontecer: a adição de um novo nó ao cluster, a atualização de nós ou até mesmo a troca para um novo contêiner para implantação. Assim, minimizar o tempo de extração pull se torna um fator crucial. É indiscutível que um contêiner pequeno é baixado muito mais rapidamente do que um grande. Se você estiver usando vários contêineres em um cluster Kubernetes, a economia de tempo pode ser bastante significativa.

Melhores práticas Kubernetes. Criando pequenos contêineres

Veja a comparação apresentada: a operação pull ao trabalhar com pequenos contêineres leva de 4 a 9 vezes menos tempo, dependendo da potência da máquina, do que a mesma operação utilizando go:onbuild. Usar imagens base de contêineres menores acelera significativamente o tempo e a velocidade com que novos nós do Kubernetes podem ser implantados e conectados à internet.

Vamos considerar a questão da segurança. Acredita-se que contêineres menores são muito mais seguros do que os grandes, pois têm uma menor superfície de ataque. Isso é realmente verdade? Uma das funcionalidades mais úteis do Google Container Registry é a capacidade de escanear automaticamente seus contêineres em busca de vulnerabilidades. Alguns meses atrás, criei contêineres tanto onbuild quanto multistage, então vamos ver se há alguma vulnerabilidade lá.

Melhores práticas Kubernetes. Criando pequenos contêineres

O resultado é impressionante: um pequeno contêiner apresentou apenas 3 vulnerabilidades médias, enquanto no grande foram encontradas 16 críticas e 376 outras vulnerabilidades. Ao examinar o conteúdo do grande contêiner, fica claro que a maioria dos problemas de segurança não está relacionada ao nosso aplicativo, mas sim a programas que nem sequer utilizamos. Portanto, quando as pessoas falam sobre uma grande superfície de ataque, é exatamente isso que elas querem dizer.

Melhores práticas Kubernetes. Criando pequenos contêineres

A conclusão é clara: crie contêineres pequenos, pois eles oferecem vantagens reais em termos de desempenho e segurança do seu sistema.

As melhores práticas do Kubernetes. Organização do Kubernetes com namespaces

Por que no hosting comum a administração do PrestaShop é lenta, e no seu não é?

Um pouco de publicidade 🙂

Obrigado por permanecer conosco. Você gosta dos nossos artigos? Quer ver mais materiais interessantes? Apoie-nos fazendo um pedido ou recomendando para conhecidos. VPS em nuvem para desenvolvedores a partir de $4.99, uma alternativa única aos servidores entry-level, que criamos para você: Toda a verdade sobre VPS (KVM) E5-2697 v3 (6 Núcleos) 10GB DDR4 480GB SSD 1Gbps a partir de $19 ou como dividir um servidor corretamente? (disponíveis opções com RAID1 e RAID10, até 24 núcleos e até 40GB DDR4).

Dell R730xd por 2 vezes mais barato no datacenter Equinix Tier IV em Amsterdã? Somente conosco 2 x Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100TB a partir de $199 na Holanda! Dell R420 — 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB — a partir de $99! Leia sobre Como construir uma infraestrutura de classe corporativa utilizando servidores Dell R730xd E5-2650 v4 com custo de 9000 euros por centavos?

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster