Introdução
O Kubernetes é um sistema poderoso de código aberto, desenvolvido inicialmente pelo Google e apoiado pela Cloud Native Computing Foundation (CNCF), para gerenciar aplicativos em contêineres em um ambiente de cluster. Ele tem como objetivo fornecer melhores maneiras de gerenciar componentes e serviços relacionados e distribuídos em infraestruturas variadas. Para saber mais sobre o Kubernetes, explore o guia abaixo. Se estiver procurando por um serviço de hospedagem Kubernetes gerenciado, confira nosso serviço Kubernetes simples e gerenciado, desenvolvido para crescimento.
Neste guia, discutiremos o que é o Kubernetes, alguns dos conceitos básicos do Kubernetes. Falaremos sobre a arquitetura do sistema, os problemas que ele resolve e o modelo que utiliza para lidar com implantações e dimensionamento em contêineres.
O que é o Kubernetes?
O Kubernetes, em seu nível básico, é um sistema para executar e coordenar aplicativos em contêineres em um cluster de máquinas. É uma plataforma projetada para gerenciar completamente o ciclo de vida de aplicativos e serviços em contêineres usando métodos que proporcionam previsibilidade, escalabilidade e alta disponibilidade.
Como usuário do Kubernetes, você pode definir como suas aplicações devem ser executadas e as maneiras como elas devem interagir com outras aplicações ou com o mundo exterior. Você pode escalar seus serviços para cima ou para baixo, realizar atualizações suaves e alternar o tráfego entre diferentes versões de suas aplicações para testar funcionalidades ou reverter implantações problemáticas. O Kubernetes fornece interfaces e primitivas de plataforma componíveis que permitem definir e gerenciar suas aplicações com alto grau de flexibilidade, potência e confiabilidade.
Arquitetura do Kubernetes
Para entender como o Kubernetes consegue fornecer essas capacidades, é útil ter uma ideia de como ele é projetado e organizado em um nível elevado. O Kubernetes pode ser visualizado como um sistema construído em camadas, com cada camada superior abstraindo a complexidade encontrada nos níveis inferiores.
Na sua base, o Kubernetes reúne máquinas físicas ou virtuais individuais em um cluster usando uma rede compartilhada para comunicar entre cada servidor, novamente, seja máquinas físicas ou virtuais. Este cluster Kubernetes é a plataforma física onde todos os componentes, capacidades e cargas de trabalho do Kubernetes são configurados.
As máquinas no cluster do Kubernetes são designadas a cada uma um papel dentro do ecossistema do Kubernetes. Um servidor (ou um pequeno grupo em implantações altamente disponíveis) funciona como o servidor mestre. Este servidor atua como um gateway e cérebro para o cluster, expondo uma API do Kubernetes para usuários e clientes, verificando a saúde de outros servidores, decidindo como melhor dividir e atribuir o trabalho (conhecido como “agendamento”), e orquestrando a comunicação entre outros componentes (às vezes referidos como orquestração de contêineres). O servidor mestre atua como o principal ponto de contato com o cluster e é responsável pela maior parte da lógica centralizada que o Kubernetes fornece.
As outras máquinas no cluster são designadas como nós: servidores responsáveis por aceitar e executar cargas de trabalho usando recursos locais e externos. Para ajudar na isolamento, gerenciamento e flexibilidade, o Kubernetes executa aplicativos e serviços em contêineres, então cada nó precisa estar equipado com um tempo de execução de contêiner (como Docker ou rkt). O nó recebe instruções de trabalho do servidor mestre e cria ou destrói contêineres conforme necessário, ajustando regras de rede para rotear e encaminhar o tráfego adequadamente.
Como mencionado acima, as aplicações e serviços em si são executados no cluster dentro de contêineres. Os componentes subjacentes garantem que o estado desejado das aplicações corresponda ao estado real do cluster. Os usuários interagem com o cluster comunicando-se com o servidor principal da API do Kubernetes, seja diretamente ou com clientes e bibliotecas. Para iniciar uma aplicação ou serviço, um plano declarativo é submetido em JSON ou YAML definindo o que criar e como deve ser gerenciado. O servidor principal então pega o plano e descobre como executá-lo na infraestrutura examinando os requisitos e o estado atual do sistema. Este grupo de aplicações definidas pelo usuário em execução de acordo com um plano especificado representa a camada final do Kubernetes.
Componentes do Servidor Principal
Conforme descrito acima, o servidor principal atua como o plano de controle primário para clusters Kubernetes. Ele serve como o principal ponto de contato para administradores e usuários, e também fornece muitos sistemas em todo o cluster para os nós de trabalho relativamente não sofisticados. No geral, os componentes no servidor principal trabalham juntos para aceitar solicitações de usuários, determinar as melhores maneiras de agendar contêineres de carga de trabalho, autenticar clientes e nós, ajustar a rede em todo o cluster e gerenciar responsabilidades de dimensionamento e verificação de saúde.
Estes componentes podem ser instalados em uma única máquina ou distribuídos entre vários servidores. Vamos dar uma olhada em cada um dos componentes individuais associados aos servidores principais para clusters Kubernetes nesta seção.
etcd
Um dos componentes fundamentais que o Kubernetes precisa para funcionar é um armazenamento de configuração globalmente disponível. O etcd, projeto desenvolvido pela equipe da CoreOS (sistema operacional), é um armazenamento de chave-valor distribuído e leve que pode ser configurado para se estender por vários nós.
O Kubernetes usa o etcd
para armazenar dados de configuração que podem ser acessados por cada um dos nós no cluster. Isso pode ser usado para descoberta de serviço e pode ajudar os componentes a se configurarem ou reconfigurarem de acordo com informações atualizadas. Também ajuda a manter o estado do cluster com recursos como eleição de líder e bloqueio distribuído. Ao fornecer uma simples API HTTP/JSON, a interface para definir ou recuperar valores é bastante direta.
Como a maioria dos outros componentes no plano de controle, o etcd
pode ser configurado em um único servidor principal ou, em cenários de produção, distribuído entre vários servidores. O único requisito é que ele seja acessível pela rede para cada uma das máquinas Kubernetes.
kube-apiserver
Um dos serviços mestre mais importantes é um servidor de API. Este é o ponto principal de gerenciamento de todo o cluster, pois permite que um usuário configure as cargas de trabalho e unidades organizacionais do Kubernetes. Também é responsável por garantir que o armazenamento etcd
e os detalhes do serviço dos contêineres implantados estejam em acordo. Age como a ponte entre vários componentes para manter a saúde do cluster e disseminar informações e comandos.
O servidor de API implementa uma interface RESTful, o que significa que muitas ferramentas e bibliotecas diferentes podem se comunicar facilmente com ele. Um cliente chamado kubectl está disponível como um método padrão de interação com o cluster Kubernetes a partir de um computador local.
kube-controller-manager
O gerenciador de controladores é um serviço geral que tem muitas responsabilidades. Primariamente, ele gerencia diferentes controladores que regulam o estado do cluster, gerenciam ciclos de vida de cargas de trabalho e realizam tarefas de rotina. Por exemplo, um controlador de replicação garante que o número de réplicas (cópias idênticas) definido para um pod corresponda ao número atualmente implantado no cluster. Os detalhes dessas operações são escritos no etcd
, onde o gerenciador de controladores observa as alterações por meio do servidor de API.
Quando uma mudança é vista, o controlador lê as novas informações e implementa o procedimento que satisfaz o estado desejado. Isso pode envolver dimensionar uma aplicação para cima ou para baixo, ajustar endpoints, etc.
kube-scheduler
O processo que realmente atribui cargas de trabalho a nós específicos no cluster é o agendador. Este serviço lê os requisitos operacionais de uma carga de trabalho, analisa o ambiente de infraestrutura atual e coloca o trabalho em um nó ou nós aceitáveis.
O agendador é responsável por rastrear a capacidade disponível em cada host para garantir que as cargas de trabalho não sejam agendadas além dos recursos disponíveis. O agendador deve conhecer a capacidade total, bem como os recursos já alocados para cargas de trabalho existentes em cada servidor.
cloud-controller-manager
O Kubernetes pode ser implantado em muitos ambientes diferentes e pode interagir com vários provedores de infraestrutura para entender e gerenciar o estado dos recursos no cluster. Embora o Kubernetes funcione com representações genéricas de recursos como armazenamento anexável e balanceadores de carga, ele precisa de uma maneira de mapeá-los para os recursos reais fornecidos por provedores de nuvem não homogêneos.
Os controladores de nuvem atuam como a cola que permite ao Kubernetes interagir com provedores com diferentes capacidades, recursos e APIs, enquanto mantêm construções relativamente genéricas internamente. Isso permite que o Kubernetes atualize suas informações de estado de acordo com as informações coletadas do provedor de nuvem, ajuste recursos na nuvem conforme as alterações são necessárias no sistema, e crie e utilize serviços adicionais na nuvem para atender aos requisitos de trabalho enviados para o cluster.
Componentes do Servidor de Nó
No Kubernetes, servidores que executam trabalho executando contêineres são conhecidos como nós. Os servidores de nó têm alguns requisitos que são necessários para se comunicar com os componentes mestre, configurar a rede de contêineres e executar as cargas de trabalho atribuídas a eles.
A Container Runtime
O primeiro componente que cada nó deve ter é um tempo de execução de contêiner. Tipicamente, esse requisito é satisfeito instalando e executando o Docker, mas alternativas como o rkt e o runc também estão disponíveis.
O tempo de execução do contêiner é responsável por iniciar e gerenciar contêineres, aplicações encapsuladas em um ambiente operacional relativamente isolado, mas leve. Cada unidade de trabalho no cluster é, em seu nível básico, implementada como um ou mais contêineres que devem ser implantados. O tempo de execução do contêiner em cada nó é o componente que finalmente executa os contêineres definidos nas cargas de trabalho enviadas para o cluster.
kubelet
O principal ponto de contato de cada nó com o grupo do cluster é um pequeno serviço chamado kubelet. Este serviço é responsável por transmitir informações para e do plano de controle de serviços, bem como interagir com a loja etcd
para ler detalhes de configuração ou escrever novos valores.
O serviço kubelet
comunica-se com os componentes principais para autenticar no cluster e receber comandos e trabalho. O trabalho é recebido na forma de um manifesto que define a carga de trabalho e os parâmetros operacionais. O processo kubelet
assume então a responsabilidade de manter o estado do trabalho no servidor do nó. Ele controla o tempo de execução do contêiner para lançar ou destruir contêineres conforme necessário.
kube-proxy
Para gerenciar a subdivisão de hosts individuais e disponibilizar serviços para outros componentes, um pequeno serviço de proxy chamado kube-proxy é executado em cada servidor de nó. Este processo encaminha solicitações para os contêineres corretos, pode realizar balanceamento de carga primitivo e é geralmente responsável por garantir que o ambiente de rede seja previsível e acessível, mas isolado quando apropriado.
Objetos e Cargas de Trabalho do Kubernetes
Enquanto os contêineres são o mecanismo subjacente usado para implantar aplicativos contêinerizados, o Kubernetes utiliza camadas adicionais de abstração sobre a interface do contêiner para fornecer recursos de dimensionamento, resiliência e gerenciamento do ciclo de vida. Em vez de gerenciar contêineres diretamente, os usuários definem e interagem com instâncias compostas por vários primitivos fornecidos pelo modelo de objeto do Kubernetes. Abaixo, veremos os diferentes tipos de objetos que podem ser usados para definir essas cargas de trabalho.
Pods
A pod is the most basic unit that Kubernetes deals with. Containers themselves are not assigned to hosts. Instead, one or more tightly coupled containers are encapsulated in an object called a pod.
A pod generally represents containers that should be controlled as a single application. Pods consist of containers that operate closely together, share a life cycle, and should always be scheduled on the same node. They are managed entirely as a unit and share their environment, volumes, and IP space. In spite of their containerized implementation, you should generally think of pods as a single, monolithic application to best conceptualize how the cluster will manage the pod’s resources and scheduling.
Normalmente, os pods consistem em um contêiner principal que satisfaz o propósito geral da carga de trabalho e, opcionalmente, alguns contêineres auxiliares que facilitam tarefas intimamente relacionadas. Esses são programas que se beneficiam de serem executados e gerenciados em seus próprios contêineres, mas estão intimamente ligados à aplicação principal. Por exemplo, um pod pode ter um contêiner executando o servidor de aplicação principal e um contêiner auxiliar baixando arquivos para o sistema de arquivos compartilhado quando são detectadas mudanças em um repositório externo. A escalabilidade horizontal geralmente não é recomendada no nível do pod porque existem outros objetos de nível mais alto mais adequados para a tarefa.
Em geral, os usuários não devem gerenciar os pods por conta própria, porque eles não fornecem algumas das funcionalidades normalmente necessárias em aplicações (como gerenciamento sofisticado do ciclo de vida e escalonamento). Em vez disso, os usuários são incentivados a trabalhar com objetos de nível mais alto que usam pods ou modelos de pod como componentes base, mas implementam funcionalidades adicionais.
Controladores de Replicação e Conjuntos de Replicação
Normalmente, ao trabalhar com Kubernetes, em vez de trabalhar com pods individuais, você estará gerenciando grupos de pods replicados idênticos. Estes são criados a partir de modelos de pod e podem ser escalonados horizontalmente por controladores conhecidos como controladores de replicação e conjuntos de replicação.
A replication controller is an object that defines a pod template and control parameters to scale identical replicas of a pod horizontally by increasing or decreasing the number of running copies. This is an easy way to distribute load and increase availability natively within Kubernetes. The replication controller knows how to create new pods as needed because a template that closely resembles a pod definition is embedded within the replication controller configuration.
O controlador de replicação é responsável por garantir que o número de pods implantados no cluster corresponda ao número de pods em sua configuração. Se um pod ou host subjacente falhar, o controlador iniciará novos pods para compensar. Se o número de réplicas na configuração de um controlador mudar, o controlador iniciará ou encerrará containers para corresponder ao número desejado. Os controladores de replicação também podem realizar atualizações progressivas para rolar um conjunto de pods para uma nova versão, um por um, minimizando o impacto na disponibilidade da aplicação.
Os conjuntos de replicação são uma iteração no design do controlador de replicação com maior flexibilidade na forma como o controlador identifica os pods que devem ser gerenciados. Os conjuntos de replicação estão começando a substituir os controladores de replicação por causa de suas maiores capacidades de seleção de réplicas, mas não conseguem realizar atualizações progressivas para ciclo de backends para uma nova versão como os controladores de replicação podem. Em vez disso, os conjuntos de replicação são destinados a serem usados dentro de unidades adicionais e de nível superior que fornecem essa funcionalidade.
Assim como os pods, tanto os controladores de replicação quanto os conjuntos de replicação raramente são as unidades com as quais você trabalhará diretamente. Embora se baseiem no design de pod para adicionar escalabilidade horizontal e garantias de confiabilidade, eles carecem de algumas das capacidades de gerenciamento de ciclo de vida mais refinadas encontradas em objetos mais complexos.
Implantações
Implantações são uma das cargas de trabalho mais comuns para criar e gerenciar diretamente. As implantações utilizam conjuntos de replicação como um bloco de construção, adicionando funcionalidades flexíveis de gerenciamento de ciclo de vida à mistura.
Embora as implantações construídas com conjuntos de replicação possam parecer duplicar a funcionalidade oferecida pelos controladores de replicação, as implantações resolvem muitos dos pontos problemáticos que existiam na implementação de atualizações em cascata. Ao atualizar aplicativos com controladores de replicação, os usuários são obrigados a enviar um plano para um novo controlador de replicação que substituiria o controlador atual. Ao usar controladores de replicação, tarefas como rastreamento de histórico, recuperação de falhas de rede durante a atualização e reversão de alterações ruins são ou difíceis ou deixadas como responsabilidade do usuário.
As implantações são um objeto de alto nível projetado para facilitar o gerenciamento do ciclo de vida de pods replicados. As implantações podem ser modificadas facilmente alterando a configuração e o Kubernetes ajustará os conjuntos de replicação, gerenciará transições entre diferentes versões de aplicativos e, opcionalmente, manterá automaticamente o histórico de eventos e capacidades de desfazer. Devido a esses recursos, as implantações provavelmente serão o tipo de objeto Kubernetes com o qual você trabalhará com mais frequência.
Conjuntos de Estados
Conjuntos de estados são controladores de pod especializados que oferecem garantias de ordenação e unicidade. Primariamente, estes são usados para ter um controle mais detalhado quando você tem requisitos especiais relacionados à ordenação de implantação, dados persistentes ou rede estável. Por exemplo, os conjuntos de estados são frequentemente associados a aplicativos orientados a dados, como bancos de dados, que precisam de acesso aos mesmos volumes mesmo se forem reprogramados para um novo nó.
Os conjuntos de estados fornecem um identificador de rede estável criando um nome único baseado em números para cada pod que persistirá mesmo se o pod precisar ser movido para outro nó. Da mesma forma, os volumes de armazenamento persistente podem ser transferidos com um pod quando for necessário reprogramar. Os volumes persistem mesmo após o pod ter sido excluído para evitar perda de dados acidental.
Ao implantar ou ajustar a escala, os conjuntos de estados realizam operações de acordo com o identificador numerado em seu nome. Isso proporciona uma maior previsibilidade e controle sobre a ordem de execução, o que pode ser útil em alguns casos.
Conjuntos de Daemons
Conjuntos de Daemons são outra forma especializada de controlador de pod que executa uma cópia de um pod em cada nó do cluster (ou um subconjunto, se especificado). Isso é mais útil quando se implantam pods que ajudam a realizar manutenção e fornecem serviços para os próprios nós do Kubernetes.
Por exemplo, coletar e encaminhar logs, agregar métricas e executar serviços que aumentam as capacidades do próprio nó são candidatos populares para conjuntos de daemon. Porque os conjuntos de daemon frequentemente fornecem serviços fundamentais e são necessários em toda a frota, eles podem contornar as restrições de agendamento de pod que impedem outros controladores de atribuir pods a determinados hosts. Como exemplo, devido às suas responsabilidades únicas, o servidor mestre é frequentemente configurado para ficar indisponível para agendamento normal de pod, mas conjuntos de daemon têm a capacidade de substituir a restrição caso a caso para garantir que os serviços essenciais estejam em execução.
Trabalhos e Trabalhos Cron
As cargas de trabalho que descrevemos até agora assumiram todas um ciclo de vida semelhante a um serviço de longa duração. O Kubernetes usa uma carga de trabalho chamada trabalhos para fornecer um fluxo de trabalho mais baseado em tarefas, onde os contêineres em execução devem sair com sucesso após algum tempo depois de terem concluído seu trabalho. Os trabalhos são úteis se você precisar realizar processamento único ou em lote em vez de executar um serviço contínuo.
Construir em trabalhos são trabalhos cron. Assim como os daemons cron
convencionais em sistemas Linux e Unix-like que executam scripts em um cronograma, os trabalhos cron no Kubernetes fornecem uma interface para executar trabalhos com um componente de agendamento. Os trabalhos cron podem ser usados para agendar um trabalho para ser executado no futuro ou em uma base regular e recorrente. Os trabalhos cron do Kubernetes são basicamente uma reimplementação do comportamento cron clássico, usando o cluster como uma plataforma em vez de um único sistema operacional.
Outros Componentes do Kubernetes
Além das cargas de trabalho que você pode executar em um cluster, o Kubernetes fornece várias outras abstrações que ajudam a gerenciar suas aplicações, controlar a rede e habilitar a persistência. Vamos discutir alguns dos exemplos mais comuns aqui.
Serviços do Kubernetes
Até agora, temos usado o termo “serviço” no sentido convencional, Unix-like: para denotar processos de longa execução, frequentemente conectados à rede, capazes de responder a solicitações. No entanto, no Kubernetes, um serviço é um componente que age como um balanceador de carga interno básico e embaixador para pods. Um serviço agrupa coleções lógicas de pods que realizam a mesma função para apresentá-los como uma única entidade.
Isso permite que você implante um serviço que possa monitorar e rotear para todos os contêineres de backend de um tipo específico. Os consumidores internos só precisam conhecer o endpoint estável fornecido pelo serviço. Enquanto isso, a abstração do serviço permite que você dimensione ou substitua as unidades de trabalho de backend conforme necessário. O endereço IP de um serviço permanece estável, independentemente de alterações nos pods aos quais ele roteia. Ao implantar um serviço, você ganha facilmente descoberta e pode simplificar seus designs de contêineres.
A qualquer momento em que precisar fornecer acesso a um ou mais pods para outra aplicação ou para consumidores externos, você deve configurar um serviço. Por exemplo, se você tiver um conjunto de pods executando servidores web que devem ser acessíveis pela internet, um serviço fornecerá a abstração necessária. Da mesma forma, se seus servidores web precisarem armazenar e recuperar dados, você desejará configurar um serviço interno para dar a eles acesso aos seus pods de banco de dados.
Embora os serviços, por padrão, estejam disponíveis apenas usando um endereço IP roteável internamente, eles podem ser disponibilizados fora do cluster escolhendo uma das várias estratégias. A configuração NodePort funciona abrindo uma porta estática na interface de rede externa de cada nó. O tráfego para a porta externa será roteado automaticamente para os pods apropriados usando um serviço de IP de cluster interno.
Alternativamente, o tipo de serviço LoadBalancer cria um balanceador de carga externo para rotear para o serviço usando a integração do balanceador de carga do Kubernetes do provedor de nuvem. O gerenciador de controladores de nuvem criará o recurso apropriado e o configurará usando os endereços de serviço do serviço interno.
Volumes e Volumes Persistentes
O compartilhamento confiável de dados e garantir sua disponibilidade entre reinicializações de contêineres é um desafio em muitos ambientes containerizados. As runtimes de contêineres geralmente fornecem algum mecanismo para anexar armazenamento a um contêiner que persiste além da vida útil do contêiner, mas as implementações geralmente carecem de flexibilidade.
Para resolver isso, o Kubernetes usa sua própria abstração de volumes que permite que os dados sejam compartilhados por todos os contêineres dentro de um pod e permaneçam disponíveis até que o pod seja encerrado. Isso significa que pods fortemente acoplados podem compartilhar arquivos facilmente sem mecanismos externos complexos. As falhas de contêineres dentro do pod não afetarão o acesso aos arquivos compartilhados. Uma vez que o pod é encerrado, o volume compartilhado é destruído, então não é uma boa solução para dados verdadeiramente persistentes.
Volumes persistentes são um mecanismo para abstrair armazenamento mais robusto que não está ligado ao ciclo de vida do pod. Em vez disso, eles permitem que os administradores configurem recursos de armazenamento para o cluster que os usuários podem solicitar e reivindicar para os pods que estão em execução. Uma vez que um pod tenha terminado com um volume persistente, a política de recuperação do volume determina se o volume é mantido até ser excluído manualmente ou removido juntamente com os dados imediatamente. Dados persistentes podem ser usados para proteger contra falhas baseadas em nó e alocar maiores quantidades de armazenamento do que estão disponíveis localmente.
Rótulos e Anotações
A Kubernetes organizational abstraction related to, but outside of the other concepts, is labeling. A label in Kubernetes is a semantic tag that can be attached to Kubernetes objects to mark them as a part of a group. These can then be selected for when targeting different instances for management or routing. For instance, each of the controller-based objects use labels to identify the pods that they should operate on. Services use labels to understand the backend pods they should route requests to.
Rótulos são fornecidos como pares de chave-valor simples. Cada unidade pode ter mais de um rótulo, mas cada unidade pode ter apenas uma entrada para cada chave. Normalmente, uma chave “nome” é usada como identificador de propósito geral, mas você também pode classificar objetos por outros critérios, como estágio de desenvolvimento, acessibilidade pública, versão da aplicação, etc.
Anotações são um mecanismo semelhante que permite que você anexe informações arbitrárias de chave-valor a um objeto. Enquanto os rótulos devem ser usados para informações semânticas úteis para combinar um pod com critérios de seleção, as anotações são mais livres e podem conter dados menos estruturados. Em geral, as anotações são uma maneira de adicionar metadados ricos a um objeto que não são úteis para fins de seleção.
Conclusão
Source:
https://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes