Conceitos Fundamentais do Kubernetes
Conceitos Fundamentais do Kubernetes
Conceitos
1: Visão Geral
1.1: Componentes do Kubernetes
1.2: Objetos do Kubernetes
1.2.1: Entendendo os objetos do Kubernetes
1.2.2: Nomes de objetos e IDs
1.2.3: Namespaces
1.2.4: Seletores de Campos
2: Arquitetura do Kubernetes
2.1: Nós
2.2: Comunicação entre Nó e Control Plane
2.3: Conceitos sobre Cloud Controller Manager
2.4: Controladores
3: Contêineres
3.1: Imagens
3.2: Ambiente de Contêiner
3.3: Classes de execução
3.4: Hooks de Ciclo de Vida do Contêiner
4: Serviços, balanceamento de carga e conectividade
4.1: Ingress
4.2: Políticas de rede
5: Armazenamento
5.1: Volumes
5.2: Volumes Persistentes
6: Configuração
6.1: Melhores Práticas de Configuração
6.2: ConfigMaps
6.3: Secrets
6.4: Gerenciamento de recursos em Pods e contêineres
6.5: Organizando o acesso ao cluster usando arquivos kubeconfig
6.6: Gerenciamento de recursos para nós Windows
7: Segurança
7.1: Visão Geral da Segurança Cloud Native
7.2: Políticas de Segurança do Pod
7.3: Segurança para Nós Windows
7.4: Controlando Acesso à API do Kubernetes
8: Políticas
8.1: Intervalos de limite
8.2: Cotas de Recursos
8.3: Gerenciadores de Recursos de Nós
9: Escalonamento, preempção e remoção
9.1: Taints e Tolerâncias
9.2: Escalonador do Kubernetes
9.3: Sobrecarga de Pod
10: Administração de Cluster
10.1: Visão Geral da Administração de Cluster
10.2: Certificates
10.3: Conectividade do Cluster
10.4: Arquitetura de Log
10.5: Logs de Sistema
10.6: Métricas para componentes do sistema Kubernetes
10.7: Configurando o Garbage Collection do kubelet
10.8: Proxies no Kubernetes
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 1/233
4/15/24, 11:56 AM Conceitos | Kubernetes
A seção de Conceitos irá te ajudar a aprender mais sobre as partes do ecossistema Kubernetes e as abstrações que o Kubernetes
usa para representar seu cluster.
Ela irá lhe ajudar a obter um entendimento mais profundo sobre como o Kubernetes funciona.
1 - Visão Geral
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.
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.
Voltando no tempo
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.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 2/233
4/15/24, 11:56 AM Conceitos | Kubernetes
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:
Criação e implantação ágil de aplicações: aumento da facilidade e eficiência na criação de imagem de contêiner comparado ao
uso de imagem de VM.
Desenvolvimento, integração e implantação contínuos: fornece capacidade de criação e de implantação de imagens de
contêiner de forma confiável e frequente, com a funcionalidade de efetuar reversões rápidas e eficientes (devido à
imutabilidade da imagem).
Separação de interesses entre Desenvolvimento e Operações: crie imagens de contêineres de aplicações no momento de
construção/liberação em vez de no momento de implantação, desacoplando as aplicações da infraestrutura.
A capacidade de observação (Observabilidade) não apenas apresenta informações e métricas no nível do sistema operacional,
mas também a integridade da aplicação e outros sinais.
Consistência ambiental entre desenvolvimento, teste e produção: funciona da mesma forma em um laptop e na nuvem.
Portabilidade de distribuição de nuvem e sistema operacional: executa no Ubuntu, RHEL, CoreOS, localmente, nas principais
nuvens públicas e em qualquer outro lugar.
Gerenciamento centrado em aplicações: eleva o nível de abstração da execução em um sistema operacional em hardware
virtualizado à execução de uma aplicação em um sistema operacional usando recursos lógicos.
Microserviços fracamente acoplados, distribuídos, elásticos e livres: as aplicações são divididas em partes menores e
independentes e podem ser implantados e gerenciados dinamicamente - não uma pilha monolítica em execução em uma
grande máquina de propósito único.
Isolamento de recursos: desempenho previsível de aplicações.
Utilização de recursos: alta eficiência e densidade.
É 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.
Descoberta de serviço e balanceamento de carga O Kubernetes pode expor um contêiner usando o nome DNS ou seu
próprio endereço IP. Se o tráfego para um contêiner for alto, o Kubernetes pode balancear a carga e distribuir o tráfego de
rede para que a implantação seja estável.
Orquestração de armazenamento O Kubernetes permite que você monte automaticamente um sistema de armazenamento
de sua escolha, como armazenamentos locais, provedores de nuvem pública e muito mais.
Lançamentos e reversões automatizadas Você pode descrever o estado desejado para seus contêineres implantados
usando o Kubernetes, e ele pode alterar o estado real para o estado desejado em um ritmo controlado. Por exemplo, você
pode automatizar o Kubernetes para criar novos contêineres para sua implantação, remover os contêineres existentes e
adotar todos os seus recursos para o novo contêiner.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 3/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Empacotamento binário automático Você fornece ao Kubernetes um cluster de nós que pode ser usado para executar
tarefas nos contêineres. Você informa ao Kubernetes de quanta CPU e memória (RAM) cada contêiner precisa. O Kubernetes
pode encaixar contêineres em seus nós para fazer o melhor uso de seus recursos.
Autocorreção O Kubernetes reinicia os contêineres que falham, substitui os contêineres, elimina os contêineres que não
respondem à verificação de integridade definida pelo usuário e não os anuncia aos clientes até que estejam prontos para
servir.
Gerenciamento de configuração e de segredos O Kubernetes permite armazenar e gerenciar informações confidenciais,
como senhas, tokens OAuth e chaves SSH. Você pode implantar e atualizar segredos e configuração de aplicações sem
reconstruir suas imagens de contêiner e sem expor segredos em sua pilha de configuração.
Kubernetes:
Não limita os tipos de aplicações suportadas. O Kubernetes visa oferecer suporte a uma variedade extremamente diversa de
cargas de trabalho, incluindo cargas de trabalho sem estado, com estado e de processamento de dados. Se uma aplicação
puder ser executada em um contêiner, ele deve ser executado perfeitamente no Kubernetes.
Não implanta código-fonte e não constrói sua aplicação. Os fluxos de trabalho de integração contínua, entrega e implantação
(CI/CD) são determinados pelas culturas e preferências da organização, bem como pelos requisitos técnicos.
Não fornece serviços em nível de aplicação, tais como middleware (por exemplo, barramentos de mensagem), estruturas de
processamento de dados (por exemplo, Spark), bancos de dados (por exemplo, MySQL), caches, nem sistemas de
armazenamento em cluster (por exemplo, Ceph), como serviços integrados. Esses componentes podem ser executados no
Kubernetes e/ou podem ser acessados por aplicações executadas no Kubernetes por meio de mecanismos portáteis, como o
Open Service Broker.
Não dita soluções de logging, monitoramento ou alerta. Ele fornece algumas integrações como prova de conceito e
mecanismos para coletar e exportar métricas.
Não fornece nem exige um sistema/idioma de configuração (por exemplo, Jsonnet). Ele fornece uma API declarativa que pode
ser direcionada por formas arbitrárias de especificações declarativas.
Não fornece nem adota sistemas abrangentes de configuração de máquinas, manutenção, gerenciamento ou autocorreção.
Adicionalmente, o Kubernetes não é um mero sistema de orquestração. Na verdade, ele elimina a necessidade de
orquestração. A definição técnica de orquestração é a execução de um fluxo de trabalho definido: primeiro faça A, depois B e
depois C. Em contraste, o Kubernetes compreende um conjunto de processos de controle independentes e combináveis que
conduzem continuamente o estado atual em direção ao estado desejado fornecido. Não importa como você vai de A para C. O
controle centralizado também não é necessário. Isso resulta em um sistema que é mais fácil de usar e mais poderoso, robusto,
resiliente e extensível.
Próximos passos
Dê uma olhada em Componentes do Kubernetes.
Pronto para Iniciar?
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 4/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Um cluster Kubernetes consiste em um conjunto de servidores de processamento, chamados nós, que executam aplicações
containerizadas. 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.
Kubernetes cluster
API server
api
Cloud controller
c-m
c-m c-c-m manager
c-c-m
c-m c-c-m (optional) c-c-m
Controller
manager c-m
etcd
api
Node Node (persistence store) etcd
api Node
api
kubelet
kubelet
sched
sched
sched
Scheduler
sched
Node
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.
kube-apiserver
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.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 5/233
4/15/24, 11:56 AM Conceitos | Kubernetes
etcd
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.
kube-scheduler
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.
kube-controller-manager
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.
cloud-controller-manager
Um componente da camada de gerenciamento do Kubernetes que incorpora a lógica de controle específica da nuvem. O
gerenciador de controle de nuvem permite que você vincule seu cluster na API do seu provedor de nuvem, e separar os
componentes que interagem com essa plataforma de nuvem a partir de componentes que apenas interagem com seu cluster.
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.
Controlador de nó: para verificar junto ao provedor de nuvem para determinar se um nó foi excluído da nuvem após parar de
responder.
Controlador de rota: para configurar rotas na infraestrutura de nuvem subjacente.
Controlador de serviço: para criar, atualizar e excluir balanceadores de carga do provedor de nuvem.
Componentes do nó
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.
kubelet
Um agente que é executado em cada nó no cluster. Ele garante que os contêineres estejam sendo executados em um Pod.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 6/233
4/15/24, 11:56 AM Conceitos | Kubernetes
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
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 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)
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.
DNS
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.
Web UI (Dashboard)
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.
Próximos passos
Aprenda sobre Nós.
Aprenda sobre Controladores.
Aprenda sobre kube-scheduler.
Leia a documentação oficial do etcd.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 7/233
4/15/24, 11:56 AM Conceitos | Kubernetes
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.
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ção para 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.
Aqui está um exemplo de arquivo .yaml que mostra os campos necessários e as especificações de objeto para uma implatação
Kubernetes:
application/deployment.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 8/233
4/15/24, 11:56 AM Conceitos | 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:
deployment.apps/nginx-deployment created
Campos obrigatórios
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.
Próximos passos
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.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 9/233
4/15/24, 11:56 AM Conceitos | Kubernetes
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.
Nomes
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.
Nota: Em casos em que objetos representam uma entidade física, como no caso de um Nó representando um host físico, caso
o host seja recriado com o mesmo nome mas o objeto Nó não seja recriado, o Kubernetes trata o novo host como o host antigo,
o que pode causar inconsistências.
Abaixo estão descritos quatro tipos de restrições de nomes comumente utilizadas para recursos.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 10/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
UIDs
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.
Próximos passos
Leia sobre labels no Kubernetes.
Consulte o documento de design Identifiers and Names in Kubernetes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 11/233
4/15/24, 11:56 AM Conceitos | Kubernetes
1.2.3 - Namespaces
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 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.
Nota: Evite criar namespaces com o prefixo kube-, já que este prefixo é reservado para namespaces do sistema Kubernetes.
Visualizando namespaces
Você pode obter uma lista dos namespaces atuais dentro de um cluster com:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 12/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Namespaces e DNS
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).
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
Rotulamento Automático
ESTADO DA FUNCIONALIDADE: Kubernetes 1.21 [beta]
Próximos passos
Leia sobre a criação de um novo namespace.
Leia sobre a eliminação de um namespace.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 13/233
4/15/24, 11:56 AM Conceitos | Kubernetes
metadata.name=my-service
metadata.namespace!=default
status.phase=Pending
O comando kubectl , mostrado a seguir, seleciona todos os Pods nos quais o valor do campo status.phase é Running :
Nota: Seletores de campos são essencialmente filtros de recursos. Por padrão, nenhum seletor/filtro é aplicado, de forma que
todos os recursos do tipo especificado são selecionados. Isso faz com que as seguintes pesquisas utilizando kubectl sejam
equivalentes: kubectl get pods e kubectl get pods --field-selector ""
Campos suportados
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:
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz
Operadores suportados
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 :
Seletores em cadeia
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
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 14/233
4/15/24, 11:56 AM Conceitos | Kubernetes
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 15/233
4/15/24, 11:56 AM Conceitos | Kubernetes
2 - Arquitetura do Kubernetes
2.1 - Nós
O Kubernetes executa sua carga de trabalho colocando contêineres em Pods para serem executados em Nós. Um nó pode ser uma
máquina virtual ou física, dependendo do cluster. Cada nó é gerenciado pela camada de gerenciamento e contém os serviços
necessários para executar Pods.
Normalmente, você tem vários nós em um cluster; em um ambiente de aprendizado ou limitado por recursos, você pode ter apenas
um nó.
Administração
Existem duas maneiras principais de adicionar Nós ao Servidor da API:
Depois de criar um objeto Nó, ou o kubelet em um nó se registra automaticamente, a camada de gerenciamento verifica se o novo
objeto Nó é válido. Por exemplo, se você tentar criar um nó a partir do seguinte manifesto JSON:
{
"kind": "Node",
"apiVersion": "v1",
"metadata": {
"name": "10.240.79.157",
"labels": {
"name": "my-first-k8s-node"
}
}
}
O Kubernetes cria um objeto nó internamente (a representação). O Kubernetes verifica se um kubelet se registrou no servidor da
API que corresponde ao campo metadata.name do Nó. Se o nó estiver íntegro (ou seja, todos os serviços necessários estiverem em
execução), ele será elegível para executar um Pod. Caso contrário, esse nó é ignorado para qualquer atividade de cluster até que se
torne íntegro.
Nota:
O Kubernetes mantém o objeto nó inválido e continua verificando se ele se torna íntegro.
Você, ou um controlador, deve excluir explicitamente o objeto Nó para interromper essa verificação de integridade.
Singularidade de nome do nó
O nome identifica um nó. Dois nós não podem ter o mesmo nome ao mesmo tempo. O Kubernetes também assume que um
recurso com o mesmo nome é o mesmo objeto. No caso de um nó, assume-se implicitamente que uma instância usando o mesmo
nome terá o mesmo estado (por exemplo, configurações de rede, conteúdo do disco raiz) e atributos como label de nó. Isso pode
levar a inconsistências se uma instância for modificada sem alterar seu nome. Se o nó precisar ser substituído ou atualizado
significativamente, o objeto Nó existente precisa ser removido do servidor da API primeiro e adicionado novamente após a
atualização.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 16/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Auto-registro de Nós
Quando a opção --register-node do kubelet for verdadeira (padrão), o kubelet tentará se registrar no servidor da API. Este é o
padrão preferido, usado pela maioria das distribuições.
Quando o modo de autorização do nó e o plug-in de admissão NodeRestriction estão ativados, os kubelets somente estarão
autorizados a criar/modificar seu próprio recurso do nó.
Nota:
Como mencionado na seção de singularidade do nome do nó, quando a configuração do nó precisa ser atualizada, é uma boa
prática registrar novamente o nó no servidor da API. Por exemplo, se o kubelet estiver sendo reiniciado com o novo conjunto de
--node-labels , mas o mesmo nome de nó for usado, a alteração não entrará em vigor, pois os labels estão sendo definidos no
registro do Nó.
Pods já agendados no Nó podem ter um comportamento anormal ou causar problemas se a configuração do Nó for alterada na
reinicialização do kubelet. Por exemplo, o Pod já em execução pode estar marcado diferente dos labels atribuídos ao Nó,
enquanto outros Pods, que são incompatíveis com esse Pod, serão agendados com base nesse novo label. O novo registro do
nó garante que todos os Pods sejam drenados e devidamente reiniciados.
Quando você quiser manualmente criar objetos Nó, defina a opção do kubelet --register-node=false .
Você pode modificar os objetos Nó, independentemente da configuração de --register-node . Por exemplo, você pode definir
labels em um nó existente ou marcá-lo como não disponível.
Você pode usar labels nos Nós em conjunto com seletores de nós nos Pods para controlar a disponibilidade. Por exemplo, você
pode restringir um Pod a ser elegível apenas para ser executado em um subconjunto dos nós disponíveis.
Marcar um nó como não disponível impede que o escalonador coloque novos pods nesse nó, mas não afeta os Pods existentes no
nó. Isso é útil como uma etapa preparatória antes da reinicialização de um nó ou outra manutenção.
Nota: Os Pods que fazem parte de um DaemonSet toleram ser executados em um nó não disponível. Os DaemonSets
geralmente fornecem serviços locais de nós que devem ser executados em um Nó, mesmo que ele esteja sendo drenado de
aplicativos de carga de trabalho.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 17/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Status do Nó
O status de um nó contém as seguintes informações:
Endereços
Condições
Capacidade
Informação
Endereços
O uso desses campos pode mudar dependendo do seu provedor de nuvem ou configuração dedicada.
HostName: O nome do host relatado pelo kernel do nó. Pode ser substituído através do parâmetro kubelet --hostname-
override .
Condições
O campo conditions descreve o status de todos os nós em execução. Exemplos de condições incluem:
Condições do nó Descrição
Ready True Se o nó estiver íntegro e pronto para aceitar pods, False se o nó não estiver íntegro e não
estiver aceitando pods, e desconhecido Unknown se o controlador do nó tiver sem notícias do nó
no último node-monitor-grace-period (o padrão é de 40 segundos)
DiskPressure True Se houver pressão sobre o tamanho do disco, ou seja, se a capacidade do disco for baixa;
caso contrário False
MemoryPressure True Se houver pressão na memória do nó, ou seja, se a memória do nó estiver baixa; caso
contrário False
PIDPressure True Se houver pressão sobre os processos, ou seja, se houver muitos processos no nó; caso
contrário False
NetworkUnavailable True Se a rede do nó não estiver configurada corretamente, caso contrário False
Nota: Se você usar as ferramentas de linha de comando para mostrar os detalhes de um nó isolado, a Condition inclui
SchedulingDisabled. SchedulingDisabled não é uma condição na API do Kubernetes; em vez disso, os nós isolados são
marcados como Unschedulable em suas especificações.
Na API do Kubernetes, a condição de um nó é representada como parte do .status do recurso do nó. Por exemplo, a seguinte
estrutura JSON descreve um nó íntegro:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 18/233
4/15/24, 11:56 AM Conceitos | Kubernetes
"conditions": [
{
"type": "Ready",
"status": "True",
"reason": "KubeletReady",
"message": "kubelet is posting ready status",
"lastHeartbeatTime": "2019-06-05T18:38:35Z",
"lastTransitionTime": "2019-06-05T11:41:27Z"
}
]
Se o status da condição Ready permanecer desconhecido ( Unknown ) ou falso ( False ) por mais tempo do que o limite da remoção
do pod ( pod-eviction-timeout ) (um argumento passado para o kube-controller-manager), o controlador de nó acionará o
remoção iniciado pela API para todos os Pods atribuídos a esse nó. A duração padrão do tempo limite da remoção é de cinco
minutos. Em alguns casos, quando o nó está inacessível, o servidor da API não consegue se comunicar com o kubelet no nó. A
decisão de excluir os pods não pode ser comunicada ao kubelet até que a comunicação com o servidor da API seja restabelecida.
Enquanto isso, os pods agendados para exclusão podem continuar a ser executados no nó particionado.
O controlador de nós não força a exclusão dos pods até que seja confirmado que eles pararam de ser executados no cluster. Você
pode ver os pods que podem estar sendo executados em um nó inacessível como estando no estado de terminando ( Terminating )
ou desconhecido ( Unknown ). Nos casos em que o Kubernetes não retirar da infraestrutura subjacente se um nó tiver deixado
permanentemente um cluster, o administrador do cluster pode precisar excluir o objeto do nó manualmente. Excluir o objeto do nó
do Kubernetes faz com que todos os objetos Pod em execução no nó sejam excluídos do servidor da API e libera seus nomes.
Quando ocorrem problemas nos nós, a camada de gerenciamento do Kubernetes cria automaticamente taints que
correspondem às condições que afetam o nó. O escalonador leva em consideração as taints do Nó ao atribuir um Pod a um Nó.
Os Pods também podem ter tolerations que os permitem funcionar em um nó, mesmo que tenha uma taint específica.
Capacidade e Alocável
Descreve os recursos disponíveis no nó: CPU, memória e o número máximo de pods que podem ser agendados no nó.
Os campos no bloco de capacidade indicam a quantidade total de recursos que um nó possui. O bloco alocado indica a quantidade
de recursos em um nó que está disponível para ser consumido por Pods normais.
Você pode ler mais sobre capacidade e recursos alocados enquanto aprende a reservar recursos de computação em um nó.
Info
Descreve informações gerais sobre o nó, como a versão do kernel, a versão do Kubernetes (versão do kubelet e kube-proxy),
detalhes do tempo de execução do contêiner e qual sistema operacional o nó usa. O kubelet coleta essas informações do nó e as
publica na API do Kubernetes.
Heartbeats
Os Heartbeats , enviados pelos nós do Kubernetes, ajudam seu cluster a determinar a disponibilidade de cada nó e a agir quando
as falhas forem detectadas.
Em comparação com as atualizações no .status de um nó, um Lease é um recurso mais leve. O uso de Leases para heartbeats
reduz o impacto no desempenho dessas atualizações para grandes clusters.
O kubelet é responsável por criar e atualizar o .status dos Nós e por atualizar suas Leases relacionadas.
O kubelet atualiza o .status do nó quando há mudança de status ou se não houve atualização para um intervalo configurado. O
intervalo padrão para atualizações .status para Nós é de 5 minutos, o que é muito maior do que o tempo limite padrão de 40
segundos para nós inacessíveis.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 19/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O kubelet cria e atualiza seu objeto Lease a cada 10 segundos (o intervalo de atualização padrão). As atualizações de Lease
ocorrem independentemente das atualizações no .status do Nó. Se a atualização do Lease falhar, o kubelet voltará a
tentativas, usando um recuo exponencial que começa em 200 milissegundos e limitado a 7 segundos.
Controlador de Nós
O controlador de nós é um componente da camada de gerenciamento do Kubernetes que gerencia vários aspectos dos nós.
O controlador de nó tem várias funções na vida útil de um nó. O primeiro é atribuir um bloco CIDR ao nó quando ele é registrado (se
a atribuição CIDR estiver ativada).
O segundo é manter a lista interna de nós do controlador de nós atualizada com a lista de máquinas disponíveis do provedor de
nuvem. Ao ser executado em um ambiente de nuvem e sempre que um nó não é íntegro, o controlador de nó pergunta ao provedor
de nuvem se a VM desse nó ainda está disponível. Caso contrário, o controlador de nós exclui o nó de sua lista de nós.
No caso de um nó se tornar inacessível, atualizar a condição NodeReady dentro do campo .status do nó. Nesse caso, o
controlador do nó define a condição de pronto ( NodeReady ) como condição desconhecida ( ConditionUnknown ).
Se um nó permanecer inacessível: será iniciado a remoção pela API para todos os Pods no nó inacessível. Por padrão, o
controlador do nó espera 5 minutos entre marcar o nó como condição desconhecida ( ConditionUnknown ) e enviar a primeira
solicitação de remoção.
O comportamento de remoção do nó muda quando um nó em uma determinada zona de disponibilidade se torna não íntegro. O
controlador de nós verifica qual porcentagem de nós na zona não são íntegras (a condição NodeReady é desconhecida
ConditionUnknown ou falsa ConditionFalse ) ao mesmo tempo:
Se a fração de nós não íntegros for ao menos --unhealthy-zone-threshold (padrão 0,55), então a taxa de remoção será
reduzida.
Se o cluster for pequeno (ou seja, tiver número de nós menor ou igual ao valor da opção --large-cluster-size-threshold -
padrão 50), então as remoções serão interrompidas.
Caso contrário, a taxa de remoção é reduzida para --secondary-node-eviction-rate de nós secundários (padrão 0,01) por
segundo.
A razão pela qual essas políticas são implementadas por zona de disponibilidade é porque a camada de gerenciamento pode perder
conexão com uma zona de disponibilidade, enquanto as outras permanecem conectadas. Se o seu cluster não abranger várias
zonas de disponibilidade de provedores de nuvem, o mecanismo de remoção não levará em conta a indisponibilidade por zona.
Uma das principais razões para espalhar seus nós pelas zonas de disponibilidade é para que a carga de trabalho possa ser
transferida para zonas íntegras quando uma zona inteira cair. Portanto, se todos os nós em uma zona não estiverem íntegros, o
controlador do nó removerá na taxa normal de --node-eviction-rate . O caso especial é quando todas as zonas estiverem
completamente insalubres (nenhum dos nós do cluster será íntegro). Nesse caso, o controlador do nó assume que há algum
problema com a conectividade entre a camada de gerenciamento e os nós e não realizará nenhuma remoção. (Se houver uma
interrupção e alguns nós reaparecerem, o controlador do nó expulsará os pods dos nós restantes que estiverem insalubres ou
inacessíveis).
O controlador de nós também é responsável por remover pods em execução nos nós com NoExecute taints, a menos que esses
pods tolerem essa taint. O controlador de nó também adiciona as taints correspondentes aos problemas de nó, como nó inacessível
ou não pronto. Isso significa que o escalonador não colocará Pods em nós não íntegros.
O escalonador do Kubernetes garante que haja recursos suficientes para todos os Pods em um nó. O escalonador verifica se a soma
das solicitações de contêineres no nó não é maior do que a capacidade do nó. Essa soma de solicitações inclui todos os contêineres
gerenciados pelo kubelet, mas exclui quaisquer contêineres iniciados diretamente pelo agente de execução de contêiner e também
exclui quaisquer processos executados fora do controle do kubelet.
Nota: Se você quiser reservar explicitamente recursos para processos que não sejam do Pod, consulte reserva de recursos para
daemons do sistema.
Topologia do Nó
ESTADO DA FUNCIONALIDADE: Kubernetes v1.16 [alpha]
Desligamento gracioso do nó
ESTADO DA FUNCIONALIDADE: Kubernetes v1.21 [beta]
O Kubelet garante que os pods sigam o processo normal de término do podpod-lifecycle/#pod-termination) durante o desligamento
do nó.
O recurso de desligamento gradual do nó depende do systemd, pois aproveita os bloqueios do inibidor do systemd para atrasar o
desligamento do nó com uma determinada duração.
O desligamento gradual do nó é controlado com recursos GracefulNodeShutdown , que é ativado por padrão na versão 1.21.
Observe que, por padrão, ambas as opções de configuração descritas abaixo, shutdownGracePeriod and
shutdownGracePeriodCriticalPods estão definidas como zero, não ativando assim a funcionalidade de desligamento gradual do nó.
Para ativar o recurso, as duas configurações do kubelet devem ser configuradas adequadamente e definidas como valores
diferentes de zero.
shutdownGracePeriod :
Especifica a duração total pela qual o nó deve atrasar o desligamento. Este é o período de carência total para o término
dos pods regulares e os críticos.
shutdownGracePeriodCriticalPods :
Especifica a duração utlizada para encerrar pods críticos durante um desligamento de nó. Este valor deve ser menor que
shutdownGracePeriod .
Nota:
Quando os pods forem removidos durante o desligamento gradual do nó, eles serão marcados como desligados. Executar o
kubectl get pods para mostrar o status dos pods removidos como Terminated . E o kubectl describe pod indica que o pod
foi removido por causa do desligamento do nó:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 21/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Reason: Terminated
Message: Pod was terminated in response to imminent node shutdown.
Para fornecer mais flexibilidade durante o desligamento gradual do nó em torno da ordem de pods durante o desligamento, o
desligamento gradual do nó respeita a PriorityClass dos Pods, desde que você tenha ativado esse recurso em seu cluster. O recurso
permite que o cluster defina explicitamente a ordem dos pods durante o desligamento gradual do nó com base em classes de
prioridade.
O recurso Desligamento Gradual do Nó, conforme descrito acima, desliga pods em duas fases, pods não críticos, seguidos por pods
críticos. Se for necessária flexibilidade adicional para definir explicitamente a ordem dos pods durante o desligamento de uma
maneira mais granular, o desligamento gradual baseado na prioridade do pod pode ser usado.
Quando o desligamento gradual do nó respeita as prioridades do pod, isso torna possível fazer o desligamento gradual do nó em
várias fases, cada fase encerrando uma classe de prioridade específica de pods. O kubelet pode ser configurado com as fases exatas
e o tempo de desligamento por fase.
custom-class-a 100000
custom-class-b 10000
custom-class-c 1000
regular/unset 0
100000 10 segundos
0 60 segundos
shutdownGracePeriodByPodPriority:
- priority: 100000
shutdownGracePeriodSeconds: 10
- priority: 10000
shutdownGracePeriodSeconds: 180
- priority: 1000
shutdownGracePeriodSeconds: 120
- priority: 0
shutdownGracePeriodSeconds: 60
A tabela acima implica que qualquer pod com valor priority >= 100000 terá apenas 10 segundos para parar qualquer pod com
valor >= 10000 e < 100000 e terá 180 segundos para parar, qualquer pod com valor >= 1000 e < 10000 terá 120 segundos para
parar. Finalmente, todos os outros pods terão 60 segundos para parar.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 22/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Não é preciso especificar valores correspondentes para todas as classes. Por exemplo, você pode usar estas configurações:
0 60 segundos
No caso acima, os pods com custom-class-b irão para o mesmo bucket que custom-class-c para desligamento.
Se não houver pods em um intervalo específico, o kubelet não irá espera por pods nesse intervalo de prioridades. Em vez disso, o
kubelet pula imediatamente para o próximo intervalo de valores da classe de prioridade.
Se esse recurso estiver ativado e nenhuma configuração for fornecida, nenhuma ação de pedido será tomada.
Antes do Kubernetes 1.22, os nós não suportavam o uso de memória swap, e um kubelet, por padrão, não iniciaria se a troca fosse
detectada em um nó. A partir de 1.22, o suporte a memória swap pode ser ativado por nó.
Para ativar a troca em um nó, o recursos NodeSwap deve estar ativado no kubelet, e a configuração de comando de linha --fail-
swap-on ou failSwapOn deve ser definida como falsa.
Aviso: Quando o recurso de memória swap está ativado, os dados do Kubernetes, como o conteúdo de objetos Secret que
foram gravados no tmpfs, agora podem ser trocados para o disco.
Opcionalmente, um usuário também pode configurar memorySwap.swapBehavior para especificar como um nó usará memória swap.
Por exemplo,
memorySwap:
swapBehavior: LimitedSwap
LimitedSwap : As cargas de trabalho do Kubernetes são limitadas na quantidade de troca que podem usar. Cargas de trabalho
no nó não gerenciadas pelo Kubernetes ainda podem ser trocadas.
UnlimitedSwap : As cargas de trabalho do Kubernetes podem usar tanta memória de swap quanto solicitarem, até o limite do
sistema.
Se a configuração do memorySwap não for especificada e o recurso estiver ativado, por padrão, o kubelet aplicará o mesmo
comportamento que a configuração LimitedSwap .
O comportamento da configuração LimitedSwap depende se o nó estiver sendo executado com v1 ou v2 de grupos de controle
(também conhecidos como "cgroups"):
cgroupsv1: As cargas de trabalho do Kubernetes podem usar qualquer combinação de memória e swap, até o limite de
memória do pod, se definido.
cgroupsv2: As cargas de trabalho do Kubernetes não podem usar memória swap.
Para obter mais informações e para ajudar nos testes e fornecer feedback, consulte KEP-2400 e sua proposta de design.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 23/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Próximos passos
Saiba mais sobre componentes que compõem um nó.
Leia a definição da API para um Nó.
Leia a seção Nó do documento de design de arquitetura.
Leia sobre taints e tolerâncias.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 24/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Os nós devem ser provisionados com o certificado root público para o cluster de tal forma que eles podem se conectar de forma
segura ao apiserver junto com o cliente válido credenciais. Por exemplo, em uma implantação padrão do GKE, as credenciais do
cliente fornecidos para o kubelet estão na forma de um certificado de cliente. Vejo bootstrapping TLS do kubelet para
provisionamento automatizado de certificados de cliente kubelet.
Os pods que desejam se conectar ao apiserver podem fazê-lo com segurança, aproveitando conta de serviço para que o Kubernetes
injetará automaticamente o certificado raiz público certificado e um token de portador válido no pod quando ele é instanciado. O
serviço kubernetes (no namespace default ) é configurado com um IP virtual endereço que é redirecionado (via kube-proxy) para
o endpoint com HTTPS no apiserver.
Os componentes do control plane também se comunicam com o apiserver do cluster através da porta segura.
Como resultado, o modo de operação padrão para conexões do cluster (nodes e pods em execução nos Nodes) para o control plane
é protegido por padrão e pode passar por redes não confiáveis e/ou públicas.
Essas conexões terminam no endpoint HTTPS do kubelet. Por padrão, o apiserver não verifica o certificado de serviço do kubelet, o
que torna a conexão sujeita a ataques man-in-the-middle, o que o torna inseguro para passar por redes não confiáveis e / ou
públicas.
Para verificar essa conexão, use a flag --kubelet-certificate-authority para fornecer o apiserver com um pacote de certificado
raiz para usar e verificar o certificado de serviço da kubelet.
Se isso não for possível, use o SSH túnel entre o apiserver e kubelet se necessário para evitar a conexão ao longo de um rede não
confiável ou pública.
Finalmente, Autenticação e/ou autorização do Kubelet deve ser ativado para proteger a API do kubelet.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 25/233
4/15/24, 11:56 AM Conceitos | Kubernetes
SSH Túnel
O Kubernetes suporta túneis SSH para proteger os caminhos de comunicação do control plane para os nós. Nesta configuração, o
apiserver inicia um túnel SSH para cada nó no cluster (conectando ao servidor ssh escutando na porta 22) e passa todo o tráfego
destinado a um kubelet, nó, pod ou serviço através do túnel. Este túnel garante que o tráfego não seja exposto fora da rede aos
quais os nós estão sendo executados.
Atualmente, os túneis SSH estão obsoletos, portanto, você não deve optar por usá-los, a menos que saiba o que está fazendo. O
serviço Konnectivity é um substituto para este canal de comunicação.
Konnectivity service
ESTADO DA FUNCIONALIDADE: Kubernetes v1.18 [beta]
Como uma substituição aos túneis SSH, o serviço Konnectivity fornece proxy de nível TCP para a comunicação do control plane para
o cluster. O serviço Konnectivity consiste em duas partes: o servidor Konnectivity na rede control plane e os agentes Konnectivity na
rede dos nós. Os agentes Konnectivity iniciam conexões com o servidor Konnectivity e mantêm as conexões de rede. Depois de
habilitar o serviço Konnectivity, todo o tráfego do control plane para os nós passa por essas conexões.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 26/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O design do Cloud Controller Manager é baseado em um mecanismo de plug-in que permite que novos provedores de nuvem se
integrem facilmente ao Kubernetes usando plug-ins. Existem planos para integrar novos provedores de nuvem no Kubernetes e
para migrar provedores de nuvem que estão utilizando o modelo antigo para o novo modelo de CCM.
Este documento discute os conceitos por trás do Cloud Controller Manager e fornece detalhes sobre suas funções associadas.
Kubelet
Kubernetes controller manager
Kubernetes API server
O CCM consolida toda a lógica que depende da nuvem dos três componentes anteriores para criar um único ponto de integração
com a nuvem. A nova arquitetura com o CCM se parece com isso:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 27/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Componentes do CCM
O CCM separa algumas das funcionalidades do KCM (Kubernetes Controller Manager) e o executa como um processo separado.
Especificamente, isso elimina os controladores no KCM que dependem da nuvem. O KCM tem os seguintes loops de controlador
dependentes de nuvem:
Node controller
Volume controller
Route controller
Service controller
Node controller
Route controller
Service controller
Nota: O Volume Controller foi deliberadamente escolhido para não fazer parte do CCM. Devido à complexidade envolvida e
devido aos esforços existentes para abstrair a lógica de volume específica do fornecedor, foi decidido que o Volume Controller
não será movido para o CCM.
O plano original para suportar volumes usando o CCM era usar volumes Flex para suportar volumes plugáveis. No entanto, um
esforço concorrente conhecido como CSI está sendo planejado para substituir o Flex.
Considerando essas dinâmicas, decidimos ter uma medida de intervalo intermediário até que o CSI esteja pronto.
Funções do CCM
O CCM herda suas funções de componentes do Kubernetes que são dependentes de um provedor de nuvem. Esta seção é
estruturada com base nesses componentes.
Node Controller
Route Controller
Service Controller
Node Controller
O Node Controller é responsável por inicializar um nó obtendo informações sobre os nós em execução no cluster do provedor de
nuvem. O Node Controller executa as seguintes funções:
Route Controller
O Route Controller é responsável por configurar as rotas na nuvem apropriadamente, de modo que os contêineres em diferentes
nodes no cluster do Kubernetes possam se comunicar entre si. O Route Controller é aplicável apenas para clusters do Google
Compute Engine.
Service controller
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 28/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O Service controller é responsável por ouvir os eventos de criação, atualização e exclusão do serviço. Com base no estado atual dos
serviços no Kubernetes, ele configura os balanceadores de carga da nuvem (como o ELB, o Google LB ou o Oracle Cloud
Infrastrucutre LB) para refletir o estado dos serviços no Kubernetes. Além disso, garante que os back-ends de serviço para
balanceadores de carga da nuvem estejam atualizados.
2. Kubelet
O Node Controller contém a funcionalidade dependente da nuvem do kubelet. Antes da introdução do CCM, o kubelet era
responsável por inicializar um nó com detalhes específicos da nuvem, como endereços IP, rótulos de região / zona e informações de
tipo de instância. A introdução do CCM mudou esta operação de inicialização do kubelet para o CCM.
Nesse novo modelo, o kubelet inicializa um nó sem informações específicas da nuvem. No entanto, ele adiciona uma marca (taint)
ao nó recém-criado que torna o nó não programável até que o CCM inicialize o nó com informações específicas da nuvem. Em
seguida, remove essa mancha (taint).
Mecanismo de plugins
O Cloud Controller Manager usa interfaces Go para permitir implementações de qualquer nuvem a ser conectada. Especificamente,
ele usa a Interface CloudProvider definidaaqui.
A implementação dos quatro controladores compartilhados destacados acima, e algumas estruturas que ficam junto com a
interface compartilhada do provedor de nuvem, permanecerão no núcleo do Kubernetes. Implementações específicas para
provedores de nuvem serão construídas fora do núcleo e implementarão interfaces definidas no núcleo.
Para obter mais informações sobre o desenvolvimento de plug-ins, consulteDesenvolvendo o Cloud Controller Manager.
Autorização
Esta seção divide o acesso necessário em vários objetos da API pelo CCM para executar suas operações.
Node Controller
O Node Controller só funciona com objetos Node. Ele requer acesso total para obter, listar, criar, atualizar, corrigir, assistir e excluir
objetos Node.
v1/Node:
Get
List
Create
Update
Patch
Watch
Delete
Rote Controller
O Rote Controller escuta a criação do objeto Node e configura as rotas apropriadamente. Isso requer acesso a objetos Node.
v1/Node:
Get
Service Controller
O Service Controller escuta eventos de criação, atualização e exclusão de objeto de serviço e, em seguida, configura pontos de
extremidade para esses serviços de forma apropriada.
Para acessar os Serviços, é necessário listar e monitorar o acesso. Para atualizar os Serviços, ele requer patch e atualização de
acesso.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 29/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Para configurar endpoints para os Serviços, é necessário acesso para criar, listar, obter, assistir e atualizar.
v1/Service:
List
Get
Watch
Patch
Update
Outros
A implementação do núcleo do CCM requer acesso para criar eventos e, para garantir a operação segura, requer acesso para criar
ServiceAccounts.
v1/Event:
Create
Patch
Update
v1/ServiceAccount:
Create
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 30/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cloud-controller-manager
rules:
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- update
- apiGroups:
- ""
resources:
- nodes
verbs:
- '*'
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
- apiGroups:
- ""
resources:
- services
verbs:
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- apiGroups:
- ""
resources:
- persistentvolumes
verbs:
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- list
- watch
- update
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 31/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Digital Ocean
Oracle
Azure
GCP
AWS
BaiduCloud
Linode
Administração de Cluster
Voce vai encontrar instruções completas para configurar e executar o CCM aqui.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 32/233
4/15/24, 11:56 AM Conceitos | Kubernetes
2.4 - Controladores
Em robótica e automação um control loop, ou em português ciclo de controle, é um ciclo não terminado que regula o estado de um
sistema.
Quando você define a temperatura, isso indica ao termostato sobre o seu estado desejado. A temperatura ambiente real é o estado
atual. O termostato atua de forma a trazer o estado atual mais perto do estado desejado, ligando ou desligando o equipamento.
No Kubernetes, controladores são ciclos de controle que observam o estado do seu cluster, e então fazer ou requisitar mudanças
onde necessário. Cada controlador tenta mover o estado atual do cluster mais perto do estado desejado.
O controlador pode executar uma ação ele próprio, ou, o que é mais comum, no Kubernetes, o controlador envia uma mensagem
para o API server (servidor de API) que tem efeitos colaterais úteis. Você vai ver exemplos disto abaixo.
Job é um recurso do Kubernetes que é executado em um Pod, ou talvez vários Pods, com o objetivo de executar uma tarefa e depois
parar.
(Uma vez agendado, objetos Pod passam a fazer parte do estado desejado para um kubelet.
Quando o controlador Job observa uma nova tarefa ele garante que, algures no seu cluster, os kubelets num conjunto de nós (Nodes)
estão correndo o número correto de Pods para completar o trabalho. O controlador Job não corre Pods ou containers ele próprio. Em
vez disso, o controlador Job informa o API server para criar ou remover Pods. Outros componentes do plano de controle (
control plane) atuam na nova informação (existem novos Pods para serem agendados e executados), e eventualmente o trabalho é
feito.
Após ter criado um novo Job, o estado desejado é que esse Job seja completado. O controlador Job faz com que o estado atual para
esse Job esteja mais perto do seu estado desejado: criando Pods que fazem o trabalho desejado para esse Job para que o Job fique
mais perto de ser completado.
Controladores também atualizam os objetos que os configuram. Por exemplo: assim que o trabalho de um Job está completo, o
controlador Job atualiza esse objeto Job para o marcar como Finished (terminado).
(Isto é um pouco como alguns termostatos desligam uma luz para indicar que a temperatura da sala está agora na temperatura que
foi introduzida).
Controle direto
Em contraste com Job, alguns controladores necessitam de efetuar mudanças fora do cluster.
Por exemplo, se usar um ciclo de controle para garantir que existem Nodes suficientes no seu cluster, então esse controlador
necessita de algo exterior ao cluster atual para configurar novos Nodes quando necessário.
Controladores que interagem com estados externos encontram o seu estado desejado a partir do API server, e então comunicam
diretamente com o sistema externo para trazer o estado atual mais próximo do desejado.
(Existe um controlador que escala horizontalmente nós no seu cluster. Veja Escalamento automático do cluster)
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 33/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O seu cluster pode mudar em qualquer momento à medida que as ações acontecem e os ciclos de controle corrigem falhas
automaticamente. Isto significa que, potencialmente, o seu cluster nunca atinge um estado estável.
Enquanto os controladores no seu cluster estiverem rodando e forem capazes de fazer alterações úteis, não importa se o estado é
estável ou se é instável.
Design
Como um princípio do seu desenho, o Kubernetes usa muitos controladores onde cada um gerencia um aspecto particular do
estado do cluster. Comumente, um particular ciclo de controle (controlador) usa uma espécie de recurso como o seu estado
desejado, e tem uma espécie diferente de recurso que o mesmo gere para garantir que esse estado desejado é cumprido.
É útil que haja controladores simples em vez de um conjunto monolítico de ciclos de controle que estão interligados. Controladores
podem falhar, então o Kubernetes foi desenhado para permitir isso.
Por exemplo: um controlador de Jobs rastreia objetos Job (para descobrir novos trabalhos) e objetos Pod (para correr o Jobs, e então
ver quando o trabalho termina). Neste caso outra coisa cria os Jobs, enquanto o controlador Job cria Pods.
Nota:
Podem existir vários controladores que criam ou atualizam a mesma espécie (kind) de objeto. Atrás das cortinas, os
controladores do Kubernetes garantem que eles apenas tomam atenção aos recursos ligados aos seus recursos controladores.
Por exemplo, você pode ter Deployments e Jobs; ambos criam Pods. O controlador de Job não apaga os Pods que o seu
Deployment criou, porque existe informação (labels) que os controladores podem usar para diferenciar esses Pods.
O controlador Deployment e o controlador Job são exemplos de controladores que veem como parte do próprio Kubernetes
(controladores "embutidos"). O Kubernetes deixa você correr o plano de controle resiliente, para que se qualquer um dos
controladores embutidos falhar, outra parte do plano de controle assume o trabalho.
Pode encontrar controladores fora do plano de controle, para extender o Kubernetes. Ou, se quiser, pode escrever um novo
controlador você mesmo. Pode correr o seu próprio controlador como um conjunto de Pods, ou externo ao Kubernetes. O que
encaixa melhor vai depender no que esse controlador faz em particular.
Próximos passos
Leia mais sobre o plano de controle do Kubernetes
Descubra alguns dos objetos Kubernetes básicos.
Aprenda mais sobre API do Kubernetes
Se pretender escrever o seu próprio controlador, veja Padrões de Extensão
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 34/233
4/15/24, 11:56 AM Conceitos | Kubernetes
3 - Contêineres
Tecnologia para empacotar aplicações com suas dependências em tempo de execução
Cada contêiner executado é repetível; a padronização de ter dependências incluídas significa que você obtém o mesmo
comportamento onde quer que você execute.
Os contêineres separam os aplicativos da infraestrutura de host subjacente. Isso torna a implantação mais fácil em diferentes
ambientes de nuvem ou sistema operacional.
Imagem de contêiner
Uma imagem de contêiner é um pacote de software pronto para executar, contendo tudo que é preciso para executar uma
aplicação: o código e o agente de execução necessário, aplicação, bibliotecas do sistema e valores padrões para qualquer
configuração essencial.
Por design, um contêiner é imutável: você não pode mudar o código de um contêiner que já está executando. Se você tem uma
aplicação conteinerizada e quer fazer mudanças, você precisa construir uma nova imagem que inclui a mudança, e recriar o
contêiner para iniciar a partir da imagem atualizada.
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).
Próximos passos
Imagens de contêineres
Pods
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 35/233
4/15/24, 11:56 AM Conceitos | Kubernetes
3.1 - Imagens
Uma imagem de contêiner representa dados binários que encapsulam uma aplicação e todas as suas dependências de software. As
imagens de contêiner são pacotes de software executáveis que podem ser executados de forma autônoma e que fazem suposições
muito bem definidas sobre seu agente de execução do ambiente.
Normalmente, você cria uma imagem de contêiner da sua aplicação e a envia para um registro antes de fazer referência a ela em
um Pod
Se você não especificar um hostname de registro, o Kubernetes presumirá que você se refere ao registro público do Docker.
Após a parte do nome da imagem, você pode adicionar uma tag (como também usar com comandos como docker e podman ). As
tags permitem identificar diferentes versões da mesma série de imagens.
Tags de imagem consistem em letras maiúsculas e minúsculas, dígitos, sublinhados ( _ ), pontos ( . ) e travessões ( - ). Existem
regras adicionais sobre onde você pode colocar o separador caracteres ( _ , - e . ) dentro de uma tag de imagem. Se você não
especificar uma tag, o Kubernetes presumirá que você se refere à tag latest (mais recente).
Cuidado:
Você deve evitar usar a tag latest quando estiver realizando o deploy de contêineres em produção, pois é mais difícil rastrear
qual versão da imagem está sendo executada, além de tornar mais difícil o processo de reversão para uma versão funcional.
Atualizando imagens
A política padrão de pull é IfNotPresent a qual faz com que o kubelet ignore o processo de pull da imagem, caso a mesma já exista.
Se você prefere sempre forçar o processo de pull, você pode seguir uma das opções abaixo:
Quando imagePullPolicy é definido sem um valor específico, ele também é definido como Always .
O próprio Kubernetes normalmente nomeia as imagens de contêiner com o sufixo -$(ARCH) . Para retrocompatibilidade, gere as
imagens mais antigas com sufixos. A ideia é gerar a imagem pause que tem o manifesto para todas as arquiteturas e pause-amd64
que é retrocompatível com as configurações anteriores ou arquivos YAML que podem ter codificado as imagens com sufixos.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 36/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: O Kubernetes padrão é compatível apenas com as seções auths e HttpHeaders na configuração do Docker. Auxiliares de
credencial do Docker (credHelpers ou credsStore) não são suportados.
Docker armazena chaves de registros privados no arquivo $HOME/.dockercfg ou $HOME/.docker/config.json . Se você colocar o
mesmo arquivo na lista de caminhos de pesquisa abaixo, o kubelet o usa como provedor de credenciais ao obter imagens.
{--root-dir:-/var/lib/kubelet}/config.json
{cwd of kubelet}/config.json
${HOME}/.docker/config.json
/.docker/config.json
{--root-dir:-/var/lib/kubelet}/.dockercfg
{cwd of kubelet}/.dockercfg
${HOME}/.dockercfg
/.dockercfg
Nota: Você talvez tenha que definir HOME=/root explicitamente no ambiente do processo kubelet.
Aqui estão as etapas recomendadas para configurar seus nós para usar um registro privado. Neste exemplo, execute-os em seu
desktop/laptop:
1. Execute docker login [servidor] para cada conjunto de credenciais que deseja usar. Isso atualiza o
$HOME/.docker/config.json em seu PC.
2. Visualize $HOME/.docker/config.json em um editor para garantir que contém apenas as credenciais que você deseja usar.
3. Obtenha uma lista de seus nós; por exemplo:
se você quiser os nomes: nodes=$( kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}' )
se você deseja obter os endereços IP: nodes=$( kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?
(@.type=="ExternalIP")]}{.address} {end}' )
4. Copie seu .docker/config.json local para uma das listas de caminhos de busca acima.
por exemplo, para testar isso: for n in $nodes; do scp ~/.docker/config.json
root@"$n":/var/lib/kubelet/config.json; done
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 37/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Para clusters de produção, use uma ferramenta de gerenciamento de configuração para que você possa aplicar esta
configuração em todos os nós que você precisar.
Verifique se está funcionando criando um pod que usa uma imagem privada; por exemplo:
pod/private-image-test-1 created
Se tudo estiver funcionando, então, após algum tempo, você pode executar:
SUCCESS
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers
Você deve garantir que todos os nós no cluster tenham o mesmo .docker/config.json . Caso contrário, os pods serão executados
com sucesso em alguns nós e falharão em outros. Por exemplo, se você usar o escalonamento automático de nós, cada modelo de
instância precisa incluir o .docker/config.json ou montar um drive que o contenha.
Todos os pods terão premissão de leitura às imagens em qualquer registro privado, uma vez que as chaves privadas do registro são
adicionadas ao .docker/config.json .
Imagens pré-obtidas
Nota: Essa abordagem é adequada se você puder controlar a configuração do nó. Isto não funcionará de forma confiável se o
seu provedor de nuvem for responsável pelo gerenciamento de nós e os substituir automaticamente.
Por padrão, o kubelet tenta realizar um "pull" para cada imagem do registro especificado. No entanto, se a propriedade
imagePullPolicy do contêiner for definida como IfNotPresent ou Never , em seguida, uma imagem local é usada (preferencial
ou exclusivamente, respectivamente).
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 38/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Se você quiser usar imagens pré-obtidas como um substituto para a autenticação do registro, você deve garantir que todos os nós
no cluster tenham as mesmas imagens pré-obtidas.
Isso pode ser usado para pré-carregar certas imagens com o intuíto de aumentar a velocidade ou como uma alternativa para
autenticação em um registro privado.
Nota: Esta é a abordagem recomendada para executar contêineres com base em imagens de registros privados.
Se você já tem um arquivo de credenciais do Docker, em vez de usar o comando acima, você pode importar o arquivo de credenciais
como um Kubernetes Secrets. Criar um segredo com base nas credenciais Docker existentes explica como configurar isso.
Isso é particularmente útil se você estiver usando vários registros privados de contêineres, como kubectl create secret docker-
registry cria um Segredo que só funciona com um único registro privado.
Nota: Os pods só podem fazer referência a pull secrets de imagem em seu próprio namespace, portanto, esse processo precisa
ser feito uma vez por namespace.
Por exemplo:
Isso precisa ser feito para cada pod que está usando um registro privado.
No entanto, a configuração deste campo pode ser automatizada definindo o imagePullSecrets em um recurso de ServiceAccount.
Verifique Adicionar ImagePullSecrets a uma conta de serviço para obter instruções detalhadas.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 39/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Você pode usar isso em conjunto com um .docker / config.json por nó. As credenciais serão mescladas.
Casos de uso
Existem várias soluções para configurar registros privados. Aqui estão alguns casos de uso comuns e soluções sugeridas.
1. Cluster executando apenas imagens não proprietárias (por exemplo, código aberto). Não há necessidade de ocultar imagens.
Use imagens públicas no Docker hub.
Nenhuma configuração necessária.
Alguns provedores de nuvem armazenam em cache ou espelham automaticamente imagens públicas, o que
melhora a disponibilidade e reduz o tempo para extrair imagens.
2. Cluster executando algumas imagens proprietárias que devem ser ocultadas para quem está fora da empresa, mas visível para
todos os usuários do cluster.
Use um registro Docker privado hospedado.
Pode ser hospedado no Docker Hub ou em outro lugar.
Configure manualmente .docker/config.json em cada nó conforme descrito acima.
Ou execute um registro privado interno atrás de seu firewall com permissão de leitura.
Nenhuma configuração do Kubernetes é necessária.
Use um serviço de registro de imagem de contêiner que controla o acesso à imagem
Funcionará melhor com o escalonamento automático do cluster do que com a configuração manual de nós.
Ou, em um cluster onde alterar a configuração do nó é inconveniente, use imagePullSecrets .
3. Cluster com imagens proprietárias, algumas das quais requerem controle de acesso mais rígido.
Certifique-se de que o controlador de admissão AlwaysPullImages está ativo. Caso contrário, todos os pods têm
potencialmente acesso a todas as imagens.
Mova dados confidenciais para um recurso "secreto", em vez de empacotá-los em uma imagem.
4. Um cluster multilocatário em que cada locatário precisa de seu próprio registro privado.
Certifique-se de que o controlador de admissão AlwaysPullImages está ativo. Caso contrário, todos os Pods de todos os
locatários terão potencialmente acesso a todas as imagens.
Execute um registro privado com autorização necessária.
Gere credenciais de registro para cada locatário, coloque em segredo e preencha o segredo para cada namespace de
locatário.
O locatário adiciona esse segredo a imagePullSecrets de cada namespace.
Se precisar de acesso a vários registros, você pode criar um segredo para cada registro. O Kubelet mesclará qualquer
imagePullSecrets em um único .docker/config.json virtual
Próximos passos
Leia a OCI Image Manifest Specification
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 40/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Ambiente de contêiner
O ambiente de contêiner do Kubernetes fornece recursos importantes para contêineres:
Informação de contêiner
O hostname de um contêiner é o nome do Pod em que o contêiner está executando. Isso é disponibilizado através do comando
hostname ou da função gethostname chamada na libc.
O nome do Pod e o Namespace são expostos como variáveis de ambiente através de um mecanismo chamado downward API.
Variáveis de ambiente definidas pelo usuário a partir da definição do Pod também são disponíveis para o contêiner, assim como
qualquer variável de ambiente especificada estáticamente na imagem Docker.
Informação do cluster
Uma lista de todos os serviços que estão executando quando um contêiner foi criado é disponibilizada para o contêiner como
variáveis de ambiente. Essas variáveis de ambiente são compatíveis com a funcionalidade docker link do Docker.
Para um serviço nomeado foo que mapeia para um contêiner nomeado bar, as seguintes variáveis são definidas:
Serviços possuem endereço IP dedicado e são disponibilizados para o contêiner via DNS, se possuírem DNS addon habilitado.
Próximos passos
Aprenda mais sobre hooks de ciclo de vida do contêiner.
Obtenha experiência prática anexando manipuladores a eventos de ciclo de vida do contêiner.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 41/233
4/15/24, 11:56 AM Conceitos | Kubernetes
RuntimeClass é uma funcionalidade para selecionar as configurações do agente de execução do contêiner. A configuração do
agente de execução de contêineres é usada para executar os contêineres de um Pod.
Motivação
Você pode configurar um RuntimeClass diferente entre os diferentes Pods para prover um equilíbrio entre performance versus
segurança. Por exemplo, se parte de sua carga de trabalho necessita de um alto nível de garantia de segurança da informação, você
pode optar em executar esses Pods em um agente de execução que usa virtualização de hardware. Você então terá o benefício do
isolamento extra de um agente de execução alternativo, ao custo de uma latência adicional.
Você pode ainda usar um RuntimeClass para executar diferentes Pods com o mesmo agente de execução de contêineres mas com
diferentes configurações.
Configuração
1. Configure a implementação do CRI nos nós (depende do agente de execução)
2. Crie o recurso RuntimeClass correspondente.
Nota: RuntimeClass assume uma configuração homogênea de nós entre todo o cluster por padrão (o que significa que todos os
nós estão configurados do mesmo jeito referente aos agentes de execução). Para suportar configurações heterogêneas, veja
Associação abaixo.
As configurações possuem um nome handler correspondente, referenciado pelo RuntimeClass. Esse nome deve ser um valor DNS
1123 válido (letras, números e o carácter - ).
O recurso RuntimeClass atualmente possui apenas 2 campos significativos: o nome do RuntimeClass ( metadata.name ) e o agente
( handler ). A definição do objeto se parece conforme a seguir:
Nota: É recomendado que operações de escrita no objeto RuntimeClass (criar/atualizar/patch/apagar) sejam restritas a
administradores do cluster. Isso geralmente é o padrão. Veja Visão Geral de autorizações para maiores detalhes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 42/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Uso
Uma vez que as classes de execução estão configuradas no cluster, usar elas é relativamente simples. Especifique um
runtimeClassName na especificação do Pod. Por exemplo:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
runtimeClassName: myclass
# ...
Isso irá instruir o kubelet a usar o RuntimeClass nomeado acima (myclass) para esse Pod. Se o nome do RuntimeClass não existir, ou
o CRI não puder executar a solicitação, o Pod entrará na fase final Failed . Procure por um evento correspondente para uma
mensagem de erro.
Se nenhum runtimeClassName for especificado, o RuntimeHandler padrão será utilizado, que é equivalente ao comportamento
quando a funcionalidade de RuntimeClass está desativada.
Configuração do CRI
Para maiores detalhes de configuração dos agentes de execução CRI, veja instalação do CRI.
dockershim
O CRI dockershim embutido no Kubernetes não suporta outros agentes de execução.
containerd
Agentes de execução são configurados através da configuração do containerd em /etc/containerd/config.toml . Agentes válidos
são configurados sob a seção de runtimes :
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.${HANDLER_NAME}]
CRI-O
Agentes de execução são configurados através da configuração do CRI-O em /etc/crio/crio.conf . Agentes válidos são
configurados na seção crio.runtime table:
[crio.runtime.runtimes.${HANDLER_NAME}]
runtime_path = "${PATH_TO_BINARY}"
Associação
ESTADO DA FUNCIONALIDADE: Kubernetes v1.16 [beta]
Ao especificar o campo scheduling para um RuntimeClass, você pode colocar limites e garantir que os Pods executando dentro de
uma RuntimeClass sejam associados a nós que suportem eles. Se o scheduling não estiver configurado, assume-se que esse
RuntimeClass é suportado por todos os nós.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 43/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Para garantir que os Pods sejam executados em um nó que suporte um RuntimeClass específico, aquele conjunto de nós deve
possuir uma marca/label padrão que é selecionado pelo campo runtimeclass.scheduling.nodeSelector . O nodeSelector do
RuntimeClass é combinado com o nodeSelector do Pod em tempo de admissão, obtendo a intersecção do conjunto de nós
selecionado por cada. Se existir um conflito, o pod será rejeitado.
Se os nós suportados possuírem marcação de restrição para prevenir outros Pods com uma classe de execução diferente de
executar no nó, você pode adicionar o campo tolerations ao objeto RuntimeClass. Assim como com o nodeSelector , o
tolerations é combinado com o campo tolerations do Pod em tempo de admissão, efetivamente pegando a intersecção do
conjunto de nós aplicáveis para cada.
Para saber mais sobre a configuração de seleção de nós e tolerâncias, veja Associando Pods a Nós.
Sobrecarga de Pods
ESTADO DA FUNCIONALIDADE: Kubernetes v1.18 [beta]
Você pode especificar os recursos extra que estão associados à execução de um Pod. Declarar esses recursos extra permite ao
cluster (incluindo o agendador/scheduler de pods) contabilizar por esses recursos quando estiver decidindo sobre Pods e recursos.
Para usar a contabilização desses recursos extras, você deve estar com o feature gate PodOverhead habilitado (ele já está habilitado
por padrão).
Os recursos extras utilizados são especificados no objeto RuntimeClass através do campo overhead . Ao usar esses campos, você
especifica o uso extra de recursos necessários para executar Pods utilizando-se desse Runtimeclass e assim contabilizar esses
recursos para o Kubernetes.
Próximos passos
RuntimeClass Design
RuntimeClass Scheduling Design
Leia mais sobre Sobrecarga de Pods
PodOverhead Feature Design
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 44/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Visão Geral
Análogo a muitas estruturas de linguagem de programação que tem hooks de ciclo de vida de componentes, como angular, o
Kubernetes fornece aos contêineres hooks de ciclo de vida. Os hooks permitem que os contêineres estejam cientes dos eventos em
seu ciclo de vida de gerenciamento e executem código implementado em um manipulador quando o hook de ciclo de vida
correspondente é executado.
Hooks do contêiner
Existem dois hooks que são expostos para os contêiners:
PostStart
Este hook é executado imediatamente após um contêiner ser criado. Entretanto, não há garantia que o hook será executado antes
do ENTRYPOINT do contêiner. Nenhum parâmetro é passado para o manipulador.
PreStop
Esse hook é chamado imediatamente antes de um contêiner ser encerrado devido a uma solicitação de API ou um gerenciamento
de evento como liveness/startup probe failure, preemption, resource contention e outros. Uma chamada ao hook PreStop falha se
o contêiner já está em um estado finalizado ou concluído e o hook deve ser concluído antes que o sinal TERM seja enviado para
parar o contêiner. A contagem regressiva do período de tolerância de término do Pod começa antes que o hook PreStop seja
executado, portanto, independentemente do resultado do manipulador, o contêiner será encerrado dentro do período de
tolerância de encerramento do Pod. Nenhum parâmetro é passado para o manipulador.
Uma descrição mais detalhada do comportamento de término pode ser encontrada em Término de Pods.
Exec - Executa um comando específico, como pre-stop.sh , dentro dos cgroups e Namespaces do contêiner.
HTTP - Executa uma requisição HTTP em um endpoint específico do contêiner.
As chamadas do manipulador do hook são síncronas no contexto do Pod que contém o contêiner. Isso significa que para um hook
PostStart , o ENTRYPOINT do contêiner e o hook disparam de forma assíncrona. No entanto, se o hook demorar muito para ser
executado ou travar, o contêiner não consegue atingir o estado running .
Os hooks PreStop não são executados de forma assíncrona a partir do sinal para parar o contêiner, o hook precisa finalizar a sua
execução antes que o sinal TERM possa ser enviado. Se um hook PreStop travar durante a execução, a fase do Pod será
Terminating e permanecerá até que o Pod seja morto após seu terminationGracePeriodSeconds expirar. Esse período de
tolerância se aplica ao tempo total necessário para o hook PreStop executar e para o contêiner parar normalmente. Se por
exemplo, o terminationGracePeriodSeconds é 60, e o hook leva 55 segundos para ser concluído, e o contêiner leva 10 segundos
para parar normalmente após receber o sinal, então o contêiner será morto antes que possa parar normalmente, uma vez que o
terminationGracePeriodSeconds é menor que o tempo total (55 + 10) que é necessário para que essas duas coisas aconteçam.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 45/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Os usuários devem tornar seus hooks o mais leve possíveis. Há casos, no entanto, em que comandos de longa duração fazem
sentido, como ao salvar o estado antes de parar um contêiner.
Geralmente, apenas entregas únicas são feitas. Se, por exemplo, um receptor de hook HTTP estiver inativo e não puder receber
tráfego, não há tentativa de reenviar. Em alguns casos raros, no entanto, pode ocorrer uma entrega dupla. Por exemplo, se um
kubelet reiniciar no meio do envio de um hook, o hook pode ser reenviado depois que o kubelet voltar a funcionar.
Events:
FirstSeen LastSeen Count From SubObjectPath Type
--------- -------- ----- ---- ------------- --------
1m 1m 1 {default-scheduler } Normal
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal
38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal
37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal
38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning
Próximos passos
Saiba mais sobre o Ambiente de contêiner.
Obtenha experiência prática anexando manipuladores a eventos de ciclo de vida do contêiner.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 46/233
4/15/24, 11:56 AM Conceitos | Kubernetes
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 47/233
4/15/24, 11:56 AM Conceitos | Kubernetes
4.1 - Ingress
Disponibilize seu serviço de rede HTTP ou HTTPS usando um mecanismo de configuração com
reconhecimento de protocolo, que entende conceitos da Web como URIs, nomes de host, caminhos e muito
mais. O conceito Ingress permite mapear o tráfego para diferentes backends com base nas regras definidas
por meio da API do Kubernetes.
Um objeto da API (do inglês "Application Programming Interface") que gerencia o acesso externo aos serviços em um cluster,
normalmente HTTP.
Um Ingress pode fornecer balanceamento de carga, terminação SSL e hospedagem virtual baseada em nomes.
Terminologia
Para fins de clareza, este guia define os seguintes termos:
O que é o Ingress?
O Ingress expõe rotas HTTP e HTTPS de fora do cluster para um serviço dentro do cluster. O roteamento do tráfego é controlado
por regras definidas no recurso Ingress.
Aqui está um exemplo simples em que o Ingress envia todo o seu tráfego para um serviço:
cluster
Pod
Ingress-managed
client load balancer Ingress routing rule Service
Pod
Figura. Ingress
Um Ingress pode ser configurado para fornecer URLs acessíveis externamente aos serviços, balanceamento de carga de tráfego,
terminação SSL/TLS e oferecer hospedagem virtual baseada em nome. Um controlador Ingress é responsável por atender o Ingress,
geralmente com um balanceador de carga, embora também possa configurar seu roteador de borda ou frontends adicionais para
ajudar a lidar com o tráfego.
Um Ingress não expõe portas ou protocolos arbitrários. Normalmente se usa um serviço do tipo Service.Type=NodePort ou
Service.Type=LoadBalancer para expor serviços à Internet que não sejam HTTP e HTTPS.
Pré-requisitos
Você deve ter um controlador Ingress para satisfazer um Ingress. Apenas a criação de um recurso Ingress não tem efeito.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 48/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Você pode precisar instalar um controlador Ingress, como ingress-nginx. Você pode escolher entre vários controladores Ingress.
Idealmente, todos os controladores Ingress devem se encaixar na especificação de referência. Na realidade, os vários controladores
Ingress operam de forma ligeiramente diferente.
Nota: Certifique-se de revisar a documentação do seu controlador Ingress para entender as ressalvas de escolhê-lo.
O recurso Ingress
Um exemplo mínimo do recurso Ingress:
service/networking/minimal-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx-example
rules:
- http:
paths:
- path: /testpath
pathType: Prefix
backend:
service:
name: test
port:
number: 80
Um Ingress precisa dos campos apiVersion , kind , metadata e spec . O nome de um objeto Ingress deve ser um nome de
subdomínio DNS válido. Para obter informações gerais sobre como trabalhar com arquivos de configuração, consulte como instalar
aplicações, como configurar contêineres e como gerenciar recursos. O Ingress frequentemente usa anotações para configurar
opções dependendo do controlador Ingress. Um exemplo deste uso é a anotação rewrite-target. Diferentes controladores Ingress
suportam diferentes anotações. Revise a documentação do seu controlador Ingress escolhido para saber quais anotações são
suportadas.
A especificação Ingress tem todas as informações necessárias para configurar um balanceador de carga ou servidor proxy. Mais
importante ainda, ele contém uma lista de regras correspondentes a todas as solicitações recebidas. O recurso Ingress suporta
apenas regras para direcionar o tráfego HTTP(S).
Se o ingressClassName for omitido, uma classe Ingress padrão deve ser definida.
Existem alguns controladores Ingress que funcionam sem a definição de uma IngressClass padrão. Por exemplo, o controlador
Ingress-NGINX pode ser configurado com uma flag --watch-ingress-without-class . No entanto, recomenda-se especificar a
IngressClass padrão, conforme mostrado abaixo.
Regras do Ingress
Cada regra HTTP contém as seguintes informações:
Um host opcional. Neste exemplo, nenhum host é especificado, portanto, a regra se aplica a todo o tráfego HTTP de entrada
através do endereço IP especificado. Se um host for fornecido (por exemplo, foo.bar.com), as regras se aplicam a esse host.
Uma lista de caminhos (por exemplo, /testpath ), cada um com um backend associado definido com um service.name e um
service.port.name ou service.port.number . Tanto o host quanto o caminho devem corresponder ao conteúdo de uma
solicitação recebida antes que o balanceador de carga direcione o tráfego para o serviço referenciado.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 49/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Um backend é uma combinação de nomes de serviço e porta, conforme descrito na documentação de Services ou um backend
de recursos personalizados por meio de um CRD. As solicitações HTTP e HTTPS para o Ingress que correspondem ao host e ao
caminho da regra são enviadas para o backend listado.
Um defaultBackend geralmente é configurado em um controlador Ingress para atender a quaisquer solicitações que não
correspondam a um caminho na especificação.
DefaultBackend
Um Ingress sem regras envia todo o tráfego para um único backend padrão e .spec.defaultBackend é o backend que deve lidar
com as solicitações nesse caso. O defaultBackend é convencionalmente uma opção de configuração do controlador Ingress e não é
especificado em seus recursos Ingress. Se nenhum .spec.rules for especificado, o .spec.defaultBackend deve ser especificado.
Se o defaultBackend não for definido, o tratamento de solicitações que não correspondem a nenhuma das regras ficará a cargo do
controlador de Ingress (consulte a documentação do seu controlador de Ingress para descobrir como ele lida com esse caso).
Se nenhum dos hosts ou caminhos corresponder à solicitação HTTP nos objetos Ingress, o tráfego será roteado para o seu backend
padrão.
Resource backends
Um Resourcebackend é um ObjectRef para outro recurso Kubernetes dentro do mesmo namespace que o objeto Ingress. Um
Resource é uma configuração mutuamente exclusiva com o serviço, e a validação irá falhar se ambos forem especificados. Um uso
comum para um Resource backend é inserir dados em um backend de armazenamento de objetos com ativos estáticos.
service/networking/ingress-resource-backend.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-backend
spec:
defaultBackend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: static-assets
rules:
- http:
paths:
- path: /icons
pathType: ImplementationSpecific
backend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: icon-assets
Depois de criar o Ingress acima, você pode visualizá-lo com o seguinte comando:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 50/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: ingress-resource-backend
Namespace: default
Address:
Default backend: APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets
Rules:
Host Path Backends
---- ---- --------
*
/icons APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets
Annotations: <none>
Events: <none>
ImplementationSpecific : Com esse tipo de caminho, a correspondência depende da IngressClass. As implementações podem
tratar isso como um pathType separado ou tratá-lo de forma idêntica aos tipos de caminho Prefix ou Exact .
Exact : Corresponde exatamente ao caminho da URL podendo ser case-sensitive.
Prefix : Corresponde com base em um prefixo de caminho de URL dividido por / . A correspondência faz distinção entre
maiúsculas e minúsculas e é feita em um caminho, elemento por elemento. Um elemento de caminho refere-se à lista de
labels no caminho dividido pelo separador / . Uma solicitação é uma correspondência para o caminho p se cada p for um
prefixo elementar de p do caminho da solicitação.
Nota: Se o último elemento do caminho for uma substring do último elemento no caminho da solicitação, não é uma
correspondência (por exemplo: /foo/bar corresponde a /foo/bar/baz, mas não corresponde a /foo/barbaz).
Exemplos
Tipos Caminho(s) Caminho(s) de solicitação Correspondências?
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 51/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Várias correspondências
Em alguns casos, vários caminhos dentro de uma entrada corresponderão a uma solicitação. Nesses casos, a precedência será dada
primeiro ao caminho correspondente mais longo. Se dois caminhos ainda estiverem iguais, a precedência será dada aos caminhos
com um tipo de caminho exato sobre o tipo de caminho de prefixo.
Hostname curingas
Os hosts podem ter correspondências precisas (por exemplo, “foo.bar.com”) ou um curinga (por exemplo, “ *.foo.com ”).
Correspondências precisas exigem que o cabeçalho do host HTTP corresponda ao campo host . As correspondências curinga
exigem que o cabeçalho do host HTTP seja igual ao sufixo da regra curinga.
*.foo.com baz.bar.foo.com Sem correspondência, o curinga cobre apenas um único rótulo DNS
*.foo.com foo.com Sem correspondência, o curinga cobre apenas um único rótulo DNS
service/networking/ingress-wildcard-host.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 52/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "*.foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80
Classe Ingress
Os Ingress podem ser implementados por diferentes controladores, muitas vezes com diferentes configurações. Cada Ingress deve
especificar uma classe, uma referência a um recurso IngressClass que contém uma configuração adicional, incluindo o nome do
controlador que deve implementar a classe.
service/networking/external-lb.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parameters:
apiGroup: k8s.example.com
kind: IngressParameters
name: external-lb
O campo .spec.parameters de uma classe Ingress permite que você faça referência a outro recurso que fornece a configuração
relacionada a essa classe Ingress.
O tipo específico de parâmetros a serem usados depende do controlador Ingress que você especificar no campo .spec.controller
da classe Ingress.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 53/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Cluster Namespaced
Se você definir o campo .spec.parameters e não definir .spec.parameters.scope , ou se você definir .spec.parameters.scope
como Cluster, então a classe Ingress se refere a um recurso com escopo de cluster. O kind (em combinação com o apiGroup )
dos parâmetros refere-se a uma API com escopo de cluster (possivelmente um recurso personalizado), e o name dos
parâmetros identifica um recurso específico com escopo de cluster para essa API.
Por exemplo:
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb-1
spec:
controller: example.com/ingress-controller
parameters:
# Os parâmetros para esta classe Ingress são especificados em um
# ClusterIngressParameter (grupo de API k8s.example.net) nomeado
# "external-config-1". Esta definição diz ao Kubernetes para
# procurar um recurso de parâmetro com escopo de cluster.
scope: Cluster
apiGroup: k8s.example.net
kind: ClusterIngressParameter
name: external-config-1
Anotação obsoleta
Antes que o recurso IngressClass e o campo ingressClassName fossem adicionados no Kubernetes 1.18, as classes Ingress foram
especificadas com uma anotação kubernetes.io/ingress.class no Ingress. Esta anotação nunca foi formalmente definida, mas foi
amplamente apoiada pelos controladores Ingress.
O campo ingressClassName mais recente no Ingress é um substituto para essa anotação, mas não é um equivalente direto. Embora
a anotação tenha sido geralmente usada para fazer referência ao nome do controlador Ingress que deve implementar o Ingress, o
campo é uma referência a um recurso IngressClass que contém a configuração Ingress adicional, incluindo o nome do controlador
Ingress.
Cuidado: Se você tiver mais de uma classe Ingress marcada como padrão para o seu cluster, o controlador de admissão impede
a criação de novos objetos Ingress que não tenham um ingressClassName especificado. Você pode resolver isso garantindo que
no máximo uma classe Ingress seja marcada como padrão no seu cluster.
Existem alguns controladores Ingress que funcionam sem a definição de uma IngressClass padrão. Por exemplo, o controlador
Ingress-NGINX pode ser configurado com uma flag --watch-ingress-without-class. No entanto, é recomendável especificar a
IngressClass padrão:
service/networking/default-ingressclass.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 54/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
labels:
app.kubernetes.io/component: controller
name: nginx-example
annotations:
ingressclass.kubernetes.io/is-default-class: "true"
spec:
controller: k8s.io/ingress-nginx
Tipos de Ingress
Ingress fornecidos por um único serviço
No Kubernetes existem conceitos que permitem expor um único serviço (veja alternativas). Você também pode fazer isso com um
Ingress especificando um backend padrão sem regras.
service/networking/test-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: test
port:
number: 80
Se você criá-lo usando kubectl apply -f , você deve ser capaz de visualizar o estado do Ingress que você adicionou:
Nota: Controladores Ingress e balanceadores de carga podem levar um ou dois minutos para alocar um endereço IP. Até
aquele momento, você costuma ver o endereço listado como <pending>.
Simples fanout
Uma configuração de fanout roteia o tráfego de um único endereço IP para mais de um serviço, com base na URI HTTP que está
sendo solicitada. Um Ingress permite que você mantenha o número de balanceadores de carga no mínimo. Por exemplo, uma
configuração como:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 55/233
4/15/24, 11:56 AM Conceitos | Kubernetes
cluster
Pod
Pod
Ingress-managed
client load balancer Ingress, 178.91.123.132
Pod
Pod
service/networking/simple-fanout-example.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 56/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
O controlador Ingress fornece um balanceador de carga específico de implementação que satisfaz o Ingress, desde que os serviços
( service1 , service2 ) existam. Quando tiver feito isso, você pode ver o endereço do balanceador de carga no campo Address .
Nota: Dependendo do controlador Ingress que você está usando, talvez seja necessário criar um serviço de backend http
padrão.
cluster
Pod
Pod
Ingress-managed
client load balancer Ingress, 178.91.123.132
Pod
Pod
O Ingress a seguir diz ao balanceador de carga de apoio para rotear solicitações com base no Host header.
service/networking/name-virtual-host-ingress.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 57/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: bar.foo.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service2
port:
number: 80
Se você criar um recurso de Ingress sem nenhum host definido nas regras, qualquer tráfego da web para o endereço IP do seu
controlador de Ingress pode ser correspondido sem que seja necessário um host virtual baseado em nome.
Por exemplo, o Ingress a seguir roteia o tráfego solicitado para first.bar.com para service1 , second.bar.com para service2 e
qualquer tráfego cujo cabeçalho de host de solicitação não corresponda a first.bar.com e second.bar.com para service3 .
service/networking/name-virtual-host-ingress-no-third-host.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 58/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: name-virtual-host-ingress-no-third-host
spec:
rules:
- host: first.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: second.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service2
port:
number: 80
- http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service3
port:
number: 80
TLS
Você pode configurar o uso de TLS no Ingress especificando um Secret que contém uma chave privada e um certificado TLS. O
recurso Ingress suporta apenas uma única porta TLS, 443, e assume a terminação TLS no ponto de entrada (o tráfego para o Serviço
e seus Pods não está criptografado o que é inseguro). Se a seção de configuração TLS em um Ingress especificar hosts diferentes,
eles serão multiplexados na mesma porta de acordo com o nome do host especificado através da extensão SNI TLS (desde que o
controlador Ingress suporte SNI). O objeto Secret do tipo TLS deve conter chaves chamadas tls.crt e tls.key que contêm o
certificado e a chave privada a ser usada para TLS.
Por exemplo:
apiVersion: v1
kind: Secret
metadata:
name: testsecret-tls
namespace: default
data:
tls.crt: base64 encoded cert
tls.key: base64 encoded key
type: kubernetes.io/tls
Fazer referência a esse segredo em um Ingress diz ao controlador Ingress para proteger o canal do cliente para o balanceador de
carga usando TLS. Você precisa ter certeza de que o objeto Secret do tipo TLS que você criou é originário de um certificado que
contém um Nome Comum (Common Name, CN), também conhecido como Nome de Domínio Totalmente Qualificado (Fully
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 59/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Tenha em mente que o TLS não funcionará na regra padrão porque os certificados teriam que ser emitidos para todos os
subdomínios possíveis. Portanto, os hosts na seção tls precisam corresponder explicitamente ao host na seção rules.
service/networking/tls-example-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- https-example.foo.com
secretName: testsecret-tls
rules:
- host: https-example.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service1
port:
number: 80
Nota: Há uma lacuna entre os recursos TLS suportados por vários controladores Ingress. Consulte a documentação sobre
nginx, GCE ou qualquer outro controlador Ingress específico da plataforma para entender como o TLS funciona em seu
ambiente.
Balanceador de carga
Um controlador Ingress é inicializado com algumas configurações de política de balanceamento de carga que se aplicam a todos os
Ingress, como o algoritmo de balanceamento de carga, esquema de peso de backend e outros. Conceitos mais avançados de
balanceamento de carga (por exemplo, sessões persistentes, pesos dinâmicos) ainda não estão expostos através do Ingress. Em vez
disso, você pode obter esses recursos através do balanceador de carga usado para um serviço.
Também vale a pena notar que, embora as verificações de integridade não sejam expostas diretamente através do Ingress, existem
conceitos paralelos no Kubernetes, como readiness probes, que permitem alcançar o mesmo resultado final. Revise a
documentação específica do controlador para ver como eles lidam com as verificações de integridade (por exemplo: nginx ou GCE).
Atualizando um Ingress
Para atualizar um Ingress existente para adicionar um novo Host, você pode atualizá-lo editando o recurso:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 60/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 35s loadbalancer-controller default/test
Isso abre um editor com a configuração existente no formato YAML. Para incluir o novo host modifique:
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
service:
name: service1
port:
number: 80
path: /foo
pathType: Prefix
- host: bar.baz.com
http:
paths:
- backend:
service:
name: service2
port:
number: 80
path: /foo
pathType: Prefix
..
Depois de salvar suas alterações, o kubectl atualizará o recurso no servidor API, que diz ao controlador Ingress para reconfigurar o
balanceador de carga.
Verifique isso:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 61/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
bar.baz.com
/foo service2:80 (10.8.0.91:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 45s loadbalancer-controller default/test
Você pode alcançar o mesmo resultado invocando kubectl replace -f em um arquivo Ingress YAML modificado.
Alternativas
Você pode expor um serviço de várias maneiras que não envolve diretamente o recurso Ingress:
Use Service.Type=LoadBalancer
Use Service.Type=NodePort
Próximos passos
Aprenda sobre a API Ingress
Aprenda sobre controladores Ingress
Configure o Ingress no Minikube usando o NGINX Controller
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 62/233
4/15/24, 11:56 AM Conceitos | Kubernetes
As entidades que um Pod pode se comunicar são identificadas através de uma combinação dos 3 identificadores à seguir:
1. Outros pods que são permitidos (exceção: um pod não pode bloquear a si próprio)
2. Namespaces que são permitidos
3. Blocos de IP (exceção: o tráfego de e para o nó que um Pod está executando sempre é permitido, independentemente do
endereço IP do Pod ou do Nó)
Quando definimos uma política de rede baseada em pod ou namespace, utiliza-se um selector para especificar qual tráfego é
permitido de e para o(s) Pod(s) que correspondem ao seletor.
Quando uma política de redes baseada em IP é criada, nós definimos a política baseada em blocos de IP (faixas CIDR).
Pré requisitos
As políticas de rede são implementadas pelo plugin de redes. Para usar uma política de redes, você deve usar uma solução de redes
que suporte o objeto NetworkPolicy . A criação de um objeto NetworkPolicy sem um controlador que implemente essas regras
não tem efeito.
Os pods tornam-se isolados ao existir uma NetworkPolicy que selecione eles. Uma vez que exista qualquer NetworkPolicy no
namespace selecionando um pod em específico, aquele pod irá rejeitar qualquer conexão não permitida por qualquer
NetworkPolicy . (Outros pod no mesmo namespace que não são selecionados por nenhuma outra NetworkPolicy irão continuar
aceitando todo tráfego de rede.)
As políticas de rede não conflitam; elas são aditivas. Se qualquer política selecionar um pod, o pod torna-se restrito ao que é
permitido pela união das regras de entrada/saída de tráfego definidas nas políticas. Assim, a ordem de avaliação não afeta o
resultado da política.
Para o fluxo de rede entre dois pods ser permitido, tanto a política de saída no pod de origem e a política de entrada no pod de
destino devem permitir o tráfego. Se a política de saída na origem, ou a política de entrada no destino negar o tráfego, o tráfego
será bloqueado.
O recurso NetworkPolicy
Veja a referência NetworkPolicy para uma definição completa do recurso.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 63/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
Nota: Criar esse objeto no seu cluster não terá efeito a não ser que você escolha uma solução de redes que suporte políticas de
rede.
Campos obrigatórios: Assim como todas as outras configurações do Kubernetes, uma NetworkPolicy necessita dos campos
apiVersion , kind e metadata . Para maiores informações sobre trabalhar com arquivos de configuração, veja Configurando
containeres usando ConfigMap, e Gerenciamento de objetos.
spec: A spec contém todas as informações necessárias para definir uma política de redes em um namespace.
podSelector: Cada NetworkPolicy inclui um podSelector que seleciona o grupo de pods que a política se aplica. A política acima
seleciona os pods com a label "role=db". Um podSelector vazio seleciona todos os pods no namespace.
policyTypes: Cada NetworkPolicy inclui uma lista de policyTypes que pode incluir Ingress , Egress ou ambos. O campo
policyTypes indica se a política se aplica ao tráfego de entrada com destino aos pods selecionados, o tráfego de saída com origem
dos pods selecionados ou ambos. Se nenhum policyType for definido então por padrão o tipo Ingress será sempre utilizado, e o
tipo Egress será configurado apenas se o objeto contiver alguma regra de saída. (campo egress a seguir).
ingress: Cada NetworkPolicy pode incluir uma lista de regras de entrada permitidas através do campo ingress . Cada regra
permite o tráfego que corresponde simultaneamente às sessões from (de) e ports (portas). A política de exemplo acima contém
uma regra simples, que corresponde ao tráfego em uma única porta, de uma das três origens definidas, sendo a primeira definida
via ipBlock , a segunda via namespaceSelector e a terceira via podSelector .
egress: Cada política pode incluir uma lista de regras de regras de saída permitidas através do campo egress . Cada regra permite o
tráfego que corresponde simultaneamente às sessões to (para) e ports (portas). A política de exemplo acima contém uma regra
simples, que corresponde ao tráfego destinado a uma porta em qualquer destino pertencente à faixa de IPs em 10.0.0.0/24 .
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 64/233
4/15/24, 11:56 AM Conceitos | Kubernetes
1. Isola os pods no namespace "default" com a label "role=db" para ambos os tráfegos de entrada e saída (se eles ainda não
estavam isolados)
2. (Regras de entrada/ingress) permite conexões para todos os pods no namespace "default" com a label "role=db" na porta TCP
6379 de:
podSelector: Seleciona Pods no mesmo namespace que a política de rede foi criada, e que deve ser permitido origens no tráfego de
entrada ou destinos no tráfego de saída.
namespaceSelector: Seleciona namespaces para o qual todos os Pods devem ser permitidos como origens no caso de tráfego de
entrada ou destino no tráfego de saída.
namespaceSelector e podSelector: Uma entrada to / from única que permite especificar ambos namespaceSelector e
podSelector e seleciona um conjunto de Pods dentro de um namespace. Seja cuidadoso em utilizar a sintaxe YAML correta; essa
política:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
contém um único elemento from permitindo conexões de Pods com a label role=client em namespaces com a label user=alice .
Mas essa política:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
- podSelector:
matchLabels:
role: client
...
contém dois elementos no conjunto from e permite conexões de Pods no namespace local com a label role=client , OU de
qualquer outro Pod em qualquer outro namespace que tenha a label user=alice .
Quando estiver em dúvida, utilize o comando kubectl describe para verificar como o Kubernetes interpretou a política.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 65/233
4/15/24, 11:56 AM Conceitos | Kubernetes
ipBlock: Isso seleciona um conjunto particular de faixas de IP a serem permitidos como origens no caso de entrada ou destinos no
caso de saída. Devem ser considerados IPs externos ao cluster, uma vez que os IPs dos Pods são efêmeros e imprevisíveis.
Os mecanismos de entrada e saída do cluster geralmente requerem que os IPs de origem ou destino sejam reescritos. Em casos em
que isso aconteça, não é definido se deve acontecer antes ou depois do processamento da NetworkPolicy que corresponde a esse
tráfego, e o comportamento pode ser diferente para cada plugin de rede, provedor de nuvem, implementação de Service , etc.
No caso de tráfego de entrada, isso significa que em alguns casos você pode filtrar os pacotes de entrada baseado no IP de origem
atual, enquanto que em outros casos o IP de origem que a NetworkPolicy atua pode ser o IP de um LoadBalancer ou do Nó em
que o Pod está executando.
No caso de tráfego de saída, isso significa que conexões de Pods para Services que são reescritos para IPs externos ao cluster
podem ou não estar sujeitos a políticas baseadas no campo ipBlock .
Políticas padrão
Por padrão, se nenhuma política existir no namespace, então todo o tráfego de entrada e saída é permitido de e para os pods nesse
namespace. Os exemplos a seguir permitem a você mudar o comportamento padrão nesse namespace.
service/networking/network-policy-default-deny-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
Isso garante que mesmo pods que não são selecionados por nenhuma outra política de rede ainda serão isolados. Essa política não
muda o comportamento padrão de isolamento de tráfego de saída nesse namespace.
service/networking/network-policy-allow-all-ingress.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 66/233
4/15/24, 11:56 AM Conceitos | Kubernetes
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-ingress
spec:
podSelector: {}
ingress:
- {}
policyTypes:
- Ingress
service/networking/network-policy-default-deny-egress.yaml
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
spec:
podSelector: {}
policyTypes:
- Egress
Isso garante que mesmo pods que não são selecionados por outra política de rede não seja permitido tráfego de saída. Essa política
não muda o comportamento padrão de tráfego de entrada.
service/networking/network-policy-allow-all-egress.yaml
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 67/233
4/15/24, 11:56 AM Conceitos | Kubernetes
service/networking/network-policy-default-deny-all.yaml
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Isso garante que mesmo pods que não são selecionados por nenhuma outra política de redes não possuam permissão de tráfego
de entrada ou saída.
Ao escrever uma política de redes, você pode selecionar uma faixa de portas ao invés de uma porta única, utilizando-se do campo
endPort conforme a seguir:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: multi-port-egress
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 32000
endPort: 32768
A regra acima permite a qualquer Pod com a label "role=db" no namespace default de se comunicar com qualquer IP na faixa
10.0.0.0/24 através de protocolo TCP, desde que a porta de destino esteja na faixa entre 32000 e 32768.
Por ser uma funcionalidade "alpha", ela é desativada por padrão. Para habilitar o campo endPort no cluster, você (ou o seu
administrador do cluster) deve habilitar o feature gate NetworkPolicyEndPort no kube-apiserver com a flag --feature-
gates=NetworkPolicyEndPort=true,... .
Nota: Seu cluster deve utilizar um plugin CNI que suporte o campo endPort na especificação da política de redes.
A camada de gerenciamento do Kubernetes configura uma label imutável kubernetes.io/metadata.name em todos os namespaces,
uma vez que o feature gate esteja habilitado por padrão. O valor dessa label é o nome do namespace.
Enquanto que um objeto NetworkPolicy não pode selecionar um namespace pelo seu nome através de um campo específico, você
pode utilizar essa label padrão para selecionar um namespace pelo seu nome.
O que você não pode fazer com NetworkPolicies (ao menos por
enquanto!)
Por enquanto no Kubernetes 1.29 as funcionalidades a seguir não existem mas você pode conseguir implementar de forma
alternativa utilizando componentes do Sistema Operacional (como SELinux, OpenVSwitch, IPtables, etc) ou tecnologias da camada 7
OSI (Ingress controllers, implementações de service mesh) ou ainda admission controllers. No caso do assunto "segurança de redes
no Kubernetes" ser novo para você, vale notar que as histórias de usuário a seguir ainda não podem ser implementadas:
Forçar o tráfego interno do cluster passar por um gateway comum (pode ser implementado via service mesh ou outros
proxies)
Qualquer coisa relacionada a TLS/mTLS (use um service mesh ou ingress controller para isso)
Políticas específicas a nível do nó kubernetes (você pode utilizar as notações de IP CIDR para isso, mas não pode selecionar nós
Kubernetes por suas identidades)
Selecionar Services pelo seu nome (você pode, contudo, selecionar pods e namespaces por seus labels o que torna-se uma
solução de contorno viável).
Criação ou gerenciamento
Políticas padrão que são aplicadas a todos os namespaces e pods (existem alguns plugins externos do Kubernetes e projetos
que podem fazer isso, e a comunidade está trabalhando nessa especificação).
Ferramental de testes para validação de políticas de redes.
Possibilidade de logar eventos de segurança de redes (conexões bloqueadas, aceitas). Existem plugins CNI que conseguem
fazer isso à parte.
Possibilidade de explicitamente negar políticas de rede (o modelo das NetworkPolicies são "negar por padrão e conforme a
necessidade, deve-se adicionar regras que permitam o tráfego).
Bloquear o tráfego que venha da interface de loopback/localhost ou que venham do nó em que o Pod se encontre.
Próximos passos
Veja o tutorial Declarando políticas de redes para mais exemplos.
Veja mais cenários comuns e exemplos de políticas de redes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 69/233
4/15/24, 11:56 AM Conceitos | Kubernetes
5 - Armazenamento
Formas de fornecer armazenamento temporário e de longa duração a Pods em seu cluster.
5.1 - Volumes
Os arquivos em disco em um contêiner são efêmeros, o que apresenta alguns problemas para aplicações não triviais quando
executadas em contêineres. Um problema é a perda de arquivos quando um contêiner quebra. O kubelet reinicia o contêiner, mas
em um estado limpo. Um segundo problema ocorre ao compartilhar arquivos entre contêineres que são executados juntos em um
Pod . A abstração de volume do Kubernetes resolve ambos os problemas. Sugere-se familiaridade com Pods .
Contexto
Docker tem um conceito de volumes, embora seja um pouco mais simples e menos gerenciado. Um volume Docker é um diretório
em disco ou em outro contêiner. O Docker oferece drivers de volume, mas a funcionalidade é um pouco limitada.
O Kubernetes suporta muitos tipos de volumes. Um Pod é capaz de utilizar qualquer quantidade de tipos de volumes
simultaneamente. Os tipos de volume efêmeros têm a mesma vida útil do pod, mas os volumes persistentes existem além da vida
útil de um pod. Quando um pod deixa de existir, o Kubernetes destrói volumes efêmeros; no entanto, o Kubernetes não destrói
volumes persistentes. Para qualquer tipo de volume em um determinado pod, os dados são preservados entre as reinicializações do
contêiner.
Em sua essência, um volume é um diretório, eventualmente com alguns dados dentro dele, que é acessível aos contêineres de um
Pod. Como esse diretório vem a ser, o meio que o suporta e o conteúdo do mesmo são determinados pelo tipo particular de volume
utilizado.
Para utilizar um volume, especifique os volumes que serão disponibilizados para o Pod em .spec.volumes e declare onde montar
esses volumes dentro dos contêineres em .spec.containers[*].volumeMounts . Um processo em um contêiner enxerga uma
visualização do sistema de arquivos composta pelo do conteúdo inicial da imagem do contêiner mais os volumes (se definidos)
montados dentro do contêiner. O processo enxerga um sistema de arquivos raiz que inicialmente corresponde ao conteúdo da
imagem do contêiner. Qualquer gravação dentro dessa hierarquia do sistema de arquivos, se permitida, afetará o que esse
processo enxerga quando ele executa um acesso subsequente ao sistema de arquivos. Os volumes são montados nos caminhos
especificados dentro da imagem. Para cada contêiner definido em um Pod, você deve especificar independentemente onde montar
cada volume utilizado pelo contêiner.
Volumes não podem ser montados dentro de outros volumes (mas você pode consultar Utilizando subPath para um mecanismo
relacionado). Além disso, um volume não pode conter um link físico para qualquer outro dado em um volume diferente.
Tipos de Volumes
Kubernetes suporta vários tipos de volumes.
awsElasticBlockStore (descontinuado)
Um volume awsElasticBlockStore monta um volume EBS da Amazon Web Services (AWS) em seu pod. Ao contrário do
emptyDir que é apagado quando um pod é removido, o conteúdo de um volume EBS é preservado e o volume é desmontado. Isto
significa que um volume EBS pode ser previamente populado com dados e que os dados podem ser compartilhados entre Pods.
Nota: Você precisa criar um volume EBS usando aws ec2 create-volume ou pela API da AWS antes que você consiga utilizá-lo.
Os nós nos quais os Pods estão sendo executados devem ser instâncias AWS EC2
Estas instâncias devem estar na mesma região e na mesma zona de disponibilidade que o volume EBS
O EBS suporta montar um volume em apenas uma única instância EC2
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 70/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Certifique-se de que a zona corresponde à mesma zona em que criou o cluster. Verifique se o tamanho e o tipo de volume EBS são
adequados para a sua utilização.
apiVersion: v1
kind: Pod
metadata:
name: test-ebs
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-ebs
name: test-volume
volumes:
- name: test-volume
# Esse volume AWS EBS já deve existir.
awsElasticBlockStore:
volumeID: "<volume id>"
fsType: ext4
Se o volume EBS estiver particionado, é possível informar o campo opcional partition: "<partition em number>" para especificar
em que partição deve ser montado.
Quando o recurso CSIMigration para awsElasticBlockStore está habilitado, todas as operações de plugin do tipo in-tree são
redirecionadas para o driver Cointainer Storage Interface (CSI) ebs.csi.aws.com . Para usar esse recurso, o driver CSI AWS EBS deve
estar instalado no cluster.
Para desabilitar o carregamento do plugin de armazenamento awsElasticBlockStore pelo gerenciador de controladores e pelo
kubelet, defina a flag InTreePluginAWSUnregister como true .
azureDisk (descontinuado)
ESTADO DA FUNCIONALIDADE: Kubernetes v1.19 [deprecated]
Quando o recurso CSIMigration para azureDisk está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas
para o Driver de Cointêiner Storage Interface (CSI) disk.csi.azure.com . Para utilizar este recurso, o Driver CSI Azure Disk deve estar
instalado no cluster.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 71/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Para desabilitar o carregamento do plugin de armazenamento azureDisk pelo gerenciador de controladores e pelo kubelet, defina
a flag InTreePluginAzureDiskUnregister como true .
azureFile (descontinuado)
ESTADO DA FUNCIONALIDADE: Kubernetes v1.21 [deprecated]
O tipo de volume azureFile monta um volume de arquivo Microsoft Azure (SMB 2.1 e 3.0) em um pod.
Quando o recurso CSIMigration para azureFile está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas
para o Driver de Cointainer Storage Interface (CSI) file.csi.azure.com . Para utilizar este recurso, o Driver CSI do Azure Disk deve
estar instalado no cluster e as feature gates CSIMigration e CSIMigrationAzureFile devem estar habilitadas.
O driver de CSI do Azure File não oferece suporte ao uso do mesmo volume por fsgroups diferentes, se a migração de CSI Azurefile
estiver habilitada, o uso do mesmo volume por fsgroups diferentes não será suportado.
Para desabilitar o carregamento do plugin de armazenamento azureFile pelo gerenciador de controladores e pelo kubelet, defina
a flag InTreePluginAzureFileUnregister como true .
cephfs
Um volume cephfs permite que um volume CephFS existente seja montado no seu Pod. Ao contrário do emptyDir que é apagado
quando um pod é removido, o conteúdo de um volume cephfs é preservado e o volume é simplesmente desmontado. Isto significa
que um volume cephfs pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods. O
volume cephfs pode ser montado por vários gravadores simultaneamente.
Nota: Você deve ter seu próprio servidor Ceph funcionando com o compartilhamento acessível antes de poder utilizá-lo.
cinder (descontinuado)
ESTADO DA FUNCIONALIDADE: Kubernetes v1.18 [deprecated]
O tipo de volume cinder é utilizado para montar o volume do OpenStack Cinder no seu pod.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 72/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-cinder
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-cinder-container
volumeMounts:
- mountPath: /test-cinder
name: test-volume
volumes:
- name: test-volume
# Esse volume OpenStack já deve existir.
cinder:
volumeID: "<volume id>"
fsType: ext4
O recurso CSIMigration para o Cinder é ativado por padrão no Kubernetes 1.21. Ele redireciona todas as operações de plugin do
tipo in-tree para o Driver de Cointainer Storage Interface (CSI) cinder.csi.openstack.org . O Driver CSI OpenStack Cinder tem de
estar instalado no cluster. Você pode desativar a migração Cinder CSI para o seu cluster definindo a feature gate
CSIMigrationOpenStack como false . Se você desativar o recurso CSIMigrationOpenStack , o plugin de volume in-tree do Cinder
assume a responsabilidade por todos os aspectos do gerenciamento de armazenamento de volume do Cinder.
configMap
Um ConfigMap oferece uma forma de injetar dados de configuração em Pods. Os dados armazenados em um ConfigMap podem ser
referenciados em um volume de tipo configMap e depois consumidos por aplicações conteinerizadas executadas em um pod.
Ao referenciar um ConfigMap, você informa o nome do ConfigMap no volume. Pode personalizar o caminho utilizado para uma
entrada específica no ConfigMap. A seguinte configuração mostra como montar o log-config do ConfigMap em um Pod chamado
configmap-pod :
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: test
image: busybox:1.28
command: ['sh', '-c', 'echo "The app is running!" && tail -f /dev/null']
volumeMounts:
- name: config-vol
mountPath: /etc/config
volumes:
- name: config-vol
configMap:
name: log-config
items:
- key: log_level
path: log_level
O ConfigMap log-config é montado como um volume e todos os conteúdos armazenados em sua entrada log_level são
montados no Pod através do caminho /etc/config/log_level . Observe que esse caminho é derivado do volume mountPath e do
path configurado com log_level .
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 73/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota:
É preciso criar um ConfigMap antes de usá-lo.
Um contêiner que utiliza ConfigMap através de um ponto de montagem com a propriedade subPath não receberá
atualizações deste ConfigMap.
Os dados de texto são expostos como arquivos utilizando a codificação de caracteres UTF-8. Para outras codificações de
caracteres, use binaryData .
downwardAPI
Um volume downwardAPI disponibiliza dados da downward API para as aplicações. Ele monta um diretório e grava os dados
solicitados em arquivos de texto sem formatação.
Nota: Um contêiner que utiliza downward API através de um ponto de montagem com a propriedade subPath não receberá
atualizações desta downward API.
emptyDir
Um volume emptyDir é criado pela primeira vez quando um Pod é atribuído a um nó e existe enquanto esse Pod estiver sendo
executado nesse nó. Como o nome diz, o volume emptyDir está inicialmente vazio. Todos os contêineres no Pod podem ler e
gravar os mesmos arquivos no volume emptyDir , embora esse volume possa ser montado no mesmo caminho ou em caminhos
diferentes em cada contêiner. Quando um Pod é removido de um nó por qualquer motivo, os dados no emptyDir são eliminados
permanentemente.
Nota: A falha de um contêiner não remove um Pod de um nó. Os dados em um volume emptyDir são mantidos em caso de
falha do contêiner.
Dependendo do seu ambiente, os volumes emptyDir são armazenados em qualquer mídia que componha o nó, como disco ou
SSD, ou armazenamento de rede. No entanto, se você definir o campo emptyDir.medium como "Memory" , o Kubernetes monta um
tmpfs (sistema de arquivos com suporte de RAM) para você. Embora o tmpfs seja muito rápido, tenha em atenção que, ao contrário
dos discos, o tmpfs é limpo na reinicialização do nó e quaisquer arquivos que grave consomem o limite de memória do seu
contêiner.
Nota: Se a feature gate SizeMemoryBackedVolumes estiver habilitada, é possível especificar um tamanho para volumes mantidos
em memória. Se nenhum tamanho for especificado, os volumes mantidos em memória são dimensionados para 50% da
memória em um host Linux.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 74/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
sizeLimit: 500Mi
fc (fibre channel)
Um tipo de volume fc permite que um volume de armazenamento de fibre channel existente seja montado em um Pod. Você
pode especificar um ou vários WWNs usando o parâmetro targetWWNs em sua configuração de volume. Se forem especificados
vários WWNs, o targetWWNs espera que esses WWNs sejam de conexões multipath.
Nota: Para que os hosts Kubernetes possam acessá-los, é necessário configurar o zoneamento FC SAN para alocar e mascarar
essas LUNs (volumes) para os WWNs de destino.
flocker (descontinuado)
Flocker é um gerenciador de volumes de dados de contêineres em cluster de código aberto. O Flocker oferece gerenciamento e
orquestração de volumes de dados suportados por uma variedade de backends de armazenamento.
Um volume flocker permite que um conjunto de dados Flocker seja montado em um Pod. Se o conjunto de dados ainda não
existir no Flocker, ele precisará ser criado primeiro com o CLI do Flocker ou usando a API do Flocker. Se o conjunto de dados já
existir, ele será anexado pelo Flocker ao nó que o pod está escalonado. Isto significa que os dados podem ser compartilhados entre
os Pods, conforme necessário.
Nota: Antes de poder utilizá-lo, é necessário ter a sua própria instalação do Flocker em execução.
gcePersistentDisk (descontinuado)
ESTADO DA FUNCIONALIDADE: Kubernetes v1.17 [deprecated]
Um volume gcePersistentDisk monta um disco persistente (PD) do Google Compute Engine (GCE) no seu Pod. Ao contrário do
emptyDir que é apagado quando um pod é removido, o conteúdo de um PD é preservado e o volume é simplesmente
desmontado. Isto significa que um PD pode ser previamente populado com dados e que os dados podem ser compartilhados entre
os Pods.
Nota: Você dever criar um PD utilizando gcloud, ou via GCE API ou via UI antes de poder utilizá-lo.
Os nós nos quais os Pods estão sendo executados devem ser VMs GCE
Essas VMs precisam estar no mesmo projeto e zona GCE que o disco persistente
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 75/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Uma característica do disco persistente GCE é o acesso simultâneo somente leitura a um disco persistente. Um volume
gcePersistentDisk permite que vários consumidores montem simultaneamente um disco persistente como somente leitura. Isto
significa que é possível alimentar previamente um PD com o seu conjunto de dados e, em seguida, disponibilizá-lo em paralelo a
quantos Pods necessitar. Infelizmente, os PDs só podem ser montados por um único consumidor no modo de leitura e escrita. Não
são permitidos gravadores simultâneos.
O uso de um disco persistente GCE com um Pod controlado por um ReplicaSet falhará, a menos que o PD seja somente leitura ou a
contagem de réplica seja 0 ou 1.
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
# Esse Disco Persistente (PD) GCE já deve existir.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 76/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-volume
spec:
capacity:
storage: 400Gi
accessModes:
- ReadWriteOnce
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
# failure-domain.beta.kubernetes.io/zone deve ser usado para versões anteriores à 1.21
- key: topology.kubernetes.io/zone
operator: In
values:
- us-central1-a
- us-central1-b
Quando o recurso CSIMigration para o GCE PD é habilitado, todas as operações de plugin do plugin in-tree existente são
redirecionadas para o Driver de Cointainer Storage Interface (CSI) pd.csi.storage.gke.io . Para utilizar este recurso, o Driver CSI
GCE PD deve ser instalado no cluster e os recursos beta CSIMigration e CSIMigrationGCE devem estar habilitados.
Para desabilitar o carregamento do plugin de armazenamento gcePersistentDisk pelo gerenciador de controladores e pelo
kubelet, defina a flag InTreePluginGCEUnregister como true .
gitRepo (descontinuado)
Aviso: O tipo de volume gitRepo foi descontinuado. Para provisionar um contêiner com um repositório git , monte um EmptyDir
em um InitContainer que clone o repositório usando git, depois monte o EmptyDir no contêiner do Pod.
Um volume gitRepo é um exemplo de um plugin de volume. Este plugin monta um diretório vazio e clona um repositório git neste
diretório para que seu Pod utilize.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 77/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: server
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /mypath
name: git-volume
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
glusterfs (removido)
O Kubernetes 1.27 não inclui um tipo de volume glusterfs .
O driver de armazenamento in-tree GlusterFS foi descontinuado na versão v1.25 do Kubernetes e, em seguida, removido totalmente
na versão v1.26.
hostPath
Aviso:
Os volumes HostPath apresentam muitos riscos de segurança e é uma prática recomendada evitar o uso de HostPaths quando
possível. Quando um volume HostPath precisa ser usado, ele deve ser definido com escopo apenas para o arquivo ou diretório
necessário e montado como ReadOnly.
Se você restringir o acesso do HostPath a diretórios específicos através da AdmissionPolicy, a propriedade volumeMounts DEVE
obrigatoriamente usar pontos de montagem readOnly para que a política seja eficaz.
Um volume hostPath monta um arquivo ou diretório do sistema de arquivos do nó do host em seu Pod. Isto não é algo de que a
maioria dos Pods irá precisar, mas oferece uma poderosa alternativa de escape para algumas aplicações.
Executar um contêiner que necessita de acesso aos documentos internos do Docker; utilizar um hostPath apontando para
/var/lib/docker
Permitir que um Pod especifique se um dado hostPath deve existir antes de o Pod ser executado, se deve ser criado e como
deve existir
Além da propriedade obrigatória path , você pode opcionalmente definir um type para um volume hostPath .
Valor Comportamento
A string vazia (padrão) é para compatibilidade com versões anteriores, o que significa que nenhuma
verificação será executada antes de montar o volume hostPath.
DirectoryOrCreate Se nada existir no caminho indicado, um diretório vazio será criado lá, conforme necessário, com
permissão definida para 0755, tendo o mesmo grupo e propriedade com a Kubelet.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 78/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Valor Comportamento
FileOrCreate Se não houver nada no caminho indicado, um arquivo vazio será criado lá, conforme necessário, com
permissão definida para 0644, tendo o mesmo grupo e propriedade com Kubelet.
Os HostPaths podem expor as credenciais privilegiadas do sistema (como para o Kubelet) ou APIs privilegiadas (como o
container runtime socket), que podem ser usadas para o explorar vulnerabilidades de escape do contêiner ou para atacar
outras partes do cluster.
Os Pods com configuração idêntica (como criado a partir de um PodTemplate) podem se comportar de forma diferente em nós
diferentes devido a arquivos diferentes nos nós
Os arquivos ou diretórios criados nos hosts subjacentes são graváveis apenas pelo root. Você precisa executar seu processo
como root em um contêiner privilegiado ou modificar as permissões de arquivo no host para poder gravar em um volume
hostPath
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# localização do diretório no host
path: /data
# este campo é opcional
type: Directory
Cuidado: O modo FileOrCreate não cria o diretório onde ficará arquivo. Se o caminho de diretório do arquivo montado não
existir, o pod não será iniciado. Para garantir que esse modo funcione, você pode tentar montar diretórios e arquivos
separadamente, como mostrado em configuração FileOrCreate.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 79/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
containers:
- name: test-webserver
image: registry.k8s.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# Certifique-se de que o diretório foi criado.
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
iscsi
Um volume iscsi permite que um volume iSCSI (SCSI sobre IP) existente seja montado no seu Pod. Ao contrário do emptyDir que
é apagado quando um Pod é removido, o conteúdo de um volume iscsi é preservado e o volume é simplesmente desmontado.
Isto significa que um volume iscsi pode ser previamente populado com dados e que os dados podem ser compartilhados entre os
Pods.
Nota: Você deve ter seu próprio servidor iSCSI rodando com o volume criado antes de poder utilizá-lo.
Uma característica do iSCSI é que ele pode ser montado como somente leitura por vários consumidores simultaneamente. Isto
significa que um volume pode ser previamente populado com seu conjunto de dados e, em seguida, ser disponibilizado em paralelo
para tantos Pods quanto necessitar. Infelizmente, os volumes iSCSI só podem ser montados por um único consumidor no modo de
leitura-escrita. Não são permitidos gravadores simultâneos.
local
Um volume local representa um dispositivo de armazenamento local montado, como um disco, partição ou diretório.
Os volumes locais só podem ser usados como um PersistentVolume criado estaticamente. O provisionamento dinâmico não é
suportado.
Em comparação com volumes hostPath , os volumes local são usados de forma durável e portátil, sem escalonamento manual
dos Pods para os nós. O sistema está ciente das restrições de nós do volume, observando a afinidade do nó com o
PersistentVolume.
No entanto, os volumes local estão sujeitos à disponibilidade do nó que o comporta e não são adequados para todas as
aplicações. Se um nó não está íntegro, então o volume local torna-se inacessível pelo pod. O pod que utiliza este volume não
consegue ser executado. Os aplicativos que usam volumes local devem ser capazes de tolerar essa disponibilidade reduzida, bem
como uma possível perda de dados, dependendo das caraterísticas de durabilidade do disco subjacente.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 80/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: PersistentVolume
metadata:
name: example-pv
spec:
capacity:
storage: 100Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: local-storage
local:
path: /mnt/disks/ssd1
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- example-node
É preciso definir a propriedade nodeAffinity do PersistentVolume ao utilizar volumes local . O escalonador do Kubernetes usa o
PersistentVolume nodeAffinity para escalonar esses pods para o nó correto.
A propriedade volumeMode do PersistentVolume pode ser definida como "Block" (ao invés do valor padrão "Filesystem") para expor
o volume local como um dispositivo de bloco bruto.
Ao usar volumes locais, é recomendável criar uma StorageClass com a propriedade volumeBindingMode definida como
WaitForFirstConsumer . Para obter mais detalhes, consulte o exemplo local StorageClass. A postergação da vinculação do volume
garante que a decisão de vinculação da PersistentVolumeClaim também será avaliada com quaisquer outras restrições de nós que o
Pod possa ter, tais como requisitos de recursos de nós, seletores de nós, afinidade do Pod e anti afinidade do Pod.
Um provisionador estático externo pode ser executado separadamente para uma melhor gestão do ciclo de vida do volume local.
Observe que este provisionador ainda não suporta o provisionamento dinâmico. Para um exemplo sobre como executar um
provisionador local externo, veja o manual do usuário do provisionador local do volume.
Nota: O PersistentVolume local exige que o usuário faça limpeza e remoção manual se o provisionador estático externo não for
utilizado para gerenciar o ciclo de vida do volume.
nfs
Um volume nfs permite que um compartilhamento NFS (Network File System) existente seja montado em um Pod. Ao contrário do
emptyDir que é apagado quando um Pod é removido, o conteúdo de um volume nfs é preservado e o volume é simplesmente
desmontado. Isto significa que um volume NFS pode ser previamente populado com dados e que os dados podem ser
compartilhados entre os Pods. O NFS pode ser montado por vários gravadores simultaneamente.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 81/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: true
Nota:
Você deve ter seu próprio servidor NFS rodando com o compartilhamento acessível antes de poder utilizá-lo.
Note também que você não pode especificar opções de montagem NFS em uma especificação de pod. Você pode definir as
opções de montagem do lado do servidor ou usar /etc/nfsmount.conf. Você também pode montar volumes NFS por meio de
PersistentVolumes, que permitem definir opções de montagem.
persistentVolumeClaim
Um volume persistentVolumeClaim é usado para montar um PersistentVolume em um Pod. PersistentVolumeClaims são uma
forma de os usuários "solicitarem" armazenamento durável (como um GCE PersistentDisk ou um volume iSCSI) sem conhecerem os
detalhes do ambiente de nuvem em particular.
portworxVolume (descontinuado)
Um portworxVolume é uma camada de armazenamento em bloco extensível que funciona hiperconvergente com Kubernetes. O
Portworx tira as impressões digitais de um armazenamento em um servidor, organiza com base nas capacidades e agrega
capacidade em múltiplos servidores. Portworx funciona em máquinas virtuais ou em nós Linux bare-metal.
Um portworxVolume pode ser criado dinamicamente através do Kubernetes ou também pode ser previamente provisionado e
referenciado dentro de um Pod. Aqui está um exemplo de um Pod referenciando um volume Portworx pré-provisionado:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 82/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-portworx-volume-pod
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /mnt
name: pxvol
volumes:
- name: pxvol
# Este volume Portworx já deve existir.
portworxVolume:
volumeID: "pxvol"
fsType: "<fs-type>"
Nota: Certifique-se de ter um PortworxVolume com o nome pxvol antes de usá-lo no Pod.
projetado
Um volume projetado mapeia várias fontes de volume existentes dentro do mesmo diretório. Para obter mais detalhes, consulte
Volumes projetados.
quobyte (descontinuado)
Um Volume quobyte permite que um volume Quobyte existente seja montado no seu Pod.
Nota: Você deve ter seu próprio Quobyte configurado e funcionando com os volumes criados antes de poder utilizá-lo.
Quobyte oferece suporte para o Container Storage Interface. CSI é o plugin recomendado para usar volumes Quobyte dentro de
Kubernetes. O projeto GitHub da Quobyte tem instruções para implantar o Quobyte usando o CSI, acompanhado de exemplos.
rbd
Um volume rbd permite que um volume Rados Block Device (RBD) seja montado em seu Pod. Ao contrário do emptyDir que é
apagado quando um pod é removido, o conteúdo de um volume rbd é preservado e o volume é desmontado. Isto significa que um
volume RBD pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
Nota: Você deve ter uma instalação Ceph em funcionamento antes de poder usar o RBD.
Uma caraterística do RBD é que ele pode ser montado como somente leitura por vários consumidores simultaneamente. Isto
significa que um volume pode ser previamente populado com seu conjunto de dados e, em seguida, ser disponibilizado em paralelo
para tantos pods quanto necessitar. Infelizmente, os volumes RBD só podem ser montados por um único consumidor no modo de
leitura-escrita. Não são permitidos gravadores simultâneos.
Quando o recurso do RBD está ativado, redireciona todas as operações do plugin in-tree existente para o driver CSI
CSIMigration
rbd.csi.ceph.com . Para utilizar este recurso, o driver Ceph CSI deve estar instalado no cluster e as feature gates CSIMigration e
csiMigrationRBD devem estar habilitadas.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 83/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota:
Como operador do cluster Kubernetes que administra o armazenamento, aqui estão os pré-requisitos que você deve atender
antes de tentar a migração para o driver CSI RBD:
Você deve instalar o driver Ceph CSI ( rbd.csi.ceph.com ), v3.5.0 ou superior, no cluster Kubernetes.
Considerando que o campo clusterID é um parâmetro necessário para o driver CSI e sua operação , mas o campo in-tree
StorageClass tem o parâmetro obrigatório monitors , um administrador de armazenamento Kubernetes precisa criar um
clusterID baseado no hash dos monitores (ex.: #echo -n '<monitors_string>' | md5sum ) no mapa de configuração do CSI
e manter os monitores sob esta configuração de clusterID.
Além disso, se o valor de adminId no Storageclass in-tree for diferente de admin , o adminSecretName mencionado no
Storageclass in-tree tem que ser corrigido com o valor base64 do valor do parâmetro adminId , caso contrário esta etapa
pode ser ignorada.
secret
Um volume secret é usado para passar informações sensíveis, tais como senhas, para Pods. Você pode armazenar segredos na
API Kubernetes e montá-los como arquivos para serem usados por pods sem necessidade de vinculação direta ao Kubernetes.
Volumes secret são mantidos pelo tmpfs (um sistema de arquivos com baseado em memória RAM) para que nunca sejam
gravados em armazenamento não volátil.
Nota:
Você deve criar um Secret na API Kubernetes antes de poder utilizá-lo.
Um secret é sempre montado como readOnly .
Um contêiner que utiliza um Secret como ponto de montagem para a propriedade subPath não receberá atualizações
deste Secret.
storageOS (descontinuado)
Um volume storageos permite que um volume StorageOS existente seja montado em seu Pod.
O StorageOS funciona como um contêiner dentro de seu ambiente Kubernetes, tornando o armazenamento local ou anexado
acessível a partir de qualquer nó dentro do cluster Kubernetes. Os dados podem ser replicados para a proteção contra falhas do nó.
O provisionamento e a compressão podem melhorar a utilização e reduzir os custos.
Em sua essência, o StorageOS fornece armazenamento em bloco para containers, acessível a partir de um sistema de arquivo.
O Conteiner StorageOS requer Linux de 64 bits e não possui dependências adicionais. Uma licença para desenvolvedores está
disponível gratuitamente.
Cuidado: Você deve executar o container StorageOS em cada nó que deseja acessar os volumes do StorageOS ou que
contribuirá com a capacidade de armazenamento para o pool. Para obter instruções de instalação, consulte a documentação do
StorageOS.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 84/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
labels:
name: redis
role: master
name: test-storageos-redis
spec:
containers:
- name: master
image: kubernetes/redis:v1
env:
- name: MASTER
value: "true"
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /redis-master-data
name: redis-data
volumes:
- name: redis-data
storageos:
# O volume `redis-vol01` já deve existir dentro do StorageOS no namespace `default`.
volumeName: redis-vol01
fsType: ext4
Para obter mais informações sobre StorageOS, provisionamento dinâmico e PersistentVolumeClaims, consulte os exemplos do
StorageOS.
vsphereVolume (descontinuado)
Um vsphereVolume é usado para montar um volume VMDK do vSphere em seu Pod. O conteúdo de um volume é preservado
quando é desmontado. Ele suporta sistemas de armazenamento de dados tanto do tipo VMFS quanto do tipo VSAN.
Primeiro acesse o ESX via ssh, depois use o seguinte comando para criar um VMDK:
vmkfstools -c 2G /vmfs/volumes/DatastoreName/volumes/myDisk.vmdk
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 85/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-vmdk
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-vmdk
name: test-volume
volumes:
- name: test-volume
# This VMDK volume must already exist.
vsphereVolume:
volumePath: "[DatastoreName] volumes/myDisk"
fsType: ext4
No Kubernetes 1.27, todas as operações para o tipo vsphereVolume in-tree são redirecionadas para o driver CSI
csi.vsphere.vmware.com .
O driver vSphere CSI deve ser instalado no cluster. Você pode encontrar conteúdos adicionais sobre como migrar o vsphereVolume
in-tree na página de documentação do VMware Migrating In-Tree vSphere Volumes to vSphere Container Storage plug-in. Se o
vSphere CSI Driver não estiver instalado, as operações de volume não poderão ser executadas no PV criado com o tipo
vsphereVolume in-tree.
Você deve executar o vSphere 7.0u2 ou posterior para migrar para o driver vSphere CSI.
Se você estiver executando uma versão do Kubernetes diferente da v1.27, consulte a documentação dessa versão do Kubernetes.
Nota:
Os seguintes parâmetros da StorageClass do plugin integrado vsphereVolume não são suportados pelo driver CSI do vSphere:
diskformat
hostfailurestotolerate
forceprovisioning
cachereservation
diskstripes
objectspacereservation
iopslimit
Os volumes existentes criados usando esses parâmetros serão migrados para o driver CSI do vSphere, mas novos volumes
criados pelo driver de CSI do vSphere não estarão respeitando esses parâmetros.
Para desativar o carregamento do plugin de armazenamento vsphereVolume pelo gerenciador de controladores e pelo kubelet,
defina a flag InTreePluginvSphereUnregister como true . Você precisa instalar o driver csi.vsphere.vmware.com CSI em todos os
nós de processamento.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 86/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O recurso CSIMigration para Portworx foi adicionado, mas desativado por padrão no Kubernetes 1.23 visto que está no estado
alfa. Ele redireciona todas as operações de plugin do tipo in-tree para o Driver de Cointainer Storage Interface (CSI)
pxd.portworx.com . O driver CSI Portworx deve ser instalado no cluster. Para ativar o recurso, defina CSIMigrationPortworx=true
no kube-controller-manager e no kubelet.
Utilizando subPath
Às vezes, é útil compartilhar um volume para múltiplos usos em um único pod. A propriedade volumeMounts[*].subPath especifica
um sub caminho dentro do volume referenciado em vez de sua raiz.
O exemplo a seguir mostra como configurar um Pod com um ambiente LAMP (Linux, Apache, MySQL e PHP) usando um único
volume compartilhado. Esta exemplo de configuração subPath não é recomendada para uso em produção.
O código e os ativos da aplicação PHP mapeiam para a pasta do volume html e o banco de dados MySQL é armazenado na pasta
do volume mysql . Por exemplo:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
Use o campo subPathExpr para construir nomes de diretório subPath a partir de variáveis de ambiente da downward API. As
propriedades subPath e subPathExpr são mutuamente exclusivas.
Neste exemplo, um Pod usa subPathExpr para criar um diretório pod1 dentro do volume hostPath /var/log/pods . O volume
hostPath recebe o nome Pod do downwardAPI . O diretório /var/log/pods/pod1 do host é montado em /logs no contêiner.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 87/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox:1.28
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
# A expansão de variáveis usa parênteses (não chaves).
subPathExpr: $(POD_NAME)
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
Recursos
A mídia de armazenamento(como Disco ou SSD) de um volume emptyDir é determinada por meio do sistema de arquivos que
mantém o diretório raiz do kubelet (normalmente /var/lib/kubelet ). Não há limite para quanto espaço um volume emptyDir ou
hostPath podem consumir, e não há isolamento entre contêineres ou entre pods.
Para saber mais sobre como solicitar espaço usando uma especificação de recursos, consulte como gerenciar recursos.
Anteriormente, todos os plugins de volume eram "in-tree". Os plugins "in-tree" eram construídos, vinculados, compilados e
distribuídos com o código principal dos binários do Kubernetes. Isto significava que a adição de um novo sistema de
armazenamento ao Kubernetes (um plugin de volume) exigia uma validação do código no repositório central de código Kubernetes.
Tanto o CSI quanto o FlexVolume permitem que os plugins de volume sejam desenvolvidos independentemente da base de código
Kubernetes e implantados (instalados) nos clusters Kubernetes como extensões.
Para fornecedores de armazenamento que procuram criar um plugin de volume out-of-tree, consulte as Perguntas mais frequentes
sobre plugins de volume.
csi
O Cointainer Storage Interface (CSI) define uma interface padrão para sistemas de orquestração de contêineres (como Kubernetes)
para expor sistemas de armazenamento arbitrários a suas cargas de trabalho de contêiner.
Nota: O suporte para as versões 0.2 e 0.3 da especificação CSI foi descontinuado no Kubernetes v1.13 e será removido em uma
versão futura.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 88/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Os controladores CSI podem não ser compatíveis em todas as versões do Kubernetes. Consulte a documentação
específica do driver CSI para ver as etapas de implantação suportadas para cada versão do Kubernetes e uma matriz de
compatibilidade.
Uma vez que um driver de volume compatível com CSI seja implantado em um cluster Kubernetes, os usuários podem usar o tipo
de volume csi para anexar ou montar os volumes expostos pelo driver CSI.
Os seguintes campos estão disponíveis para administradores de armazenamento configurarem um volume persistente de CSI:
driver : Um valor do tipo string que especifica o nome do driver de volume a ser usado. Este valor deve corresponder ao valor
retornado no GetPluginInfoResponse pelo driver CSI, conforme definido na especificação CSI. Ele é usado pelo Kubernetes
para identificar qual driver CSI chamar, e pelos componentes do driver CSI para identificar quais objetos PV pertencem ao
driver CSI.
volumeHandle : Um valor do tipo string que identifica exclusivamente o volume. Este valor deve corresponder ao valor
retornado no campo volume.id em CreateVolumeResponse pelo driver CSI, conforme definido na especificação CSI. O valor é
passado como volume_id em todas as chamadas para o driver de volume CSI quando se faz referência ao volume.
readOnly : Um valor booleano opcional que indica se o volume deve ser "ControllerPublished" (anexado) como somente
leitura. O valor padrão é false. Este valor é passado para o driver CSI através do campo readonly em
ControllerPublishVolumeRequest .
fsType : Se o VolumeMode do PV for Filesystem então este campo pode ser usado para especificar o sistema de arquivos que
deve ser usado para montar o volume. Se o volume não tiver sido formatado e a formatação for suportada, este valor será
utilizado para formatar o volume. Este valor é passado para o driver CSI através do campo VolumeCapability nas
propriedades ControllerPublishVolumeRequest , NodeStageVolumeRequest e NodePublishVolumeRequest .
volumeAttributes : Um mapa de valores do tipo string para string que especifica propriedades estáticas de um volume. Este
mapa deve corresponder ao mapa retornado no campo volume.attributes do CreateVolumeResponse pelo driver CSI,
conforme definido na especificação CSI. O mapa é passado para o driver CSI através do campo volume_context nas
propriedades ControllerPublishVolumeRequest , NodeStageVolumeRequest , e NodePublishVolumeRequest .
controllerPublishSecretRef : Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver
CSI para completar as chamadas CSI ControllerPublishVolume e ControllerUnpublishVolume . Este campo é opcional e pode
estar vazio se não for necessário nenhum segredo. Se o Secret contiver mais de um segredo, todos os segredos serão
passados.
nodeStageSecretRef : Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver de CSI
para completar a chamada de CSI do NodeStageVolume . Este campo é opcional e pode estar vazio se não for necessário
nenhum segredo. Se o Secret contiver mais de um segredo, todos os segredos serão passados.
nodePublishSecretRef : Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver de CSI
para completar a chamada de CSI do NodePublishVolume . Este campo é opcional e pode estar vazio se não for necessário
nenhum segredo. Se o objeto Secret contiver mais de um segredo, todos os segredos serão passados.
Os fornecedores com drivers CSI externos podem implementar o suporte de volume de blocos brutos nas cargas de trabalho
Kubernetes.
Você pode configurar o PersistentVolume/PersistentVolumeClaim com suporte de volume de bloco bruto , como habitualmente,
sem quaisquer alterações específicas de CSI.
É possível configurar diretamente volumes CSI dentro da especificação do Pod. Os volumes especificados desta forma são efêmeros
e não persistem nas reinicializações do pod. Consulte Volumes efêmeros para obter mais informações.
Para obter mais informações sobre como desenvolver um driver CSI, consulte a documentação kubernetes-csi
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 89/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Quando o recurso CSIMigration está habilitado, direciona operações relacionadas a plugins in-tree existentes para plugins CSI
correspondentes (que devem ser instalados e configurados). Como resultado, os operadores não precisam fazer nenhuma alteração
de configuração para Storage Classes, PersistentVolumes ou PersistentVolumeClaims existentes (referindo-se aos plugins in-tree)
quando a transição para um driver CSI que substitui um plugin in-tree.
Plugins in-tree que suportam CSIMigration e têm um driver CSI correspondente implementado são listados em tipos de volumes.
Os seguintes plug-ins in-tree suportam armazenamento persistente em nós do Windows:
awsElasticBlockStore
azureDisk
azureFile
gcePersistentDisk
vsphereVolume
flexVolume (descontinuado)
ESTADO DA FUNCIONALIDADE: Kubernetes v1.23 [deprecated]
O FlexVolume é uma interface de plugin out-of-tree que usa um modelo baseado em execução para fazer interface com drivers de
armazenamento. Os binários do driver FlexVolume devem ser instalados em um caminho de plugin de volume predefinido em cada
nó e, em alguns casos, também nos nós da camada de gerenciamento.
Os Pods interagem com os drivers do FlexVolume através do plugin de volume in-tree flexVolume . Para obter mais detalhes,
consulte o documento README do FlexVolume.
Nota:
O FlexVolume foi descontinuado. Usar um driver CSI out-of-tree é a maneira recomendada de integrar o armazenamento
externo com Kubernetes.
Os mantenedores do driver FlexVolume devem implementar um driver CSI e ajudar a migrar usuários de drivers FlexVolume
para CSI. Os usuários do FlexVolume devem mover suas cargas de trabalho para usar o driver CSI equivalente.
Propagação de montagem
A propagação de montagem permite compartilhar volumes montados por um contêiner para outros contêineres no mesmo pod, ou
mesmo para outros pods no mesmo nó.
None - Este volume de montagem não receberá do host nenhuma montagem posterior que seja montada para este volume
ou qualquer um de seus subdiretórios. De forma semelhante, nenhum ponto de montagem criado pelo contêiner será visível
no host. Este é o modo padrão.
Este modo é igual à propagação de montagem private conforme descrito na documentação do kernel Linux
HostToContainer- Este volume de montagem receberá todas as montagens posteriores que forem montadas para este
volume ou qualquer um de seus subdiretórios.
Em outras palavras, se o host montar qualquer coisa dentro do volume de montagem, o container o visualizará montado ali.
Da mesma forma, se qualquer Pod com propagação de montagem Bidirectional para o mesmo volume montar qualquer
coisa lá, o contêiner com propagação de montagem HostToContainer o reconhecerá.
Este modo é igual à propagação de montagem rslave conforme descrito na documentação do kernel Linux
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 90/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Bidirectional - Esta montagem de volume se comporta da mesma forma que a montagem de volume HostToContainer .
Além disso, todas as montagens de volume criadas pelo contêiner serão propagadas de volta ao host e a todos os contêineres
de todas os pods que utilizam o mesmo volume.
Um caso de uso típico para este modo é um Pod com um driver FlexVolume ou CSI ou um Pod que precisa montar algo no host
utilizando um volume hostPath .
Este modo é igual à propagação de montagem rshared conforme descrito na documentação do kernel Linux
Aviso: A propagação de montagem Bidirectional pode ser perigosa. Ela pode danificar o sistema operacional do host e,
portanto, ela só é permitida em contêineres privilegiados. A familiaridade com o comportamento do kernel Linux é
fortemente recomendada. Além disso, quaisquer montagens de volume criadas por contêineres em pods devem ser
destruídas ( desmontadas) pelos contêineres ao final.
Configuração
Antes que a propagação da montagem possa funcionar corretamente em algumas distribuições (CoreOS, RedHat/Centos, Ubuntu), o
compartilhamento de montagem deve ser configurado corretamente no Docker como mostrado abaixo.
Edite seu arquivo de serviços systemd do Docker. Configure a propriedade MountFlags da seguinte forma:
MountFlags=shared
Próximos passos
Siga um exemplo de implantação do WordPress e MySQL com volumes persistentes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 91/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Introdução
O gerenciamento de armazenamento é uma questão bem diferente do gerenciamento de instâncias computacionais. O subsistema
PersistentVolume provê uma API para usuários e administradores que mostra de forma detalhada de como o armazenamento é
provido e como ele é consumido. Para isso, nós introduzimos duas novas APIs: PersistentVolume e PersistentVolumeClaim.
Um PersistentVolume (PV) é uma parte do armazenamento dentro do cluster que tenha sido provisionada por um administrador, ou
dinamicamente utilizando Classes de Armazenamento. Isso é um recurso dentro do cluster da mesma forma que um nó também é.
PVs são plugins de volume da mesma forma que Volumes, porém eles têm um ciclo de vida independente de qualquer Pod que
utilize um PV. Essa API tem por objetivo mostrar os detalhes da implementação do armazenamento, seja ele NFS, iSCSI, ou um
armazenamento específico de um provedor de cloud pública.
Uma PersistentVolumeClaim (PVC) é uma requisição para armazenamento por um usuário. É similar a um Pod. Pods utilizam recursos
do nó e PVCs utilizam recursos do PV. Pods podem solicitar níveis específicos de recursos (CPU e Memória). Claims podem solicitar
tamanho e modos de acesso específicos (exemplo: montagem como ReadWriteOnce, ReadOnlyMany ou ReadWriteMany, veja
Modos de Acesso).
Enquanto as PersistentVolumeClaims permitem que um usuário utilize recursos de armazenamento de forma limitada, é comum
que usuários precisem de PersistentVolumes com diversas propriedades, como desempenho, para problemas diversos. Os
administradores de cluster precisam estar aptos a oferecer uma variedade de PersistentVolumes que difiram em tamanho e modo
de acesso, sem expor os usuários a detalhes de como esses volumes são implementados. Para necessidades como essas, temos o
recurso de StorageClass.
Provisionamento
Existem duas formas de provisionar um PV: estaticamente ou dinamicamente.
Estático
O administrador do cluster cria uma determinada quantidade de PVs. Eles possuem todos os detalhes do armazenamento os quais
estão atrelados, que neste caso fica disponível para utilização por um usuário dentro do cluster. Eles estão presentes na API do
Kubernetes e disponíveis para utilização.
Dinâmico
Quando nenhum dos PVs estáticos, que foram criados anteriormente pelo administrador, satisfazem os critérios de uma
PersistentVolumeClaim enviado por um usuário, o cluster pode tentar realizar um provisionamento dinâmico para atender a essa
PVC. Esse provisionamento é baseado em StorageClasses: a PVC deve solicitar uma classe de armazenamento e o administrador
deve ter previamente criado e configurado essa classe para que o provisionamento dinâmico possa ocorrer. Requisições que
solicitam a classe "" efetivamente desabilitam o provisionamento dinâmico para elas mesmas.
Para habilitar o provisionamento de armazenamento dinâmico baseado em classe de armazenamento, o administrador do cluster
precisa habilitar o controle de admissão DefaultStorageClass no servidor da API. Isso pode ser feito, por exemplo, garantindo que
DefaultStorageClass esteja entre aspas simples, ordenado por uma lista de valores para a flag --enable-admission-plugins ,
componente do servidor da API. Para mais informações sobre os comandos das flags do servidor da API, consulte a documentação
kube-apiserver.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 92/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Binding
Um usuário cria, ou em caso de um provisionamento dinâmico já ter criado, uma PersistentVolumeClaim solicitando uma
quantidade específica de armazenamento e um determinado modo de acesso. Um controle de loop no master monitora por novas
PVCs, encontra um PV (se possível) que satisfaça os requisitos e realiza o bind. Se o PV foi provisionado dinamicamente por uma
PVC, o loop sempre vai fazer o bind desse PV com essa PVC em específico. Caso contrário, o usuário vai receber no mínimo o que ele
havia solicitado, porém, o volume possa exceder em relação à solicitação inicial. Uma vez realizado esse processo,
PersistentVolumeClaim sempre vai ter um bind exclusivo, sem levar em conta como o isso aconteceu. Um bind entre uma PVC e um
PV é um mapeamento de um para um, utilizando o ClaimRef que é um bind bidirecional entre o PersistentVolume e o
PersistentVolumeClaim.
As requisições permanecerão sem bind se o volume solicitado não existir. O bind ocorrerá somente se os requisitos forem
atendidos exatamente da mesma forma como solicitado. Por exemplo, um bind de uma PVC de 100 GB não ocorrerá num cluster
que foi provisionado com vários PVs de 50 GB. O bind ocorrerá somente no momento em que um PV de 100 GB for adicionado.
Utilização
Pods utilizam requisições como volumes. O cluster inspeciona a requisição para encontrar o volume atrelado a ela e monta esse
volume para um Pod. Para volumes que suportam múltiplos modos de acesso, o usuário especifica qual o modo desejado quando
utiliza essas requisições.
Uma vez que o usuário tem a requisição atrelada a um PV, ele pertence ao usuário pelo tempo que ele precisar. Usuários agendam
Pods e acessam seus PVs requisitados através da seção persistentVolumeClaim no bloco volumes do Pod. Para mais detalhes
sobre isso, veja Requisições como Volumes.
Nota: Uma PVC está sendo utilizada por um Pod quando existe um Pod que está usando essa PVC.
Se um usuário deleta uma PVC que está sendo utilizada por um Pod, esta PVC não é removida imediatamente. A remoção da PVC é
adiada até que a PVC não esteja mais sendo utilizado por nenhum Pod. Se um administrador deleta um PV que está atrelado a uma
PVC, o PV não é removido imediatamente também. A remoção do PV é adiada até que o PV não esteja mais atrelado à PVC.
Note que uma PVC é protegida quando o status da PVC é Terminating e a lista Finalizers contém kubernetes.io/pvc-
protection :
Note que um PV é protegido quando o status da PVC é Terminating e a lista Finalizers contém kubernetes.io/pv-protection
também:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 93/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Recuperação
Quando um usuário não precisar mais utilizar um volume, ele pode deletar a PVC pela API, que, permite a recuperação do recurso. A
política de recuperação para um PersistentVolume diz ao cluster o que fazer com o volume após ele ter sido liberado da sua
requisição. Atualmente, volumes podem ser Retidos, Reciclados ou Deletados.
Retenção
A política Retain permite a recuperação de forma manual do recurso. Quando a PersistentVolumeClaim é deletada, ela continua
existindo e o volume é considerado "livre". Mas ele ainda não está disponível para outra requisição porque os dados da requisição
anterior ainda permanecem no volume. Um administrador pode manualmente recuperar o volume executando os seguintes
passos:
1. Deletar o PersistentVolume. O armazenamento associado à infraestrutura externa (AWS EBS, GCE PD, Azure Disk ou Cinder
volume) ainda continuará existindo após o PV ser deletado.
2. Limpar os dados de forma manual no armazenamento associado.
3. Deletar manualmente o armazenamento associado. Caso você queira utilizar o mesmo armazenamento, crie um novo
PersistentVolume com esse armazenamento.
Deletar
Para plugins de volume que suportam a política de recuperação Delete , a deleção vai remover o tanto o PersistentVolume do
Kubernetes, quanto o armazenamento associado à infraestrutura externa, como AWS EBS, GCE PD, Azure Disk, ou Cinder volume.
Volumes que foram provisionados dinamicamente herdam a política de retenção da sua StorageClass, que por padrão é Delete . O
administrador precisa configurar a StorageClass de acordo com as necessidades dos usuários. Caso contrário, o PV deve ser editado
ou reparado após sua criação. Veja Alterar a política de retenção de um PersistentVolume.
Reciclar
Aviso: A política de retenção Recycle está depreciada. Ao invés disso, recomendamos a utilização de provisionamento
dinâmico.
Em caso do volume plugin ter suporte a essa operação, a política de retenção Recycle faz uma limpeza básica ( rm -rf
/thevolume/* ) no volume e torna ele disponível novamente para outra requisição.
Contudo, um administrador pode configurar um template personalizado de um Pod reciclador utilizando a linha de comando do
gerenciamento de controle do Kubernetes como descrito em referência. O Pod reciclador personalizado deve conter a spec volume
como é mostrado no exemplo abaixo:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 94/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: pv-recycler
namespace: default
spec:
restartPolicy: Never
volumes:
- name: vol
hostPath:
path: /any/path/it/will/be/replaced
containers:
- name: pv-recycler
image: "registry.k8s.io/busybox"
command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]* /scrub/* && test -z \"$(ls -A /
volumeMounts:
- name: vol
mountPath: /scrub
Contudo, o caminho especificado no Pod reciclador personalizado em volumes é substituído pelo caminho do volume que está
sendo reciclado.
Reservando um PersistentVolume
A camada de gerenciamento pode fazer o bind de um PersistentVolumeClaims com PersistentVolumes equivalentes no cluster.
Contudo, se você quer que uma PVC faça um bind com um PV específico, é preciso fazer o pré-bind deles.
Especificando um PersistentVolume na PersistentVolumeClaim, você declara um bind entre uma PVC e um PV específico. O bind
ocorrerá se o PersistentVolume existir e não estiver reservado por uma PersistentVolumeClaims através do seu campo claimRef .
O bind ocorre independentemente se algum volume atender ao critério, incluindo afinidade de nó. A camada de gerenciamento
verifica se a classe de armazenamento, modo de acesso e tamanho do armazenamento solicitado ainda são válidos.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: foo-pvc
namespace: foo
spec:
storageClassName: "" # Empty string must be explicitly set otherwise default StorageClass will be set
volumeName: foo-pv
...
Esse método não garante nenhum privilégio de bind no PersistentVolume. Para evitar que alguma outra PersistentVolumeClaims
possa usar o PV que você especificar, você precisa primeiro reservar esse volume de armazenamento. Especifique sua
PersistentVolumeClaim no campo claimRef do PV para que outras PVCs não façam bind nele.
apiVersion: v1
kind: PersistentVolume
metadata:
name: foo-pv
spec:
storageClassName: ""
claimRef:
name: foo-pvc
namespace: foo
...
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 95/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Isso é útil se você deseja utilizar PersistentVolumes que possuem suas persistentVolumeReclaimPolicy configuradas para Retain ,
incluindo situações onde você estiver reutilizando um PV existente.
Agora, o suporte à expansão de PersistentVolumeClaims (PVCs) já é habilitado por padrão. Você pode expandir os tipos de volumes
abaixo:
gcePersistentDisk
awsElasticBlockStore
Cinder
glusterfs
rbd
Azure File
Azure Disk
Portworx
FlexVolumes
CSI
Você só pode expandir uma PVC se o campo da classe de armazenamento allowVolumeExpansion é true .
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gluster-vol-default
provisioner: kubernetes.io/glusterfs
parameters:
resturl: "http://192.168.10.100:8080"
restusuário: ""
secretNamespace: ""
secretName: ""
allowVolumeExpansion: true
Para solicitar um volume maior para uma PVC, edite a PVC e especifique um tamanho maior. Isso irá fazer com o que volume
atrelado ao respectivo PersistentVolume seja expandido. Nunca um PersistentVolume é criado para satisfazer a requisição. Ao invés
disso, um volume existente é redimensionado.
O suporte à expansão de volumes CSI é habilitada por padrão, porém é necessário um driver CSI específico para suportar a
expansão do volume. Verifique a documentação do driver CSI específico para mais informações.
Quando um volume contém um sistema de arquivo, o sistema de arquivo somente é redimensionado quando um novo Pod está
utilizando a PersistentVolumeClaim no modo ReadWrite . A expansão de sistema de arquivo é feita quando um Pod estiver
inicializando ou quando um Pod estiver em execução e o respectivo sistema de arquivo tenha suporte para expansão a quente.
FlexVolumes permitem redimensionamento se o RequiresFSResize do drive é configurado como true . O FlexVolume pode ser
redimensionado na reinicialização do Pod.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 96/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: A Expansão de PVCs em uso está disponível como beta desde o Kubernetes 1.15, e como alpha desde a versão 1.11. A
funcionalidade ExpandInUsePersistentVolumes precisa ser habilitada, o que já está automático para vários clusters que
possuem funcionalidades beta. Verifique a documentação feature gate para mais informações.
Neste caso, você não precisa deletar e recriar um Pod ou um deployment que está sendo utilizado por uma PVC existente.
Automaticamente, qualquer PVC em uso fica disponível para o Pod assim que o sistema de arquivo for expandido. Essa
funcionalidade não tem efeito em PVCs que não estão em uso por um Pod ou deployment. Você deve criar um Pod que utilize a PVC
antes que a expansão seja completada.
Da mesma forma que outros tipos de volumes - volumes FlexVolume também podem ser expandidos quando estiverem em uso por
um Pod.
Nota: Redimensionamento de FlexVolume somente é possível quando o respectivo driver suportar essa operação.
Nota: Expandir volumes do tipo EBS é uma operação que toma muito tempo. Além disso, só é possível fazer uma modificação
por volume a cada 6 horas.
1. Marque o PersistentVolume(PV) que estiver atrelado à PersistentVolumeClaim(PVC) com a política de recuperação Retain .
2. Delete a PVC. Desde que o PV tenha a política de recuperação Retain - nenhum dado será perdido quando a PVC for recriada.
3. Delete a entrada claimRef da especificação do PV para que uma PVC possa fazer bind com ele. Isso deve tornar o PV
Available .
4. Recrie a PVC com um tamanho menor que o PV e configure o campo volumeName da PCV com o nome do PV. Isso deve fazer o
bind de uma nova PVC a um PV existente.
5. Não esqueça de restaurar a política de recuperação do PV.
flexVolume - FlexVolume
hostPath - HostPath volume (somente para teste de nó único; ISSO NÃO FUNCIONARÁ num cluster multi-nós; ao invés disso,
considere a utilização de volume local .)
iscsi - iSCSI (SCSI over IP) storage
photonPersistentDisk - Controlador Photon para disco persistente. (Esse tipo de volume não funciona mais desde a
removação do provedor de cloud correspondente.)
portworxVolume - Volume Portworx
Volumes Persistentes
Cada PV contém uma spec e um status, que é a especificação e o status do volume. O nome do PersistentVolume deve ser um DNS
válido.
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs:
path: /tmp
server: 172.17.0.2
Nota: Talvez sejam necessários programas auxiliares para um determinado tipo de volume utilizar um PersistentVolume no
cluster. Neste exemplo, o PersistentVolume é do tipo NFS e o programa auxiliar /sbin/mount.nfs é necessário para suportar a
montagem dos sistemas de arquivos NFS.
Capacidade
Geralmente, um PV terá uma capacidade de armazenamento específica. Isso é configurado usando o atributo capacity do PV. Veja
o Modelo de Recurso do Kubernetes para entender as unidades aceitas pelo atributo capacity .
Atualmente, o tamanho do armazenamento é o único recurso que pode ser configurado ou solicitado. Os futuros atributos podem
incluir IOPS, throughput, etc.
Modo do Volume
ESTADO DA FUNCIONALIDADE: Kubernetes v1.18 [stable]
volumeMode é um parâmetro opcional da API. Filesystem é o modo padrão utilizado quando o parâmetro volumeMode é omitido.
Um volume com volumeMode: Filesystem é montado em um diretório nos Pods. Se o volume for de um dispositivo de bloco e ele
estiver vazio, o Kubernetes cria o sistema de arquivo no dispositivo antes de fazer a montagem pela primeira vez.
Você pode configurar o valor do volumeMode para Block para utilizar um disco bruto como volume. Esse volume é apresentado
num Pod como um dispositivo de bloco, sem nenhum sistema de arquivo. Esse modo é útil para prover ao Pod a forma mais rápida
para acessar um volume, sem nenhuma camada de sistema de arquivo entre o Pod e o volume. Por outro lado, a aplicação que
estiver rodando no Pod deverá saber como tratar um dispositivo de bloco. Veja Suporte a Volume de Bloco Bruto para um exemplo
de como utilizar o volume como volumeMode: Block num Pod.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 98/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Modos de Acesso
Um PersistentVolume pode ser montado num host das mais variadas formas suportadas pelo provedor. Como mostrado na tabela
abaixo, os provedores terão diferentes capacidades e cada modo de acesso do PV são configurados nos modos específicos
suportados para cada volume em particular. Por exemplo, o NFS pode suportar múltiplos clientes read/write, mas um PV NFS
específico pode ser exportado no server como read-only. Cada PV recebe seu próprio modo de acesso que descreve suas
capacidades específicas.
RWO - ReadWriteOnce
ROX - ReadOnlyMany
RWX - ReadWriteMany
Importante! Um volume somente pode ser montado utilizando um único modo de acesso por vez, independente se ele suportar
mais de um. Por exemplo, um GCEPersistentDisk pode ser montado como ReadWriteOnce por um único nó ou ReadOnlyMany
por vários nós, porém não simultaneamente.
AWSElasticBlockStore ✓ - -
AzureFile ✓ ✓ ✓
AzureDisk ✓ - -
CephFS ✓ ✓ ✓
Cinder ✓ - -
FC ✓ ✓ -
Flocker ✓ - -
GCEPersistentDisk ✓ ✓ -
Glusterfs ✓ ✓ ✓
HostPath ✓ - -
iSCSI ✓ ✓ -
Quobyte ✓ ✓ ✓
NFS ✓ ✓ ✓
RBD ✓ ✓ -
PortworxVolume ✓ - ✓
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 99/233
4/15/24, 11:56 AM Conceitos | Kubernetes
ScaleIO ✓ ✓ -
StorageOS ✓ - -
Classe
Um PV pode ter uma classe, que é especificada na configuração do atributo storageClassName com o nome da StorageClass. Um PV
de uma classe específica só pode ser atrelado a requisições PVCs dessa mesma classe. Um PV sem storageClassName não possui
nenhuma classe e pode ser montado somente a PVCs que não solicitem nenhuma classe em específico.
Política de Retenção
Atualmente as políticas de retenção são:
Atualmente, somente NFS e HostPath suportam reciclagem. Volumes AWS EBS, GCE PD, Azure Disk e Cinder suportam delete.
Opções de Montagem
Um administrador do Kubernetes pode especificar opções de montagem adicionais quando um Volume Persistente é montado num
nó.
AWSElasticBlockStore
AzureDisk
AzureFile
CephFS
Cinder (OpenStack block storage)
GCEPersistentDisk
Glusterfs
NFS
Quobyte Volumes
RBD (Ceph Block Device)
StorageOS
VsphereVolume
iSCSI
Não há validação em relação às opções de montagem. A montagem irá falhar se houver alguma opção inválida.
No passado, a notação volume.beta.kubernetes.io/mount-options era usada no lugar do atributo mountOptions . Essa notação
ainda funciona. Contudo, ela será totalmente depreciada numa futura versão do Kubernetes.
Afinidade de Nó
Nota: Para a maioria dos tipos de volume, a configuração desse campo não se faz necessária. Isso é automaticamente
populado pelos seguintes volumes de bloco do tipo: AWS EBS, GCE PD e Azure Disk. Você precisa deixar isso configurado para
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 100/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Um PV pode especificar uma afinidade de nó para definir restrições em relação ao limite de nós que podem acessar esse volume.
Pods que utilizam um PV serão somente reservados para nós selecionados pela afinidade de nó.
Estado
Um volume sempre estará em um dos seguintes estados:
Available -- um recurso que está livre e ainda não foi atrelado a nenhuma requisição
Bound -- um volume atrelado a uma requisição
Released -- a requisição foi deletada, mas o curso ainda não foi recuperado pelo cluster
Failed -- o volume fracassou na sua recuperação automática
PersistentVolumeClaims
Cada PVC contém uma spec e um status, que é a especificação e estado de uma requisição. O nome de um objeto
PersistentVolumeClaim precisa ser um DNS válido.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
Modos de Acesso
As requisições usam as mesmas convenções que os volumes quando eles solicitam um armazenamento com um modo de acesso
específico.
Modos de Volume
As requisições usam as mesmas convenções que os volumes quando eles indicam o tipo de volume, seja ele um sistema de arquivo
ou dispositivo de bloco.
Recursos
Assim como Pods, as requisições podem solicitar quantidades específicas de recurso. Neste caso, a solicitação é por
armazenamento. O mesmo modelo de recurso vale para volumes e requisições.
Seletor
Requisições podem especifiar um seletor de rótulo para posteriormente filtrar um grupo de volumes. Somente os volumes que
possuam rótulos que satisfaçam os critérios do seletor podem ser atrelados à requisição. O seletor pode conter dois campos:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 101/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Todos os requisitos de matchLabels e matchExpressions , são do tipo AND - todos eles juntos devem ser atendidos.
Classe
Uma requisição pode solicitar uma classe específica através da StorageClass utilizando o atributo storageClassName . Neste caso o
bind ocorrerá somente com os PVs que possuírem a mesma classe do storageClassName dos PVCs.
As PVCs não precisam necessariamente solicitar uma classe. Uma PVC com sua storageClassName configurada como "" sempre
solicitará um PV sem classe, dessa forma ela sempre será atrelada a um PV sem classe (que não tenha nenhuma notação, ou seja,
igual a "" ). Uma PVC sem storageClassName não é a mesma coisa e será tratada pelo cluster de forma diferente, porém isso
dependerá se o puglin de admissão DefaultStorageClass estiver habilitado.
Se o plugin de admissão estiver habilitado, o administrador poderá especificar a StorageClass padrão. Todas as PVCs que não
tiverem storageClassName podem ser atreladas somente a PVs que atendam a esse padrão. A especificação de uma
StorageClass padrão é feita através da notação storageclass.kubernetes.io/is-default-class recebendo o valor true no
objeto da StorageClass. Se o administrador não especificar nenhum padrão, o cluster vai tratar a criação de uma PVC como se
o plugin de admissão estivesse desabilitado. Se mais de um valor padrão for especificado, o plugin de admissão proíbe a
criação de todas as PVCs.
Se o plugin de admissão estiver desabilitado, não haverá nenhuma notação para a StorageClass padrão. Todas as PVCs que
não tiverem storageClassName poderão ser atreladas somente aos PVs que não possuem classe. Neste caso, as PVCs que não
tiverem storageClassName são tratadas da mesma forma como as PVCs que possuem suas storageClassName configuradas
como "" .
Dependendo do modo de instalação, uma StorageClass padrão pode ser implantada num cluster Kubernetes durante a instalação
pelo addon manager.
Quando uma PVC especifica um selector para solicitar uma StorageClass, os requisitos são do tipo AND: somente um PV com a
classe solicitada e com o rótulo requisitado pode ser atrelado à PVC.
Nota: Atualmente, uma PVC que tenha selector não pode ter um PV dinamicamente provisionado.
No passado, a notação volume.beta.kubernetes.io/storage-class era usada no lugar do atributo storageClassName Essa notação
ainda funciona. Contudo, ela será totalmente depreciada numa futura versão do Kubernetes.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 102/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Sobre Namespaces
Os binds dos PersistentVolumes são exclusivos e, desde que as PersistentVolumeClaims são objetos do namespace, fazer a
montagem das requisições com "Muitos" nós ( ROX , RWX ) é possível somente para um namespace.
Os plugins de volume abaixo suportam volumes de bloco bruto, incluindo provisionamento dinâmico onde for aplicável:
AWSElasticBlockStore
AzureDisk
CSI
FC (Fibre Channel)
GCEPersistentDisk
iSCSI
Local volume
OpenStack Cinder
RBD (Ceph Block Device)
VsphereVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWWNs: ["50060e801049cfd1"]
lun: 0
readOnly: false
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 103/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
apiVersion: v1
kind: Pod
metadata:
name: pod-with-block-volume
spec:
containers:
- name: fc-container
image: fedora:26
command: ["/bin/sh", "-c"]
args: [ "tail -f /dev/null" ]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-pvc
Nota: Quando adicionar um dispositivo de bloco bruto num Pod, você especifica o caminho do dispositivo no contêiner ao invés
de um ponto de montagem.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 104/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: O provisionamento estático de volumes é suportado somente na versão alpha. Os administradores devem tomar cuidado
ao considerar esses valores quando estiverem trabalhando com dispositivos de bloco bruto.
O snapshot de volume é suportado somente pelo plugin de volume CSI. Veja Snapshot de Volume para mais detalhes. Plugins de
volume in-tree estão depreciados. Você pode consultar sobre os plugins de volume depreciados em Perguntas Frequentes sobre
Plugins de Volume.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: restore-pvc
spec:
storageClassName: csi-hostpath-sc
dataSource:
name: new-snapshot-test
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Clonagem de Volume
A Clonagem de Volume é possível somente com plugins de volume CSI.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 105/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cloned-pvc
spec:
storageClassName: my-csi-plugin
dataSource:
name: existing-src-pvc-name
kind: PersistentVolumeClaim
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
Inclua objetos PersistentVolumeClaim em seu pacote de configuração (com Deployments, ConfigMaps, etc.).
Não inclua objetos PersistentVolume na configuração, pois o usuário que irá instanciar a configuração talvez não tenha
permissão para criar PersistentVolume.
Dê ao usuário a opção dele informar o nome de uma classe de armazenamento quando instanciar o template.
Se o usuário informar o nome de uma classe de armazenamento, coloque esse valor no campo
persistentVolumeClaim.storageClassName . Isso fará com que a PVC encontre a classe de armazenamento correta se o
cluster tiver a StorageClasses habilitado pelo administrador.
Se o usuário não informar o nome da classe de armazenamento, deixe o campo
persistentVolumeClaim.storageClassName sem nenhum valor (vazio). Isso fará com que o PV seja provisionado
automaticamente no cluster para o usuário com o StorageClass padrão. Muitos ambientes de cluster já possuem uma
StorageClass padrão, ou então os administradores podem criar suas StorageClass de acordo com seus critérios.
Durante suas tarefas de administração, busque por PVCs que após um tempo não estão sendo atreladas, pois, isso talvez
indique que o cluster não tem provisionamento dinâmico (onde o usuário deveria criar um PV que satisfaça os critérios da PVC)
ou cluster não tem um sistema de armazenamento (onde usuário não pode realizar um deploy solicitando PVCs).
Próximos passos
Saiba mais sobre Criando um PersistentVolume.
Saiba mais sobre Criando um PersistentVolumeClaim.
Leia a documentação sobre planejamento de Armazenamento Persistente.
Referência
PersistentVolume
PersistentVolumeSpec
PersistentVolumeClaim
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 106/233
4/15/24, 11:56 AM Conceitos | Kubernetes
6 - Configuração
6.1 - Melhores Práticas de Configuração
Esse documento destaca e consolida as melhores práticas de configuração apresentadas em todo o guia de usuário, na
documentação de introdução e nos exemplos.
Este é um documento vivo. Se você pensar em algo que não está nesta lista, mas pode ser útil para outras pessoas, não hesite em
criar uma issue ou submeter um PR.
Os arquivos de configuração devem ser armazenados em um sistema de controle antes de serem enviados ao cluster. Isso
permite que você reverta rapidamente uma alteração de configuração, caso necessário. Isso também auxilia na recriação e
restauração do cluster.
Escreva seus arquivos de configuração usando YAML ao invés de JSON. Embora esses formatos possam ser usados
alternadamente em quase todos os cenários, YAML tende a ser mais amigável.
Agrupe objetos relacionados em um único arquivo sempre que fizer sentido. Geralmente, um arquivo é mais fácil de gerenciar
do que vários. Veja o guestbook-all-in-one.yaml como exemplo dessa sintaxe.
Observe também que vários comandos kubectl podem ser chamados em um diretório. Por exemplo, você pode chamar
kubectl apply em um diretório de arquivos de configuração.
Não especifique valores padrões desnecessariamente: configurações simples e mínimas diminuem a possibilidade de erros.
Coloque descrições de objetos nas anotações para permitir uma melhor análise.
Criar um Deployment, que cria um ReplicaSet para garantir que o número desejado de Pods esteja disponível e especifica uma
estratégia para substituir os Pods (como RollingUpdate), é quase sempre preferível do que criar Pods diretamente, exceto para
alguns cenários explícitos de restartPolicy:Never. Um Job também pode ser apropriado.
Services
Crie o Service antes de suas cargas de trabalho de backend correspondentes (Deployments ou ReplicaSets) e antes de
quaisquer cargas de trabalho que precisem acessá-lo. Quando o Kubernetes inicia um contêiner, ele fornece variáveis de
ambiente apontando para todos os Services que estavam em execução quando o contêiner foi iniciado. Por exemplo, se um
Service chamado foo existe, todos os contêineres vão receber as seguintes variáveis em seu ambiente inicial:
Isso implica em um requisito de pedido - qualquer Service que um Pod quer acessar precisa ser criado antes do Pod em si, ou
então as variáveis de ambiente não serão populadas. O DNS não possui essa restrição.
Um cluster add-on opcional (embora fortemente recomendado) é um servidor DNS. O servidor DNS monitora a API do
Kubernetes buscando novos Services e cria um conjunto de DNS para cada um. Se o DNS foi habilitado em todo o cluster,
então todos os Pods devem ser capazes de fazer a resolução de Services automaticamente.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 107/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Não especifique um hostPort para um Pod a menos que isso seja absolutamente necessário. Quando você vincula um Pod a
um hostPort , isso limita o número de lugares em que o Pod pode ser agendado, porque cada combinação de < hostIP ,
hostPort , protocol > deve ser única. Se você não especificar o hostIP e protocol explicitamente, o Kubernetes vai usar
0.0.0.0 como o hostIP padrão e TCP como protocol padrão.
Se você precisa de acesso a porta apenas para fins de depuração, pode usar o apiserver proxy ou o kubectl port-forward .
Se você precisa expor explicitamente a porta de um Pod no nó, considere usar um Service do tipo NodePort antes de recorrer
a hostPort .
Use headless Services (que tem um ClusterIP ou None ) para descoberta de serviço quando você não precisar de um
balanceador de carga kube-proxy .
Usando Labels
Defina e use labels que identifiquem atributos semânticos da sua aplicação ou Deployment, como { app: myapp, tier:
frontend, phase: test, deployment: v3 } . Você pode usar essas labels para selecionar os Pods apropriados para outros
recursos; por exemplo, um Service que seleciona todos os Pods tier: frontend , ou todos os componentes de app: myapp .
Veja o app guestbook para exemplos dessa abordagem.
Um Service pode ser feito para abranger vários Deployments, omitindo labels específicas de lançamento de seu seletor. Quando
você precisar atualizar um serviço em execução sem downtime, use um Deployment.
Um estado desejado de um objeto é descrito por um Deployment, e se as alterações nesse spec forem aplicadas o controlador do
Deployment altera o estado real para o estado desejado em uma taxa controlada.
Use as labels comuns do Kubernetes para casos de uso comuns. Essas labels padronizadas enriquecem os metadados de uma
forma que permite que ferramentas, incluindo kubectl e a dashboard, funcionem de uma forma interoperável.
Você pode manipular labels para depuração. Como os controladores do Kubernetes (como ReplicaSet) e Services se
relacionam com os Pods usando seletor de labels, remover as labels relevantes de um Pod impedirá que ele seja considerado
por um controlador ou que seja atendido pelo tráfego de um Service. Se você remover as labels de um Pod existente, seu
controlador criará um novo Pod para substituí-lo. Essa é uma maneira útil de depurar um Pod anteriormente "ativo" em um
ambiente de "quarentena". Para remover ou alterar labels interativamente, use kubectl label .
Imagens de Contêiner
A imagePullPolicy e tag da imagem afetam quando o kubelet tenta puxar a imagem especificada.
imagePullPolicy: IfNotPresent : a imagem é puxada apenas se ainda não estiver presente localmente.
imagePullPolicy: Always : sempre que o kubelet inicia um contêiner, ele consulta o registry da imagem do contêiner para
verificar o resumo de assinatura da imagem. Se o kubelet tiver uma imagem do contêiner com o mesmo resumo de assinatura
armazenado em cache localmente, o kubelet usará a imagem em cache, caso contrário, o kubelet baixa(pulls) a imagem com o
resumo de assinatura resolvido, e usa essa imagem para iniciar o contêiner.
imagePullPolicyé omitido se uma tag da imagem existe mas não :latest : imagePullPolicy é automaticamente definido
como ifNotPresent . Observe que isto não será atualizado para Always se a tag for removida ou alterada para :latest .
imagePullPolicy: Never : presume-se que a imagem exista localmente. Não é feita nenhuma tentativa de puxar a imagem.
Nota: Para garantir que seu contêiner sempre use a mesma versão de uma imagem, você pode especificar seu resumo de
assinatura; substitua <nome-da-imagem>:<tag> por <nome-da-imagem>@<hash> (por exemplo,
image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2). Esse resumo de assinatura identifica
exclusivamente uma versão específica de uma imagem, então isso nunca vai ser atualizado pelo Kubernetes a menos que você
mude o valor do resumo de assinatura da imagem.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 108/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Você deve evitar o uso da tag :latest em produção, pois é mais difícil rastrear qual versão da imagem está sendo
executada e mais difícil reverter adequadamente.
Nota: A semântica de cache do provedor de imagem subjacente torna até mesmo imagePullPolicy: Always eficiente, contanto
que o registro esteja acessível de forma confiável. Com o Docker, por exemplo, se a imagem já existe, a tentativa de baixar(pull)
é rápida porque todas as camadas da imagem são armazenadas em cache e nenhum download de imagem é necessário.
Usando kubectl
Use kubectl apply -f <directory> . Isso procura por configurações do Kubernetes em todos os arquivos .yaml , .yml em
<directory> e passa isso para apply .
Use labels selectors para operações get e delete em vez de nomes de objetos específicos. Consulte as seções sobre label
selectors e usando Labels efetivamente.
Use kubectl create deployment e kubectl expose para criar rapidamente Deployments e Services de um único contêiner.
Consulte Use um Service para acessar uma aplicação em um cluster para obter um exemplo.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 109/233
4/15/24, 11:56 AM Conceitos | Kubernetes
6.2 - ConfigMaps
Um ConfigMap é um objeto da API usado para armazenar dados não-confidenciais em pares chave-valor. Pods podem consumir
ConfigMaps como variáveis de ambiente, argumentos de linha de comando ou como arquivos de configuração em um volume.
Um ConfigMap ajuda a desacoplar configurações vinculadas ao ambiente das imagens de contêiner, de modo a tornar aplicações
mais facilmente portáveis.
Cuidado: O ConfigMap não oferece confidencialidade ou encriptação. Se os dados que você deseja armazenar são
confidenciais, utilize Secret ao invés de um ConfigMap, ou utilize ferramentas adicionais (de terceiros) para manter seus dados
privados.
Motivação
Utilize um ConfigMap para manter a configuração separada do código da aplicação.
Por exemplo, imagine que você esteja desenvolvendo uma aplicação que pode ser executada no seu computador local (para
desenvolvimento) e na nuvem (para manipular tráfego real). Você escreve código para ler a variável de ambiente chamada
DATABASE_HOST . No seu ambiente local, você configura essa variável com o valor localhost . Na nuvem, você configura essa
variável para referenciar um serviço do Kubernetes que expõe o componente do banco de dados ao seu cluster. Isto permite que
você baixe uma imagem de contêiner que roda na nuvem e depure exatamente o mesmo código localmente se necessário.
Um ConfigMap não foi planejado para conter grandes quantidades de dados. Os dados armazenados em um ConfigMap não podem
exceder 1 MiB. Se você precisa armazenar configurações que são maiores que este limite, considere montar um volume ou utilizar
um serviço separado de banco de dados ou de arquivamento de dados.
Objeto ConfigMap
Um ConfigMap é um objeto da API que permite o armazenamento de configurações para consumo por outros objetos.
Diferentemente de outros objetos do Kubernetes que contém um campo spec , o ConfigMap contém os campos data e
binaryData . Estes campos aceitam pares chave-valor como valores. Ambos os campos data e binaryData são opcionais. O
campo data foi pensado para conter sequências de bytes UTF-8, enquanto o campo binaryData foi planejado para conter dados
binários em forma de strings codificadas em base64.
Cada chave sob as seções data ou binaryData pode conter quaisquer caracteres alfanuméricos, - , _ e . . As chaves
armazenadas na seção data não podem colidir com as chaves armazenadas na seção binaryData .
A partir da versão v1.19 do Kubernetes, é possível adicionar o campo immutable a uma definição de ConfigMap para criar um
ConfigMap imutável.
ConfigMaps e Pods
Você pode escrever uma spec para um Pod que se refere a um ConfigMap e configurar o(s) contêiner(es) neste Pod baseados em
dados do ConfigMap. O Pod e o ConfigMap devem estar no mesmo namespace.
Nota: A spec de um Pod estático não pode se referir a um ConfigMap ou a quaisquer outros objetos da API.
Exemplo de um ConfigMap que contém algumas chaves com valores avulsos e outras chaves com valores semelhantes a
fragmentos de arquivos de configuração:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 110/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
# chaves com valores de propriedades; cada chave mapeia para um valor avulso
player_initial_lives: "3"
ui_properties_file_name: "user-interface.properties"
Existem quatro formas diferentes para consumo de um ConfigMap na configuração de um contêiner dentro de um Pod:
Os diferentes métodos de consumo oferecem diferentes formas de modelar os dados sendo consumidos. Para os três primeiros
métodos, o kubelet utiliza os dados de um ConfigMap quando o(s) contêiner(es) do Pod são inicializados.
O quarto método envolve escrita de código para leitura do ConfigMap e dos seus dados. No entanto, como a API do Kubernetes está
sendo utilizada diretamente, a aplicação pode solicitar atualizações sempre que o ConfigMap for alterado e reagir quando isso
ocorre. Acessar a API do Kubernetes diretamente também permite ler ConfigMaps em outros namespaces.
Exemplo de um Pod que utiliza valores do ConfigMap game-demo para configurar um Pod:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 111/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo-pod
spec:
containers:
- name: demo
image: alpine
command: ["sleep", "3600"]
env:
# Define as variáveis de ambiente
- name: PLAYER_INITIAL_LIVES # Note que aqui a variável está definida em caixa alta,
# diferente da chave no ConfigMap.
valueFrom:
configMapKeyRef:
name: game-demo # O ConfigMap de onde esse valor vem.
key: player_initial_lives # A chave que deve ser buscada.
- name: UI_PROPERTIES_FILE_NAME
valueFrom:
configMapKeyRef:
name: game-demo
key: ui_properties_file_name
volumeMounts:
- name: config
mountPath: "/config"
readOnly: true
volumes:
# Volumes são definidos no escopo do Pod, e os pontos de montagem são definidos
# nos contêineres dentro dos pods.
- name: config
configMap:
# Informe o nome do ConfigMap que deseja montar.
name: game-demo
# Uma lista de chaves do ConfigMap para serem criadas como arquivos.
items:
- key: "game.properties"
path: "game.properties"
- key: "user-interface.properties"
path: "user-interface.properties"
ConfigMaps não diferenciam entre propriedades com valores simples ou valores complexos, que ocupam várias linhas. O
importante é a forma que Pods e outros objetos consomem tais valores.
Neste exemplo, definir um volume e montar ele dentro do contêiner demo no caminho /config cria dois arquivos:
/config/game.properties e /config/user-interface.properties , embora existam quatro chaves distintas no ConfigMap. Isso se
deve ao fato de que a definição do Pod contém uma lista items na seção volumes . Se a lista items for omitida, cada chave do
ConfigMap torna-se um arquivo cujo nome é a sua chave correspondente, e quatro arquivos serão criados.
Usando ConfigMaps
ConfigMaps podem ser montados como volumes de dados. ConfigMaps também podem ser utilizados por outras partes do sistema
sem serem diretamente expostos ao Pod. Por exemplo, ConfigMaps podem conter dados que outras partes do sistema devem usar
para configuração.
A forma mais comum de utilização de ConfigMaps é a configuração de contêineres executando em Pods no mesmo namespace.
Você também pode utilizar um ConfigMap separadamente.
Por exemplo, existem complementos ou operadores que adaptam seus comportamentos de acordo com dados de um ConfigMap.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 112/233
4/15/24, 11:56 AM Conceitos | Kubernetes
1. Crie um ConfigMap ou utilize um ConfigMap existente. Múltiplos Pods podem referenciar o mesmo ConfigMap.
2. Modifique sua definição de Pod para adicionar um volume em .spec.volumes[] . Escolha um nome qualquer para o seu
volume, e referencie o seu objeto ConfigMap no campo .spec.volumes[].configMap.name .
3. Adicione um campo a cada um dos contêineres que precisam do ConfigMap. Especifique
.spec.containers[].volumeMounts[]
.spec.containers[].volumeMounts[].readOnly = true e informe no campo .spec.containers[].volumeMounts[].mountPath
um caminho de um diretório não utilizado onde você deseja que este ConfigMap apareça.
4. Modifique sua imagem ou linha de comando de modo que o programa procure por arquivos no diretório especificado no
passo anterior. Cada chave no campo data do ConfigMap será transformado em um nome de arquivo no diretório
especificado por mountPath .
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
configMap:
name: myconfigmap
Cada ConfigMap que você deseja utilizar precisa ser referenciado em .spec.volumes .
Se houver múltiplos contêineres no Pod, cada contêiner deve ter seu próprio bloco volumeMounts , mas somente uma instância de
.spec.volumes é necessária por ConfigMap.
ConfigMaps que são consumidos como variáveis de ambiente não atualizam automaticamente e requerem uma reinicialização do
pod.
ConfigMaps imutáveis
ESTADO DA FUNCIONALIDADE: Kubernetes v1.21 [stable]
A funcionalidade Secrets e ConfigMaps imutáveis do Kubernetes fornece uma opção para marcar Secrets e ConfigMaps individuais
como imutáveis. Para clusters que utilizam ConfigMaps extensivamente (ao menos centenas de milhares de mapeamentos únicos
de ConfigMaps para Pods), prevenir alterações dos seus dados traz as seguintes vantagens:
protege de atualizações acidentais ou indesejadas que podem causar disrupção na execução de aplicações
melhora o desempenho do cluster através do fechamento de watches de ConfigMaps marcados como imutáveis, diminuindo
significativamente a carga no kube-apiserver
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 113/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Essa funcionalidade é controlada pelo feature gate ImmutableEphemeralVolumes . É possível criar um ConfigMap imutável
adicionando o campo immutable e marcando seu valor com true . Por exemplo:
apiVersion: v1
kind: ConfigMap
metadata:
...
data:
...
immutable: true
Após um ConfigMap ser marcado como imutável, não é possível reverter a alteração, nem alterar o conteúdo dos campos data ou
binaryData . É possível apenas apagar e recriar o ConfigMap. Como Pods existentes que consomem o ConfigMap em questão
mantém um ponto de montagem que continuará referenciando este objeto após a remoção, é recomendado recriar estes pods.
Próximos passos
Leia sobre Secrets (em inglês).
Leia Configure a Pod to Use a ConfigMap (em inglês).
Leia The Twelve-Factor App (em inglês) para entender a motivação da separação de código e configuração.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 114/233
4/15/24, 11:56 AM Conceitos | Kubernetes
6.3 - Secrets
Um Secret é um objeto que contém uma pequena quantidade de informação sensível, como senhas, tokens ou chaves. Este tipo de
informação poderia, em outras circunstâncias, ser colocada diretamente em uma configuração de Pod ou em uma
imagem de contêiner. O uso de Secrets evita que você tenha de incluir dados confidenciais no seu código.
Secrets podem ser criados de forma independente dos Pods que os consomem. Isto reduz o risco de que o Secret e seus dados
sejam expostos durante o processo de criação, visualização e edição ou atualização de Pods. O Kubernetes e as aplicações que
rodam no seu cluster podem também tomar outras precauções com Secrets, como por exemplo evitar a escrita de dados
confidenciais em local de armazenamento persistente (não-volátil).
Secrets são semelhantes a ConfigMaps, mas foram especificamente projetados para conter dados confidenciais.
Cuidado:
Os Secrets do Kubernetes são, por padrão, gravados não-encriptados no sistema de armazenamento de dados utilizado pelo
servidor da API (etcd). Qualquer pessoa com acesso à API ou ao etcd consegue obter ou modificar um Secret. Além disso,
qualquer pessoa que possui autorização para criar Pods em um namespace consegue utilizar este privilégio para ler qualquer
Secret naquele namespace. Isso inclui acesso indireto, como por exemplo a permissão para criar Deployments.
Para utilizar Secrets de forma segura, siga pelo menos as instruções abaixo:
A camada de gerenciamento do Kubernetes também utiliza Secrets. Por exemplo, os Secrets de tokens de autoinicialização são um
mecanismo que auxilia a automação do registro de nós.
Alternativas a Secrets
Ao invés de utilizar um Secret para proteger dados confidenciais, você pode escolher uma maneira alternativa. Algumas das opções
são:
se o seu componente cloud native precisa autenticar-se a outra aplicação que está rodando no mesmo cluster Kubernetes,
você pode utilizar uma ServiceAccount e seus tokens para identificar seu cliente.
existem ferramentas fornecidas por terceiros que você pode rodar, no seu cluster ou externamente, que providenciam
gerenciamento de Secrets. Por exemplo, um serviço que Pods accessam via HTTPS, que revelam um Secret se o cliente
autenticar-se corretamente (por exemplo, utilizando um token de ServiceAccount).
para autenticação, você pode implementar um serviço de assinatura de certificados X.509 personalizado, e utilizar
CertificateSigningRequests para permitir ao serviço personalizado emitir certificados a pods que os necessitam.
você pode utilizar um plugin de dispositivo para expor a um Pod específico um hardware de encriptação conectado a um nó.
Por exemplo, você pode agendar Pods confiáveis em nós que oferecem um Trusted Platform Module, configurado em um fluxo
de dados independente.
Você pode também combinar duas ou mais destas opções, incluindo a opção de utilizar objetos do tipo Secret.
Por exemplo: implemente (ou instale) um operador que solicite tokens de sessão de curta duração a um serviço externo, e crie
Secrets baseado nestes tokens. Pods rodando no seu cluster podem fazer uso de tokens de sessão, e o operador garante que estes
permanecem válidos. Esta separação significa que você pode rodar Pods que não precisam ter conhecimento do mecanismo exato
para geração e atualização de tais tokens de sessão.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 115/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Você pode especificar o campo data e/ou o campo stringData na criação de um arquivo de configuração de um Secret. Ambos os
campos data e stringData são opcionais. Os valores das chaves no campo data devem ser strings codificadas no formato
base64. Se a conversão para base64 não for desejável, você pode optar por informar os dados no campo stringData , que aceita
strings arbitrárias como valores.
As chaves dos campos data e stringData devem consistir de caracteres alfanuméricos, - , _ , ou . . Todos os pares chave-valor
no campo stringData são internamente combinados com os dados do campo data . Se uma chave aparece em ambos os campos,
o valor informado no campo stringData tem a precedência.
Limite de tamanho
Secrets individuais são limitados a 1MiB em tamanho. Esta limitação tem por objetivo desencorajar a criação de Secrets muito
grandes que possam exaurir a memória do servidor da API e do kubelet. No entanto, a criação de vários Secrets pequenos também
pode exaurir a memória. Você pode utilizar uma cota de recurso a fim de limitar o número de Secrets (ou outros recursos) em um
namespace.
Editando um Secret
Você pode editar um Secret existente utilizando kubectl:
Este comando abre o seu editor padrão configurado e permite a modificação dos valores do Secret codificados em base64 no
campo data . Por exemplo:
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file, it will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: { ... }
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 116/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Este manifesto de exemplo define um Secret com duas chaves no campo data : username and password . Os valores são strings
codificadas em formato base64. No entanto, quando um Secret é utilizado em um Pod, o kubelet fornece os dados decodificados ao
Pod e seus contêineres.
Você pode especificar muitas chaves e valores em um Secret só, ou utilizar muitos Secrets. Escolha a opção que for mais
conveniente para o caso de uso.
Utilizando Secrets
Secrets podem ser montados como volumes de dados ou expostos como variáveis de ambiente para serem utilizados num
container de um Pod. Secrets também podem ser utilizados por outras partes do sistema, sem serem diretamente expostos ao Pod.
Por exemplo, Secrets podem conter credenciais que outras partes do sistema devem utilizar para interagir com sistemas externos
no lugar do usuário.
Secrets montados como volumes são verificados para garantir que o nome referenciado realmente é um objeto do tipo Secret.
Portanto, um Secret deve ser criado antes de quaisquer Pods que dependem deste Secret.
Se um Secret não puder ser encontrado (porque não existe, ou devido a um problema de conectividade com o servidor da API) o
kubelet tenta periodicamente reiniciar aquele Pod. O kubelet também relata um evento para aquele Pod, incluindo detalhes do
problema ao buscar o Secret.
Secrets Opcionais
Quando você define uma variável de ambiente em um contêiner baseada em um Secret, você pode especificar que o Secret em
questão será opcional. O padrão é o Secret ser requerido.
Nenhum dos contêineres de um Pod irão inicializar até que todos os Secrets requeridos estejam disponíveis.
Se um Pod referencia uma chave específica em um Secret e o Secret existe, mas não possui a chave com o nome referenciado, o
Pod falha durante a inicialização.
1. Crie um Secret ou utilize um previamente existente. Múltiplos Pods podem referenciar o mesmo secret.
2. Modifique sua definição de Pod para adicionar um volume na lista .spec.volumes[] . Escolha um nome qualquer para o seu
volume e adicione um campo .spec.volumes[].secret.secretName com o mesmo valor do seu objeto Secret.
3. Adicione um ponto de montagem de volume à lista .spec.containers[].volumeMounts[] de cada contêiner que requer o
Secret. Especifique .spec.containers[].volumeMounts[].readOnly = true e especifique o valor do campo
.spec.containers[].volumeMounts[].mountPath com o nome de um diretório não utilizado onde você deseja que os Secrets
apareçam.
4. Modifique sua imagem ou linha de comando de modo que o programa procure por arquivos naquele diretório. Cada chave no
campo data se torna um nome de arquivo no diretório especificado em mountPath .
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 117/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret # configuração padrão; "mysecret" precisa existir
Cada Secret que você deseja utilizar deve ser referenciado na lista .spec.volumes .
Se existirem múltiplos contêineres em um Pod, cada um dos contêineres necessitará seu próprio bloco volumeMounts , mas
somente um volume na lista .spec.volumes é necessário por Secret.
Nota:
Versões do Kubernetes anteriores a v1.22 criavam automaticamente credenciais para acesso à API do Kubernetes. Este
mecanismo antigo era baseado na criação de Secrets com tokens que podiam então ser montados em Pods em execução. Em
versões mais recentes, incluindo o Kubernetes v1.29, credenciais para acesso à API são obtidas diretamente através da API
TokenRequest e são montadas em Pods utilizando um volume projetado. Os tokens obtidos através deste método possuem
tempo de vida limitado e são automaticamente invalidados quando o Pod em que estão montados é removido.
Você ainda pode criar manualmente um Secret de token de service account se você precisa de um token que não expire, por
exemplo. No entanto, o uso do subrecurso TokenRequest é recomendado para obtenção de um token para acesso à API ao
invés do uso de Secrets de token de service account.
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
Neste caso:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 118/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Se .spec.volumes[].secret.items for utilizado, somente chaves especificadas na lista items são projetadas. Para consumir todas
as chaves do Secret, deve haver um item para cada chave no campo items .
Se você listar as chaves explicitamente, então todas as chaves listadas precisam existir no Secret correspondente. Caso contrário, o
volume não é criado.
Por exemplo, você pode especificar uma permissão padrão da seguinte maneira:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 0400
Dessa forma, o Secret será montado em /etc/foo e todos os arquivos criados no volume terão a permissão 0400 .
Nota: Se você estiver definindo um Pod ou um template de Pod utilizando JSON, observe que a especificação JSON não suporta
a notação octal. Você pode utilizar o valor decimal para o campo defaultMode (por exemplo, 0400 em base octal equivale a 256
na base decimal).
Se você estiver escrevendo YAML, você pode escrever o valor para defaultMode em octal.
ls /etc/foo
O resultado é semelhante a:
username
password
cat /etc/foo/username
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 119/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O resultado é semelhante a:
admin
cat /etc/foo/password
O resultado é semelhante a:
1f2d1e2e67df
A aplicação rodando dentro do contêiner é responsável pela leitura dos Secrets dentro dos arquivos.
Nota: Um contêiner que utiliza Secrets através de um volume montado com a propriedade subPath não recebe atualizações
automatizadas para este Secret.
O kubelet mantém um cache das chaves e valores atuais dos Secrets que são utilizados em volumes de Pods daquele nó. Você pode
configurar a forma que o kubelet detecta diferenças dos valores armazenados em cache. O campo
configMapAndSecretDetectionStrategy na configuração do kubelet controla qual estratégia o kubelet usa. A estratégia padrão é
Watch .
Atualizações em Secrets podem ser propagadas por um mecanismo de observação da API (estratégia padrão), baseado em cache
com um tempo de expiração definido (time-to-live), ou solicitado diretamente ao servidor da API do cluster a cada iteração do ciclo
de sincronização do kubelet.
Como resultado, o atraso total entre o momento em que o Secret foi atualizado até o momento em que as novas chaves são
projetadas no Pod pode ser tão longo quanto a soma do tempo de sincronização do kubelet somado ao tempo de atraso de
propagação do cache, onde o atraso de propagação do cache depende do tipo de cache escolhido. Seguindo a mesma ordem listada
no parágrafo anterior, estes valores são: atraso de propagação via watch, tempo de expiração configurado no cache (time-to-live, ou
TTL), ou zero para solicitação direta ao servidor da API.
1. Crie um Secret ou utilize um já existente. Múltiplos Pods podem referenciar o mesmo Secret.
2. Modifique a definição de cada contêiner do Pod em que desejar consumir o Secret, adicionando uma variável de ambiente
para cada uma das chaves que deseja consumir. A variável de ambiente que consumir o valor da chave em questão deverá
popular o nome do Secret e a sua chave correspondente no campo env[].valueFrom.secretKeyRef .
3. Modifique sua imagem de contêiner ou linha de comando de forma que o programa busque os valores nas variáveis de
ambiente especificadas.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 120/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
optional: false # valor padrão; "mysecret" deve existir
# e incluir uma chave com o nome "username"
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
optional: false # valor padrão; "mysecret" deve existir
# e incluir uma chave com o nome "password"
restartPolicy: Never
Se você definir um Pod contendo um nome de variável de ambiente inválido, os eventos de inicialização do Pod incluirão um evento
com a razão InvalidVariableNames e uma mensagem que lista as chaves inválidas ignoradas. O exemplo abaixo demonstra um
Pod que referencia um Secret chamado mysecret , onde mysecret contém duas chaves inválidas: 1badkey and 2alsobad .
O resultado é semelhante a:
echo $SECRET_USERNAME
O resultado é semelhante a:
admin
echo $SECRET_PASSWORD
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 121/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O resultado é semelhante a:
1f2d1e2e67df
Nota: Se um contêiner já consome um Secret em uma variável de ambiente, uma atualização do Secret não será detectada pelo
contêiner a menos que este seja reiniciado. Há soluções de terceiros que fornecem a funcionalidade de reinicialização
automática de Pods quando o valor dos Secrets mudam.
O campo de um Pod é uma lista de referências a Secrets no mesmo namespace que o Pod. Você pode utilizar
imagePullSecrets
imagePullSecrets para enviar credenciais para acesso a um registro de contêineres ao kubelet. O kubelet utiliza essa informação
para baixar uma imagem privada no lugar do seu Pod. Veja o campo PodSpec na referência da API de Pods para maiores detalhes
sobre o campo imagePullSecrets .
Usando imagePullSecrets
O campo é uma lista de referências a Secrets no mesmo namespace. Você pode utilizar o campo
imagePullSecrets
imagePullSecrets para enviar um Secret que contém uma senha para um registro de imagens de contêiner do Docker (ou outro
registro de imagens de contêiner). O kubelet utiliza essa informação para baixar uma imagem privada no lugar do seu Pod. Veja a
API PodSpec para mais informações sobre o campo imagePullSecrets .
Casos de uso
Caso de uso: Como variáveis de ambiente em um contêiner
Crie um manifesto de Secret
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
USER_NAME: YWRtaW4=
PASSWORD: MWYyZDFlMmU2N2Rm
Utilize envFrom para definir todos os dados do Secret como variáveis de ambiente do contêiner. Cada chave do Secret se torna o
nome de uma variável de ambiente no Pod.
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- secretRef:
name: mysecret
restartPolicy: Never
O resultado é semelhante a:
Você também pode criar um manifesto kustomization.yaml com um campo secretGenerator contendo chaves SSH.
Cuidado:
Analise cuidadosamente antes de enviar suas próprias chaves SSH: outros usuários do cluster podem ter acesso a este Secret.
Como alternativa, você pode criar uma chave SSH privada representando a identidade de um serviço que você deseja que seja
acessível a todos os usuários com os quais você compartilha o cluster do Kubernetes em questão. Desse modo, você pode
revogar esta credencial em caso de comprometimento.
Agora você pode criar um Pod que referencia o Secret com a chave SSH e consome-o em um volume:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 123/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: mySshImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
/etc/secret-volume/ssh-publickey
/etc/secret-volume/ssh-privatekey
O contêiner então pode utilizar os dados do secret para estabelecer uma conexão SSH.
Você pode criar um manifesto kustomization.yaml com um secretGenerator ou rodar kubectl create secret .
O resultado é semelhante a:
Você pode também criar um Secret com credenciais para o ambiente de testes.
O resultado é semelhante a:
Nota:
Caracteres especiais como $ , \ , * , + e ! serão interpretados pelo seu shell e precisam de sequências de escape.
Na maioria dos shells, a forma mais fácil de gerar sequências de escape para suas senhas é escrevê-las entre aspas simples ( ' ).
Por exemplo, se a sua senha for S!B\*d$zDsb= , você deve executar o comando da seguinte forma:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 124/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Não é necessário gerar sequências de escape para caracteres especiais em arquivos (utilizados com a opção --from-file ).
kubectl apply -k .
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 125/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Ambos os contêineres terão os seguintes arquivos presentes nos seus sistemas de arquivos, com valores para cada um dos
ambientes dos contêineres:
/etc/secret-volume/username
/etc/secret-volume/password
Observe como as spec s para cada um dos Pods diverge somente em um campo. Isso facilita a criação de Pods com capacidades
diferentes a partir de um template mais genérico.
Você pode simplificar ainda mais a definição básica do Pod através da utilização de duas service accounts diferentes:
apiVersion: v1
kind: Pod
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
serviceAccount: prod-db-client
containers:
- name: db-client-container
image: myClientImage
apiVersion: v1
kind: Secret
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: registry.k8s.io/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 126/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Este volume irá conter um único arquivo, chamado .secret-file , e o contêiner dotfile-test-container terá este arquivo
presente no caminho /etc/secret-volume/.secret-file .
Nota: Arquivos com nomes iniciados por um caractere de ponto são ocultados do resultado do comando ls -l. Você precisa
utilizar ls -la para vê-los ao listar o conteúdo de um diretório.
Esta aplicação poderia ser dividida em dois processos, separados em dois contêineres distintos: um contêiner de front-end, que
manipula as interações com o usuário e a lógica de negócio, mas não consegue ver a chave privada; e um contêiner assinador, que
vê a chave privada e responde a requisições simples de assinatura do front-end (por exemplo, através de rede local).
Com essa abordagem particionada, um invasor agora precisa forçar o servidor de aplicação a rodar comandos arbitrários, o que é
mais difícil de ser feito do que apenas ler um arquivo presente no disco.
Tipos de Secrets
Ao criar um Secret, você pode especificar o seu tipo utilizando o campo type do objeto Secret, ou algumas opções de linha de
comando equivalentes no comando kubectl , quando disponíveis. O campo type de um Secret é utilizado para facilitar a
manipulação programática de diferentes tipos de dados confidenciais.
O Kubernetes oferece vários tipos embutidos de Secret para casos de uso comuns. Estes tipos variam em termos de validações
efetuadas e limitações que o Kubernetes impõe neles.
Você pode definir e utilizar seu próprio tipo de Secret definindo o valor do campo type como uma string não-nula em um objeto
Secret (uma string em branco é tratada como o tipo Opaque ).
O Kubernetes não restringe nomes de tipos. No entanto, quando tipos embutidos são utilizados, você precisa atender a todos os
requisitos daquele tipo.
Se você estiver definindo um tipo de Secret que seja para uso público, siga a convenção e estruture o tipo de Secret para conter o
seu domínio antes do nome, separado por uma barra ( / ). Por exemplo: cloud-hosting.example.net/cloud-api-credentials .
Para melhor desempenho em uma requisição get repetitiva, clientes podem criar objetos que referenciam o Secret e então utilizar
a requisição watch neste novo objeto, requisitando o Secret novamente quando a referência mudar. Além disso, uma API de
"observação em lotes" para permitir a clientes observar recursos individuais também foi proposta e provavelmente estará
disponível em versões futuras do Kubernetes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 127/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Opaque é o tipo predefinido de Secret quando o campo type é omitido em um arquivo de configuração de Secret. Quando um
Secret é criado usando o comando kubectl , você deve usar o subcomando generic para indicar que um Secret é do tipo Opaque .
Por exemplo, o comando a seguir cria um Secret vazio do tipo Opaque :
A coluna DATA demonstra a quantidade de dados armazenados no Secret. Neste caso, 0 significa que este objeto Secret está
vazio.
apiVersion: v1
kind: Secret
metadata:
name: secret-sa-sample
annotations:
kubernetes.io/service-account-name: "sa-name"
type: kubernetes.io/service-account-token
data:
# Você pode incluir pares chave-valor adicionais, da mesma forma que faria com
# Secrets do tipo Opaque
extra: YmFyCg==
Ao criar um Pod, o Kubernetes automaticamente cria um Secret de service account e automaticamente atualiza o seu Pod para
utilizar este Secret. O Secret de token de service account contém credenciais para acessar a API.
A criação automática e o uso de credenciais de API podem ser desativados ou substituídos se desejado. Porém, se tudo que você
necessita é poder acessar o servidor da API de forma segura, este é o processo recomendado.
Veja a documentação de ServiceAccount para mais informações sobre o funcionamento de service accounts. Você pode verificar
também os campos automountServiceAccountToken e serviceAccountName do Pod para mais informações sobre como referenciar
service accounts em Pods.
kubernetes.io/dockercfg
kubernetes.io/dockerconfigjson
O tipo kubernetes.io/dockercfg é reservado para armazenamento de um arquivo ~/.dockercfg serializado. Este arquivo é o
formato legado para configuração do utilitário de linha de comando do Docker. Ao utilizar este tipo de Secret, é preciso garantir que
o campo data contém uma chave .dockercfg cujo valor é o conteúdo do arquivo ~/.dockercfg codificado no formato base64.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 128/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O tipo kubernetes.io/dockerconfigjson foi projetado para armazenamento de um conteúdo JSON serializado que obedece às
mesmas regras de formato que o arquivo ~/.docker/config.json . Este arquivo é um formato mais moderno para o conteúdo do
arquivo ~/.dockercfg . Ao utilizar este tipo de Secret, o conteúdo do campo data deve conter uma chave .dockerconfigjson em
que o conteúdo do arquivo ~/.docker/config.json é fornecido codificado no formato base64.
apiVersion: v1
kind: Secret
metadata:
name: secret-dockercfg
type: kubernetes.io/dockercfg
data:
.dockercfg: |
"<base64 encoded ~/.dockercfg file>"
Nota: Se você não desejar fazer a codificação em formato base64, você pode utilizar o campo stringData como alternativa.
Ao criar estes tipos de Secret utilizando um manifesto (arquivo YAML), o servidor da API verifica se a chave esperada existe no
campo data e se o valor fornecido pode ser interpretado como um conteúdo JSON válido. O servidor da API não verifica se o
conteúdo informado é realmente um arquivo de configuração do Docker.
Quando você não tem um arquivo de configuração do Docker, ou quer utilizar o comando kubectl para criar um Secret de registro
de contêineres, você pode rodar o comando:
Esse comando cria um secret do tipo kubernetes.io/dockerconfigjson . Se você obtiver o conteúdo do campo
.data.dockerconfigjson deste novo Secret e decodificá-lo do formato base64:
o resultado será equivalente a este documento JSON (que também é um arquivo de configuração válido do Docker):
{
"auths": {
"my-registry.example:5000": {
"username": "tiger",
"password": "pass1234",
"email": "tiger@acme.example",
"auth": "dGlnZXI6cGFzczEyMzQ="
}
}
}
Nota: O valor do campo auth no exemplo acima é codificado em base64; ele está ofuscado mas não criptografado. Qualquer
pessoa com acesso a este Secret pode ler o conteúdo do token bearer.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 129/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Ambos os valores para estas duas chaves são textos codificados em formato base64. Você pode fornecer os valores como texto
simples utilizando o campo stringData na criação do Secret.
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
username: admin # required field for kubernetes.io/basic-auth
password: t0p-Secret # required field for kubernetes.io/basic-auth
O tipo de autenticação básica é fornecido unicamente por conveniência. Você pode criar um Secret do tipo Opaque utilizado para
autenticação básica. No entanto, utilizar o tipo embutido e público de Secret ( kubernetes.io/basic-auth ) auxilia outras pessoas a
compreenderem o propósito do seu Secret, e define uma convenção de expectativa de nomes de chaves O tipo embutido também
fornece verificação dos campos requeridos pelo servidor da API.
O manifesto abaixo é um exemplo de configuração para um Secret de autenticação SSH com um par de chaves pública/privada:
apiVersion: v1
kind: Secret
metadata:
name: secret-ssh-auth
type: kubernetes.io/ssh-auth
data:
# os dados estão abreviados neste exemplo
ssh-privatekey: |
MIIEpQIBAAKCAQEAulqb/Y ...
O Secret de autenticação SSH é fornecido apenas para a conveniência do usuário. Você pode criar um Secret do tipo Opaque para
credentials utilizadas para autenticação SSH. No entanto, a utilização do tipo embutido e público de Secret ( kubernetes.io/tls )
auxilia outras pessoas a compreenderem o propósito do seu Secret, e define uma convenção de quais chaves podem ser esperadas.
O tipo embutido também fornece verificação dos campos requeridos em uma configuração de Secret.
Cuidado: Chaves privadas SSH não estabelecem, por si só, uma comunicação confiável entre um cliente SSH e um servidor.
Uma forma secundária de estabelecer confiança é necessária para mitigar ataques man-in-the-middle (MITM), como por
exemplo um arquivo known_hosts adicionado a um ConfigMap.
Secrets TLS
O Kubernetes fornece o tipo embutido de Secret kubernetes.io/tls para armazenamento de um certificado e sua chave associada
que são tipicamente utilizados para TLS.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 130/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Uma utilização comum de Secrets TLS é a configuração de encriptação em trânsito para um recurso Ingress, mas este tipo de secret
pode também ser utilizado com outros recursos ou diretamente por uma carga de trabalho.
Ao utilizar este tipo de Secret, as chaves tls.key e tls.crt devem ser informadas no campo data (ou stringData ) da
configuração do Secret, embora o servidor da API não valide o conteúdo de cada uma destas chaves.
apiVersion: v1
kind: Secret
metadata:
name: secret-tls
type: kubernetes.io/tls
data:
# os dados estão abreviados neste exemplo
tls.crt: |
MIIC2DCCAcCgAwIBAgIBATANBgkqh ...
tls.key: |
MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...
O tipo TLS é fornecido para a conveniência do usuário. Você pode criar um Secret do tipo Opaque para credenciais utilizadas para o
servidor e/ou cliente TLS. No entanto, a utilização do tipo embutido auxilia a manter a consistência dos formatos de Secret no seu
projeto; o servidor da API valida se os campos requeridos estão presentes na configuração do Secret.
Ao criar um Secret TLS utilizando a ferramenta de linha de comando kubectl , você pode utilizar o subcomando tls conforme
demonstrado no exemplo abaixo:
O par de chaves pública/privada deve ser criado previamente. O certificado de chave pública a ser utilizado no argumento --cert
deve ser codificado em formato DER conforme especificado na seção 5.1 da RFC 7468 e deve corresponder à chave privada
fornecida no argumento --key (PKCS #8 no formato DER; seção 11 da RFC 7468).
Nota:
Um Secret kubernetes.io/tls armazena o conteúdo de chaves e certificados em formato DER codificado em base64. Se você tem
familiaridade com o formato PEM para chaves privadas e certificados, o conteúdo é o mesmo do formato PEM, excluindo-se a
primeira e a última linhas.
Por exemplo, para um certificado, você não inclui as linhas --------BEGIN CERTIFICATE----- e -------END CERTIFICATE---- .
Um Secret de token de autoinicialização é normalmente criado no namespace kube-system e nomeado na forma bootstrap-token-
<id-do-token> , onde <id-do-token> é um texto com 6 caracteres contendo a identificação do token.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 131/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-5emitj
namespace: kube-system
type: bootstrap.kubernetes.io/token
data:
auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4=
expiration: MjAyMC0wOS0xM1QwNDozOToxMFo=
token-id: NWVtaXRq
token-secret: a3E0Z2lodnN6emduMXAwcg==
usage-bootstrap-authentication: dHJ1ZQ==
usage-bootstrap-signing: dHJ1ZQ==
token-id : Uma string com 6 caracteres aleatórios como identificador do token. Requerido.
token-secret : Uma string de 16 caracteres aleatórios como o conteúdo secreto do token. Requerido.
description : Uma string contendo uma descrição do propósito para o qual este token é utilizado. Opcional.
expiration : Um horário absoluto UTC no formato RFC3339 especificando quando o token deve expirar. Opcional.
usage-bootstrap-<usage> : Um conjunto de flags booleanas indicando outros usos para este token de autoinicialização.
auth-extra-groups: Uma lista separada por vírgulas de nomes de grupos que serão autenticados adicionalmente, além do
grupo system:bootstrappers .
O YAML acima pode parecer confuso, já que os valores estão todos codificados em formato base64. Você pode criar o mesmo Secret
utilizando este YAML:
apiVersion: v1
kind: Secret
metadata:
# Observe como o Secret é nomeado
name: bootstrap-token-5emitj
# Um Secret de token de inicialização geralmente fica armazenado no namespace
# kube-system
namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
auth-extra-groups: "system:bootstrappers:kubeadm:default-node-token"
expiration: "2020-09-13T04:39:10Z"
# Esta identificação de token é utilizada no nome
token-id: "5emitj"
token-secret: "kq4gihvszzgn1p0r"
# Este token pode ser utilizado para autenticação
usage-bootstrap-authentication: "true"
# e pode ser utilizado para assinaturas
usage-bootstrap-signing: "true"
Secrets imutáveis
ESTADO DA FUNCIONALIDADE: Kubernetes v1.21 [stable]
O Kubernetes permite que você marque Secrets (e ConfigMaps) específicos como imutáveis. Prevenir mudanças nos dados de um
Secret existente tem os seguintes benefícios:
protege você de alterações acidentais (ou indesejadas) que poderiam provocar disrupções em aplicações.
em clusters com uso extensivo de Secrets (pelo menos dezenas de milhares de montagens únicas de Secrets a Pods), utilizar
Secrets imutáveis melhora o desempenho do seu cluster através da redução significativa de carga no kube-apiserver. O
kubelet não precisa manter um watch em Secrets que são marcados como imutáveis.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 132/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Secret
metadata:
...
data:
...
immutable: true
Você pode também atualizar qualquer Secret mutável existente para torná-lo imutável.
Nota: Uma vez que um Secret ou ConfigMap seja marcado como imutável, não é mais possível reverter esta mudança, nem
alterar os conteúdos do campo data. Você pode somente apagar e recriar o Secret. Pods existentes mantém um ponto de
montagem referenciando o Secret removido - é recomendado recriar tais Pods.
Secrets frequentemente contém valores dentro de um espectro de importância, muitos dos quais podem provocar escalações de
privilégios dentro do Kubernetes (por exemplo, um token de service account) e em sistemas externos. Mesmo que uma aplicação
individual possa avaliar o poder dos Secrets com os quais espera interagir, outras aplicações dentro do mesmo namespace podem
tornar tais suposições inválidas.
Um Secret só é enviado a um nó se um Pod naquele nó precisa do Secret em questão. Para montar Secrets em Pods, o kubelet
armazena uma cópia dos dados dentro de um sistema de arquivos tmpfs , de modo que os dados confidenciais não sejam escritos
em armazenamento durável. Uma vez que o Pod que dependia do Secret seja removido, o kubelet apaga sua cópia local dos dados
confidenciais do Secret.
Um Pod pode possuir vários contêineres. Por padrão, contêineres que você define têm acesso somente à ServiceAccount padrão e
seu Secret relacionado. Você deve explicitamente definir variáveis de ambiente ou mapear um volume dentro de um contêiner para
ter acesso a qualquer outro Secret.
Podem haver Secrets para vários Pods no mesmo nó. No entanto, somente os Secrets que um Pod requisitou estão potencialmente
visíveis dentro de seus contêineres. Portanto, um Pod não tem acesso aos Secrets de outro Pod.
Aviso: Quaisquer contêineres privilegiados em um nó são passíveis de acesso a todos os Secrets naquele nó.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 133/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Cuidado: Um usuário que pode criar um Pod que utiliza um Secret pode também ver o valor daquele Secret. Mesmo que as
permissões do cluster não permitam ao usuário ler o Secret diretamente, o mesmo usuário poderia ter acesso a criar um Pod
que então expõe o Secret.
Restrinja a habilidade de usar as requisições watch e list para listar todos os Secrets em um cluster (utilizando a API do
Kubernetes) de modo que somente os componentes mais privilegiados e de nível de sistema possam realizar esta ação.
Ao instalar aplicações que interajam com a API de Secrets, você deve limitar o acesso utilizando políticas de autorização, como
por exemplo RBAC.
No servidor da API, objetos (incluindo Secrets) são persistidos no etcd; portanto:
somente permita a administradores do sistema o acesso ao etcd (incluindo acesso somente-leitura);
habilite encriptação em disco para objetos Secret, de modo que os dados de tais Secrets não sejam armazenados em
texto plano no etcd;
considere a destruição do armazenamento durável previamente utilizado pelo etcd quando não estiver mais em uso;
se houverem múltiplas instâncias do etcd em uso, garanta que o etcd esteja configurado para utilizar SSL/TLS para
comunicação entre instâncias.
Próximos passos
Aprenda a gerenciar Secrets utilizando kubectl
Aprenda a gerenciar Secrets utilizando arquivos de configuração
Aprenda a gerenciar Secrets utilizando kustomize
Leia a documentação de referência da API de Secrets
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 134/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Quando você especifica o requerimento de recursos em um Pod, o kube-scheduler utiliza esta informação para decidir a qual nó o
Pod será atribuído. Quando você especifica um limite de recurso para um contêiner, o kubelet garante o cumprimento de tais
limites, de modo que o contêiner em execução não consiga utilizar uma quantidade de tal recurso além do limite especificado. O
kubelet também reserva pelo menos o requerimento daquele recurso de sistema especificamente para que este contêiner utilize.
Requerimentos e limites
Se o nó em que um Pod está rodando tem o suficiente de um recurso específico disponível, é possível (e permitido) a um contêiner
utilizar mais do que o seu request para aquele recurso especifica. No entanto, não é permitido a um contêiner consumir mais do
que o seu limit para um recurso.
Por exemplo, se você especificar um requerimento de memory de 256 MiB para um contêiner, e aquele contêiner está em um Pod
atribuído a um nó com 8GiB de memória, sem outros Pods, então este contêiner pode tentar consumir mais memória RAM.
Se você especificar um limite de memory de 4GiB para aquele contêiner, o kubelet (e o agente de execução de contêiner) vão
garantir o cumprimento do limite. O agente de execução impede que o contêiner utilize mais de um recurso do que seu limite
configurado. Por exemplo, quando um processo no contêiner tenta consumir mais que o limite permitido de memória, o núcleo do
sistema encerra o processo que tentou efetuar a alocação de memória com um erro de memória esgotada (out of memory (OOM)
error).
Limites podem ser implementados de forma reativa (o sistema intervém quando uma violação ocorre) ou por garantia (o sistema
previne o contêiner de exceder o limite). Diferentes agentes de execução implementam as mesmas restrições de maneiras
diferentes.
Nota: Se um contêiner especifica seu próprio limite de memória, mas não especifica seu requerimento de memória, o
Kubernetes automaticamente cria um requerimento de memória com o mesmo valor do limite. A mesma regra vale para o
limite de CPU: quando não há requerimento de CPU, o Kubernetes automaticamente cria um requerimento de CPU idêntico ao
limite.
Tipos de recursos
CPU e memória são tipos de recursos. Um tipo de recurso possui uma unidade básica. CPU representa processamento computacional
e é especificada em unidades de CPU do Kubernetes. Memória é especificada em bytes. Em cargas de trabalho Linux, você pode
especificar o recurso huge pages. Huge pages são uma funcionalidade específica do Linux que permite ao núcleo do sistema
operacional alocar blocos de memória muito maiores que o tamanho de página de memória padrão.
Por exemplo, em um sistema onde o tamanho da página de memória padrão é de 4 KiB, você pode especificar um limite hugepages-
2Mi: 80Mi . Se o contêiner tentar alocar mais de 40 huge pages de 2 MiB cada, ou um total de 80 MiB, essa alocação irá falhar.
Nota: Você não pode superdimensionar (ou solicitar acima do limite físico) recursos do tipo hugepages-*. O recurso hugepages-
* difere dos recursos memory e cpu neste aspecto.
CPU e memória são chamados coletivamente de recursos computacionais, ou apenas recursos. Recursos computacionais são
quantidades mensuráveis que podem ser requisitadas, alocadas, e consumidas. Estes recursos diferem dos recursos de API.
Recursos de API, como Pods e Services são objetos que podem ser lidos e modificados através do servidor da API do Kubernetes.
spec.containers[].resources.limits.cpu
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 135/233
4/15/24, 11:56 AM Conceitos | Kubernetes
spec.containers[].resources.limits.memory
spec.containers[].resources.limits.hugepages-<size>
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory
spec.containers[].resources.requests.hugepages-<size>
Embora você possa especificar apenas requerimentos e limites para contêineres individuais, é útil também pensar sobre os
requerimentos e limites gerais de um Pod. Para um recurso em particular, um requerimento ou limite de recurso de um Pod é a soma
de todos os valores dos requerimentos ou limites de um recurso daquele tipo, especificados em cada um dos contêineres daquele
Pod.
Requerimentos fracionários são permitidos. Quando você define um contêiner cujo valor do campo
spec.containers[].resources.requests.cpu é 0.5 , você está solicitando metade da quantidade de CPU que teria sido solicitada
caso o valor fosse 1.0 . No caso de unidades de recurso de CPU, a expressão de quantidade 0.1 é equivalente à expressão 100m ,
que pode ser lida como "cem milicpus", ou "cem milinúcleos". "Milicpu" ou "milinúcleo" equivalem à milésima parte de um núcleo ou
CPU, de modo que "100m" equivalem a 10% do tempo computacional de um processador.
Recursos de CPU são sempre especificados como uma quantidade absoluta de recurso, nunca como uma quantidade relativa. Por
exemplo, 500m de CPU representam grosseiramente a mesma quantidade de poder computacional, independentemente do
contêiner rodar em uma máquina com processador de núcleo único, de dois núcleos ou de 48 núcleos.
Nota: O Kubernetes não permite que você especifique recursos de CPU com uma precisão maior que 1m. Devido a isso, é útil
especificar unidades de CPU menores do que 1.0 ou 1000m utilizando a notação de milicpu. Por exemplo, 5m ao invés de 0.005.
Tome cuidado com os sufixos. Se você solicitar 400m de memória, esta quantidade estará de fato requerendo o equivalente a 0,4
byte de memória. A intenção da pessoa que fez esta requisição provavelmente era solictar 400 mebibytes ( 400Mi ) ou 400
megabytes ( 400M ).
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 136/233
4/15/24, 11:56 AM Conceitos | Kubernetes
---
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
No Linux, o agente de execução de contêiner normalmente configura os cgroups que aplicam e garantem os limites que você
definiu.
O limite de CPU determina um teto de quanto tempo de CPU o contêiner pode utilizar. A cada intervalo de agendamento, o
núcleo do sistema operacional do Linux verifica se este limite foi excedido; se este for o caso, o núcleo aguarda antes de
permitir que aquele cgroup continue sua execução.
O requerimento de CPU normalmente define um método de balanceamento. Se vários contêineres diferentes (cgroups)
querem rodar em um sistema disputado, cargas de trabalho com requerimentos maiores de CPU têm mais tempo de CPU
alocado para si do que cargas de trabalho com pequenos requerimentos.
O requerimento de memória é usado principalmente durante o agendamento de um Pod. Em um nó que utiliza cgroups v2, o
agente de execução de contêiner pode utilizar o requerimento de memória como uma dica para definir valores para
memory.min e memory.low .
O limite de memória define um limite de memória para aquele cgroup. Se o contêiner tenta alocar mais memória que aquele
limite, o subsistema out-of-memory do núcleo do sistema operacional Linux é ativado e, normalmente, intervém encerrando
um dos processos do contêiner que tentou alocar mais memória. Se o processo em questão for o PID 1 do contêiner, e o
contêiner estiver marcado como reinicializável, então o Kubernetes irá reiniciar o contêiner.
O limite de memória para um Pod ou contêiner é também aplicado a páginas em volumes armazenados em memória, como
um emptyDir . O kubelet considera sistemas de arquivos tmpfs em volumes do tipo emptyDir como uso de memória em um
contêiner, ao invés de armazenamento efêmero local.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 137/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Se um contêiner exceder seu requerimento de memória e o nó em que esse contêiner está rodando ficar com pouca memória no
total, é provável que o Pod a que este contêiner pertence seja removido.
A um contêiner pode ou não ser permitido exceder seu limite de CPU por períodos de tempo estendidos. No entanto, agentes de
execução de contêiner não encerram Pods por uso excessivo de CPU.
A fim de determinar se um contêiner não pode ser agendado ou está sendo encerrado devido a limites de recursos, consulte a
seção de solução de problemas.
Se ferramentas opcionais para monitoramento de recursos estiverem disponíveis em seu cluster, a utilização de recursos de um
Pod pode ser verificada diretamente através de API de métricas ou através das suas ferramentas de monitoramento
Nós possuem armazenamento efêmero local, através de dispositivos de escrita conectados localmente ou através de RAM.
"Efêmero" significa que não há garantia de longo termo com relação a durabilidade.
Pods utilizam armazenamento local efêmero para dados temporários, cache e logs. O kubelet pode fornecer armazenamento
temporário a Pods que utilizam armazenamento local efêmero para montar volumes do tipo emptyDir em contêineres.
O kubelet também utiliza este tipo de armazenamento para logs de contêineres a nível de nó, imagens de contêiner e camadas
graváveis de contêineres em execução.
Cuidado: Se um nó falhar, os dados em seu armazenamento efêmero podem ser perdidos. Suas aplicações não devem ter
expectativas de cumprimento de SLAs de desempenho (como quantidade de operações de entrada e saída de disco por
segundo (IOPS), por exemplo) pelo armazenamento local efêmero.
Com esta funcionalidade em fase beta, o Kubernetes permite que você rastreie, reserve e limite quanto armazenamento local
efêmero um Pod pode consumir.
Nesta configuração, você armazena todos os tipos diferentes de dados locais efêmeros (volumes do tipo emptyDir , camadas
graváveis, imagens de contêiner, logs) em um sistema de arquivos único. A forma mais efetiva de configurar o kubelet é dedicar
este sistema de arquivos aos dados do Kubernetes (kubelet).
O kubelet também escreve logs de contêiner a nível de nó e trata estes logs de maneira semelhante ao armazenamento
efêmero local.
O kubelet escreve logs em arquivos dentro do seu diretório de log configurado ( /var/log por padrão) e possui um diretório
base para outros dados armazenados localmente ( /var/lib/kubelet por padrão).
Normalmente, ambos os diretórios /var/lib/kubelet e /var/log encontram-se no sistema de arquivos raiz, e o kubelet é
projetado com este desenho em mente.
Seu nó pode ter tantos outros sistemas de arquivos não utilizados pelo Kubernetes quantos você desejar.
O kubelet consegue medir quanto armazenamento local está sendo utilizado. O kubelet faz isso desde que:
o feature gate LocalStorageCapacityIsolation esteja habilitado (a funcionalidade está ligada por padrão), e
você tenha configurado o nó utilizando uma das configurações suportadas para o armazenamento local efêmero.
Se você tiver uma configuração diferente, o kubelet não irá aplicar limites de recursos para o armazenamento local efêmero.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 138/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: O kubelet rastreia volumes emptyDir que utilizem o sistema de arquivos tmpfs como uso de memória de contêiner, ao
invés de consumo de armazenamento local efêmero.
spec.containers[].resources.limits.ephemeral-storage
spec.containers[].resources.requests.ephemeral-storage
Limites e requerimentos de ephemeral-storage são medidos em quantidades de bytes. Você pode expressar armazenamento
como um inteiro ou como um valor de ponto fixo utilizando um dos seguintes sufixos: E, P, T, G, M, k. Você pode também utilizar os
equivalentes de potência de dois: Ei, Pi, Ti, Gi, Mi, Ki. Por exemplo, as quantidades abaixo representam grosseiramente o mesmo
valor:
128974848
129e6
129M
123Mi
No exemplo a seguir, o Pod tem dois contêineres. Cada contêiner tem um requerimento de 2GiB de armazenamento efêmero local.
Cada contêiner tem um limite de 4GiB de armazenamento efêmero local. Portanto, o Pod tem um requerimento de 4GiB e um limite
de 8GiB de armazenamento efêmero local.
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
volumeMounts:
- name: ephemeral
mountPath: "/tmp"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
ephemeral-storage: "2Gi"
limits:
ephemeral-storage: "4Gi"
volumeMounts:
- name: ephemeral
mountPath: "/tmp"
volumes:
- name: ephemeral
emptyDir: {}
O escalonador garante que a soma dos requerimentos de recursos dos contêineres agendados é menor que a capacidade do nó.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 139/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Se um Pod estiver utilizando mais armazenamento efêmero do que o permitido, o kubelet irá gerar um sinal de remoção para
aquele Pod.
Para isolamento a nível de contêiner, se o consumo de armazenamento de um contêiner em camadas graváveis e logs exceder seu
limite de armazenamento, o kubelet irá marcar o Pod para remoção.
Para isolamento a nível de Pod, o kubelet calcula um limite de armazenamento total para um Pod somando os limites de cada
contêiner naquele Pod. Neste caso, se a soma do consumo de armazenamento efêmero local de todas os contêineres e também
dos volumes emptyDir de um Pod exceder o limite de armazenamento total do Pod, então o kubelet marca o Pod para remoção.
Cuidado:
Se o kubelet não estiver medindo armazenamento efêmero local, um Pod que exeder seu limite de armazenamento local não
será removido por exceder os limites de recurso de armazenamento local.
No entanto, se o espaço de um sistema de arquivos para camadas de contêiner graváveis, logs a nível de nó, ou volumes
emptyDir ficar reduzido, o nó irá marcar a si próprio com um taint indicando que está com armazenamento local reduzido, e
esse taint dispara a remoção de Pods que não toleram o taint em questão.
O kubelet executa verificações agendadas, em intervalos regulares, que varrem cada volume do tipo emptyDir , diretório de log
de contêiner, e camada gravável de contêiner.
Nota:
Neste modo, o kubelet não rastreia descritores de arquivos abertos para arquivos removidos.
Se você (ou um contêiner) criar um arquivo dentro de um volume emptyDir , um processo ou usuário abrir tal arquivo, e
você apagar o arquivo enquanto ele ainda estiver aberto, o nó de índice para o arquivo apagado será mantido até que o
arquivo seja fechado novamente. O kubelet, no entanto, não computa este espaço como espaço em uso.
Recursos estendidos
Recursos estendidos são nomes de recursos absolutos fora do domínio kubernetes.io . Estes recursos permitem a operadores de
cluster anunciar e a usuários consumir recursos que não são embutidos pelo Kubernetes.
Dois passos são necessários para a utilização de recursos estendidos. Primeiramente, o operador do cluster deve anunciar um
recurso estendido. Em segundo lugar, os usuários devem solicitar o recurso estendido em Pods.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 140/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Outros recursos
A fim de anunciar um novo recurso estendido a nível de nó, o operador do cluster pode enviar uma requisição HTTP com o método
PATCH para o servidor da API do Kubernetes para especificar a quantidade disponível em um nó no cluster, através do campo
status.capacity . Após a realização desta operação, o campo status.capacity do nó irá conter um novo recurso. O campo
status.allocatable é atualizado automaticamente pelo kubelet, de forma assíncrona, com o novo recurso.
Como o escalonador utiliza o valor do campo status.allocatable do nó ao verificar a saúde do Pod, o escalonador somente
considerará o novo valor do campo após esta atualização assíncrona. Pode haver um pequeno atraso entre a atualização da
capacidade do nó com um novo recurso e o momento em que o primeiro Pod que requer o recurso poderá ser agendado naquele
nó.
Exemplo:
Este exemplo demonstra como utilizar a ferramenta curl para criar uma requisição HTTP que anuncia cinco recursos
"example.com/foo" no nó k8s-node-1 , cujo nó da camada de gerenciamento é k8s-master .
Nota: Na requisição anterior, a notação ~1 é a codificação do caractere / no campo path para a operação de atualização. O
valor do campo path em JSON-Patch é interpretado como um JSON-Pointer. Para maiores detalhes, veja a seção 3 da IETF RFC
6901.
Você pode especificar os recursos estendidos que são manipulados por extensões do escalonador nas configurações do kube-
scheduler.
Exemplo:
A configuração abaixo para uma política do escalonador indica que o recurso estendido a nível de cluster "example.com/foo" é
manipulado pelas extensões do escalonador.
O escalonador envia um Pod para a extensão do escalonador somente se o Pod solicitar "example.com/foo".
O campo ignoredByScheduler especifica que o escalonador não verifica o recurso "example.com/foo" em seu predicado
PodFitsResources .
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 141/233
4/15/24, 11:56 AM Conceitos | Kubernetes
{
"kind": "Policy",
"apiVersion": "v1",
"extenders": [
{
"urlPrefix":"<extender-endpoint>",
"bindVerb": "bind",
"managedResources": [
{
"name": "example.com/foo",
"ignoredByScheduler": true
}
]
}
]
}
O servidor da API limita as quantidades de recursos estendidos a números inteiros. Exemplos de quantidades válidas são 3 , 3000m
e 3Ki . Exemplos de quantidades inválidas são 0.5 e 1500m .
Nota: Recursos estendidos substituem os Recursos Inteiros Opacos. Usuários podem escolher qualquer prefixo de nome de
domínio, com exceção do domínio kubernetes.io, que é reservado.
Para consumir um recurso estendido em um Pod, inclua o nome do recurso como uma chave no mapa
spec.containers[].resources.limits na especificação do contêiner.
Nota: Recursos estendidos não podem ser superdimensionados. Portanto, request e limit devem ser iguais se ambos
estiverem presentes na especificação de um contêiner.
Um Pod só é agendado se todos os seus requerimentos de recursos forem satisfeitos, incluindo CPU, memória e quaisquer recursos
estendidos. O Pod permanece no estado PENDING enquanto seus requerimentos de recursos não puderem ser satisfeitos.
Exemplo:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: myimage
resources:
requests:
cpu: 2
example.com/foo: 1
limits:
example.com/foo: 1
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 142/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Limitação de PID
Limites de ID de processo (PID) permitem à configuração de um kubelet limitar o número de PIDs que um dado Pod pode consumir.
Consulte PID Limiting para mais informações.
Solução de problemas
Meus pods estão pendentes com um evento FailedScheduling
Se o escalonador não conseguir encontrar nenhum nó que atenda aos requisitos de recursos do Pod, este Pod permanecerá não-
agendado até que um local destino possa ser encontrado. Um Evento é produzido cada vez que o escalonador falhar em encontrar
um local para agendar o Pod. Você pode utilizar o utilitário kubectl para ver os eventos de um Pod. Por exemplo:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 23s default-scheduler 0/42 nodes available: insufficient cpu
No exemplo acima, o Pod de nome "frontend" não pôde ser agendado devido à nenhum nó possuir CPU suficiente para suprir seu
requerimento de CPU. Mensagens de erro semelhantes a essa podem sugerir falha devido a falta de memória
( PodExceedsFreeMemory ). De maneira geral, se um Pod estiver pendente com uma mensagem deste tipo, há diversas possibilidades
de solução a serem tentadas:
Você pode verificar capacidades de nós e quantidades alocadas com o comando kubectl describe nodes . Por exemplo:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 143/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: e2e-test-node-pool-4lw4
[ ... linhas abreviadas para simplificação ...]
Capacity:
cpu: 2
memory: 7679792Ki
pods: 110
Allocatable:
cpu: 1800m
memory: 7474992Ki
pods: 110
[ ... linhas abreviadas para simplificação ...]
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits
--------- ---- ------------ ---------- --------------- -------------
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 200Mi (2%) 200Mi (2%)
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 100Mi (1%) 170Mi (2%)
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0 (0%) 0 (0%)
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 600Mi (8%) 600Mi (8%)
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20Mi (0%) 100Mi (1%)
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
CPU Requests CPU Limits Memory Requests Memory Limits
------------ ---------- --------------- -------------
680m (34%) 400m (20%) 920Mi (11%) 1070Mi (13%)
No exemplo anterior, você pode verificar que se um Pod requisitar mais que 1,120 CPUs ou mais que 6,23Gi de memória, tal Pod
não caberá neste nó.
Ao verificar a seção "Pods", você pode observar quais Pods estão consumindo espaço neste nó.
A quantidade de recursos disponível aos Pods é menor que a capacidade do nó, pois daemons do sistema utilizam uma parcela dos
recursos disponíveis. Dentro da API do Kubernetes, cada nó tem um campo .status.allocatable (consulte NodeStatus para mais
detalhes).
O campo .status.allocatable descreve a quantidade de recursos que está disponível a Pods naquele nó (por exemplo: 15 CPUs
virtuais e 7538 MiB de memória). Para mais informações sobre recursos alocáveis do nó no Kubernetes, veja Reserve Compute
Resources for System Daemons.
Você pode configurar quotas de recursos para limitar a quantidade total de recursos que um namespace pode consumir. O
Kubernetes garante quotas para objetos em um namespace específico quando há uma ResourceQuota naquele namespace. Por
exemplo, se você atribuir namespaces específicos a times diferentes, você pode adicionar ResourceQuota s nestes namespaces.
Criar quotas de recursos ajuda a evitar que um time utilize tanto de um recurso que chegue a afetar outros times utilizando o
mesmo cluster.
Você deve também considerar o nível de acesso fornecido aos usuários de qualquer namespace: acesso completo para escrita
permite a alguém com este acesso remover qualquer recurso, incluindo uma configuração de ResourceQuota .
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 144/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Containers:
simmemleak:
Image: saadali/simmemleak:latest
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2019 12:54:41 -0700
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Started: Fri, 07 Jul 2019 12:54:30 -0700
Finished: Fri, 07 Jul 2019 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Normal Pulled 41s kubelet Container image "saadali/simmemleak:latest" already present on machine
Normal Created 41s kubelet Created container simmemleak
Normal Started 40s kubelet Started container simmemleak
Normal Killing 32s kubelet Killing container with id ead3fb35-5cf5-44ed-9ae1-488115be66c6: Need t
No exemplo acima, o campo Restart Count: 5 indica que o contêiner simmemleak deste Pod foi terminado e reiniciado cinco
vezes até o momento. A razão OOMKilled demonstra que o contêiner tentou consumir mais memória do que o seu limite.
O próximo passo neste cenário seria vasculhar e depurar o código da aplicação, procurando por vazamentos de memória. Se você
determinar que a aplicação está se comportando conforme o esperado, considere aumentar o limite (e possivelmente o
requerimento) de memória para aquele contêiner.
Próximos passos
Pratique a criação de requerimentos de recursos de memória em contêineres e Pods.
Pratique a criação de requerimentos de CPU em contêineres and Pods.
Leia como a referência da API define um contêiner e seus requerimentos de recursos.
Leia sobre quotas de projeto no XFS.
Leia mais sobre a referência de configuração do kube-scheduler (v1beta3).
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 145/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Um arquivo que é utilizado para configurar o acesso aos clusters é chamado de kubeconfig. Esta á uma forma genérica de
referenciamento para um arquivo de configuração desta natureza. Isso não significa que existe um arquivo com o nome
kubeconfig.
Por padrão, o kubectl procura por um arquivo de nome config no diretório $HOME/.kube
Você pode especificar outros arquivos kubeconfig através da variável de ambiente KUBECONFIG ou adicionando a opção --
kubeconfig .
Para maiores detalhes na criação e especificação de um kubeconfig, veja o passo a passo em Configurar Acesso para Múltiplos
Clusters.
Através de arquivos kubeconfig, você pode organizar os seus clusters, usuários, e namespaces. Você também pode definir contextos
para uma fácil troca entre clusters e namespaces.
Contexto
Um elemento de contexto em um kubeconfig é utilizado para agrupar parâmetros de acesso em um nome conveniente. Cada
contexto possui três parâmetros: cluster, namespace, e usuário.
Por padrão, a ferramenta de linha de comando kubectl utiliza os parâmetros do contexto atual para se comunicar com o cluster.
Se a variável de ambiente KUBECONFIG existir, o kubectl utilizará uma configuração que é o resultado da combinação dos arquivos
listados na variável de ambiente KUBECONFIG .
Como descrito anteriormente, a saída poderá ser resultado de um único arquivo kubeconfig, ou poderá ser o resultado da junção
de vários arquivos kubeconfig.
Aqui estão as regras que o kubectl utiliza quando realiza a combinação de arquivos kubeconfig:
1. Se o argumento --kubeconfig está definido, apenas o arquivo especificado será utilizado. Apenas uma instância desta flag é
permitida.
Caso contrário, se a variável de ambiente KUBECONFIG estiver definida, esta deverá ser utilizada como uma lista de arquivos a
serem combinados, seguindo o fluxo a seguir:
Caso contrário, utilize o arquivo kubeconfig padrão encontrado no diretório $HOME/.kube/config , sem qualquer tipo de
combinação.
2. Determine o contexto a ser utilizado baseado no primeiro padrão encontrado, nesta ordem:
3. Determinar o cluster e o usuário. Neste ponto, poderá ou não existir um contexto. Determinar o cluster e o usuário no
primeiro padrão encontrado de acordo com a ordem à seguir. Este procedimento deverá executado duas vezes: uma para
definir o usuário a outra para definir o cluster.
4. Determinar as informações do cluster atual a serem utilizadas. Neste ponto, poderá ou não existir informações de um cluster.
Construir cada peça de informação do cluster baseado nas opções à seguir; a primeira ocorrência encontrada será a opção
vencedora:
Referências de arquivos
Arquivos e caminhos referenciados em um arquivo kubeconfig são relativos à localização do arquivo kubeconfig.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 147/233
4/15/24, 11:56 AM Conceitos | Kubernetes
No arquivo $HOME/.kube/config , caminhos relativos são armazenados de forma relativa, e caminhos absolutos são armazenados
de forma absoluta.
Próximos passos
Configurar Accesso para Multiplos Clusters
kubectl config
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 148/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Em nós Linux, cgroups são usados como uma divisão para o controle de recursos em Pods. Os contêineres são criados dentro desse
limite para o isolamento de rede, processo e sistema de arquivos. As APIs de cgroup do Linux podem ser usadas para coletar
estatísticas de uso de CPU, E/S e memória.
Em contraste, o Windows usa um objeto de trabalho por contêiner com um filtro de namespace do sistema para conter todos os
processos em um contêiner e fornecer isolamento lógico ao hospedar. (Os objetos de trabalho são um mecanismo de isolamento de
processo do Windows e são diferentes dos que o Kubernetes chama de Job).
Não há como executar um contêiner do Windows sem a filtragem de namespace. Isso significa que os privilégios do sistema não
podem ser assegurados no contexto do host e, portanto, os contêineres privilegiados não estão disponíveis no Windows. Os
contêineres não podem assumir uma identidade do host porque o Gerente de Conta de Segurança (Security Account Manager, ou
SAM) é separado.
Gerenciamento de memória
O Windows não possui um eliminador de processo por falta de memória como o Linux. O Windows sempre trata todas as alocações
de memória do modo de usuário como virtuais e os arquivos de paginação são obrigatórios.
Os nós Windows não superdimensionam a memória para os processos. O efeito real é que o Windows não atingirá as condições de
falta de memória da mesma forma que o Linux, e estará processando a página em disco em vez de estar sujeito ao encerramento
por falta de memória (OOM). Se a memória for superprovisionada e toda a memória física estiver esgotada, a paginação poderá
diminuir o desempenho.
Gerenciamento de CPU
O Windows pode limitar a quantidade de tempo de CPU alocado para diferentes processos, mas não pode garantir uma quantidade
mínima de tempo de CPU.
No Windows, o kubelet oferece suporte a uma flag de linha de comando para definir a prioridade do escalonador do processo
kubelet: --windows-priorityclass . Essa flag permite que o processo kubelet obtenha mais fatias de tempo de CPU quando
comparado a outros processos em execução no host do Windows. Mais informações sobre os valores permitidos e os seus
significados estão disponíveis em classes de prioridade do Windows. Para garantir que os Pods em execução não deixem o kubelet
sem ciclos de CPU, defina essa flag como ABOVE_NORMAL_PRIORITY_CLASS ou acima.
Reserva de recursos
Para contabilizar a memória e a CPU usadas pelo sistema operacional, o agente de execução de contêiner e os processos de host do
Kubernetes, como o kubelet, você pode (e deve) reservar recursos de memória e CPU com as flags --kube-reserved e/ou --
system-reserved do kubelet. No Windows, esses valores são usados apenas para calcular o recursos alocáveis pelo nó.
Cuidado:
Conforme você implanta cargas de trabalho, defina a memória de recursos e os limites de CPU nos contêineres. Isso também
subtrai de NodeAllocatable e ajuda o escalonador de todo o cluster a determinar quais pods colocar em quais nós.
Alocar pods sem limites pode superprovisionar os nós do Windows e, em casos extremos, fazer com que os nós não sejam
íntegros.
Para determinar quanta CPU reservar, identifique a densidade máxima do pod para cada nó e monitore o uso da CPU dos serviços
do sistema em execução, depois escolha um valor que atenda às necessidades das suas cargas de trabalho.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 149/233
4/15/24, 11:56 AM Conceitos | Kubernetes
7 - Segurança
7.1 - Visão Geral da Segurança Cloud Native
Esta visão geral define um modelo para pensar sobre a segurança em Kubernetes no contexto da Segurança em Cloud Native.
Aviso: Este modelo de segurança no contêiner fornece sugestões, não prova políticas de segurança da informação.
Nota: Esta abordagem em camadas aumenta a defesa em profundidade para segurança, que é amplamente considerada como
uma boa prática de segurança para software de sistemas.
Cada camada do modelo de segurança Cloud Native é construída sobre a próxima camada mais externa. A camada de código se
beneficia de uma base forte (Cloud, Cluster, Contêiner) de camadas seguras. Você não pode proteger contra padrões ruins de
segurança nas camadas de base através de segurança no nível do Código.
Cloud
De muitas maneiras, a Cloud (ou servidores co-localizados, ou o datacenter corporativo) é a base de computação confiável de um
cluster Kubernetes. Se a camada de Cloud é vulnerável (ou configurado de alguma maneira vulnerável), então não há garantia de
que os componentes construídos em cima desta base estejam seguros. Cada provedor de Cloud faz recomendações de segurança
para executar as cargas de trabalho com segurança nos ambientes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 150/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Segurança de Infraestrutura
Sugestões para proteger sua infraestrutura em um cluster Kubernetes:
Acesso de rede ao Todo o acesso ao control plane do Kubernetes publicamente na Internet não é permitido e é
servidor API (Control controlado por listas de controle de acesso à rede restritas ao conjunto de endereços IP necessários
plane) para administrar o cluster.
Acesso de rede aos Nós Os nós devem ser configurados para só aceitar conexões (por meio de listas de controle de acesso à
(nodes) rede) do control plane nas portas especificadas e aceitar conexões para serviços no Kubernetes do
tipo NodePort e LoadBalancer. Se possível, esses nós não devem ser expostos inteiramente na
Internet pública.
Acesso do Kubernetes à Cada provedor de nuvem precisa conceder um conjunto diferente de permissões para o control
API do provedor de plane e nós do Kubernetes. É melhor fornecer ao cluster permissão de acesso ao provedor de nuvem
Cloud que segue o princípio do menor privilégio para os recursos que ele precisa administrar. A
documentação do Kops fornece informações sobre as políticas e roles do IAM.
Acesso ao etcd O acesso ao etcd (o armazenamento de dados do Kubernetes) deve ser limitado apenas ao control
plane. Dependendo de sua configuração, você deve tentar usar etcd sobre TLS. Mais informações
podem ser encontradas na documentação do etcd.
Encriptação etcd Sempre que possível, é uma boa prática encriptar todas as unidades de armazenamento, mas como
o etcd mantém o estado de todo o cluster (incluindo os Secrets), seu disco deve ser criptografado.
Cluster
Existem duas áreas de preocupação para proteger o Kubernetes:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 151/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Componentes do Cluster
Se você deseja proteger seu cluster de acesso acidental ou malicioso e adotar boas práticas de informação, leia e siga os conselhos
sobre protegendo seu cluster.
Autenticação https://kubernetes.io/docs/concepts/security/controlling-access/
Contêiner
A segurança do contêiner está fora do escopo deste guia. Aqui estão recomendações gerais e links para explorar este tópico:
Scanners de Vulnerabilidade de Como parte da etapa de construção de imagem, você deve usar algum scanner em
Contêiner e Segurança de seus contêineres em busca de vulnerabilidades.
Dependência de SO
Assinatura Imagem e Enforcement Assinatura de imagens de contêineres para manter um sistema de confiança para o
conteúdo de seus contêineres.
Proibir Usuários Privilegiados Ao construir contêineres, consulte a documentação para criar usuários dentro dos
contêineres que tenham o menor nível de privilégio no sistema operacional necessário
para cumprir o objetivo do contêiner.
Use o Contêiner em Runtime com Selecione classes de contêiner runtime com o provedor de isolamento mais forte.
Isolamento mais Forte
Código
O código da aplicação é uma das principais superfícies de ataque sobre a qual você tem maior controle. Embora a proteção do
código do aplicativo esteja fora do tópico de segurança do Kubernetes, aqui são recomendações para proteger o código do
aplicativo:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 152/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Segurança de código
Área de Atenção
para o Código Recomendação
Acesso só através Se seu código precisar se comunicar por TCP, execute um handshake TLS com o cliente
de TLS antecipadamente. Com exceção de alguns casos, encripte tudo em trânsito. Indo um passo adiante, é
uma boa ideia encriptar o tráfego de rede entre os serviços. Isso pode ser feito por meio de um processo
conhecido como mutual ou mTLS, que realiza uma verificação bilateral da comunicação mediante os
certificados nos serviços.
Limitando Essa recomendação pode ser um pouco autoexplicativa, mas, sempre que possível, você só deve expor
intervalos de porta as portas em seu serviço que são absolutamente essenciais para a comunicação ou coleta de métricas.
de comunicação
Segurança na É uma boa prática verificar regularmente as bibliotecas de terceiros de sua aplicação em busca de
Dependência de vulnerabilidades de segurança. Cada linguagem de programação possui uma ferramenta para realizar
Terceiros essa verificação automaticamente.
Análise de Código A maioria das linguagens fornece uma maneira para analisar um extrato do código referente a quaisquer
Estático práticas de codificação potencialmente inseguras. Sempre que possível, você deve automatizar
verificações usando ferramentas que podem verificar as bases de código em busca de erros de
segurança comuns. Algumas das ferramentas podem ser encontradas em OWASP Source Code Analysis
Tools.
Ataques de Existem algumas ferramentas automatizadas que você pode executar contra seu serviço para tentar
sondagem dinâmica alguns dos ataques mais conhecidos. Isso inclui injeção de SQL, CSRF e XSS. Uma das ferramentas de
análise dinâmica mais populares é o OWASP Zed Attack proxy.
Próximos passos
Saiba mais sobre os tópicos de segurança do Kubernetes:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 153/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Em vez de usar PodSecurityPolicy, você pode aplicar restrições semelhantes em Pods usando um ou ambos:
Para obter um guia de migração, consulte Migre de PodSecurityPolicy para o controlador de admissão PodSecurity embutido. Para
obter mais informações sobre a remoção desta API, veja Descontinuação de PodSecurityPolicy: passado, presente e futuro.
Se você não estiver executando o Kubernetes v1.29, verifique a documentação para sua versão do Kubernetes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 154/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Os contêineres Windows oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator. As diferenças entre
estas duas contas de usuário são descritas em When to use ContainerAdmin and ContainerUser user accounts dentro da
documentação da Microsoft Secure Windows containers.
Os usuários locais podem ser adicionados às imagens do contêiner durante o processo de criação do mesmo.
Nota:
Imagens baseadas no Nano Server rodam como ContainerUser por padrão.
Imagens baseadas no Server Core rodam como ContainerAdministrator por padrão.
Contêineres Windows também podem rodar como identidades do Active Directory usando Group Managed Service Accounts
Contêineres privilegiados não são suportados no Windows. Em vez disso, contêineres HostProcess podem ser usados no Windows
para realizar muitas das tarefas realizadas por contêineres privilegiados no Linux.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 155/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Usuários podem acessar a API do Kubernetes utilizando kubectl , bibliotecas, ou executando requisições REST. Ambos, usuários
humanos e Contas de serviço do Kubernetes podem ser autorizados a acessar à API. Quando uma requisição chega à API, ela passa
por diversos estágios, ilustrados no seguinte diagrama:
Se o seu cluster utiliza uma autoridade privada de certificados, voce precisa de uma cópia do certificado da autoridade de
certificados (CA) dentro do arquivo de configuração ~/.kube/config , no lado do cliente, para que voce possa confiar na conexão e
tenha a garantia de que não há interceptação de tráfego.
Autenticação
Uma vez em que a segurança na camada de transporte (TLS) é estabelecida, a requisição HTTP move para o passo de autenticação.
Isto é demonstrado no passo 1 no diagrama acima. O script de criação do cluster ou configurações de administração configuram o
servidor de API para executar um ou mais módulos autenticadores.
A entrada para o passo de autenticação é a requisição HTTP completa; no entanto, tipicamente são verificados os cabeçalhos e/ou o
certificado de cliente.
Módulos de autenticação incluem certificados de cliente, senhas, tokens simples, tokens de auto-inicialização e JSON Web Tokens
(utilizados para contas de serviço).
Vários módulos de autenticação podem ser especificados, em que cada um será verificado em sequência, até que um deles tenha
sucesso.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 156/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Se a requisição não pode ser autenticada, será rejeitada com o código de status HTTP 401 (não autorizado). Caso contrário, o
usuário é autenticado com um "nome de usuário" específico e o nome de usuário está disponível para as etapas subsequentes para
usar em suas decisões. Alguns autenticadores também fornecem as associações de grupo do usuário, enquanto outros
autenticadores não o fazem.
Enquanto o Kubernetes usa nomes de usuário para decisões de controle de acesso e no registro de requisições, ele não possui um
objeto user nem armazena nomes de usuários ou outras informações sobre usuários em sua API.
Autorização
Após a requisição ser autenticada como originada de um usuário específico, a requisição deve ser autorizada. Isso é mostrado no
passo 2 no diagrama.
Uma requisição deve incluir o nome do usuário requerente, a ação requisitada e o objeto afetado pela ação. A requisição é
autorizada se uma política existente declarar que o usuário tem as devidas permissões para concluir a ação requisitada.
Por exemplo, se Bob possui a política abaixo, então ele somente poderá ler pods no namespace projectCaribou :
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "bob",
"namespace": "projectCaribou",
"resource": "pods",
"readonly": true
}
}
Se Bob fizer a seguinte requisição, a requisição será autorizada porque ele tem permissão para ler objetos no namespace
projectCaribou :
{
"apiVersion": "authorization.k8s.io/v1beta1",
"kind": "SubjectAccessReview",
"spec": {
"resourceAttributes": {
"namespace": "projectCaribou",
"verb": "get",
"group": "unicorn.example.org",
"resource": "pods"
}
}
}
Se Bob fizer uma requisição para escrever ( create ou update ) em objetos no namespace projectCaribou , sua autorização será
negada. Se Bob fizer uma requisição para ler ( get ) objetos em um namespace diferente, como projectFish , sua autorização será
negada.
A autorização do Kubernetes requer que você use atributos comuns a REST para interagir com os sistemas de controle de acesso
existentes em toda uma organização ou em todo o provedor de nuvem utilizado. É importante usar a formatação REST porque
esses sistemas de controle podem interagir com outras APIs além da API do Kubernetes.
O Kubernetes oferece suporte a vários módulos de autorização, como o modo de controle de acesso baseado em atributos (ABAC),
o modo de controle de acesso baseado em função (RBAC) e o modo Webhook. Quando um administrador cria um cluster, ele
configura os módulos de autorização que devem ser utilizados no servidor de API. Se mais de um módulo de autorização for
configurado, o Kubernetes verificará cada módulo e, se algum módulo autorizar a requisição, a requisição poderá prosseguir. Se
todos os módulos negarem a requisição, a requisição será negada (com código de status HTTP 403 - Acesso Proibido).
Para saber mais sobre a autorização do Kubernetes, incluindo detalhes sobre como criar políticas usando os módulos de
autorização compatíveis, consulte Visão Geral de Autorização.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 157/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Controle de admissão
Os módulos de controle de admissão são módulos de software que podem modificar ou rejeitar requisições. Além dos atributos
disponíveis para os módulos de Autorização, os módulos do controlador de admissão podem acessar o conteúdo do objeto que
está sendo criado ou modificado.
Os controladores de admissão atuam em requisições que criam, modificam, excluem ou age como um proxy para outro objeto. Os
controladores de admissão não agem em requisições que apenas leem objetos. Quando vários controladores de admissão são
configurados, eles são chamados em ordem.
Ao contrário dos módulos de autenticação e autorização, se algum módulo controlador de admissão rejeita, a solicitação é
imediatamente rejeitada.
Além de rejeitar objetos, os controladores de admissão também podem definir valores padrão complexos para campos.
Após uma requisição passar por todos os controladores de admissão, ela é validada usando as rotinas de validação para o objeto de
API correspondente e, em seguida, gravados no armazenamento de objetos (mostrado como etapa 4 no diagrama).
Auditoria
A auditoria do Kubernetes fornece um conjunto de registros cronológicos relevantes para a segurança que documentam a
sequência de ações em um cluster. O cluster audita as atividades geradas pelos usuários, pelos aplicativos que usam a API do
Kubernetes e pela própria camada de gerenciamento.
1. Porta localhost :
destina-se a testes e auto-inicialização e a outros componentes do nó mestre (scheduler, controller-manager) para falar
com a API
sem segurança na camada de transporte (TLS)
o padrão é a porta 8080
IP padrão é localhost, mude com a flag --insecure-bind-address .
a requisição ignora os módulos de autenticação e autorização .
requisição tratada pelo(s) módulo(s) de controle de admissão.
protegido pela necessidade de ter acesso ao host
2. “Porta segura”:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 158/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Próximos passos
Consulte mais documentação sobre autenticação, autorização e controle de acesso à API:
Autenticação
Autenticando com Tokens de Inicialização
Using Admission Controllers
Dynamic Admission Control
Autorização
Using RBAC Authorization
Using ABAC Authorization
Using Node Authorization
Webhook Mode
Certificate Signing Requests
incluindo Approval or rejection of Certificate Signing Requests e Signing certificates
Contas de serviço
Configure Service Accounts for Pods
Managing Service Accounts
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 159/233
4/15/24, 11:56 AM Conceitos | Kubernetes
8 - Políticas
Políticas que você pode configurar e que afetam grupos de recursos.
Aplicar o uso mínimo e máximo de recursos computacionais por pod ou contêiner em um namespace.
Impor a solicitação de armazenamento mínimo e máximo por PersistentVolumeClaim em um namespace.
Impor a proporção entre solicitação e limite para um recurso em um namespace.
Definir a solicitação/limite padrão para recursos computacionais em um namespace e utilizá-los automaticamente nos
contêineres em tempo de execução.
Ativando o LimitRange
O suporte ao LimitRange foi ativado por padrão desde o Kubernetes 1.10.
Alguns exemplos de políticas que podem ser criadas utilizando os intervalos de limite são:
Em um cluster de 2 nós com capacidade de 8 GiB de RAM e 16 núcleos, restrinja os Pods em um namespace para solicitar
100m de CPU com um limite máximo de 500m para CPU e solicitar 200Mi para memória com um limite máximo de 600Mi para
memória.
Defina o limite e a solicitação de CPU padrão para 150m e a solicitação padrão de memória para 300Mi para contêineres
iniciados sem solicitações de CPU e memória em suas especificações.
Caso os limites totais do namespace sejam menores que a soma dos limites dos Pods/Contêineres, pode haver contenção por
recursos. Nesse caso, os contêineres ou Pods não serão criados.
Próximos passos
Consulte o documento de design LimitRanger para obter mais informações.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 160/233
4/15/24, 11:56 AM Conceitos | Kubernetes
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 161/233
4/15/24, 11:56 AM Conceitos | Kubernetes
As cotas de recursos são uma ferramenta para os administradores resolverem essa preocupação.
Uma cota de recurso, definida por um objeto ResourceQuota , fornece restrições que limitam consumo de recursos agregados por
namespace. Pode limitar a quantidade de objetos que podem ser criado em um namespace por tipo, bem como a quantidade total
de recursos computacionais que podem ser consumidos por recursos nesse namespace.
Diferentes equipes trabalham em diferentes namespaces. Atualmente, isso é voluntário, mas o suporte para tornar isso
obrigatório por meio de ACLs está planejado.
Os usuários criam recursos (pods, serviços, etc.) no namespace e o sistema de cotas rastreia o uso para garantir que ele não
exceda os limites de recursos definidos em um ResourceQuota .
Se a criação ou atualização de um recurso violar uma restrição de cota, a solicitação falhará com código de status HTTP 403
FORBIDDEN acompanhado de uma mensagem explicando a restrição que foi violada.
Se a cota estiver habilitada em um namespace para recursos computacionais como cpu e memória , os usuários devem
especificar solicitações ou limites para esses valores; caso contrário, o sistema de cotas poderá rejeitar a criação de pods. Dica:
use o controlador de admissão LimitRanger para forçar padrões para pods que não exigem recursos computacionais.
Exemplos de políticas que podem ser criadas usando namespaces e cotas são:
Em um cluster com capacidade de 32 GiB de RAM e 16 núcleos, deixe a equipe A usar 20 GiB e 10 núcleos, deixe B usar 10GiB e
4 núcleos e mantenha 2GiB e 2 núcleos em reserva para alocação futura.
Limite o namespace "testing" para usar 1 núcleo e 1GiB de RAM. Deixe o namespace "produção" usar qualquer quantia.
Caso a capacidade total do cluster seja menor que a soma das cotas dos namespaces, pode haver contenção de recursos. Isso é
tratado por ordem de chegada.
Uma cota de recurso é aplicada em um namespace específico quando há um ResourceQuota nesse namespace.
limits.cpu Em todos os pods em um estado não terminal, a soma dos limites de CPU não pode exceder esse valor.
limits.memory Em todos os pods em um estado não terminal, a soma dos limites de memória não pode exceder esse
valor.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 162/233
4/15/24, 11:56 AM Conceitos | Kubernetes
requests.cpu Em todos os pods em um estado não terminal, a soma das solicitações da CPU não pode exceder esse
valor.
requests.memory Em todos os pods em um estado não terminal, a soma das solicitações de memória não pode exceder
esse valor.
hugepages- Em todos os pods em um estado não terminal, o número de solicitações de grandes páginas do
<size> tamanho especificado não pode exceder esse valor.
Como o overcommit não é permitido para recursos estendidos, não faz sentido especificar tanto requests e limits para o
mesmo recurso estendido em uma cota. Portanto, para recursos estendidos, apenas itens de cota com prefixo requests. é
permitido por enquanto.
Tome o recurso GPU como exemplo, se o nome do recurso for nvidia.com/gpu e você quiser limitar o número total de GPUs
solicitadas em um namespace para 4, você pode definir uma cota da seguinte maneira:
requests.nvidia.com/gpu: 4
Além disso, você pode limitar o consumo de recursos de armazenamento com base na classe de armazenamento associada.
Por exemplo, se um operador deseja cotar armazenamento com classe de armazenamento gold separada da classe de
armazenamento bronze , o operador pode definir uma cota da seguinte forma:
gold.storageclass.storage.k8s.io/requests.storage: 500Gi
bronze.storageclass.storage.k8s.io/requests.storage: 100Gi
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 163/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Na versão 1.8, o suporte de cota para armazenamento temporário local foi adicionado como um recurso alfa:
requests.ephemeral- Em todos os pods no namespace, a soma das solicitações de armazenamento local efêmero
storage não pode exceder esse valor.
limits.ephemeral- Em todos os pods no namespace, a soma dos limites de armazenamento temporário local
storage não pode exceder esse valor.
Nota: Ao usar um tempo de execução do contêiner CRI, os logs do contêiner serão contabilizados na cota de armazenamento
efêmero. Isso pode resultar no despejo inesperado de pods que esgotaram suas cotas de armazenamento. Consulte
Arquitetura de registro para mais detalhes.
Exemplo de conjunto de recursos que os usuários podem querer colocar na cota de contagem de objetos:
count/persistentvolumeclaims
count/services
count/secrets
count/configmaps
count/replicationcontrollers
count/deployments.apps
count/replicasets.apps
count/statefulsets.apps
count/jobs.batch
count/cronjobs.batch
A mesma sintaxe pode ser usada para recursos personalizados. Por exemplo, para criar uma cota em um recurso personalizado
widgets no grupo de API example.com , use count/widgets.example.com .
Ao usar a cota de recurso count/* , um objeto é cobrado na cota se existir no armazenamento do servidor. Esses tipos de cotas são
úteis para proteger contra o esgotamento dos recursos de armazenamento. Por exemplo, você pode desejar limitar o número de
segredos em um servidor devido ao seu grande tamanho. Muitos segredos em um cluster podem na verdade, impedir que
servidores e controladores sejam iniciados. Você pode definir uma cota para projetos para proteger contra um CronJob mal
configurado. CronJobs que criam muitos Jobs em um namespace podem levar a uma negação de serviço.
Também é possível fazer uma cota de contagem de objetos genéricos em um conjunto limitado de recursos. Os seguintes tipos são
suportados:
pods O número total de pods em um estado não terminal que pode existir no namespace. Um pod
está em um estado terminal se .status.phase in (Failed, Succeeded) for verdadeiro.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 164/233
4/15/24, 11:56 AM Conceitos | Kubernetes
services.loadbalancers O número total de serviços do tipo LoadBalancer que podem existir no namespace.
services.nodeports O número total de serviços do tipo NodePort que podem existir no namespace.
Por exemplo, a cota de pods conta e impõe um número máximo de pods criados em um único namespace que não é terminal.
Você pode querer definir uma cota pods em um namespace para evitar o caso em que um usuário cria muitos pods pequenos e
esgota o fornecimento de IPs de pod do cluster.
Escopos de cota
Cada cota pode ter um conjunto associado de scopes . Uma cota só medirá o uso de um recurso se corresponder a interseção de
escopos enumerados.
Quando um escopo é adicionado à cota, ele limita o número de recursos aos quais ele dá suporte a aqueles que pertencem ao
escopo. Os recursos especificados na cota fora do conjunto permitido resultam em um erro de validação.
Escopo Descrição
NotBestEffort Pods correspondentes que não têm qualidade de serviço de melhor esforço.
PriorityClass Corresponde aos pods que fazem referência à classe de prioridade especificada.
pods
Os escopos Termination , NotTerminate , NotBestEffort e PriorityClass restringem uma cota para rastrear os seguintes
recursos:
pods
cpu
memory
requests.cpu
requests.memory
limits.cpu
limits.memory
Observe que você não pode especificar os escopos Terminate e o NotTerminate na mesma cota, e você também não pode
especificar o BestEffort e NotBestEffort na mesma cota.
In
NotIn
Exists
DoesNotExist
Ao usar um dos seguintes valores como o scopeName ao definir o scopeSelector , o operator deve ser Exists .
Terminating
NotTerminating
BestEffort
NotBestEffort
Se o operator for In ou NotIn , o campo values deve ter pelo menos um valor. Por exemplo:
scopeSelector:
matchExpressions:
- scopeName: PriorityClass
operator: In
values:
- middle
Se o operator for Exists ou DoesNotExist , o campo values NÃO deve ser especificado.
Os pods podem ser criados em uma prioridade específica. Você pode controlar o consumo de recursos do sistema de um pod com
base na prioridade de um pod, usando o scopeSelector campo na especificação de cota.
Uma cota é correspondida e consumida apenas se scopeSelector na especificação de cota selecionar o pod.
Quando a cota está no escopo da classe de prioridade usando o campo scopeSelector , objeto de cota está restrito a rastrear
apenas os seguintes recursos:
pods
cpu
memory
ephemeral-storage
limits.cpu
limits.memory
limits.ephemeral-storage
requests.cpu
requests.memory
requests.ephemeral-storage
Este exemplo cria um objeto de cota e o corresponde a pods em prioridades específicas. O exemplo funciona da seguinte forma:
Os pods no cluster têm uma das três classes de prioridade, "baixa", "média", "alta".
Um objeto de cota é criado para cada prioridade.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 166/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: List
items:
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-high
spec:
hard:
cpu: "1000"
memory: 200Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["high"]
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-medium
spec:
hard:
cpu: "10"
memory: 20Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["medium"]
- apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-low
spec:
hard:
cpu: "5"
memory: 10Gi
pods: "10"
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["low"]
resourcequota/pods-high created
resourcequota/pods-medium created
resourcequota/pods-low created
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 167/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 1k
memory 0 200Gi
pods 0 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
Crie um pod com prioridade "high". Salve o seguinte YAML em um arquivo high-priority-pod.yml .
apiVersion: v1
kind: Pod
metadata:
name: high-priority
spec:
containers:
- name: high-priority
image: ubuntu
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
resources:
requests:
memory: "10Gi"
cpu: "500m"
limits:
memory: "10Gi"
cpu: "500m"
priorityClassName: high
Verifique se as estatísticas "Used" para a cota de prioridade "high", pods-high foram alteradas e se as outras duas cotas
permanecem inalteradas.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 168/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: pods-high
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 500m 1k
memory 10Gi 200Gi
pods 1 10
Name: pods-low
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 5
memory 0 10Gi
pods 0 10
Name: pods-medium
Namespace: default
Resource Used Hard
-------- ---- ----
cpu 0 10
memory 0 20Gi
pods 0 10
Os operadores podem usar o escopo de cota CrossNamespacePodAffinity para limitar quais namespaces têm permissão para ter
pods com termos de afinidade que cruzam namespaces. Especificamente, ele controla quais pods são permitidos para definir os
campos namespaces ou namespaceSelector em termos de afinidade de pod.
Impedir que os usuários usem termos de afinidade entre namespaces pode ser desejável, pois um pod com restrições antiafinidade
pode bloquear pods de todos os outros namespaces de ser agendado em um domínio de falha.
O uso desses operadores de escopo pode impedir certos namespaces ( foo-ns no exemplo abaixo) de ter pods que usam afinidade
de pod entre namespaces criando um objeto de cota de recurso nesse namespace com escopo CrossNamespaceAffinity e limite
rígido de 0:
apiVersion: v1
kind: ResourceQuota
metadata:
name: disable-cross-namespace-affinity
namespace: foo-ns
spec:
hard:
pods: "0"
scopeSelector:
matchExpressions:
- scopeName: CrossNamespaceAffinity
Se os operadores quiserem proibir o uso de namespaces e namespaceSelector por padrão, e permitir apenas para namespaces
específicos, eles podem configurar CrossNamespaceAffinity como um recurso limitado definindo o sinalizador kube-apiserver --
admission-control-config-file para o caminho do seguinte arquivo de configuração:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 169/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ResourceQuotaConfiguration
limitedResources:
- resource: pods
matchScopes:
- scopeName: CrossNamespaceAffinity
Com a configuração acima, os pods podem usar namespaces e namespaceSelector apenas na afinidade do pod se o namespace em
que foram criados tiver um objeto de cota de recurso com escopo CrossNamespaceAffinity e um limite rígido maior ou igual ao
número de pods usando esses campos.
Esse recurso é beta e ativado por padrão. Você pode desativá-lo usando o feature gate PodAffinityNamespaceSelector no kube-
apiserver e no kube-scheduler.
Se a cota tiver um valor especificado para requests.cpu ou requests.memory , ela exigirá que cada container faça uma solicitação
explícita para esses recursos. Se a cota tiver um valor especificado para limits.cpu ou limits.memory , em seguida exige que cada
contêiner de entrada especifique um limite explícito para esses recursos.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 170/233
4/15/24, 11:56 AM Conceitos | Kubernetes
NAME AGE
compute-resources 30s
object-counts 32s
Name: compute-resources
Namespace: myspace
Resource Used Hard
-------- ---- ----
limits.cpu 0 2
limits.memory 0 2Gi
requests.cpu 0 1
requests.memory 0 1Gi
requests.nvidia.com/gpu 0 4
Name: object-counts
Namespace: myspace
Resource Used Hard
-------- ---- ----
configmaps 0 10
persistentvolumeclaims 0 4
pods 0 4
replicationcontrollers 0 20
secrets 1 10
services 0 10
services.loadbalancers 0 2
Kubectl also supports object count quota for all standard namespaced resources using the syntax count/<resource>.<group> :
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 171/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Name: test
Namespace: myspace
Resource Used Hard
-------- ---- ----
count/deployments.apps 1 2
count/pods 2 3
count/replicasets.apps 1 4
count/secrets 1 4
Tais políticas podem ser implementadas usando ResourceQuotas como blocos de construção, por escrevendo um "controlador"
que observa o uso da cota e ajusta os limites rígidos da cota de cada namespace de acordo com outros sinais.
Observe que a cota de recursos divide os recursos agregados do cluster, mas não cria restrições em torno dos nós: pods de vários
namespaces podem ser executados no mesmo nó.
Com este mecanismo, os operadores podem restringir o uso de certas classes de prioridade para um número limitado de
namespaces , e nem todos poderão consumir essas classes de prioridade por padrão.
Para impor isso, a flag kube-apiserver --admission-control-config-file deve ser usada para passar o caminho para o seguinte
arquivo de configuração:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 172/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: "ResourceQuota"
configuration:
apiVersion: apiserver.config.k8s.io/v1
kind: ResourceQuotaConfiguration
limitedResources:
- resource: pods
matchScopes:
- scopeName: PriorityClass
operator: In
values: ["cluster-services"]
policy/priority-class-resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: pods-cluster-services
spec:
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: ["cluster-services"]
resourcequota/pods-cluster-services created
Uma solicitação de criação de pod é rejeitada caso seu priorityClassName estiver definido como cluster-services e deve ser
criado em um namespace diferente de kube-system .
Próximos passos
Veja o documento de design de cota de recursos para mais informações.
Veja um exemplo detalhado de como usar a cota de recursos.
Leia o documento de design de suporte de cota para prioridade de classe.
Veja recursos limitados
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 173/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O gerenciador principal, o gerenciador de topologia, é um componente do Kubelet que coordena o processo geral de
gerenciamento de recursos por meio da sua política.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 174/233
4/15/24, 11:56 AM Conceitos | Kubernetes
No Kubernetes, escalonamento refere-se à certeza de que Pods correspondam aos nós para que o Kubelet possa executá-los.
Preempção é o processo de finalizar Pods com menor prioridade para que os Pods com maior prioridade possam ser escalonados
nos nós. Remoção é o processo de finalização de um ou mais Pods em nós.
Escalonamento
Escalonador do Kubernetes
Atribuindo Pods à Nós
Sobrecarga de Pod
Restrições de Propagação da Topologia do Pod
Taints e Tolerâncias
Framework do Escalonador
Refinando a Performance do Escalonador
Empacotamento de Recursos para Recursos Estendidos
Disrupção do Pod
Disrupção do Pod é o processo pelo qual Pods ou nós são interrompidos de forma voluntária ou involuntária.
Disrupções voluntárias são iniciadas intencionalmente pelos donos das aplicações ou administradores dos clusters. Disrupções
involuntárias não são intencionais e podem ser encadeadas por problemas inevitáveis como Nós com poucos recursos, ou por
exclusões acidentais.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 175/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Tolerâncias são aplicadas em pods e permitem, mas não exigem, que os pods sejam alocados em nós com taints correspondentes.
Taints e tolerâncias trabalham juntos para garantir que pods não sejam alocados em nós inapropriados. Um ou mais taints são
aplicados em um nó; isso define que o nó não deve aceitar nenhum pod que não tolera essas taints.
Conceitos
Você adiciona um taint a um nó utilizando kubectl taint. Por exemplo,
define um taint no nó node1 . O taint tem a chave key1 , valor value1 e o efeito NoSchedule . Isso significa que nenhum pod
conseguirá ser executado no nó node1 a menos que possua uma tolerância correspondente.
Para remover o taint adicionado pelo comando acima, você pode executar:
Você especifica uma tolerância para um pod na especificação do Pod. Ambas as seguintes tolerâncias "correspondem" ao taint
criado pelo kubectl taint acima, e assim um pod com qualquer uma delas poderia ser executado no node1 :
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
tolerations:
- key: "key1"
operator: "Exists"
effect: "NoSchedule"
pods/pod-with-toleration.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 176/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
o valor de operator é Exists (no caso nenhum value deve ser especificado), ou
o valor de operator é Equal e os valores de value são iguais.
Nota:
Existem dois casos especiais:
Uma key vazia com o operador Exists "casa" todas as chaves, valores e efeitos, o que significa que o pod irá tolerar tudo.
O exemplo acima usou effect de NoSchedule . De forma alternativa, você pode usar effect de PreferNoSchedule . Nesse efeito,
o sistema tentará evitar que o pod seja alocado ao nó caso ele não tolere os taints definidos, contudo a alocação não será evitada de
forma obrigatória. Pode-se dizer que o PreferNoSchedule é uma versão permissiva do NoSchedule . O terceiro tipo de effect é o
NoExecute que será descrito posteriormente.
Você pode colocar múltiplos taints no mesmo nó e múltiplas tolerâncias no mesmo pod. O jeito que o Kubernetes processa
múltiplos taints e tolerâncias é como um filtro: começa com todos os taints de um nó, em seguida ignora aqueles para os quais o
pod tem uma tolerância relacionada; os taints restantes que não foram ignorados indicam o efeito no pod. Mais especificamente,
se existe pelo menos um taint não tolerado com o efeito NoSchedule , o Kubernetes não alocará o pod naquele nó
se existe um taint não tolerado com o efeito NoSchedule , mas existe pelo menos um taint não tolerado com o efeito
PreferNoSchedule , o Kubernetes tentará não alocar o pod no nó
se existe pelo menos um taint não tolerado com o efeito NoExecute , o pod será expulso do nó (caso já esteja em execução) e
não será alocado ao nó (caso ainda não esteja em execução).
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 177/233
4/15/24, 11:56 AM Conceitos | Kubernetes
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
Nesse caso, o pod não será alocado ao nó porque não possui uma tolerância para o terceiro taint. Porém, se ele já estiver rodando
no nó quando o taint foi adicionado, não será afetado e continuará rodando, tendo em vista que o terceiro taint é o único não
tolerado pelo pod.
Normalmente, se um taint com o efeito NoExecute é adicionado a um nó, qualquer pod que não o tolere será expulso
imediatamente e pods que o toleram nunca serão expulsos. Contudo, uma tolerância com efeito NoExecute pode especificar de
forma opcional o campo tolerationSeconds , que determina quanto tempo o pod continuará alocado ao nó depois que o taint é
adicionado. Por exemplo,
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
significa que se esse pod está sendo executado e um taint correspondente é adicionado ao nó, o pod irá continuar rodando neste
nó por 3600 segundos e depois será expulso. Se o taint for removido antes desse tempo acabar, o pod não será expulso.
Nós Dedicados: Se você quiser dedicar um conjunto de nós para uso exclusivo de um conjunto específico de usuários, poderá
adicionar um taint nesses nós. (digamos, kubectl taint nodes nodename dedicated=groupName:NoSchedule ) e em seguida
adicionar uma tolerância correspondente para seus pods (isso seria feito mais facilmente com a escrita de um controlador de
admissão customizado). Os pods com tolerância terão sua execução permitida nos nós com taints (dedicados), assim como em
qualquer outro nó no cluster. Se você quiser dedicar nós a esses pods e garantir que eles usem apenas os nós dedicados,
precisará adicionar uma label similar ao taint para o mesmo conjunto de nós (por exemplo, dedicated=groupName ), e o
controle de admissão deverá adicionar uma afinidade de nó para exigir que os pods podem ser executados apenas nos nós
definidos com a label dedicated=groupName .
Nós com hardware especial: Em um cluster no qual um pequeno grupo de nós possui hardware especializado (por exemplo,
GPUs), é desejável manter pods que não necessitem desse tipo de hardware fora desses nós, dessa forma o recurso estará
disponível para pods que precisem do hardware especializado. Isso pode ser feito aplicando taints nos nós com o hardware
especializado (por exemplo, kubectl taint nodes nodename special=true:NoSchedule or kubectl taint nodes nodename
special=true:PreferNoSchedule ) e aplicando uma tolerância correspondente nos pods que usam o hardware especial. Assim
como no caso de uso de nós dedicados, é provavelmente mais fácil aplicar as tolerâncias utilizando um controlador de
admissão. Por exemplo, é recomendado usar Extended Resources para representar hardware especial, adicione um taint ao
seus nós de hardware especializado com o nome do recurso estendido e execute o controle de admissão
ExtendedResourceToleration. Agora, tendo em vista que os nós estão marcados com um taint, nenhum pod sem a tolerância
será executado neles. Porém, quando você submete um pod que requisita o recurso estendido, o controlador de admissão
ExtendedResourceToleration irá adicionar automaticamente as tolerâncias necessárias ao pod que irá, por sua vez, ser
alocado no nó com hardware especial. Isso garantirá que esses nós de hardware especial serão dedicados para os pods que
requisitarem tal recurso e você não precisará adicionar manualmente as tolerâncias aos seus pods.
Expulsões baseadas em Taint: Um comportamento de expulsão configurada por pod quando problemas existem em um nó,
o qual será descrito na próxima seção.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 178/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O efeito de taint NoExecute , mencionado acima, afeta pods que já estão rodando no nó da seguinte forma
O controlador de nó automaticamente adiciona um taint ao Nó quando certas condições se tornam verdadeiras. Os seguintes taints
são embutidos:
node.kubernetes.io/not-ready : Nó não está pronto. Isso corresponde ao NodeCondition Ready com o valor " False ".
node.kubernetes.io/unreachable : Nó é inalcançável a partir do controlador de nó. Isso corresponde ao NodeCondition Ready
com o valor " Unknown ".
node.kubernetes.io/memory-pressure : Nó possui pressão de memória.
node.kubernetes.io/disk-pressure : Nó possui pressão de disco.
node.kubernetes.io/pid-pressure : Nó possui pressão de PID.
node.kubernetes.io/network-unavailable : A rede do nó está indisponível.
node.kubernetes.io/unschedulable : Nó não é alocável.
node.cloudprovider.kubernetes.io/uninitialized : Quando o kubelet é iniciado com um provedor de nuvem "externo", esse
taint é adicionado ao nó para que ele seja marcado como não utilizável. Após o controlador do cloud-controller-manager
inicializar o nó, o kubelet remove esse taint.
No caso de um nó estar prestes a ser expulso, o controlador de nó ou kubelet adicionam os taints relevantes com o efeito
NoExecute . Se a condição de falha retorna ao normal, o kubelet ou controlador de nó podem remover esses taints.
Nota: A camada de gerenciamento limita a taxa de adição de novos taints aos nós. Esse limite gerencia o número de expulsões
que são disparadas quando muitos nós se tornam inalcançáveis ao mesmo tempo (por exemplo: se ocorre uma falha na rede).
Você pode especificar tolerationSeconds em um Pod para definir quanto tempo ele ficará alocado em um nó que está falhando ou
está sem resposta.
Por exemplo, você talvez queira manter uma aplicação com vários estados salvos localmente alocado em um nó por um longo
período na ocorrência de uma divisão na rede, esperando que essa divisão se recuperará e assim a expulsão do pod pode ser
evitada. A tolerância que você define para esse Pod poderia ficar assim:
tolerations:
- key: "node.kubernetes.io/unreachable"
operator: "Exists"
effect: "NoExecute"
tolerationSeconds: 6000
Nota:
O Kubernetes automaticamente adiciona uma tolerância para node.kubernetes.io/not-ready e
node.kubernetes.io/unreachable com tolerationSeconds=300 , a menos que você, ou um controlador, defina essas
tolerâncias explicitamente.
Essas tolerâncias adicionadas automaticamente significam que Pods podem continuar alocados aos Nós por 5 minutos após um
desses problemas ser detectado.
Pods do tipo DaemonSet são criados com tolerâncias NoExecute sem a propriedade tolerationSeconds para os seguintes taints:
node.kubernetes.io/unreachable
node.kubernetes.io/not-ready
Isso garante que esses pods do DaemonSet nunca sejam expulsos por conta desses problemas.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 179/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O agendador verifica taints, não condições de nó, quando realiza suas decisões de agendamento. Isso garante que as condições de
nó não afetem diretamente o agendamento. Por exemplo, se a condição de nó DiskPressure está ativa, a camada de
gerenciamento adiciona o taint node.kubernetes.io/disk-pressure e não aloca novos pods no nó afetado. Se a condição
MemoryPressure está ativa, a camada de gerenciamento adiciona o taint node.kubernetes.io/memory-pressure .
Você pode ignorar condições de nó para pods recém-criados adicionando tolerâncias correspondentes. A camada de controle
também adiciona a tolerância node.kubernetes.io/memory-pressure em pods que possuem uma classe de QoS diferente de
BestEffort . Isso ocorre porque o Kubernetes trata pods nas classes de QoS Guaranteed ou Burstable (até mesmo pods sem
requisitos de memória definidos) como se fossem capazes de lidar com pressão de memória, enquanto novos pods com
BestEffort não são alocados no nó afetado.
O controlador DaemonSet adiciona automaticamente as seguintes tolerâncias de NoSchedule para todos os daemons, prevenindo
que DaemonSets quebrem.
node.kubernetes.io/memory-pressure
node.kubernetes.io/disk-pressure
Adicionando essas tolerâncias garante retro compatibilidade. Você também pode adicionar tolerâncias de forma arbitrária aos
DaemonSets.
Próximos passos
Leia sobre Node-pressure Eviction e como você pode configurá-la
Leia sobre Pod Priority
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 180/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Se você quiser entender por que os Pods são alocados em um Node específico ou se planeja implementar um escalonador
personalizado, esta página ajudará você a aprender sobre escalonamento.
kube-scheduler
kube-scheduler é o escalonador padrão do Kubernetes e é executado como parte do control plane. O kube-scheduler é projetado
para que, se você quiser e precisar, possa escrever seu próprio componente de escalonamento e usá-lo.
Para cada Pod recém-criado ou outros Pods não escalonados, o kube-scheduler seleciona um Node ideal para execução. No
entanto, todos os contêineres nos Pods têm requisitos diferentes de recursos e cada Pod também possui requisitos diferentes.
Portanto, os Nodes existentes precisam ser filtrados de acordo com os requisitos de escalonamento específicos.
Em um cluster, Nodes que atendem aos requisitos de escalonamento para um Pod são chamados de Nodes viáveis. Se nenhum dos
Nodes for adequado, o Pod permanece não escalonado até que o escalonador possa alocá-lo.
O escalonador encontra Nodes viáveis para um Pod e, em seguida, executa um conjunto de funções para pontuar os Nodes viáveis
e escolhe um Node com a maior pontuação entre os possíveis para executar o Pod. O escalonador então notifica o servidor da API
sobre essa decisão em um processo chamado binding.
Fatores que precisam ser levados em consideração para decisões de escalonamento incluem requisitos individuais e coletivos de
recursos, restrições de hardware / software / política, especificações de afinidade e anti-afinidade, localidade de dados, interferência
entre cargas de trabalho e assim por diante.
1. Filtragem
2. Pontuação
A etapa de filtragem localiza o conjunto de Nodes onde é possível alocar o Pod. Por exemplo, o filtro PodFitsResources verifica se um
Node candidato possui recursos disponíveis suficientes para atender às solicitações de recursos específicas de um Pod. Após esta
etapa, a lista de Nodes contém quaisquer Nodes adequados; frequentemente, haverá mais de um. Se a lista estiver vazia, esse Pod
(ainda) não é escalonável.
Na etapa de pontuação, o escalonador classifica os Nodes restantes para escolher o mais adequado. O escalonador atribui uma
pontuação a cada Node que sobreviveu à filtragem, baseando essa pontuação nas regras de pontuação ativa.
Por fim, o kube-scheduler atribui o Pod ao Node com a classificação mais alta. Se houver mais de um Node com pontuações iguais,
o kube-scheduler seleciona um deles aleatoriamente.
1. Políticas de Escalonamento permitem configurar Predicados para filtragem e Prioridades para pontuação.
2. Perfis de Escalonamento permitem configurar Plugins que implementam diferentes estágios de escalonamento, incluindo:
QueueSort , Filter , Score , Bind , Reserve , Permit , e outros. Você também pode configurar o kube-scheduler para
executar diferentes perfis.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 181/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Próximos passos
Leia sobre ajuste de desempenho do escalonador
Leia sobre restrições de propagação da topologia de pod
Leia a documentação de referência para o kube-scheduler
Aprenda como configurar vários escalonadores
Aprenda sobre políticas de gerenciamento de topologia
Aprenda sobre Pod Overhead
Saiba mais sobre o agendamento de pods que usam volumes em:
Suporte de topologia de volume
Rastreamento de capacidade de armazenamento
Limites de volumes específicos do nó
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 182/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Quando você executa um Pod num nó, o próprio Pod usa uma quantidade de recursos do sistema. Estes recursos são adicionais aos
recursos necessários para executar o(s) contêiner(s) dentro do Pod. Sobrecarga de Pod, do inglês Pod Overhead, é uma
funcionalidade que serve para contabilizar os recursos consumidos pela infraestrutura do Pod para além das solicitações e limites
do contêiner.
No Kubernetes, a sobrecarga de Pods é definido no tempo de admissão de acordo com a sobrecarga associada à RuntimeClass do
Pod.
Quando é ativada a Sobrecarga de Pod, a sobrecarga é considerada adicionalmente à soma das solicitações de recursos do
contêiner ao agendar um Pod. Semelhantemente, o kubelet incluirá a sobrecarga do Pod ao dimensionar o cgroup do Pod e ao
executar a classificação de prioridade de migração do Pod em caso de drain do Node.
Exemplo de uso
Para usar a funcionalidade PodOverhead, é necessário uma RuntimeClass que define o campo overhead . Por exemplo, poderia
usar a definição da RuntimeClass abaixo com um agente de execução de contêiner virtualizado que use cerca de 120MiB por Pod
para a máquina virtual e o sistema operacional convidado:
---
kind: RuntimeClass
apiVersion: node.k8s.io/v1beta1
metadata:
name: kata-fc
handler: kata-fc
overhead:
podFixed:
memory: "120Mi"
cpu: "250m"
As cargas de trabalho que são criadas e que especificam o manipulador RuntimeClass kata-fc irão usar a sobrecarga de memória
e cpu em conta para os cálculos da quota de recursos, agendamento de nós, assim como dimensionamento do cgroup do Pod.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 183/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
runtimeClassName: kata-fc
containers:
- name: busybox-ctr
image: busybox
stdin: true
tty: true
resources:
limits:
cpu: 500m
memory: 100Mi
- name: nginx-ctr
image: nginx
resources:
limits:
cpu: 1500m
memory: 100Mi
No tempo de admissão o controlador de admissão RuntimeClass atualiza o PodSpec da carga de trabalho de forma a incluir o
overhead como descrito na RuntimeClass. Se o PodSpec já tiver este campo definido o Pod será rejeitado. No exemplo dado, como
apenas o nome do RuntimeClass é especificado, o controlador de admissão muda o Pod de forma a incluir um overhead .
A saída é:
map[cpu:250m memory:120Mi]
Se for definido um ResourceQuota, a soma das requisições dos contêineres assim como o campo overhead são contados.
Quando o kube-scheduler está decidindo que nó deve executar um novo Pod, o agendador considera o overhead do pod, assim
como a soma de pedidos aos contêineres para esse Pod. Para este exemplo, o agendador adiciona as requisições e a sobrecarga,
depois procura um nó com 2.25 CPU e 320 MiB de memória disponível.
Assim que um Pod é agendado a um nó, o kubelet nesse nó cria um novo cgroup para o Pod. É dentro deste Pod que o agente de
execução de contêiners subjacente vai criar contêineres.
Se o recurso tiver um limite definido para cada contêiner (QoS garantida ou Burstrable QoS com limites definidos), o kubelet definirá
um limite superior para o cgroup do Pod associado a esse recurso (cpu.cfs_quota_us para CPU e memory.limit_in_bytes de
memória). Este limite superior é baseado na soma dos limites do contêiner mais o overhead definido no PodSpec.
Para CPU, se o Pod for QoS garantida ou Burstrable QoS, o kubelet vai definir cpu.shares baseado na soma dos pedidos ao
contêiner mais o overhead definido no PodSpec.
Olhando para o nosso exemplo, verifique as requisições ao contêiner para a carga de trabalho:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 184/233
4/15/24, 11:56 AM Conceitos | Kubernetes
A saída mostra que 2250m CPU e 320MiB de memória são solicitados, que inclui PodOverhead:
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
O caminho do cgroup resultante inclui o contêiner pause do Pod. O cgroup no nível do Pod está um diretório acima.
"cgroupsPath": "/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/7ccf55aee35dd16aca4189c952d83487297f3cd760
335544320
Observabilidade
Uma métrica kube_pod_overhead está disponível em kube-state-metrics para ajudar a identificar quando o PodOverhead está sendo
utilizado e para ajudar a observar a estabilidade das cargas de trabalho em execução com uma sobrecarga (Overhead) definida. Esta
funcionalidade não está disponível na versão 1.9 do kube-state-metrics, mas é esperado em uma próxima versão. Os usuários
necessitarão entretanto construir o kube-state-metrics a partir do código fonte.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 185/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Próximos passos
RuntimeClass
PodOverhead Design
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 186/233
4/15/24, 11:56 AM Conceitos | Kubernetes
10 - Administração de Cluster
Detalhes de baixo nível relevantes para criar ou administrar um cluster Kubernetes.
A visão geral da administração do cluster é para qualquer pessoa que crie ou administre um cluster do Kubernetes. É pressuposto
alguma familiaridade com os conceitos principais do Kubernetes.
Planejando um cluster
Consulte os guias em Configuração para exemplos de como planejar, instalar e configurar clusters Kubernetes. As soluções listadas
neste artigo são chamadas de distros.
Nota: Nem todas as distros são mantidas ativamente. Escolha distros que foram testadas com uma versão recente do
Kubernetes.
Você quer experimentar o Kubernetes em seu computador ou deseja criar um cluster de vários nós com alta disponibilidade?
Escolha as distros mais adequadas ás suas necessidades.
Você vai usar um cluster Kubernetes gerenciado , como o Google Kubernetes Engine, ou vai hospedar seu próprio cluster?
Seu cluster será local, ou na nuvem (IaaS)? O Kubernetes não oferece suporte direto a clusters híbridos. Em vez disso, você
pode configurar vários clusters.
Se você estiver configurando o Kubernetes local, leve em consideração qual modelo de rede se encaixa melhor.
Você vai executar o Kubernetes em um hardware bare metal ou em máquinas virtuais? (VMs)?
Você deseja apenas executar um cluster ou espera participar ativamente do desenvolvimento do código do projeto
Kubernetes? Se for a segunda opção, escolha uma distro desenvolvida ativamente. Algumas distros usam apenas versão
binária, mas oferecem uma maior variedade de opções.
Familiarize-se com os componentes necessários para executar um cluster.
Gerenciando um cluster
Aprenda como gerenciar nós.
Aprenda a configurar e gerenciar a quota de recursos para clusters compartilhados.
Protegendo um cluster
Gerar Certificados descreve os passos para gerar certificados usando diferentes cadeias de ferramentas.
Ambiente de Contêineres do Kubernetes descreve o ambiente para contêineres gerenciados pelo kubelet em um nó
Kubernetes.
Controle de Acesso a API do Kubernetes descreve como o Kubernetes implementa o controle de acesso para sua própria API.
Usando Controladores de Admissão explica plugins que interceptam requisições para o servidor da API Kubernetes após a
autenticação e autorização.
usando Sysctl em um Cluster Kubernetes descreve a um administrador como usar a ferramenta de linha de comando sysctl
para definir os parâmetros do kernel.
Protegendo o kubelet
Comunicação Control Plane-Nó
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 187/233
4/15/24, 11:56 AM Conceitos | Kubernetes
TLS bootstrapping
Autenticação/autorização do kubelet
Registro e Monitoramento da Atividade do Cluster explica como funciona o logging no Kubernetes e como implementá-lo.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 188/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Planejando um cluster
Veja os guias em Setup para exemplos de como planejar, iniciar e configurar clusters Kubernetes. As soluções listadas neste artigo
são chamadas distros.
Você quer experimentar o Kubernetes no seu computador, ou você quer construir um cluster de alta disponibilidade e multi-
nós? Escolha as distros mais adequadas às suas necessidades.
Se você esta projetando para alta-disponibilidade, saiba mais sobre configuração clusters em múltiplas zonas.
Você usará um cluster Kubernetes hospedado, como Google Kubernetes Engine, ou hospedará seu próprio cluster?
Seu cluster será on-premises, ou in the cloud (IaaS)? Kubernetes não suporta diretamente clusters híbridos. Em vez disso,
você pode configurar vários clusters.
Se você estiver configurando um Kubernetes on-premisess, considere qual modelo de rede melhor se adequa.
Você estará executando o Kubernetes em hardware "bare metal" ou em máquinas virtuais (VMs)?
Você quer apenas rodar um cluster, ou você espera fazer desenvolvimento ativo do código de projeto do Kubernetes? Se
for a segunda opção, escolha uma distro mais ativa. Algumas distros fornecem apenas binários, mas oferecem uma maior
variedade de opções.
Nota: Nem todas as distros são ativamente mantidas. Escolha as distros que foram testadas com uma versão recente do
Kubernetes.
Gerenciando um cluster
Gerenciando um cluster descreve vários tópicos relacionados ao ciclo de vida de um cluster: criando um novo cluster,
atualizando o nó mestre e os nós de trabalho do cluster, executando manutenção de nó (por exemplo, atualizações de kernel)
e atualizando a versão da API do Kubernetes de um cluster em execução.
Protegendo um cluster
Certificados descreve as etapas para gerar certificados usando diferentes ferramentas.
Ambiente de Container Kubernetes descreve o ambiente para contêineres gerenciados pelo Kubelet em um nó do Kubernetes.
Controlando Acesso a API Kubernetes API descreve como configurar a permissão para usuários e contas de serviço.
Usando Controladores de Admissão explica plug-ins que interceptam solicitações ao servidor da API do Kubernetes após
autenticação e autorização.
Usando Sysctls em um Cluster Kubernetes descreve a um administrador como usar a ferramenta de linha de comando
sysctl para definir os parâmetros do kernel.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 189/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Protegendo o kubelet
Comunicação Master-Node
TLS bootstrapping
Autenticação/Autorização Kubelet
Logando e monitorando a atividade de cluster explica como o log funciona no Kubernetes e como implementá-lo.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 190/233
4/15/24, 11:56 AM Conceitos | Kubernetes
10.2 - Certificates
Ao usar um client para autenticação de certificado, você pode gerar certificados manualmente através easyrsa , openssl ou
cfssl .
easyrsa
easyrsa pode gerar manualmente certificados para o seu cluster.
3. Gere o certificado e a chave do servidor. O argumento --subject-alt-name define os possíveis IPs e nomes (DNS) que o
servidor de API usará para ser acessado. O MASTER_CLUSTER_IP é geralmente o primeiro IP do serviço CIDR que é especificado
como argumento em --service-cluster-ip-range para o servidor de API e o componente gerenciador do controlador. O
argumento --days é usado para definir o número de dias após o qual o certificado expira. O exemplo abaixo também assume
que você está usando cluster.local como DNS de domínio padrão
./easyrsa --subject-alt-name="IP:${MASTER_IP},"\
"IP:${MASTER_CLUSTER_IP},"\
"DNS:kubernetes,"\
"DNS:kubernetes.default,"\
"DNS:kubernetes.default.svc,"\
"DNS:kubernetes.default.svc.cluster,"\
"DNS:kubernetes.default.svc.cluster.local" \
--days=10000 \
build-server-full server nopass
--client-ca-file=/yourdirectory/ca.crt
--tls-cert-file=/yourdirectory/server.crt
--tls-private-key-file=/yourdirectory/server.key
openssl
openssl pode gerar manualmente certificados para o seu cluster.
2. De acordo com o ca.key, gere um ca.crt (use -days para definir o tempo efetivo do certificado):
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 191/233
4/15/24, 11:56 AM Conceitos | Kubernetes
4. Crie um arquivo de configuração para gerar uma solicitação de assinatura de certificado (CSR - Certificate Signing Request).
Certifique-se de substituir os valores marcados com colchetes angulares (por exemplo, <MASTER_IP> ) com valores reais antes
de salvá-lo em um arquivo (por exemplo, csr.conf ). Note que o valor para o MASTER_CLUSTER_IP é o IP do cluster de serviços
para o Servidor de API, conforme descrito na subseção anterior. O exemplo abaixo também assume que você está usando
cluster.local como DNS de domínio padrão
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = <country>
ST = <state>
L = <city>
O = <organization>
OU = <organization unit>
CN = <MASTER_IP>
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
IP.1 = <MASTER_IP>
IP.2 = <MASTER_CLUSTER_IP>
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
7. Veja o certificado:
Por fim, adicione os mesmos parâmetros nos parâmetros iniciais do Servidor de API.
cfssl
cfssl é outra ferramenta para geração de certificados.
1. Baixe, descompacte e prepare as ferramentas de linha de comando, conforme mostrado abaixo. Observe que você pode
precisar adaptar os comandos de exemplo abaixo com base na arquitetura do hardware e versão cfssl que você está usando.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 192/233
4/15/24, 11:56 AM Conceitos | Kubernetes
mkdir cert
cd cert
../cfssl print-defaults config > config.json
../cfssl print-defaults csr > csr.json
3. Crie um arquivo de configuração JSON para gerar o arquivo CA, por exemplo, ca-config.json :
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
4. Crie um arquivo de configuração JSON para o CA - solicitação de assinatura de certificado (CSR - Certificate Signing Request),
por exemplo, ca-csr.json . Certifique-se de substituir os valores marcados com colchetes angulares por valores reais que
você deseja usar.
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names":[{
"C": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>"
}]
}
6. Crie um arquivo de configuração JSON para gerar chaves e certificados para o Servidor de API, por exemplo, server-csr.json .
Certifique-se de substituir os valores entre colchetes angulares por valores reais que você deseja usar. O MASTER_CLUSTER_IP é
o IP do serviço do cluster para o servidor da API, conforme descrito na subseção anterior. O exemplo abaixo também assume
que você está usando cluster.local como DNS de domínio padrão
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 193/233
4/15/24, 11:56 AM Conceitos | Kubernetes
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"<MASTER_IP>",
"<MASTER_CLUSTER_IP>",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [{
"C": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>"
}]
}
7. Gere a chave e o certificado para o Servidor de API, que são, por padrão, salvos nos arquivos server-key.pem e server.pem
respectivamente:
API de certificados
Você pode usar a API certificates.k8s.io para provisionar certificados x509 a serem usados para autenticação conforme
documentado aqui.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 194/233
4/15/24, 11:56 AM Conceitos | Kubernetes
1. Comunicações contêiner-para-contêiner altamente acopladas: Isso é resolvido por Pods e comunicações através do
localhost .
Kubernetes é basicamente o compartilhamento de máquinas entre aplicações. Tradicionalmente, compartilhar máquinas requer a
garantia de que duas aplicações não tentem utilizar as mesmas portas. Coordenar a alocação de portas entre múltiplos
desenvolvedores é muito dificil de fazer em escala e expõe os usuários a problemas em nível do cluster e fora de seu controle.
A alocação dinâmica de portas traz uma série de complicações para o sistema - toda aplicação deve obter suas portas através de
flags de configuração, os servidores de API devem saber como inserir números dinämicos de portas nos blocos de configuração,
serviços precisam saber como buscar um ao outro, etc. Ao invés de lidar com isso, o Kubernetes faz de uma maneira diferente.
O Kubernetes impõe os seguintes requisitos fundamentais para qualquer implementação de rede (exceto qualquer política de
segmentação intencional):
pods em um nó podem se comunicar com todos os pods em todos os nós sem usar NAT.
agentes em um nó (por exemplo o kubelet ou um serviço local) podem se comunicar com todos os Pods naquele nó.
Nota: Para as plataformas que suportam Pods executando na rede do host (como o Linux):
pods alocados na rede do host de um nó podem se comunicar com todos os pods em todos os nós sem NAT.
Esse modelo não só é menos complexo, mas é principalmente compatível com o desejo do Kubernetes de permitir a portabilidade
com baixo esforço de aplicações de VMs para contêineres. Se a sua aplicação executava anteriormente em uma VM, sua VM possuía
um IP e podia se comunicar com outras VMs no seu projeto. Esse é o mesmo modelo básico.
Os endereços de IP no Kubernetes existem no escopo do Pod - contêineres em um Pod compartilham o mesmo network
namespace - incluíndo seu endereço de IP e MAC. Isso significa que contêineres que compõem um Pod podem se comunicar entre
eles através do endereço localhost e respectivas portas. Isso também significa que contêineres em um mesmo Pod devem
coordenar a alocação e uso de portas, o que não difere do modelo de processos rodando dentro de uma mesma VM. Isso é
chamado de modelo "IP-por-pod".
É possível solicitar uma porta no nó que será encaminhada para seu Pod (chamado de portas do host), mas isso é uma operação
muito específica. Como esse encaminhamento é implementado é um detalhe do agente de execução do contêiner. O Pod mesmo
desconhece a existência ou não de portas do host.
As seguintes opções estão organizadas alfabeticamente e não implicam preferência por qualquer solução.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 195/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Esta seção tem links para projetos de terceiros que fornecem a funcionalidade exigida pelo Kubernetes. Os autores do
projeto Kubernetes não são responsáveis por esses projetos. Esta página obedece as diretrizes de conteúdo do site CNCF,
listando os itens em ordem alfabética. Para adicionar um projeto a esta lista, leia o guia de conteúdo antes de enviar sua
alteração.
Antrea
O projeto Antrea é uma solução de conectividade para Kubernetes que pretende ser nativa. Ela utiliza o Open vSwitch na camada de
conectividade de dados. O Open vSwitch é um switch virtual de alta performance e programável que suporta Linux e Windows. O
Open vSwitch permite ao Antrea implementar políticas de rede do Kubernetes (NetworkPolicies) de uma forma muito performática e
eficiente.
Graças à característica programável do Open vSwitch, o Antrea consegue implementar uma série de funcionalidades de rede e
segurança.
O uso desse plugin permite aos Pods no Kubernetes ter o mesmo endereço de IP dentro do pod como se eles estivessem dentro da
rede do VPC. O CNI (Container Network Interface) aloca um Elastic Networking Interface (ENI) para cada nó do Kubernetes e usa uma
faixa de endereços IP secundário de cada ENI para os Pods no nó. O CNI inclui controles para pré alocação dos ENIs e endereços IP
para um início mais rápido dos pods e permite clusters com até 2,000 nós.
Adicionalmente, esse CNI pode ser utilizado junto com o Calico para a criação de políticas de rede (NetworkPolicies). O projeto AWS
VPC CNI tem código fonte aberto com a documentação no Github.
Calico
Calico é uma solução de conectividade e segurança para contêineres, máquinas virtuais e serviços nativos em hosts. O Calico
suporta múltiplas camadas de conectividade/dados, como por exemplo: uma camada Linux eBPF nativa, uma camada de
conectividade baseada em conceitos padrão do Linux e uma camada baseada no HNS do Windows. O calico provê uma camada
completa de conectividade e rede, mas também pode ser usado em conjunto com CNIs de provedores de nuvem para permitir a
criação de políticas de rede.
Cilium
Cilium é um software de código fonte aberto para prover conectividade e segurança entre contêineres de aplicação. O Cilium pode
lidar com tráfego na camada de aplicação (ex. HTTP) e pode forçar políticas de rede nas camadas L3-L7 usando um modelo de
segurança baseado em identidade e desacoplado do endereçamento de redes, podendo inclusive ser utilizado com outros plugins
CNI.
Flannel
Flannel é uma camada muito simples de conectividade que satisfaz os requisitos do Kubernetes. Muitas pessoas reportaram
sucesso em utilizar o Flannel com o Kubernetes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 196/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Essa bridge é criada pelo Kubelet (controlada pela opção --network-plugin=kubenet ) de acordo com a informação .spec.podCIDR
do Nó.
O Docker irá agora alocar IPs do bloco cbr-cidr . Contêineres podem alcançar outros contêineres e nós através da interface cbr0 .
Esses IPs são todos roteáveis dentro da rede do projeto do GCE.
O GCE mesmo não sabe nada sobre esses IPs, então não irá mascará-los quando tentarem se comunicar com a internet. Para
permitir isso uma regra de IPTables é utilizada para mascarar o tráfego para IPs fora da rede do projeto do GCE (no exemplo abaixo,
10.0.0.0/8):
Por fim, o encaminhamento de IP deve ser habilitado no Kernel de forma a processar os pacotes vindos dos contêineres:
sysctl net.ipv4.ip_forward=1
O resultado disso tudo é que Pods agora podem alcançar outros Pods e podem também se comunicar com a Internet.
Kube-router
Kube-router é uma solução construída que visa prover alta performance e simplicidade operacional. Kube-router provê um proxy de
serviços baseado no LVS/IPVS, uma solução de comunicação pod-para-pod baseada em encaminhamento de pacotes Linux e sem
camadas adicionais, e funcionalidade de políticas de redes baseadas no IPTables/IPSet.
Siga a parte "With Linux Bridge devices" desse tutorial super bacana do Lars Kellogg-Stedman.
Multus suporta todos os plugins referência (ex. Flannel, DHCP, Macvlan) que implementam a especificação de CNI e plugins de
terceiros (ex. Calico, Weave, Cilium, Contiv). Adicionalmente, Multus suporta cargas de trabalho no Kubernetes que necessitem de
funcionalidades como SRIOV, DPDK, OVS-DPDK & VPP.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 197/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Próximos passos
Design inicial do modelo de conectividade do Kubernetes e alguns planos futuros estão descritos com maiores detalhes no
documento de design de redes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 198/233
4/15/24, 11:56 AM Conceitos | Kubernetes
No entanto, a funcionalidade nativa fornecida por um mecanismo de contêiner ou tempo de execução geralmente não é suficiente
para uma solução completa de log. Por exemplo, se um contêiner travar, um pod for despejado ou um nó morrer, geralmente você
ainda desejará acessar os logs do aplicativo. Dessa forma, os logs devem ter armazenamento e ciclo de vida separados,
independentemente de nós, pods ou contêineres. Este conceito é chamado cluster-level-logging. O log no nível de cluster requer um
back-end separado para armazenar, analisar e consultar logs. O kubernetes não fornece uma solução de armazenamento nativa
para dados de log, mas você pode integrar muitas soluções de log existentes no cluster do Kubernetes.
As arquiteturas de log no nível de cluster são descritas no pressuposto de que um back-end de log esteja presente dentro ou fora
do cluster. Se você não estiver interessado em ter o log no nível do cluster, ainda poderá encontrar a descrição de como os logs são
armazenados e manipulados no nó para serem úteis.
debug/counter-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
A saída será:
pod/counter created
A saída será:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 199/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Você pode usar kubectl logs para recuperar logs de uma instanciação anterior de um contêiner com o sinalizador --previous ,
caso o contêiner tenha falhado. Se o seu pod tiver vários contêineres, você deverá especificar quais logs do contêiner você deseja
acessar anexando um nome de contêiner ao comando. Veja a documentação do kubectl logs para mais destalhes.
Logs no nível do Nó
Tudo o que um aplicativo em contêiner grava no stdout e stderr é tratado e redirecionado para algum lugar por dentro do
mecanismo de contêiner. Por exemplo, o mecanismo de contêiner do Docker redireciona esses dois fluxos para um driver de log,
configurado no Kubernetes para gravar em um arquivo no formato json.
Nota: O driver de log json do Docker trata cada linha como uma mensagem separada. Ao usar o driver de log do Docker, não há
suporte direto para mensagens de várias linhas. Você precisa lidar com mensagens de várias linhas no nível do agente de log ou
superior.
Por padrão, se um contêiner reiniciar, o kubelet manterá um contêiner terminado com seus logs. Se um pod for despejado do nó,
todos os contêineres correspondentes também serão despejados, juntamente com seus logs.
Uma consideração importante no log no nível do nó está implementado a rotação de log, para que os logs não consumam todo o
armazenamento disponível no nó. Atualmente, o Kubernentes não é responsável pela rotação de logs, mas uma ferramenta de
deployment deve configurar uma solução para resolver isso. Por exemplo, nos clusters do Kubernetes, implementados pelo script
kube-up.sh , existe uma ferramenta logrotate configurada para executar a cada hora. Você pode configurar um tempo de
execução do contêiner para girar os logs do aplicativo automaticamente, por exemplo, usando o log-opt do Docker. No script
kube-up.sh , a última abordagem é usada para imagem COS no GCP, e a anterior é usada em qualquer outro ambiente. Nos dois
casos por padrão, a rotação é configurada para ocorrer quando o arquivo de log exceder 10MB.
Como exemplo, você pode encontrar informações detalhadas sobre como o kube-up.sh define o log da imagem COS no GCP no
script correspondente.
Quando você executa kubectl logs como no exemplo de log básico acima, o kubelet no nó lida com a solicitação e lê diretamente
do arquivo de log, retornando o conteúdo na resposta.
Nota: Atualmente, se algum sistema externo executou a rotação, apenas o conteúdo do arquivo de log mais recente estará
disponível através de kubectl logs. Por exemplo, se houver um arquivo de 10MB, o logrotate executa a rotação e existem dois
arquivos, um com 10MB de tamanho e um vazio, o kubectl logs retornará uma resposta vazia.
O tempo de execução do kubelet e do contêiner, por exemplo, Docker, não é executado em contêineres.
Nas máquinas com systemd, o tempo de execução do kubelet e do container é gravado no journald. Se systemd não estiver
presente, eles gravam em arquivos .log no diretório /var/log . Os componentes do sistema dentro dos contêineres sempre
gravam no diretório /var/log , ignorando o mecanismo de log padrão. Eles usam a biblioteca de logs klog. Você pode encontrar as
convenções para a gravidade do log desses componentes nos documentos de desenvolvimento sobre log.
Da mesma forma que os logs de contêiner, os logs de componentes do sistema no diretório /var/log devem ser rotacionados. Nos
clusters do Kubernetes criados pelo script kube-up.sh , esses logs são configurados para serem rotacionados pela ferramenta
logrotate diariamente ou quando o tamanho exceder 100MB.
Você pode implementar o log em nível de cluster incluindo um agente de log em nível de nó em cada nó. O agente de log é uma
ferramenta dedicada que expõe logs ou envia logs para um back-end. Geralmente, o agente de log é um contêiner que tem acesso a
um diretório com arquivos de log de todos os contêineres de aplicativos nesse nó.
Como o agente de log deve ser executado em todos os nós, é comum implementá-lo como uma réplica do DaemonSet, um pod de
manifesto ou um processo nativo dedicado no nó. No entanto, as duas últimas abordagens são obsoletas e altamente
desencorajadas.
O uso de um agente de log no nível do nó é a abordagem mais comum e incentivada para um cluster Kubernetes, porque ele cria
apenas um agente por nó e não requer alterações nos aplicativos em execução no nó. No entanto, o log no nível do nó funciona
apenas para a saída padrão dos aplicativos e o erro padrão.
O Kubernetes não especifica um agente de log, mas dois agentes de log opcionais são fornecidos com a versão Kubernetes:
Stackdriver Logging para uso com o Google Cloud Platform e Elasticsearch. Você pode encontrar mais informações e instruções nos
documentos dedicados. Ambos usam fluentd com configuração customizada como um agente no nó.
Fazendo com que seus contêineres de sidecar fluam para seus próprios stdout e stderr , você pode tirar proveito do kubelet e do
agente de log que já executam em cada nó. Os contêineres sidecar lêem logs de um arquivo, socket ou journald. Cada contêiner
sidecar individual imprime o log em seu próprio stdout ou stderr stream.
Essa abordagem permite separar vários fluxos de logs de diferentes partes do seu aplicativo, algumas das quais podem não ter
suporte para gravar em stdout ou stderr . A lógica por trás do redirecionamento de logs é mínima, portanto dificilmente
representa uma sobrecarga significativa. Além disso, como stdout e stderr são manipulados pelo kubelet, você pode usar
ferramentas internas como o kubectl logs .
Considere o seguinte exemplo. Um pod executa um único contêiner e grava em dois arquivos de log diferentes, usando dois
formatos diferentes. Aqui está um arquivo de configuração para o Pod:
admin/logging/two-files-counter-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 202/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Seria uma bagunça ter entradas de log de diferentes formatos no mesmo fluxo de logs, mesmo se você conseguisse redirecionar os
dois componentes para o fluxo stdout do contêiner. Em vez disso, você pode introduzir dois contêineres sidecar. Cada contêiner
sidecar pode direcionar um arquivo de log específico de um volume compartilhado e depois redirecionar os logs para seu próprio
fluxo stdout .
Aqui está um arquivo de configuração para um pod que possui dois contêineres sidecar:
admin/logging/two-files-counter-pod-streaming-sidecar.yaml
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-2
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Agora, quando você executa este pod, é possível acessar cada fluxo de log separadamente, executando os seguintes comandos:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 203/233
4/15/24, 11:56 AM Conceitos | Kubernetes
O agente no nível do nó instalado em seu cluster coleta esses fluxos de logs automaticamente sem nenhuma configuração
adicional. Se desejar, você pode configurar o agente para analisar as linhas de log, dependendo do contêiner de origem.
Observe que, apesar do baixo uso da CPU e da memória (ordem de alguns milicores por CPU e ordem de vários megabytes de
memória), gravar logs em um arquivo e depois transmiti-los para o stdout pode duplicar o uso do disco. Se você tem um aplicativo
que grava em um único arquivo, geralmente é melhor definir /dev/stdout como destino, em vez de implementar a abordagem de
contêiner de transmissão no sidecar.
Os contêineres sidecar também podem ser usados para rotacionar arquivos de log que não podem ser rotacionados pelo próprio
aplicativo. Um exemplo dessa abordagem é um pequeno contêiner executando logrotate periodicamente. No entanto, é
recomendável usar o stdout e o stderr diretamente e deixar as políticas de rotação e retenção no kubelet.
Se o agente de log no nível do nó não for flexível o suficiente para sua situação, você poderá criar um contêiner secundário com um
agente de log separado que você configurou especificamente para executar com seu aplicativo.
Nota: O uso de um agente de log em um contêiner sidecar pode levar a um consumo significativo de recursos. Além disso, você
não poderá acessar esses logs usando o comando kubectl logs, porque eles não são controlados pelo kubelet.
Como exemplo, você pode usar o Stackdriver, que usa fluentd como um agente de log. Aqui estão dois arquivos de configuração
que você pode usar para implementar essa abordagem. O primeiro arquivo contém um ConfigMap para configurar o fluentd.
admin/logging/fluentd-sidecar-config.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 204/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-config
data:
fluentd.conf: |
<source>
type tail
format none
path /var/log/1.log
pos_file /var/log/1.log.pos
tag count.format1
</source>
<source>
type tail
format none
path /var/log/2.log
pos_file /var/log/2.log.pos
tag count.format2
</source>
<match **>
type google_cloud
</match>
Nota: A configuração do fluentd está além do escopo deste artigo. Para obter informações sobre como configurar o fluentd,
consulte a documentação oficial do fluentd.
O segundo arquivo descreve um pod que possui um contêiner sidecar rodando fluentemente. O pod monta um volume onde o
fluentd pode coletar seus dados de configuração.
admin/logging/two-files-counter-pod-agent-sidecar.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 205/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-agent
image: registry.k8s.io/fluentd-gcp:1.30
env:
- name: FLUENTD_ARGS
value: -c /etc/fluentd-config/fluentd.conf
volumeMounts:
- name: varlog
mountPath: /var/log
- name: config-volume
mountPath: /etc/fluentd-config
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-config
Depois de algum tempo, você pode encontrar mensagens de log na interface do Stackdriver.
Lembre-se de que este é apenas um exemplo e você pode realmente substituir o fluentd por qualquer agente de log, lendo de
qualquer fonte dentro de um contêiner de aplicativo.
Você pode implementar o log no nível do cluster, expondo ou enviando logs diretamente de todos os aplicativos; no entanto, a
implementação desse mecanismo de log está fora do escopo do Kubernetes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 206/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Klog
Klog é a biblioteca de logs do Kubernetes. Responsável por gerar as mensagens de log para os componentes do sistema.
Para mais informações acerca da sua configuração, veja a documentação da ferramenta de linha de comando.
Logs Estruturados
ESTADO DA FUNCIONALIDADE: Kubernetes v1.19 [alpha]
Aviso:
A migração pro formato de logs estruturados é um processo em andamento. Nem todos os logs estão dessa forma na versão
atual. Sendo assim, para realizar o processamento de arquivos de log, você também precisa lidar com logs não estruturados.
A estruturação dos logs trás uma estrutura uniforme para as mensagens de log, permitindo a extração programática de
informações. Logs estruturados podem ser armazenados e processados com menos esforço e custo. Esse formato é totalmente
retrocompatível e é habilitado por padrão.
Exemplo:
Aviso:
Algumas opções da biblioteca klog ainda não funcionam com os logs em formato JSON. Para ver uma lista completa de quais
são estas, veja a documentação da ferramenta de linha de comando.
Nem todos os logs estarão garantidamente em formato JSON (como por exemplo durante o início de processos). Sendo assim,
se você pretende realizar o processamento dos logs, seu código deverá saber tratar também linhas que não são JSON.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 207/233
4/15/24, 11:56 AM Conceitos | Kubernetes
A opção --logging-format=json muda o formato dos logs, do formato padrão da klog para JSON. Abaixo segue um exemplo de um
log em formato JSON (identado):
{
"ts": 1580306777.04728,
"v": 4,
"msg": "Pod status updated",
"pod":{
"name": "nginx-1",
"namespace": "default"
},
"status": "ready"
}
kube-controller-manager
kube-apiserver
kube-scheduler
kubelet
Aviso: A funcionalidade de limpeza dos logs pode causar impactos significativos na performance, sendo portanto
contraindicada em produção.
A opção --experimental-logging-sanitization habilita o filtro de limpeza dos logs. Quando habilitado, esse filtro inspeciona todos
os argumentos dos logs, procurando por campos contendo dados sensíveis (como senhas, chaves e tokens). Tais campos não serão
expostos nas mensagens de log.
kube-controller-manager
kube-apiserver
kube-scheduler
kubelet
Nota: O filtro de limpeza dos logs não impede a exposição de dados sensíveis nos logs das aplicações em execução.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 208/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Em máquinas com systemd, o kubelet e os agentes de execução gravam os logs no journald. Em outros casos, eles escrevem os logs
em arquivos .log no diretório /var/log . Já os componentes executados dentro de contêineres, sempre irão escrever os logs em
arquivos .log no diretório /var/log , ignorando o mecanismo padrão de log.
De forma similar aos logs de contêiner, os logs de componentes do sistema no diretório /var/log devem ser rotacionados. Nos
clusters Kubernetes criados com o script kube-up.sh , a rotação dos logs é configurada pela ferramenta logrotate . Essa
ferramenta rotaciona os logs diariamente ou quando o tamanho do arquivo excede 100MB.
Próximos passos
Leia sobre Arquitetura de Logs do Kubernetes
Leia sobre Logs Estruturados
Leia sobre Convenções sobre os níveis de logs
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 209/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Componentes do Kubernetes emitem métricas no formato Prometheus. Esse formato é um texto simples estruturado, projetado
para que pessoas e máquinas possam lê-lo.
Métricas no Kubernetes
Na maioria dos casos, as métricas estão disponíveis no endpoint /metrics do servidor HTTP. Para componentes que não expõem o
endpoint por padrão, ele pode ser ativado usando a flag --bind-address .
kube-controller-manager
kube-proxy
kube-apiserver
kube-scheduler
kubelet
Em um ambiente de produção, você pode querer configurar o Servidor Prometheus ou algum outro coletor de métricas e
disponibilizá-las em algum tipo de banco de dados temporais.
Observe que o kubelet também expõe métricas nos endpoints /metrics/cadvisor , /metrics/resource e /metrics/probes . Essas
métricas não possuem o mesmo ciclo de vida.
Se o seu cluster usa RBAC, ler as métricas requer autorização por meio de um usuário, grupo ou ServiceAccount com um ClusterRole
que conceda o acesso ao /metrics .
Por exemplo:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: prometheus
rules:
- nonResourceURLs:
- "/metrics"
verbs:
- get
A métrica alfa não tem garantias de estabilidade. Essas métricas podem ser modificadas ou deletadas a qualquer momento.
Métricas estáveis possuem a garantia de que não serão alteradas. Isso significa:
Uma métrica estável sem uma assinatura ultrapassada não será deletada ou renomeada
O tipo de uma métrica estável não será modificado
As métricas ultrapassadas estão programadas para exclusão, mas ainda estão disponíveis para uso. Essas métricas incluem uma
anotação sobre a versão em que se tornarão ultrapassadas.
Por exemplo:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 210/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Métricas ocultas não são mais publicadas para extração, mas ainda estão disponíveis para uso. Para usar uma métrica oculta, por
favor consulte a seção mostrar métricas ocultas.
Métricas excluídas não estão mais disponíveis e não podem mais ser usadas.
A flag show-hidden-metrics-for-version usa uma versão para a qual você deseja mostrar métricas ultrapassadas nessa versão. A
versão é expressada como x.y, onde x é a versão principal e y a versão secundária. A versão de patch não é necessária mesmo que
uma métrica possa ser descontinuada em uma versão de patch, o motivo é que a política de descontinuação de métricas é
executada na versão secundária.
A flag só pode usar a versão secundária anterior como seu valor. Todas as métricas ocultas no anterior serão emitidas se os
administradores definirem a versão anterior como show-hidden-metrics-for-version . A versão muito antiga não é permitida
porque viola a política de métricas ultrapassadas.
Utilize a métrica A como exemplo, assumindo que A está obsoleto em 1.n. De acordo com a política de métricas ultrapassadas,
podemos chegar à seguinte conclusão:
Na versão 1.n , a métrica está ultrapassada, e pode ser emitida por padrão.
Na versão 1.n+1 , a métrica está oculta por padrão e pode ser emitida via linha de comando show-hidden-metrics-for-
version=1.n .
Na versão 1.n+2 , a métrica deve ser removida do código fonte. Não há mais escape hatch.
Se você está atualizando da versão 1.12 para 1.13 , mas ainda depende da métrica A ultrapassada em 1.12 , você deve definir
métricas ocultas via linha de comando: --show-hidden-metrics=1.12 e lembre-se de remover essa dependência de métrica antes
de atualizar para 1.14 .
A responsabilidade de colear métricas do accelerator agora pertence ao fornecedor, e não ao kubelet. Os fornecedores devem
providenciar um contêiner que colete métricas e as exponha ao serviço de métricas (por exemplo, Prometheus).
O DisableAcceleratorUsageMetrics feature gate desabilita as métricas coletadas pelo kubelet, com uma timeline para habilitar esse
recurso por padrão.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 211/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Métricas de componentes
Métricas do kube-controller-manager
As métricas do controller manager fornecem informações importantes sobre o desempenho e a integridade do controller manager.
Essas métricas incluem métricas comuns do agente de execução da linguagem Go, tais como a quantidade de go_routine e métricas
específicas do controller, como latência de requisições etcd ou latência da API dos provedores de serviços de nuvem (AWS, GCE,
OpenStack), que podem ser usadas para medir a integridade de um cluster.
A partir do Kubernetes 1.7, métricas detalhadas de provedores de serviços de nuvem estão disponíveis para operações de
armazenamento para o GCE, AWS, Vsphere e OpenStack. Essas métricas podem ser usadas para monitorar a integridade das
operações de volumes persistentes.
Métricas do kube-scheduler
ESTADO DA FUNCIONALIDADE: Kubernetes v1.21 [beta]
O scheduler expõe métricas opcionais que relatam os recursos solicitados e os limites desejados de todos os pods em execução.
Essas métricas podem ser usadas para criar dashboards de planejamento de capacidade, avaliar os limites de agendamentos atuais
ou históricos, identificar rapidamente cargas de trabalho que não podem ser agendadas devido à falta de recursos e comparar o
uso atual com a solicitação do pod.
O kube-scheduler identifica as requisições de recursos e limites configurado para cada Pod; quando uma requisição ou limite é
diferente de zero o kube-scheduler relata uma timeseries de métricas. Essa timeseries é etiquetada por:
namespace
nome do pod
o nó onde o pod está programado ou uma string vazia caso ainda não esteja programado
prioridade
o scheduler atribuído para esse pod
o nome do recurso (por exemplo, cpu )
a unidade do recurso, se conhecida (por exemplo, cores )
Uma vez que o pod alcança um estado de conclusão (sua restartPolicy está como Never ou onFailure e está na fase de
Succeeded ou Failed , ou foi deletado e todos os contêineres tem um estado de terminado), a série não é mais relatada já que o
scheduler agora está livre para agendar a execução de outros pods. As duas métricas são chamadas de kube_pod_resource_request
e kube_pod_resource_limit .
As métricas são expostas no endpoint HTTP /metrics/resources e requerem a mesma autorização que o endpoint /metrics no
scheduler. Você deve usar a flag --show-hidden-metrics-for-version=1.20 para expor essas métricas de estabilidade alfa.
Desativando métricas
Você pode desativar explicitamente as métricas via linha de comando utilizando a flag --disabled-metrics . Isso pode ser desejado
se, por exemplo, uma métrica estiver causando um problema de desempenho. A entrada é uma lista de métricas desabilitadas (ou
seja, --disabled-metrics=metric1,metric2 ).
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 212/233
4/15/24, 11:56 AM Conceitos | Kubernetes
No estágio alfa, a flag pode receber apenas uma série de mapeamentos como lista de permissões de labels para uma métrica. Cada
mapeamento tem o formato <metric_name>,<label_name>=<allowed_labels> onde <allowed_labels> é uma lista separada por
vírgulas de nomes aceitáveis para a label.
Próximos passos
Leia sobre o formato de texto do Prometheus para métricas
Veja a lista de métricas estáveis do Kubernetes
Leia sobre a Política de suspensão de uso do Kubernetes
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 213/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Ferramentas externas de garbage collection não são recomendadas, pois podem potencialmente interromper o comportamento do
kubelet removendo os contêineres que existem.
Coleta de imagens
O Kubernetes gerencia o ciclo de vida de todas as imagens através do imageManager, com a cooperação do cadvisor.
A política para o garbage collection de imagens leva dois fatores em consideração: HighThresholdPercent e LowThresholdPercent .
Uso do disco acima do limite acionará o garbage collection. O garbage collection excluirá as imagens que foram menos usadas
recentemente até que o nível fique abaixo do limite.
Coleta de container
A política para o garbage collection de contêineres considera três variáveis definidas pelo usuário. MinAge é a idade mínima em que
um contêiner pode ser coletado. MaxPerPodContainer é o número máximo de contêineres mortos que todo par de pod (UID,
container name) pode ter. MaxContainers é o número máximo de contêineres mortos totais. Essas variáveis podem ser
desabilitadas individualmente, definindo MinAge como zero e definindo MaxPerPodContainer e MaxContainers respectivamente
para menor que zero.
O Kubelet atuará em contêineres não identificados, excluídos ou fora dos limites definidos pelos sinalizadores mencionados. Os
contêineres mais antigos geralmente serão removidos primeiro. MaxPerPodContainer e MaxContainer podem potencialmente
conflitar entre si em situações em que a retenção do número máximo de contêineres por pod ( MaxPerPodContainer ) estaria fora do
intervalo permitido de contêineres globais mortos ( MaxContainers ). O MaxPerPodContainer seria ajustado nesta situação: O pior
cenário seria fazer o downgrade do MaxPerPodContainer para 1 e remover os contêineres mais antigos. Além disso, os contêineres
pertencentes a pods que foram excluídos são removidos assim que se tornem mais antigos que MinAge .
Os contêineres que não são gerenciados pelo kubelet não estão sujeitos ao garbage collection de contêiner.
Configurações do usuário
Os usuários podem ajustar os seguintes limites para ajustar o garbage collection da imagem com os seguintes sinalizadores do
kubelet:
1. image-gh-high-threshold , a porcentagem de uso de disco que aciona o garbage collection da imagem. O padrão é 85%.
2. image-gc-low-threshold , a porcentagem de uso de disco com o qual o garbage collection da imagem tenta liberar. O padrão é
80%.
Também permitimos que os usuários personalizem a política do garbagem collection através dos seguintes sinalizadores do
kubelet:
1. minimum-container-ttl-duration , idade mínima para um contêiner finalizado antes de ser colectado. O padrão é 0 minuto, o
que significa que todo contêiner finalizado será coletado como lixo.
2. maximum-dead-containers-per-container , número máximo de instâncias antigas a serem retidas por contêiner. O padrão é 1.
3. maximum-dead-containers , número máximo de instâncias antigas de contêineres para retenção global. O padrão é -1, o que
significa que não há limite global.
Os contêineres podem ser potencialmente coletados como lixo antes que sua utilidade expire. Esses contêineres podem conter logs
e outros dados que podem ser úteis para solucionar problemas. Um valor suficientemente grande para maximum-dead-containers-
per-container é altamente recomendado para permitir que pelo menos 1 contêiner morto seja retido por contêiner esperado. Um
valor maior para maximum-dead-containers também é recomendados por um motivo semelhante. Consulte esta issue para obter
mais detalhes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 214/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Descontinuado
Alguns recursos do Garbage Collection neste documento serão substituídos pelo kubelet eviction no futuro.
Incluindo:
Próximos passos
Consulte Configurando a Manipulação de Recursos Insuficientes para mais detalhes.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 215/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Proxies
Existem vários tipos diferentes de proxies que você pode encontrar usando Kubernetes:
1. O kubectl proxy:
Quando o kubectl proxy é utilizado ocorre o seguinte: - executa na máquina do usuário ou em um pod - redireciona/encapsula
conexões direcionadas ao localhost para o servidor de API - a comunicação entre o cliente e o o proxy usa HTTP - a comunicação
entre o proxy e o servidor de API usa HTTPS - o proxy localiza o servidor de API do cluster - o proxy adiciona os cabeçalhos de
comunicação.
1. O apiserver proxy:
a existência e a implementação de tal elemento varia de cluster para cluster, por exemplo nginx
fica entre todos os clientes e um ou mais serviços
atua como balanceador de carga se existe mais de um servidor de API.
4. Balanceadores de carga da nuvem em serviços externos:
são fornecidos por algum provedor de nuvem (e.x AWS ELB, Google Cloud Load Balancer)
são criados automaticamente quando o serviço de Kubernetes tem o tipo LoadBalancer
geralmente suportam apenas UDP/TCP
O suporte ao SCTP fica por conta da implementação do balanceador de carga da provedora de nuvem
a implementação varia de acordo com o provedor de cloud.
Os usuários de Kubernetes geralmente não precisam se preocupar com outras coisas além dos dois primeiros tipos. O
administrador do cluster tipicamente garante que os últimos tipos serão configurados corretamente.
Redirecionamento de requisições
Os proxies substituíram as capacidades de redirecionamento. O redirecionamento foi depreciado.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 216/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Esta página lista alguns dos complementos disponíveis e links com suas respectivas instruções de instalação.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 217/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Descoberta de Serviço
CoreDNS é um servidor DNS flexível e extensível que pode ser instalado como o serviço de DNS dentro do cluster para ser
utilizado por pods.
Infraestrutura
KubeVirt é um complemento para executar máquinas virtuais no Kubernetes. É geralmente executado em clusters em
máquina física.
Complementos Legados
Existem vários outros complementos documentados no diretório cluster/addons que não são mais utilizados.
Projetos bem mantidos devem ser listados aqui. PRs são bem-vindos!
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 218/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Controlar o comportamento do servidor da API Kubernetes em uma situação de sobrecarga é uma tarefa chave para
administradores de cluster. O kube-apiserver tem alguns controles disponíveis (ou seja, as flags --max-requests-inflight e --max-
mutating-requests-inflight ) para limitar a quantidade de trabalho pendente que será aceito, evitando que uma grande
quantidade de solicitações de entrada sobrecarreguem, e potencialmente travando o servidor da API, mas essas flags não são
suficientes para garantir que as solicitações mais importantes cheguem em um período de alto tráfego.
O recurso de prioridade e imparcialidade da API (do inglês API Priority and Fairness, APF) é uma alternativa que melhora as limitações
mencionadas acima. A APF classifica e isola os pedidos de uma forma mais refinada. Também introduz uma quantidade limitada de
filas, para que nenhuma solicitação seja rejeitada nos casos de sobrecargas muito breves. As solicitações são despachadas das filas
usando uma técnica de filas justa para que, por exemplo, um controller não precise negar as outras requisições (mesmo no mesmo
nível de prioridade).
Esse recurso foi projetado para funcionar bem com controladores padrão, que usam informantes e reagem a falhas de solicitações
da API com exponencial back-off, e outros clientes que também funcionam desta forma.
Cuidado: Solicitações classificadas como "de longa duração" — principalmente watches — não são sujeitas ao filtro da
prioridade e imparcialidade da API. Isso também é verdade para a flag --max-requests-inflight sem o recurso da APF ativado.
kube-apiserver \
--feature-gates=APIPriorityAndFairness=false \
--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=false,flowcontrol.apiserver.k8s.io/v1beta2=false \
# …and other flags as usual
Como alternativa, você pode habilitar a versão v1alpha1 do grupo de APIs com --runtime-
config=flowcontrol.apiserver.k8s.io/v1alpha1=true .
A flag --enable-priority-and-fairness=false desabilitará o recurso de prioridade e imparcialidade da API, mesmo que outras flags
o tenha ativado.
Conceitos
Existem vários recursos distintos envolvidos na APF. As solicitações recebidas são classificadas por atributos da solicitação usando
FlowSchemas e atribuídos a níveis de prioridade. Os níveis de prioridade adicionam um grau de isolamento mantendo limites de
simultaneidade separados, para que as solicitações atribuídas a diferentes níveis de prioridade não travem outros. Dentro de um
nível de prioridade, um algoritmo de fair queuing impede que solicitações de diferentes flows fiquem sem energia entre si, e permite
que os pedidos sejam enfileirados para evitar que um alto tráfego cause falhas nas solicitações quando a carga média é
aceitavelmente baixa.
Níveis de prioridade
Sem o APF ativado, a simultaneidade geral no servidor de API é limitada pelo kube-apiserver as flags --max-requests-inflight e
--max-mutating-requests-inflight . Com o APF ativado, os limites de simultaneidade definidos por esses sinalizadores são
somados e, em seguida, a soma é dividida entre um conjunto configurável de níveis de prioridade. Cada solicitação recebida é
atribuída a um nível de prioridade único, e cada nível de prioridade só despachará tantos solicitações simultâneas conforme sua
configuração permite.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 219/233
4/15/24, 11:56 AM Conceitos | Kubernetes
A configuração padrão, por exemplo, inclui níveis de prioridade separados para solicitações de eleição de líder, solicitações de
controladores integrados e solicitações de Pods. Isso significa que um pod mal-comportado que inunda o servidor da API com
solicitações não podem impedir a eleição do líder ou ações dos controladores integrados de ter sucesso.
Enfileiramento
Mesmo dentro de um nível de prioridade pode haver um grande número de fontes distintas de tráfego. Em uma situação de
sobrecarga, é importante evitar um fluxo de pedidos de outros serviços (em particular, no caso relativamente comum de um único
cliente buggy inundando o kube-apiserver com solicitações, esse cliente buggy idealmente não teria muito impacto em outros
clientes). Isto é tratadas pelo uso de um algoritmo de fair queuing para processar solicitações que são atribuídas ao mesmo nível de
prioridade. Cada solicitação é atribuída a um flow, identificado pelo nome do FlowSchema correspondente mais um flow distincter —
que é o usuário solicitante, o namespace do recurso de destino ou nada — e o sistema tenta dar peso aproximadamente igual a
solicitações em diferentes fluxos do mesmo nível de prioridade. Para habilitar o tratamento distinto de instâncias distintas, os
controladores que muitas instâncias devem ser autenticadas com nomes de usuário distintos
Depois de classificar uma solicitação em um fluxo, a APF pode então atribuir a solicitação a uma fila. Esta atribuição usa uma técnica
conhecida como shuffle sharding, que faz uso relativamente eficiente de filas para isolar fluxos de baixa intensidade de fluxos de
alta intensidade.
Os detalhes do algoritmo de enfileiramento são ajustáveis para cada nível de prioridade e permitem que os administradores
troquem o uso de memória, justiça (a propriedade que fluxos independentes irão progredir quando o tráfego total exceder a
capacidade), tolerância para tráfego e a latência adicionada induzida pelo enfileiramento.
Solicitações de isenção
Alguns pedidos são considerados suficientemente importantes para que não estejam sujeitos a qualquer uma das limitações
impostas por este recurso. Estas isenções impedem uma configuração de controle de fluxo mal configurada de desabilitar
totalmente um servidor da API.
Recursos
A API de controle de fluxo envolve dois tipos de recursos. PriorityLevelConfigurations define as classes de isolamento disponíveis, a
parte da concorrência disponível que cada um pode tratar e permite o ajuste fino do comportamento das filas. FlowSchemas são
usados para classificar solicitações de entrada individuais, correspondendo cada uma a um único PriorityLevelConfiguration. Há
também uma versão v1alpha1 do mesmo grupo de APIs e tem os mesmos tipos com a mesma sintaxe e semântica.
PriorityLevelConfiguration
Um PriorityLevelConfiguration representa uma única classe de isolamento. Cada PriorityLevelConfiguration tem um limite
independente no número de solicitações de pendências e limitações no número de solicitações enfileiradas.
Os limites de simultaneidade para PriorityLevelConfigurations não são especificados no número absoluto de solicitações, mas sim
em "compartilhamentos de simultaneidade". A simultaneidade limite total para o servidor da API é distribuído entre os
PriorityLevelConfigurations existentes em proporção com esses compartilhamentos. Isso permite um administrador de cluster
aumentar ou diminuir a quantidade total de tráfego para um servidor reiniciando kube-apiserver com um valor diferente para --
max-requests-inflight (ou --max-mutating-requests-inflight ), e todos os PriorityLevelConfigurations verá sua simultaneidade
máxima permitida aumentar (ou abaixar) pela mesma proporção.
Cuidado: Com o recurso prioridade e imparcialidade ativado, o limite total de simultaneidade para o servidor é definido como a
soma de --max-requests-inflight e --max-mutating-requests-inflight. Já não há distinção entre solicitações mutantes e não
mutantes; se você quiser tratá-las separadamente para um determinado recurso, faça FlowSchemas separados que
correspondam ao verbos mutantes e não mutantes, respectivamente.
Quando o volume de solicitações de entrada atribuídas a um único PriorityLevelConfiguration é maior do que o permitido por seu
nível de simultaneidade, o O campo type de sua especificação determina o que acontecerá com solicitações extras. Um tipo de
'Reject' significa que o excesso de tráfego será imediatamente rejeitado com um erro HTTP 429 (Too Many Requests). Um tipo de
Queue significa que as solicitações acima do limite será enfileirado, com as técnicas de shuffle sharding e fair queuing usadas para
equilibrar o progresso entre os fluxos de solicitação.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 220/233
4/15/24, 11:56 AM Conceitos | Kubernetes
A configuração de enfileiramento permite ajustar o algoritmo de fair queuing para um nível de prioridade. Os detalhes do algoritmo
podem ser lidos no proposta de melhoria, mas resumindo:
Aumentar as 'filas' reduz a taxa de colisões entre diferentes fluxos, o custo do aumento do uso de memória. Um valor de 1
aqui efetivamente desabilita a lógica de fair queuing, mas ainda permite que as solicitações sejam enfileiradas.
Aumentar o queueLengthLimit permite que tráfegos maiores sejam sustentados sem deixar de lado nenhum pedido, ao custo
de aumento latência e uso de memória.
Alterar handSize permite ajustar a probabilidade de colisões entre fluxos diferentes e a simultaneidade geral disponível para
um único fluxo em um situação de sobrecarga.
Nota: Um 'handSize' maior torna menos provável que dois fluxos individuais colidam (e, portanto, um bloqueie a
solicitação do outro), mas é mais provável que um pequeno número de fluxos pode dominar o apiserver. Um handSize
maior também aumenta potencialmente a quantidade de latência que um único fluxo de alto tráfego pode causar. O
número máximo de solicitações enfileiradas possíveis de um fluxo único é handSize * queueLengthLimit.
A seguir está uma tabela mostrando uma coleção interessante de configurações do shuffle sharding, mostrando para cada uma a
probabilidade de que um determinado rato (fluxo de baixa intensidade) é esmagado pelos elefantes (fluxo de alta intensidade) para
uma coleção ilustrativa de números de elefantes. Veja https://play.golang.org/p/Gi0PLgVHiUg , que calcula esta tabela.
FlowSchema
Um FlowSchema corresponde a algumas solicitações de entrada e as atribui a um nível de prioridade. Cada solicitação de entrada é
testada em relação a cada FlowSchema, por sua vez, começando com aqueles com valores numericamente mais baixos --- que
consideramos ser o logicamente mais alto --- matchingPrecedence e trabalhando adiante. A primeira correspondência ganha.
Cuidado: Somente o primeiro FlowSchema correspondente para uma determinada solicitação é importante. Se vários
FlowSchemas correspondem a uma única solicitação de entrada, ela será atribuída com base na com o maior em
matchingPrecedence. Se vários FlowSchemas com igual matchingPrecedence corresponde ao mesmo pedido, aquele com menor
name lexicográfico vencerá, mas é melhor não confiar nisso e, em vez disso, certifique-se de que dois FlowSchemas não tenham
o mesmo matchingPrecedence.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 221/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Um FlowSchema corresponde a uma determinada solicitação se pelo menos uma de suas regras são correspondidas. Uma regra
corresponde se pelo menos um de seus assuntos e pelo menos uma de suas resourceRules ou nonResourceRules (dependendo
se a solicitação de entrada é para um recurso ou URL de não-recurso) corresponde à solicitação.
Para o campo name em assuntos, e os campos verbs , apiGroups , resources , namespaces e nonResourceURLs de regras de
recursos e não recursos, o wildcard * pode ser especificado para corresponder a todos os valores do campo fornecido,
efetivamente removendo-o de consideração.
O distinguisherMethod.type de um FlowSchema determina como as solicitações correspondentes a esse esquema será separado
em fluxos. Pode ser ou ByUser , caso em que um usuário solicitante não poderá ser bloqueado por outros, ou ByNamespace , caso
em que solicitações de recursos em um namespace não será capaz de privar os pedidos de recursos em outros namespaces de
capacidade, ou pode estar em branco (ou distinguisherMethod pode ser omitido inteiramente), caso em que todas as solicitações
correspondidas por este FlowSchema serão considerados parte de um único fluxo. A escolha correta para um determinado
FlowSchema depende do recurso e do seu ambiente específico.
Padrões
Cada kube-apiserver mantém dois tipos de objetos de configuração APF: obrigatória e sugerida.
O nível de prioridade obrigatório exempt é usado para solicitações que são não sujeito a controle de fluxo: eles sempre serão
despachados imediatamente. O FlowSchema obrigatório exempt classifica todos solicitações do grupo system:masters para
este nível de prioridade. Você pode definir outros FlowSchemas que direcionam outras solicitações a este nível de prioridade,
se apropriado.
O nível de prioridade obrigatório catch-all é usado em combinação com o FlowSchema catch-all obrigatório para garantir
que todas as solicitações recebam algum tipo de classificação. Normalmente você não deve confiar nesta configuração catch-
all, e deve criar seu próprio FlowSchema catch-all e PriorityLevelConfiguration (ou use o nível de prioridade global-default
que é instalado por padrão) como apropriado. Como não se espera que seja usado normalmente, o o nível de prioridade
obrigatório catch-all tem uma simultaneidade muito pequena compartilha e não enfileira solicitações.
O nível de prioridade system é para solicitações não relacionadas à integridade do grupo system:nodes , ou seja, Kubelets,
que deve ser capaz de contatar o servidor de API para que as cargas de trabalho possam ser agendadas eles.
O nível de prioridade leader-election é para solicitações de eleição de líder de controladores embutidos (em particular,
solicitações para endpoints , configmaps , ou leases vindo do system:kube-controller-manager ou usuários system:kube-
scheduler e contas de serviço no namespace kube-system ). Estes são importantes para isolar de outro tráfego porque as
falhas na eleição do líder fazem com que seus controladores falhem e reiniciem, o que por sua vez causa tráfego mais caro à
medida que os novos controladores sincronizam seus informantes.
O nível de prioridade workload-low é para solicitações de qualquer outra conta de serviço, que normalmente incluirá todas as
solicitações de controladores em execução Pods.
O nível de prioridade global-default trata de todos os outros tráfegos, por exemplo, comandos kubectl interativos
executados por usuários não privilegiados.
Os FlowSchemas sugeridos servem para direcionar as solicitações para os níveis de prioridade acima, e não são enumerados aqui.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 222/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Para os objetos de configuração obrigatórios, a manutenção consiste em garantir que o objeto existe e, se existir, tem a
especificação adequada. O servidor se recusa a permitir uma criação ou atualização com uma especificação que é inconsistente com
o comportamento do guarda-corpo do servidor.
A manutenção de objetos de configuração sugeridos é projetada para permitir que suas especificações sejam substituídas. A
exclusão, por outro lado, não é respeitada: a manutenção restaurará o objeto. Se você não quer um objeto de configuração
sugerido, então você precisa mantê-lo por perto, mas defina sua especificação para ter consequências mínimas. Manutenção de
objetos sugeridos também é projetada para suportar a migração automática quando uma nova versão do kube-apiserver é
lançada, embora potencialmente com thrashing enquanto há uma população mista de servidores.
A manutenção de um objeto de configuração sugerido consiste em cria-lo --- com a especificação sugerida pelo servidor --- se o
objeto não existir. OTOH, se o objeto já existir, o comportamento de manutenção depende se os kube-apiservers ou os usuários
controlam o objeto. No primeiro caso, o servidor garante que a especificação do objeto é o que o servidor sugere; no último caso, a
especificação é deixada sozinho.
A questão de quem controla o objeto é respondida primeiro olhando para uma anotação com a chave
apf.kubernetes.io/autoupdate-spec . Se existe tal anotação e seu valor é true então o kube-apiservers controlam o objeto. Se
houver tal anotação e seu valor for false , os usuários controlarão o objeto. Se nenhuma dessas condições é satisfeita entaão a
metadata.generation do objeto é consultado. Se for 1, o kube-apiservers controla o objeto. Caso contrário, os usuários controlam o
objeto. Essas regras foram introduzido na versão 1.22 e sua consideração de metadata.generation é para migrar do mais simples
comportamento anterior. Usuários que desejam controlar um objeto de configuração sugerido deve definir sua anotação
apf.kubernetes.io/autoupdate-spec para 'falso'.
A manutenção de um objeto de configuração obrigatório ou sugerido também inclui garantir que ele tenha uma anotação
apf.kubernetes.io/autoupdate-spec que reflete com precisão se os kube-apiservers controlam o objeto.
A manutenção também inclui a exclusão de objetos que não são obrigatórios nem sugeridos, mas são anotados
apf.kubernetes.io/autoupdate-spec=true .
Se você adicionar o seguinte FlowSchema adicional, isso isenta aquelas solicitações de limitação de taxa.
Cuidado: Fazer essa alteração também permite que qualquer parte hostil envie solicitações de verificação de integridade que
correspondam a este FlowSchema, em qualquer volume. Se você tiver um filtro de tráfego da Web ou outro mecanismo de
segurança externa semelhante para proteger o servidor de API do seu cluster do trafego geral de internet, você pode configurar
regras para bloquear qualquer solicitação de verificação de integridade que se originam de fora do seu cluster.
priority-and-fairness/health-for-strangers.yaml
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 223/233
4/15/24, 11:56 AM Conceitos | Kubernetes
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: health-for-strangers
spec:
matchingPrecedence: 1000
priorityLevelConfiguration:
name: exempt
rules:
- nonResourceRules:
- nonResourceURLs:
- "/healthz"
- "/livez"
- "/readyz"
verbs:
- "*"
subjects:
- kind: Group
group:
name: system:unauthenticated
Diagnóstico
Cada resposta HTTP de um servidor da API com o recurso de prioridade e justiça ativado tem dois cabeçalhos extras: X-Kubernetes-
PF-FlowSchema-UID e X-Kubernetes-PF-PriorityLevel-UID , observando o esquema de fluxo que corresponde à solicitação e o nível
de prioridade ao qual foi atribuído, respectivamente. Os nomes dos objetos da API não são incluídos nesses cabeçalhos caso o
usuário solicitante não tenha permissão para visualizá-los, então ao depurar você pode usar um comando como
Observabilidade
Metricas
Nota: Nas versões do Kubernetes anteriores à v1.20, as labels flow_schema e priority_level foram nomeados de forma
inconsistente como flowSchema e priorityLevel, respectivamente. Se você estiver executando versões do Kubernetes v1.19 ou
anteriores, você deve consultar a documentação da sua versão.
Quando você ativa o APF, o kube-apiserver exporta métricas adicionais. Monitorá-los pode ajudá-lo a determinar se a sua
configuração está limitando indevidamente o tráfego importante, ou encontrar cargas de trabalho mal comportadas que podem
estar prejudicando a integridade do sistema.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 224/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Nota: Um valor discrepante em um histograma aqui significa que é provável que um único fluxo (ou seja, solicitações de
um usuário ou de um namespace, dependendo da configuração) está inundando o servidor de API e sendo limitado. Por
contraste, se o histograma de um nível de prioridade mostrar que todas as filas para essa prioridade são mais longos do
que os de outros níveis de prioridade, pode ser apropriado aumentar os compartilhamentos de simultaneidade desse
PriorityLevelConfiguration.
Nota: Como cada FlowSchema sempre atribui solicitações a um único PriorityLevelConfiguration, você pode adicionar os
histogramas para todos os FlowSchemas para um nível de prioridade para obter o histograma efetivo para solicitações
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 225/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Debug endpoints
Quando você ativa A APF, o kube-apiserver serve os seguintes caminhos adicionais em suas portas HTTP[S].
/debug/api_priority_and_fairness/dump_queues - uma listagem de todas as filas e seu estado atual. Você pode buscar assim:
/debug/api_priority_and_fairness/dump_requests - uma lista de todos os pedidos que estão atualmente esperando em uma
fila. Você pode buscar assim:
Além das solicitações enfileiradas, a saída inclui uma linha fantasma para cada nível de prioridade isento de limitação.
Você pode obter uma lista mais detalhada com um comando como este:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 226/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Próximos passos
Para obter informações básicas sobre detalhes de design para prioridade e justiça da API, consulte a proposta de aprimoramento.
Você pode fazer sugestões e solicitações de recursos por meio do SIG API Machinery ou do canal do slack.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 227/233
4/15/24, 11:56 AM Conceitos | Kubernetes
11 - Extendendo o Kubernetes
11.1 - Extendendo a API do Kubernetes
11.1.1 - Extendendo a API do Kubernetes com a camada
de agregação
A camada de agregação permite ao Kubernetes ser estendido com APIs adicionais, para além do que é oferecido pelas APIs centrais
do Kubernetes. As APIs adicionais podem ser soluções prontas tal como o catálogo de serviços, ou APIs que você mesmo
desenvolva.
A camada de agregação é diferente dos Recursos Personalizados, que são uma forma de fazer o kube-apiserver reconhecer novas
espécies de objetos.
Camada de agregação
A camada de agregação executa em processo com o kube-apiserver. Até que um recurso de extensão seja registado, a camada de
agregação não fará nada. Para registar uma API, terá de adicionar um objeto APIService que irá "reclamar" o caminho URL na API do
Kubernetes. Nesta altura, a camada de agregação procurará qualquer coisa enviada para esse caminho da API (e.g.
/apis/myextension.mycompany.io/v1/… ) para o APIService registado.
A maneira mais comum de implementar o APIService é executar uma extensão do servidor API em Pods que executam no seu cluster.
Se estiver a usar o servidor de extensão da API para gerir recursos no seu cluster, o servidor de extensão da API (também escrito
como "extension-apiserver") é tipicamente emparelhado com um ou mais controladores. A biblioteca apiserver-builder providencia
um esqueleto para ambos os servidores de extensão da API e controladores associados.
Latência da resposta
Servidores de extensão de APIs devem ter baixa latência de rede de e para o kube-apiserver. Pedidos de descoberta são necessários
que façam a ida e volta do kube-apiserver em 5 segundos ou menos.
Se o seu servidor de extensão da API não puder cumprir com o requisito de latência, considere fazer alterações que permitam
atingi-lo. Pode também definir portal de funcionalidade EnableAggregatedDiscoveryTimeout=false no kube-apiserver para
desativar a restrição de intervalo. Esta portal de funcionalidade deprecado será removido num lançamento futuro.
Próximos passos
Para pôr o agregador a funcionar no seu ambiente, configure a camada de agregação.
De seguida, configura um api-server de extensão para funcionar com a camada de agregação.
Também, aprenda como pode estender a API do Kubernetes através do use de Definições de Recursos Personalizados.
Leia a especificação do APIService
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 228/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Plugins CNI: Aderentes à especificação Container Network Interface (CNI), desenhados para interoperabilidade.
Kubernetes usa a versão v0.4.0 da especificação CNI.
Plugin kubenet: Implementa o cbr0 básico usando os plugins CNI bridge e host-local
Instalação
O kubelet possui um plugin único padrão, e um plugin padrão comum para todo o cluster. Ele verifica o plugin quando inicia, se
lembra o que encontrou, e executa o plugin selecionado em momentos oportunos dentro do ciclo de vida de um Pod (isso é
verdadeiro apenas com o Docker, uma vez que o CRI gerencia seus próprios plugins de CNI). Existem dois parâmetros de linha de
comando no Kubelet para se ter em mente quando usando plugins:
Por padrão, se nenhum plugin de rede é configurado no kubelet, o plugin noop é utilizado, que configura net/bridge/bridge-nf-
call-iptables=1 para garantir que configurações simples (como Docker com bridge Linux) operem corretamente com o proxy
iptables.
CNI
O plugin de CNI é selecionado utilizando-se da opção --network-plugin=cni no início do Kubeket. O Kubelet lê um arquivo do
diretório especificado em --cni-conf-dir (padrão /etc/cni/net.d ) e usa a configuração de CNI desse arquivo para configurar a
rede de cada Pod. O arquivo de configuração do CNI deve usar a especificação de CNI, e qualquer plugin referenciado nesse arquivo
deve estar presente no diretório --cni-bin-dir (padrão /opt/cni/bin ).
Se existirem múltiplos arquivos de configuração no diretório, o kubelet usa o arquivo de configuração que vier primeiro pelo nome,
em ordem alfabética.
Adicionalmente ao plugin de CNI especificado no arquivo de configuração, o Kubernetes requer o plugin CNI padrão lo ao menos
na versão 0.2.0.
Suporte a hostPort
O plugin de redes CNI suporta hostPort . Você pode utilizar o plugin oficial portmap ou usar seu próprio plugin com a
funcionalidade de portMapping.
Caso você deseje habilitar o suporte a hostPort , você deve especificar portMappings capability no seu cni-conf-dir . Por
exemplo:
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 229/233
4/15/24, 11:56 AM Conceitos | Kubernetes
{
"name": "k8s-pod-network",
"cniVersion": "0.4.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "portmap",
"capabilities": {"portMappings": true},
"externalSetMarkChain": "KUBE-MARK-MASQ"
}
]
}
O plugin de rede CNI também suporta o controle de banda de entrada e saída. Você pode utilizar o plugin oficial bandwidth
desenvolvido ou usar seu próprio plugin de controle de banda.
Se você habilitar o suporte ao controle de banda, você deve adicionar o plugin bandwidth no seu arquivo de configuração de CNI
(padrão /etc/cni/net.d ) e garantir que o programa exista no diretório de binários do CNI (padrão /opt/cni/bin ).
{
"name": "k8s-pod-network",
"cniVersion": "0.4.0",
"plugins": [
{
"type": "calico",
"log_level": "info",
"datastore_type": "kubernetes",
"nodename": "127.0.0.1",
"ipam": {
"type": "host-local",
"subnet": "usePodCidr"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig"
}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 230/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Agora você pode adicionar as anotações kubernetes.io/ingress-bandwidth e kubernetes.io/egress-bandwidth em seu pod. Por
exemplo:
apiVersion: v1
kind: Pod
metadata:
annotations:
kubernetes.io/ingress-bandwidth: 1M
kubernetes.io/egress-bandwidth: 1M
...
kubenet
Kubenet é um plugin de rede muito simples, existente apenas no Linux. Ele não implementa funcionalidades mais avançadas, como
rede entre nós ou políticas de rede. Ele é geralmente utilizado junto a um provedor de nuvem que configura as regras de
roteamento para comunicação entre os nós, ou em ambientes com apenas um nó.
O Kubenet cria uma interface bridge no Linux chamada cbr0 e cria um par veth para cada um dos pods com o host como a outra
ponta desse par, conectado à cbr0 . Na interface no lado do Pod um endereço IP é alocado de uma faixa associada ao nó, sendo
parte de alguma configuração no nó ou pelo controller-manager. Na interface cbr0 é associado o MTU equivalente ao menor MTU
de uma interface de rede do host.
Os plugins CNI padrão bridge , lo e host-local são obrigatórios, ao menos na versão 0.2.0. O Kubenet buscará inicialmente
esses plugins no diretório /opt/cni/bin . Especifique a opção cni-bin-dir no kubelet para fornecer um diretório adicional de
busca. O primeiro local equivalente será o utilizado.
O kubelet deve ser executado com a opção --network-plugin=kubenet para habilitar esse plugin.
O Kubelet deve ainda ser executado com a opção --non-masquerade-cidr=<clusterCidr> para garantir que o tráfego de IPs
para fora dessa faixa seja mascarado.
O nó deve possuir uma subrede associada, através da opção --pod-cidr configurada na inicialização do kubelet, ou as opções
--allocate-node-cidrs=true --cluster-cidr=<cidr> utilizadas na inicialização do controller-manager.
Sempre que necessário, você pode configurar explicitamente o MTU com a opção network-plugin-mtu no kubelet. Por exemplo, na
AWS o MTU da eth0 geralmente é 9001 então você deve especificar --network-plugin-mtu=9001 . Se você estiver usando IPSEC
você deve reduzir o MTU para permitir o encapsulamento excedente; por exemplo: --network-plugin-mtu=8773 .
Essa opção faz parte do plugin de rede. Atualmente apenas o kubenet suporta a configuração network-plugin-mtu .
Resumo de uso
--network-plugin=cni especifica que devemos usar o plugin de redes cni com os binários do plugin localizados em --cni-
bin-dir (padrão /opt/cni/bin ) e as configurações do plugin localizadas em --cni-conf-dir (default /etc/cni/net.d ).
--network-plugin=kubenet especifica que iremos usar o plugin de rede kubenet com os plugins CNI bridge , lo e host-
local localizados em /opt/cni/bin ou cni-bin-dir .
--network-plugin-mtu=9001 especifica o MTU a ser utilizado, atualmente apenas em uso pelo plugin de rede kubenet
Próximos passos
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 231/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Motivação
O padrão operador tem como objetivo capturar o principal objetivo de um operador humano que está gerenciando um serviço ou
conjunto de serviços. Operadores humanos que cuidam de aplicativos e serviços específicos possuem um conhecimento profundo
de como o sistema deve se comportar, como implantá-lo e como reagir se houver problemas.
As pessoas que executam cargas de trabalho no Kubernetes muitas vezes gostam de usar automação para cuidar de tarefas
repetitivas. O padrão do operador captura como você pode escrever código para automatizar uma tarefa além do que o próprio
Kubernetes fornece.
Operadores no Kubernetes
O Kubernetes é projetado para automação. Por padrão, você tem bastante automação integrada ao núcleo do Kubernetes. Você
pode usar o Kubernetes para automatizar a implantação e execução de cargas de trabalho, e pode automatizar como o Kubernetes
faz isso.
O conceito de padrão operador do Kubernetes permite a extensão do comportamento sem modificar o código do próprio
Kubernetes, vinculando controladores a um ou mais recursos personalizados. Os operadores são clientes da API do Kubernetes que
atuam como controladores para um recurso personalizado.
Exemplo de um operador
Algumas das coisas que você pode automatizar usando um operador incluem:
1. Um recurso personalizado (custom resource) chamado SampleDB, que você pode configurar dentro do cluster.
2. Um Deployment que garante que um Pod esteja em execução contendo a parte do controlador do operador.
3. Uma imagem de contêiner do código do operador.
4. Código do controlador que consulta a camada de gerenciamento para descobrir quais recursos SampleDB estão configurados.
5. O núcleo do Operador é o código que informa ao servidor da API como fazer com que a realidade corresponda aos recursos
configurados.
Se você adicionar um novo SampleDB, o operador configura PersistentVolumeClaims para fornecer armazenamento
durável da base de dados, um StatefulSet para executar o SampleDB e um Job para lidar com a configuração inicial.
Se você excluir um SampleDB, o operador cria um instantâneo e em seguida, garante que o StatefulSet e os Volumes
também sejam removidos.
6. O operador também gerencia backups regulares da base de dados. Para cada recurso SampleDB, o operador determina
quando criar um Pod que pode se conectar ao banco de dados e fazer backups. Esses Pods dependeriam de um ConfigMap
e/ou um Secret que tenha detalhes da conexão e credenciais do banco de dados.
7. Considerando que o Operador tem como objetivo fornecer automação robusta para o recurso que gerencia, haveria código de
suporte adicional. Para este exemplo, o código verifica se o banco de dados está a executando uma versão antiga e, se estiver,
cria objetos Job que fazem a atualização para você.
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 232/233
4/15/24, 11:56 AM Conceitos | Kubernetes
Implantando operadores
A maneira mais comum de implantar um operador é adicionar a definição personalizada de recurso (Custom Resource Definition) e o
Controlador associado ao seu cluster. O Controlador normalmente é executado fora da camada de gerenciamento, assim como
você executaria qualquer aplicação que rode em contêineres. Por exemplo, você pode executar o controlador no seu cluster como
um Deployment.
Usando um operador
Depois de implantar um operador, você o usaria adicionando, modificando ou excluindo o tipo de recurso que o operador usa.
Seguindo o exemplo acima, você configuraria um Deployment para o próprio operador, e depois:
…e é isso! O Operador cuidará de aplicar as alterações, bem como manter o serviço existente em bom estado.
Você também pode implementar um operador (ou seja, um Controlador) usando qualquer linguagem/agente de execução que
possa atuar como um cliente para a API do Kubernetes.
A seguir estão algumas bibliotecas e ferramentas que você pode usar para escrever seu próprio operador nativo de nuvem.
Nota: Esta seção tem links para projetos de terceiros que fornecem a funcionalidade exigida pelo Kubernetes. Os autores do
projeto Kubernetes não são responsáveis por esses projetos. Esta página obedece as diretrizes de conteúdo do site CNCF,
listando os itens em ordem alfabética. Para adicionar um projeto a esta lista, leia o guia de conteúdo antes de enviar sua
alteração.
Próximos passos
Leia o whitepaper sobre operadores da CNCF
Saiba mais sobre Custom Resources
Encontre operadores prontos em OperatorHub.io para atender ao seu caso de uso
Publique seu operador para outras pessoas usarem
Leia o artigo original do CoreOS que introduziu o padrão de operador (esta é uma versão arquivada do artigo original)
Leia um artigo do Google Cloud sobre as melhores práticas para construir operadores
https://kubernetes.io/pt-br/docs/concepts/_print/#pg-6b5ccadd699df0904e8e9917c5450c4b 233/233