DEVOXX UK. Kubernetes em produção: implantação azul / verde, dimensionamento automático e automação de implantação. Parte 1

O Kubernetes é uma ótima ferramenta para executar contêineres do Docker em um ambiente de produção em cluster. No entanto, existem tarefas que o Kubernetes não consegue resolver. Ao implantar com frequência em um ambiente de produção, precisamos de uma implantação azul / verde totalmente automatizada para evitar o tempo de inatividade nesse processo, que também requer solicitações HTTP externas e upload de SSL. Isso requer integração com um balanceador de carga, como ha-proxy. Outra tarefa é o dimensionamento semiautomático do próprio cluster Kubernetes ao trabalhar na nuvem, por exemplo, redução parcial da escala do cluster à noite.

Embora o Kubernetes não tenha esses recursos prontos para uso, ele fornece uma API que pode ser usada para resolver esses problemas. As ferramentas de implantação e escala automatizadas azul / verde do cluster Kubernetes foram desenvolvidas como parte do projeto de código aberto Cloud RTI.

Esta transcrição de vídeo descreve como configurar o Kubernetes junto com outros componentes de código-fonte aberto para obter um ambiente pronto para produção que aceita código da confirmação de alteração de confirmação do git sem tempo de inatividade na produção.



Hoje falaremos sobre o Kubernetes, em particular, sobre sua automação. Vamos dar uma olhada no básico deste sistema e depois seguiremos como integrar o Kubernetes em projetos na fase de desenvolvimento. Meu nome é Paul, sou da Holanda, trabalho para uma empresa chamada Luminis Technologies e sou o autor dos livros "Designing Cloud Applications with OSGi" e "Modulating Java 9". O que vou falar é muito diferente do tema desses livros.
No último ano, passei a maior parte do tempo trabalhando em uma plataforma de infraestrutura baseada no Kubernetes e criando ferramentas para ele, principalmente no Golang. Além disso, continuo trabalhando no livro Java 9. Meu hobby é o levantamento de peso. Então, vamos ao que interessa.

Por que cuidar do Kubernetes? Primeiro de tudo, porque ele permite executar o Docker em clusters. Se você não usa o Docker, não está no assunto. Se você trabalha com o Docker, sabe que ele foi projetado principalmente para executar contêineres em sua própria máquina. Ele melhora o trabalho com muitas redes, no entanto, tudo isso é limitado a uma máquina, portanto não há como executar contêineres em um cluster.



Os criadores do Docker estão constantemente expandindo seus recursos, mas se você realmente precisar executar contêineres na produção, precisará de algo como o Kubernetes, porque o Docker com sua linha de comando não ajudará.

Vamos falar sobre o básico do Kubernetes. Antes de analisarmos o uso da API para automação, precisamos entender o conceito de como essa plataforma funciona. Um cluster típico inclui os seguintes elementos. O nó principal gerencia e controla a operação de todo o cluster e decide onde os contêineres serão planejados e como serão lançados. Ele lança o servidor da API, que é o elemento mais importante do trabalho da plataforma. Mais tarde, consideraremos esse problema em detalhes.



Há vários nós de trabalho do Node que contêm pods de pods com contêineres do Docker e etcd de armazenamento distribuído. Nós é o local onde seus contêineres serão executados. O Kubernetes não funciona diretamente com contêineres do Docker, mas usa uma abstração chamada Pod para isso. Nós de trabalho iniciam vários contêineres e o nó Mestre garante que eles funcionem. Além disso, há um armazenamento etcd do tipo keyd-value distribuído, que armazena todas as informações sobre o cluster. O etcd é tolerante a falhas; portanto, pelo menos consiste em 3 nós independentes. Isso garante que o assistente funcione sem perder o estado.

Após iniciar o Kubernetes com todos os componentes acima, os contêineres de agendamento são implantados. Implantação significa que os contêineres começam a trabalhar em um cluster. Para fazer isso, primeiro de tudo, você precisa de um objeto chamado Replication Controller, iniciado no servidor mestre, que permite criar e monitorar o status de várias instâncias de lareiras.



Para configurar o controlador de replicação para criar, por exemplo, 5 réplicas de contêineres em cinco nós de trabalho diferentes, você precisa ter muitos nós. Além do fato de o controlador iniciar a operação desses contêineres, ele monitora seu status. Se, devido à falta de memória, um dos contêineres falhar, o controlador registrará uma diminuição no número de 5 para 4 e iniciará um novo contêiner em um dos nós disponíveis. Isso significa que, quando o Kubernetes está em execução, você não inicia os contêineres em nenhum nó específico, mas define o estado necessário - configure a plataforma para implantar 5 contêineres e transfira o controle para o controlador de replicação, que cuida da manutenção desse estado. Portanto, o Replication Controller é um conceito muito importante.

Como eu disse, o Kubernetes não funciona diretamente com contêineres. Ele faz isso através do Pod - uma abstração em cima de contêineres. É importante que o Kubernetes opere não apenas com contêineres do Docker, mas também, por exemplo, com seus contêineres alternativos - rkt. Este não é um suporte oficial, porque se você olhar para a documentação técnica do Kubernetes, ela fala apenas sobre contêineres do Docker. No entanto, à medida que a plataforma se desenvolve, a compatibilidade com contêineres de outros formatos é adicionada a ela.



Cada um deles pode conter muitos contêineres com o mesmo ciclo de vida. Isso significa que não poderemos executar contêineres para vários propósitos no mesmo pod, porque todos eles podem existir apenas no mesmo período de tempo. Eles começam simultaneamente e simultaneamente interrompem seu trabalho. Portanto, se você trabalha com microsserviços, não pode colocá-los todos na mesma sub. Os contêineres dentro da lareira “se vêem” no host local.

Se você, por exemplo, estiver implantando um serviço da Web, o pod para este aplicativo conterá o contêiner nginx, e o nginx não é modificado, mas diretamente pronto para uso. Para que esse nginx funcione, precisamos adicionar nossos próprios arquivos HTML e colocá-los em um contêiner separado para arquivos da web. Ambos os contêineres são colocados em um submarino comum e começam a trabalhar juntos, como se existissem na mesma máquina física, para que eles vissem arquivos do mesmo sistema de arquivos localizados no mesmo host local. Os serviços que fornecem a interação dos componentes do cluster operam usando variáveis ​​de ambiente do ambiente.

A próxima coisa que fornece é rede. Se você executar vários contêineres na mesma máquina física, que também pode estar localizada na nuvem, e todos esses contêineres usarem portas, por exemplo, usaremos três aplicativos Java que funcionam com a mesma porta 8080, isso estará repleto de conflitos. Para evitá-lo, você precisará de mapeamento de portas, o que complicará bastante o processo de implantação de aplicativos.



Portanto, seria ótimo se cada contêiner lançado tivesse seu próprio endereço IP virtual com acesso a todas as portas disponíveis, sem pensar em seu possível conflito. É exatamente isso que o Kubernetes fornece.

Cada vez que ele cria um pod, ele cria seu próprio endereço IP virtual para ele. As portas não são compartilhadas entre o restante dos pods, portanto, não há conflito. A única coisa que trabalha nesse endereço IP é o que esse contêiner faz. Tudo simplifica.
No entanto, isso gera um novo problema: se o seu endereço IP virtual muda toda vez que você reinicia os contêineres, o que geralmente acontece, então como você pode usá-los? Suponha que tenhamos 2 pods diferentes que se comunicam, mas seus endereços IP mudam o tempo todo. O Kubernetes usa um conceito chamado serviços para resolver esse problema. Esses serviços configuram proxies em cima de seus lares e continuam a usar endereços IP virtuais de um determinado intervalo, mas são endereços fixos que não mudam o tempo todo.

Portanto, quando os pods desejam se comunicar, eles fazem isso não diretamente, mas através de serviços, usando esses endereços IP fixos.



Esses serviços organizam o tráfego de todas as réplicas trocadas entre os componentes do cluster. Portanto, os serviços são muito importantes para garantir a comunicação entre os componentes.
O conceito de Serviços facilita muito o processo de implantação de vários componentes quando vários componentes fazem parte de um aplicativo maior, como a arquitetura de microsserviços, embora eu pessoalmente não goste de lidar com microsserviços.



Cada componente que você possui pode ser implantado como um submarino separado com seu próprio ciclo de vida. Eles são independentes um do outro e têm espaços para nome separados, seus próprios endereços IP e intervalos de números de portas, podem ser atualizados e dimensionados independentemente. O uso de serviços facilita muito a comunicação entre componentes. O slide a seguir mostra um exemplo de aplicação de vários componentes.



O primeiro no Frontend é uma interface do usuário que usa vários serviços de back-end ou réplicas de serviços de back-end. Você vê um pacote de vários desses pods para os quais os serviços são usados ​​como proxy. Você não deve se preocupar com o desempenho de cada pod, porque se um deles falhar, o Kubernetes reiniciará automaticamente o novo. O serviço de back-end usa vários outros serviços localizados em diferentes pods e todos eles usam o conceito de serviços para interação. Tudo isso funciona muito bem; portanto, se você usar essa arquitetura, o Kubernetes poderá implantá-la facilmente. Se a arquitetura for baseada em um princípio diferente, você poderá ter problemas.

O próximo conceito importante a ser introduzido é o namespace de Namespaces.



Esses são espaços isolados no Kubernetes que contêm lares, controladores de replicação e serviços. Isolamento significa, por exemplo, que quando o ambiente de desenvolvimento está em um espaço para nome e a produção em outro, você usa serviços com o mesmo nome para evitar conflitos entre diferentes espaços para nome. Dessa forma, você pode facilmente colocar diferentes ambientes no mesmo cluster físico do Kubernetes.

A implantação do aplicativo é uma etapa necessária antes de liberá-lo na produção. A documentação do Kubernetes indica que você deve usar a ferramenta de linha de comando kubectl para concluir a implantação. Essa ferramenta está sendo aprimorada constantemente e é perfeita para implantar qualquer coisa.



Você vê os arquivos de configuração yaml que precisa criar para a API usando o comando kubectl. O próximo slide mostra como é um arquivo yaml típico.



Neste arquivo, configuramos o controlador de replicação. A primeira parte importante é a linha com o número de réplicas que queremos replicar: 3. Este número é igual ao número de nós a serem utilizados. Nesse caso, o número 3 significa que queremos executar pods em três máquinas diferentes em nosso cluster. O controlador de replicação monitora o estado do sistema e, se necessário, reinicia automaticamente os pods para garantir a operação contínua de um determinado número de réplicas.

Na parte inferior do código, há linhas representando a especificação da lareira. Ele descreve as portas, nós de armazenamento, o nome e a imagem do servidor da Web e outras informações necessárias para o contêiner do Docker.

Finalmente, há um monte de metadados aqui, como rótulos. Os rótulos são pares de valores-chave e são adicionados a objetos como pods. Eles são usados ​​para agrupar e selecionar subconjuntos de objetos. Eles são muito importantes para organizar interações de API, vinculando controladores, pods e serviços.

O pod não sabe qual controlador de replicação o criou eo controlador de replicação não conhece a lista de pods que ele cria. Mas os pods e o controlador têm rótulos, cuja coincidência indica que um sub específico pertence a um controlador específico. Essa é uma conexão bastante fraca, mas flexível, que garante a operação estável da API e coisas automatizadas.

Agora você verá uma breve demonstração mostrando o trabalho do kubectl e depois aprofundaremos o trabalho do balanceador de carga e o uso da API. Então, insiro o comando kubectl get pods, mas o sistema não mostra nenhuma lareira porque ainda não executamos nada. Em seguida, insiro o comando ls para visualizar uma lista de arquivos disponíveis.



Agora, insiro o nome do primeiro arquivo da lista e o arquivo yaml de configuração é exibido, semelhante ao que acabamos de ver. Vamos usar esse arquivo para criar uma lareira digitando kubectl create –f nginx-controller.yaml. Como resultado, teremos criado abaixo. Repetindo o comando kubectl get pods, você pode ver que este funciona.



Mas este é apenas um abaixo. Vamos tentar escalar nosso controlador criando várias réplicas. Para fazer isso, insiro o comando kubectl scale rc nginx - replicas = 5, em que rc é o controlador de replicação e 5 é o número necessário de instâncias ou réplicas desse controlador. Você vê o progresso da criação de contêineres e, se você digitar novamente o comando kubectl get pods após alguns segundos, poderá ver que a maioria dos contêineres criados já começou a funcionar.



Assim, aumentamos o número de lares ou réplicas trabalhando em nosso cluster para 5 cópias. Além disso, por exemplo, você pode dar uma olhada no endereço IP criado para a primeira réplica digitando o comando kubectl description pod nginx-772ia. Este é o endereço IP virtual anexado a esse contêiner em particular.



Seu trabalho será fornecido pelos serviços mencionados acima. Vamos ver o que acontece se você destruir uma das réplicas em funcionamento, pois, em qualquer caso, devemos garantir o trabalho de um determinado número de cópias. Entro no comando kubectl delete pod nginx-772ia e o sistema relata que o item com esse identificador foi excluído. Usando o comando kubectl get pods, vemos que 5 instâncias do controlador estão funcionando novamente e, em vez da réplica remota nginx-772ia, uma nova com o identificador nginx-sunfn apareceu.



Isso aconteceu porque o Kubernetes notou a falha de uma das réplicas. Na realidade, isso não foi um mau funcionamento acidental, mas uma ação deliberada, na medida em que eu o apaguei pessoalmente. Porém, como o número de réplicas especificadas pela configuração do cluster permaneceu inalterado, o controlador de replicação observou o desaparecimento de uma das instâncias e restaurou imediatamente o estado necessário do cluster, criando e iniciando um novo contêiner com um novo ID. Obviamente, este é um exemplo estúpido quando eu excluo uma réplica e espero o controlador restaurá-la, mas situações semelhantes ocorrem na vida real devido a uma falha do contêiner, por exemplo, devido à falta de memória. Nesse caso, o controlador também será reiniciado em.

Se tivermos vários cenários de produção nos quais o aplicativo Java não está configurado corretamente, por exemplo, a memória insuficiente é instalada, isso pode causar um travamento algumas horas e uma semana após o início do programa. Nesses casos, o Kubernetes cuida para que o fluxo de trabalho não seja interrompido.

Deixe-me lembrá-lo mais uma vez de que tudo isso não é aplicável no estágio de produção, quando você não deve usar a linha de comando do kubectl e outras coisas inseridas no teclado para garantir a operação do produto. Portanto, antes de começarmos a implantar a automação, precisamos resolver outro grande problema. Suponha que eu tenha um contêiner nginx em execução no momento, mas não tenho acesso a ele do "mundo exterior". No entanto, se for um aplicativo da Web, posso acessá-lo pela Internet. Para garantir a estabilidade desse processo, é usado um balanceador de carga, localizado na frente do cluster.
Precisamos ser capazes de gerenciar os serviços Kubernetes do mundo exterior, e esse recurso não é automaticamente suportado imediatamente. Por exemplo, para garantir o balanceamento de HTTP, você precisa usar o descarregamento de SSL ou o upload de SSL. Esse é o processo de remoção da criptografia baseada em SSL do tráfego de entrada que o servidor da Web recebe para liberar o servidor da descriptografia de dados. Para equilibrar o tráfego, você também pode usar a compactação Gzip de páginas da web.

Versões recentes do Kubernetes, como 1.02, têm um novo recurso chamado Ingress. Serve para configurar o balanceador de carga. Este é um novo conceito na API, no qual você pode escrever um plug-in que configurará qualquer balanceador de carga externo usado.



Infelizmente, hoje esse conceito não está finalizado e é oferecido na versão alfa. Você pode demonstrar como funcionará no futuro, mas não corresponderá à maneira como funciona hoje. Eu uso o balanceador fornecido pelo Google Cloud Engine, no entanto, se você não trabalhar com este serviço, precisará fazer algo sozinho, pelo menos no momento. No futuro, provavelmente em um mês, será muito mais fácil - você pode usar a função de ingresso para equilibrar o tráfego.

Hoje, esse problema é resolvido com a criação de um balanceador de tráfego personalizado. Primeiro de tudo, você pode usar o ha-proxy localizado na frente do cluster Kubernetes. Ele roda fora do cluster em uma máquina externa ou conjunto de máquinas. Em seguida, é necessário fornecer configuração dinâmica automática do ha-proxy, para não configurá-lo manualmente ao criar cada nova lareira. Um trabalho semelhante precisa ser feito para o nginx, Apache e outros servidores, e o ha-proxy atua como uma ferramenta facilmente integrada.

O slide a seguir mostra como o nó do balanceador de carga lida com o tráfego HTTPS recebido e o ha-proxy está localizado em uma máquina externa ou em um cluster de máquinas localizadas fora do cluster Kubernetes. O upload de SSL também está localizado aqui. O proxy detecta os endereços solicitados e passa o tráfego para os serviços Kubernetes, sem se interessar pelos endereços IP dos lares que podem mudar com o tempo. Em seguida, os serviços transmitem tráfego para pods em execução com endereços IP dinâmicos.



Se você usa a AWS, pode usar o conceito de balanceador de carga ELB. O Elastic Load Balancing redireciona o tráfego para instâncias saudáveis ​​da Amazon para garantir a estabilidade do aplicativo. Esse mecanismo é especialmente bom se você precisar de escalabilidade do balanceador de carga.



Nesse caso, o tráfego é enviado primeiro ao serviço da AWS, onde o SSL é descarregado, após o qual entra no nó do balanceador de carga ha-proxy.

Você pode fazer o mesmo se seus clusters estiverem completamente dentro de uma rede VPN virtual privada. Nesse caso, o uso do AWS ELB garante totalmente a segurança do sistema. Você não precisa implementar o SSL entre vários componentes fora do cluster. A única coisa que estará conectada com o mundo exterior é o nosso proxy ha.



Conceitualmente, parece bastante simples, mas como funciona na realidade? Como faço para configurar um ha-proxy para que ele conheça os serviços do Kubernetes? Se você olhar para o ha-proxy da mesma maneira que consideramos o nginx, notará que ele ainda usa arquivos de configuração estáticos. Portanto, se você deseja adicionar um novo back-end, que neste caso são nossos serviços Kubernetes, precisamos alterar o arquivo de configuração, recarregar o ha-proxy e somente depois disso tudo funcionará como deveria. Obviamente, não queremos fazer isso manualmente. Portanto, você pode usar uma pequena ferramenta de código aberto chamada Confd, que gerencia arquivos de configuração de aplicativos locais usando dados etcd. Se ocorrerem alterações no armazenamento de metadados, etcd, o Confd gerará automaticamente um modelo de configuração,que reconfigura o ha-proxy de acordo com as novas condições de trabalho.

Pode parecer que essa abordagem exija esforços adicionais, no entanto, é uma ferramenta muito simples que funciona com modelos, portanto, seu uso é uma tarefa bastante trivial.

26:00 min. A

continuação será muito em breve ...


Um pouco de publicidade :)


Obrigado por ficar com a gente. Você gosta dos nossos artigos? Deseja ver materiais mais interessantes? Ajude-nos fazendo um pedido ou recomendando aos seus amigos o VPS na nuvem para desenvolvedores a partir de US $ 4,99 , um analógico exclusivo de servidores de nível básico que foi inventado por nós para você: Toda a verdade sobre o VPS (KVM) E5-2697 v3 (6 núcleos) 10 GB DDR4 480 GB SSD 1 Gbps de US $ 19 ou como dividir o servidor? (as opções estão disponíveis com RAID1 e RAID10, até 24 núcleos e até 40GB DDR4).

Dell R730xd 2 vezes mais barato no data center Equinix Tier IV em Amsterdã? Somente nós temos 2 TVs Intel TetraDeca-Core Xeon 2x E5-2697v3 2.6GHz 14C 64GB DDR4 4x960GB SSD 1Gbps 100 TV a partir de US $ 199 na Holanda!Dell R420 - 2x E5-2430 2.2Ghz 6C 128GB DDR3 2x960GB SSD 1Gbps 100TB - a partir de US $ 99! Leia sobre Como criar um prédio de infraestrutura. classe c usando servidores Dell R730xd E5-2650 v4 que custam 9.000 euros por um centavo?

All Articles