Kubernetes é um plataforma de código aberto, portável e extensiva para o gerenciamento de cargas de trabalho e serviços distribuídos em contêineres, que facilita tanto a configuração declarativa quanto a automação. Ele possui um ecossistema grande, e de rápido crescimento. Serviços, suporte, e ferramentas para Kubernetes estão amplamente disponíveis.
Essa página é uma visão geral do Kubernetes.
Kubernetes é um plataforma de código aberto, portável e extensiva para o gerenciamento de cargas de trabalho e serviços distribuídos em contêineres, que facilita tanto a configuração declarativa quanto a automação. Ele possui um ecossistema grande, e de rápido crescimento. Serviços, suporte, e ferramentas para Kubernetes estão amplamente disponíveis.
O Google tornou Kubernetes um projeto de código-aberto em 2014. O Kubernetes combina mais de 15 anos de experiência do Google executando cargas de trabalho produtivas em escala, com as melhores idéias e práticas da comunidade.
O nome Kubernetes tem origem no Grego, significando timoneiro ou piloto. K8s é a abreviação derivada pela troca das oito letras "ubernete" por "8", se tornado K"8"s.
Vamos dar uma olhada no porque o Kubernetes é tão útil, voltando no tempo.
Era da implantação tradicional: No início, as organizações executavam aplicações em servidores físicos. Não havia como definir limites de recursos para aplicações em um mesmo servidor físico, e isso causava problemas de alocação de recursos. Por exemplo, se várias aplicações fossem executadas em um mesmo servidor físico, poderia haver situações em que uma aplicação ocupasse a maior parte dos recursos e, como resultado, o desempenho das outras aplicações seria inferior. Uma solução para isso seria executar cada aplicação em um servidor físico diferente. Mas isso não escalava, pois os recursos eram subutilizados, e se tornava custoso para as organizações manter muitos servidores físicos.
Era da implantação virtualizada: Como solução, a virtualização foi introduzida. Esse modelo permite que você execute várias máquinas virtuais (VMs) em uma única CPU de um servidor físico. A virtualização permite que as aplicações sejam isoladas entre as VMs, e ainda fornece um nível de segurança, pois as informações de uma aplicação não podem ser acessadas livremente por outras aplicações.
A virtualização permite melhor utilização de recursos em um servidor físico, e permite melhor escalabilidade porque uma aplicação pode ser adicionada ou atualizada facilmente, reduz os custos de hardware e muito mais. Com a virtualização, você pode apresentar um conjunto de recursos físicos como um cluster de máquinas virtuais descartáveis.
Cada VM é uma máquina completa que executa todos os componentes, incluindo seu próprio sistema operacional, além do hardware virtualizado.
Era da implantação em contêineres: Contêineres são semelhantes às VMs, mas têm propriedades de isolamento flexibilizados para compartilhar o sistema operacional (SO) entre as aplicações. Portanto, os contêineres são considerados leves. Semelhante a uma VM, um contêiner tem seu próprio sistema de arquivos, compartilhamento de CPU, memória, espaço de processo e muito mais. Como eles estão separados da infraestrutura subjacente, eles são portáveis entre nuvens e distribuições de sistema operacional.
Contêineres se tornaram populares porque eles fornecem benefícios extra, tais como:
Os contêineres são uma boa maneira de agrupar e executar suas aplicações. Em um ambiente de produção, você precisa gerenciar os contêineres que executam as aplicações e garantir que não haja tempo de inatividade. Por exemplo, se um contêiner cair, outro contêiner precisa ser iniciado. Não seria mais fácil se esse comportamento fosse controlado por um sistema?
É assim que o Kubernetes vem ao resgate! O Kubernetes oferece uma estrutura para executar sistemas distribuídos de forma resiliente. Ele cuida do escalonamento e da recuperação à falha de sua aplicação, fornece padrões de implantação e muito mais. Por exemplo, o Kubernetes pode gerenciar facilmente uma implantação no método canário para seu sistema.
O Kubernetes oferece a você:
O Kubernetes não é um sistema PaaS (plataforma como serviço) tradicional e completo. Como o Kubernetes opera no nível do contêiner, e não no nível do hardware, ele fornece alguns recursos geralmente aplicáveis comuns às ofertas de PaaS, como implantação, escalonamento, balanceamento de carga, e permite que os usuários integrem suas soluções de logging, monitoramento e alerta. No entanto, o Kubernetes não é monolítico, e essas soluções padrão são opcionais e conectáveis. O Kubernetes fornece os blocos de construção para a construção de plataformas de desenvolvimento, mas preserva a escolha e flexibilidade do usuário onde é importante.
Kubernetes:
Ao implantar o Kubernetes, você obtém um cluster.
Um cluster Kubernetes consiste em um conjunto de servidores de processamento, chamados nós, que executam aplicações conteinerizadas. Todo cluster possui ao menos um servidor de processamento (worker node).
O(s) servidor(es) de processamento hospeda(m) os Pods, que são componentes de uma aplicação. A camada de gerenciamento gerencia os nós de processamento e os Pods no cluster. Em ambientes de produção, a camada de gerenciamento geralmente executa em múltiplos computadores e um cluster geralmente executa múltiplos nós, fornecendo tolerância a falhas e alta disponibilidade.
Este documento descreve os vários componentes que você precisa ter para implantar um cluster Kubernetes completo e funcional.
Os componentes de um cluster do Kubernetes
Os componentes da camada de gerenciamento tomam decisões globais sobre o cluster
(por exemplo, alocação de Pods), bem como detectam e respondem aos eventos
do cluster (por exemplo, inicialização de um novo Pod
quando o campo replicas de um Deployment não está atendido).
Os componentes da camada de gerenciamento podem ser executados em qualquer máquina do cluster. Contudo, para simplificar, os scripts de configuração normalmente iniciam todos os componentes da camada de gerenciamento na mesma máquina, e contêineres com cargas de trabalho do usuário não rodam nesta máquina. Veja Construindo clusters altamente disponíveis com o kubeadm para um exemplo de configuração da camada de gerenciamento que roda em múltiplas máquinas.
O servidor da API é um componente da camada de gerenciamento do Kubernetes que expõe a API do Kubernetes. O servidor da API é o front end para a camada de gerenciamento do Kubernetes.
A principal implementação de um servidor de API do Kubernetes é o kube-apiserver. O kube-apiserver foi projetado para ser escalonado horizontalmente — ou seja, ele pode ser escalonado com a criação de mais instâncias. Você pode executar várias instâncias do kube-apiserver e distribuir o tráfego entre essas instâncias.
Armazenamento do tipo chave-valor consistente e de alta-disponibilidade, usado como armazenamento de apoio do Kubernetes para todos os dados do cluster.
Se o seu cluster Kubernetes usa o etcd como seu armazenamento de apoio, certifique-se de ter um plano de backup para seus dados.
Você pode encontrar informações detalhadas sobre o etcd na documentação oficial.
Componente da camada de gerenciamento que observa os Pods recém-criados e que ainda não foram atribuídos a um nó, e seleciona um nó para executá-los.
Os fatores levados em consideração para as decisões de alocação incluem: requisitos de recursos individuais e coletivos, restrições de hardware/software/política, especificações de afinidade e antiafinidade, localidade de dados, interferência entre cargas de trabalho, e prazos.
Componente da camada de gerenciamento que executa os processos de controlador.
Logicamente, cada controlador está em um processo separado, mas para reduzir a complexidade, eles todos são compilados num único binário e executam em um processo único.
Alguns tipos desses controladores são:
default para novos namespaces.O cloud-controller-manager executa apenas controladores que são específicos para seu provedor de nuvem. Se você estiver executando o Kubernetes em suas próprias instalações ou em um ambiente de aprendizagem dentro de seu próprio PC, o cluster não possui um gerenciador de controlador de nuvem.
Tal como acontece com o kube-controller-manager, o cloud-controller-manager combina vários ciclos de controle logicamente independentes em um binário único que você executa como um processo único. Você pode escalonar horizontalmente (executar mais de uma cópia) para melhorar o desempenho ou para auxiliar na tolerância a falhas.
Os seguintes controladores podem ter dependências de provedor de nuvem:
Os componentes do nó são executados em todos os nós, mantendo os Pods em execução e fornecendo o ambiente de execução do Kubernetes.
Um agente que é executado em cada nó no cluster. Ele garante que os contêineres estejam sendo executados em um Pod.
O kubelet utiliza um conjunto de PodSpecs que são fornecidos por vários mecanismos e garante que os contêineres descritos nesses PodSpecs estejam funcionando corretamente. O kubelet não gerencia contêineres que não foram criados pelo Kubernetes.
kube-proxy é um proxy de rede executado em cada nó no seu cluster, implementando parte do conceito de serviço do Kubernetes.
kube-proxy mantém regras de rede nos nós. Estas regras de rede permitem a comunicação de rede com seus pods a partir de sessões de rede dentro ou fora de seu cluster.
kube-proxy usa a camada de filtragem de pacotes do sistema operacional se houver uma e estiver disponível. Caso contrário, o kube-proxy encaminha o tráfego ele mesmo.
O agente de execução (runtime) de contêiner é o software responsável por executar os contêineres.
O Kubernetes suporta diversos agentes de execução de contêineres: Docker, containerd, CRI-O, e qualquer implementação do Kubernetes CRI (Container Runtime Interface).
Complementos (addons) usam recursos do Kubernetes (DaemonSet,
Deployment, etc) para implementar funcionalidades
do cluster. Como fornecem funcionalidades em nível do cluster, recursos de complementos
que necessitem ser criados dentro de um namespace pertencem ao namespace kube-system.
Alguns complementos selecionados são descritos abaixo; para uma lista estendida dos complementos disponíveis, consulte Instalando Complementos.
Embora os outros complementos não sejam estritamente necessários, todos os clusters do Kubernetes devem ter um DNS do cluster, já que muitos exemplos dependem disso.
O DNS do cluster é um servidor DNS, além de outros servidores DNS em seu ambiente, que fornece registros DNS para serviços do Kubernetes.
Os contêineres iniciados pelo Kubernetes incluem automaticamente esse servidor DNS em suas pesquisas DNS.
O dashboard é uma interface de usuário Web, de uso geral, para clusters do Kubernetes. Ele permite que os usuários gerenciem e solucionem problemas de aplicações em execução no cluster, bem como o próprio cluster.
O monitoramento de recursos do contêiner registra métricas de série temporal genéricas sobre os contêineres em um banco de dados central e fornece uma interface de usuário para navegar por esses dados.
Um mecanismo de logging a nível do cluster é responsável por guardar os logs dos contêineres em um armazenamento central de logs com uma interface para navegação/pesquisa.
Esta página explica como os objetos do Kubernetes são representados na API do Kubernetes e como você pode expressá-los no formato .yaml.
Os objetos do Kubernetes são entidades persistentes no Kubernetes. Kubernetes utiliza estas entidades para representar o estado do cluster. Especificamente, eles podem descrever:
Um objeto do Kubernetes é um “registro de intenção”-uma vez criado o objeto, o sistema do Kubernetes trabalha constantemente para garantir que este objeto existe. Ao criar um objeto, você está efetivamente falando para o sistema do Kubernetes como você quer que a carga do seu cluster seja. Este é o estado desejado do seu cluster.
Para trabalhar com objetos do Kubernetes seja para criar, modificar ou deletar eles, você precisará usar a API do Kubernetes. Quando você usa a interface de linha de comando do kubectl, por exemplo, o CLI faz as chamadas necessárias na API do Kubernetes para você. Você também pode usar a API do Kubernetes diretamente no seu próprio programa usando uma das Bibliotecas.
Quase todos os objetos do Kubernetes incluem dois campos de objetos aninhados que governam a configuração do objeto: a especificação do objeto e o status do objeto. Para objetos que têm especificação, você tem que definir isso quando você cria o objeto, fornecendo uma descrição das características que você quer que o recurso tenha: o seu estado desejado.
O status descreve o estado atual do objeto, fornecido e atualizado pelo Kubernetes e seus componentes. A camada de gerenciamento do Kubernetes gerência continuamente e ativamente o real estado para corresponder ao estado desejado que você forneceu.
Por exemplo, no Kubernetes, o Deployment é um objeto que pode representar uma aplicação executando no seu cluster. Quando você cria o Deployment, você pode alterar a especificaçãopara definir que você quer três réplicas da aplicação em execução simultânea. O Kubernetes lê as especificações do Deployment e inicia três instâncias do seu aplicativo desejado, atualizando o status para corresponder às suas especificações. Se uma dessas instâncias falhar (um status mudar), o Kubernetes responde as diferenças entre as especificações e o status fazendo uma correção-neste caso, iniciando uma instância de substituição.
Para mais informações sobre especificações do objeto, status e metadados, veja Kubernetes API Conventions.
Quando se cria um objeto do Kubernetes, deve-se fornecer a especificação do objeto que descreve seu estado desejado, bem como algumas informações básicas sobre o objeto (como um nome, por exemplo). Quando utiliza a API Kubernetes para criar o objeto (diretamente ou via kubectl), essa solicitação de API deve incluir essa informação como JSON no corpo da solicitação. Na maioria das vezes, você fornece as informações ao comando kubectl em um arquivo .yaml. O comandokubectl converte a informação para JSON ao fazer a requisição para a API.
Aqui está um exemplo de arquivo .yaml que mostra os campos necessários e as especificações de objeto para uma implatação Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # diz ao deployment para executar 2 pods que correspondam ao modelo
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Uma maneira de criar um Deployment usando um arquivo .yaml como o representado acima é usar o comando kubectl apply na interface de linha de comando kubectl, passando o arquivo .yaml como argumento. Aqui está um exemplo:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
A saída será similar a esta:
deployment.apps/nginx-deployment created
No arquivo .yaml para o objeto Kubernetes que pretende criar, você precisará definir valores para os seguintes campos:
apiVersion - Qual a versão de API do objeto que será usado no Kubernetes para criar esse objeto.kind - Qual tipo de objeto pretende criar.metadata - Dados que ajudam a identificar de forma única o objeto, incluindo uma string nome, UID e um namespace.spec - Que estado deseja para o objeto.O formato preciso do objeto spec é diferente para cada objeto Kubernetes, e contém campos aninhados específicos para aquele objeto. A documentação de referência da API do Kubernetes pode ajudar a encontrar o formato de especificação para todos os objetos que você pode criar usando Kubernetes.
Por exemplo, veja o campo de spec field para a referência Pod API.
Para cada Pod, o campo .spec especifica o pod e seu estado desejado (como o nome da imagem do contêiner para cada recipiente dentro daquela cápsula).
Outro exemplo de especificação de um objeto é o
campo spec .
Para o StatefulSet, o campo .spec especifica o StatefulSet e seu estado desejado.
Dentro do .spec de um StatefulSet está um template
para objetos de Pod. Esse modelo descreve os Pods que o controlador StatefulSet criará para
satisfazer a especificação do StatefulSet. Diferentes tipos de objetos também podem ter diferentes
.status; novamente, as páginas de referência API detalham a estrutura daquele campo .status,
e seu conteúdo para cada tipo diferente de objeto.
Aprenda sobre os mais importantes objetos básicos Kubernetes, como o Pod. Aprenda sobre as controladoras do Kubernetes. Usando a API Kubernetes explica mais alguns conceitos da API.
Cada objeto em seu cluster possui um Nome que é único para aquele tipo de recurso. Todo objeto do Kubernetes também possui um UID que é único para todo o cluster.
Por exemplo, você pode ter apenas um Pod chamado myapp-1234 dentro de um
namespace, porém
você pode ter um Pod e um Deployment ambos com o nome myapp-1234.
Para atributos não-únicos definidos pelo usuário, o Kubernetes fornece labels e annotations.
Uma string fornecida pelo cliente que referencia um objeto em uma URL de
recurso, como por exemplo /api/v1/pods/qualquer-nome.
Somente um objeto de um dado tipo pode ter um certo nome por vez. No entanto, se você remover o objeto, você poderá criar um novo objeto com o mesmo nome.
Abaixo estão descritos quatro tipos de restrições de nomes comumente utilizadas para recursos.
A maior parte dos recursos do Kubernetes requerem um nome que possa ser utilizado como um nome de subdomínio DNS, conforme definido na RFC 1123. Isso significa que o nome deve:
Alguns tipos de recurso requerem que seus nomes sigam o padrão de rótulos DNS definido na RFC 1123. Isso significa que o nome deve:
Alguns tipos de recurso requerem que seus nomes sigam o padrão de rótulos DNS definido na RFC 1035. Isso significa que o nome deve:
Alguns tipos de recurso requerem que seus nomes possam ser seguramente codificados como um segmento de caminho, ou seja, o nome não pode ser "." ou ".." e não pode conter "/" ou "%".
Exemplo de um manifesto para um Pod chamado nginx-demo.
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Uma string gerada pelos sistemas do Kubernetes para identificar objetos de forma única.
Cada objeto criado durante todo o ciclo de vida do cluster do Kubernetes possui um UID distinto. O objetivo deste identificador é distinguir ocorrências históricas de entidades semelhantes.
UIDs no Kubernetes são identificadores únicos universais (também conhecidos como UUIDs). UUIDs seguem os padrões ISO/IEC 9834-8 e ITU-T X.667.
No Kubernetes, namespaces disponibilizam um mecanismo para isolar grupos de recursos dentro de um único cluster. Nomes de recursos precisam ser únicos dentro de um namespace, porém podem se repetir em diferentes namespaces. Escopos baseados em namespaces são aplicáveis apenas para objetos com namespace (como: Deployments, Services, etc) e não em objetos que abrangem todo o cluster (como: StorageClass, Nodes, PersistentVolumes, etc).
Namespaces devem ser utilizados em ambientes com múltiplos usuários espalhados por diversos times ou projetos. Para clusters com poucos ou até algumas dezenas de usuários, você não deveria precisar criar ou pensar a respeito de namespaces. Comece a utilizar namespaces quando você precisar das funcionalidades que eles oferecem.
Namespaces oferecem escopo para nomes. Nomes de recursos precisam ser únicos dentro de um namespace, porém não em diferentes namespaces. Namespaces não podem ser aninhados dentro de outros namespaces e cada recurso Kubernetes pode pertencer à apenas um namespace.
Namespaces nos permitem dividir os recursos do cluster entre diferentes usuários (via resource quota).
Não é necessário utilizar múltiplos namespaces para separar recursos levemente diferentes, como diferentes versões de um mesmo software: use labels para distinguir recursos dentro de um mesmo namespace.
default. Em vez disso, crie e utilize outros namespaces.O Kubernetes é inicializado com quatro namespaces:
defaultkube-node-leasekube-publickube-systemCriação e eliminação de namespaces estão descritas na documentação de namespaces do guia de administradores.
kube-, já que este prefixo é reservado para namespaces do sistema Kubernetes.Você pode obter uma lista dos namespaces atuais dentro de um cluster com:
kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-node-lease Active 1d
kube-public Active 1d
kube-system Active 1d
Para preparar o namespace para a requisição atual, utilize o parâmetro --namespace. Por exemplo:
kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>
kubectl get pods --namespace=<insert-namespace-name-here>
Você pode salvar permanentemente o namespace para todos os comandos kubectl subsequentes no mesmo contexto:
kubectl config set-context --current --namespace=<insert-namespace-name-here>
# Validando
kubectl config view --minify | grep namespace:
Quando você cria um Serviço, ele cria uma
entrada DNS correspondente.
Esta entrada possui o formato: <service-name>.<namespace-name>.svc.cluster.local, de forma que se um contêiner utilizar apenas <service-name> ele será resolvido para um serviço que é local ao namespace.
Isso é útil para utilizar a mesma configuração em vários namespaces, por exemplo em Desenvolvimento, Staging e Produção. Se você quiser acessar múltiplos namespaces, precisará utilizar um Fully Qualified Domain Name (FQDN).
Nomes de namespaces devem ser válidos conforme a RFC 1123 para rótulos DNS.
Ao criar namespaces com o mesmo nome de domínios de topo públicos (TLDs), os Services dentro desses namespaces podem ter nomes DNS curtos que colidem com registros DNS públicos. Com isso, cargas de trabalho de qualquer namespace que realizem consultas DNS sem um ponto final (trailing dot) podem ser redirecionadas para esses serviços, tendo precedência sobre o DNS público.
Para mitigar esse risco, limite a criação de namespaces apenas a usuários confiáveis. Se necessário, você também pode configurar controles de segurança de terceiros, como admission webhooks, para bloquear a criação de namespaces com nomes que coincidam com TLDs públicos.
A maior parte dos recursos Kubernetes (como Pods, Services, controladores de replicação e outros) pertencem a algum namespace. Entretanto, recursos de namespaces não pertencem a nenhum namespace. Além deles, recursos de baixo nível, como nodes e persistentVolumes, também não pertencem a nenhum namespace.
Para visualizar quais recursos Kubernetes pertencem ou não a algum namespace, utilize:
# Em um namespace
kubectl api-resources --namespaced=true
# Sem namespace
kubectl api-resources --namespaced=false
Kubernetes 1.22 [stable]
A camada de gerenciamento Kubernetes configura um label imutável kubernetes.io/metadata.name em todos os namespaces.
O valor do label é o nome do namespace.
Os Seletores de Campos permitem que você selecione recursos do Kubernetes baseado no valor de um ou mais campos de um recurso. Seguem alguns exemplos de buscas utilizando seletores de campos:
metadata.name=my-servicemetadata.namespace!=defaultstatus.phase=PendingO comando kubectl, mostrado a seguir, seleciona todos os Pods nos quais o valor do campo status.phase é Running:
kubectl get pods --field-selector status.phase=Running
kubectl sejam equivalentes: kubectl get pods e kubectl get pods --field-selector ""Os campos de seleção suportados variam dependendo do tipo de recurso Kubernetes. Todos os tipos de recursos suportam os campos metadata.name e metadata.namespace. Utilizar campos não suportados produz um erro. Como por exemplo:
kubectl get ingress --field-selector foo.bar=baz
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"
Você pode utilizar os operadores =, == e != com seletores de campos (= e == significam a mesma coisa). Por exemplo, o comando kubectl a seguir seleciona todos os Kubernetes Services que não estão no namespace default:
kubectl get services --all-namespaces --field-selector metadata.namespace!=default
Assim como label e outros tipos de seletores, podem ser utilizados em cadeia através de uma lista separada por vírgula. O comando kubectl a seguir seleciona todos os Pods nos quais status.phase não é igual a Running e spec.restartPolicy é igual a Always
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
Você pode utilizar seletores de campos através de múltiplos tipos de recursos. Por exemplo, o comando kubectl a seguir seleciona todos Statefulsets e Services que não estão presentes no namespace default.
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default