Você está na página 1de 178

5/14/22, 11:15 AM Conceitos | Kubernetes

Conceitos
1: Intervalos de limite
2: Cotas de Recursos
3: Visão Geral
3.1: O que é Kubernetes?
3.2: Componentes do Kubernetes
3.3: Objetos do Kubernetes
3.3.1: Nomes
3.3.2: Namespaces
3.3.3: Seletores de Campos
4: Volumes Persistentes
5: Arquitetura do Kubernetes
5.1: Comunicação entre Nó e Control Plane
5.2: Conceitos sobre Cloud Controller Manager
5.3: Controladores
6: Contêineres
6.1: Imagens
6.2: Ambiente de Contêiner
6.3: Classes de execução
6.4: Hooks de Ciclo de Vida do Contêiner
7: Serviços, balanceamento de carga e conectividade
7.1: Políticas de rede
8: Configuração
8.1: Melhores Práticas de Configuração
8.2: ConfigMaps
8.3: Secrets
8.4: Gerenciamento de recursos em Pods e contêineres
8.5: Organizando o acesso ao cluster usando arquivos kubeconfig
9: Segurança
9.1: Visão Geral da Segurança Cloud Native
10: Escalonamento
10.1: Taints e Tolerâncias
10.2: Escalonador do Kubernetes
10.3: Sobrecarga de Pod
11: Administração de Cluster
11.1: Visão Geral da Administração de Cluster
11.2: Certificates
11.3: Conectividade do Cluster
11.4: Arquitetura de Log
11.5: Logs de Sistema
11.6: Métricas para componentes do sistema Kubernetes
11.7: Configurando o Garbage Collection do kubelet
11.8: Proxies no Kubernetes
11.9: Instalando Complementos
12: Extendendo o Kubernetes
12.1: Extendendo a API do Kubernetes
12.1.1: Extendendo a API do Kubernetes com a camada de agregação
12.2: Extensões de Computação, armazenamento e redes
12.2.1: Plugins de rede

https://kubernetes.io/pt-br/docs/concepts/_print/ 1/178
5/14/22, 11:15 AM Conceitos | Kubernetes

12.3: Padrão Operador

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 - Intervalos de limite
Por padrão, os cointêineres são executados com recursos computacionais ilimitados em um
cluster Kubernetes. Com cotas de recursos, os administradores de cluster podem restringir o
consumo e a criação de recursos baseado no namespace. Dentro de um namespace, pod ou
contêiner pode haver o consumo de quantidade de CPU e memória definidos de acordo com
a cota de recursos do namespace. Existe a preocupação de que um Pod ou contêiner possa
monopolizar todos os recursos disponíveis, justamente por conta disso existe o conceito de
Limit Range, ou intervalos de limite, que pode ser definido como uma política utilizada para a
restrição de alocação de recursos (para pods ou contêineres) em um namespace.

Um LimitRange fornece restrições que podem:

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.

Um LimitRange é aplicado em um namespace específico quando há um objeto LimitRange


nesse namespace.

O nome de um objeto LimitRange deve ser um nome de subdomínio DNS válido.

Visão geral do Limit Range


O administrador cria um LimitRange em um namespace.
Os usuários criam recursos como pods, contêineres e PersistentVolumeClaims no
namespace.
O controlador de admissão LimitRanger impõe padrões e limites para todos os pods e
contêineres que não definem os requisitos de recursos computacionais e rastreia o uso
para garantir que não exceda o mínimo, o máximo e a proporção de recursos definidos
em qualquer LimitRange presente no namespace.
Se estiver criando ou atualizando um recurso (Pod, Container, PersistentVolumeClaim)
que viola uma restrição LimitRange, a solicitação ao servidor da API falhará com um
código de status HTTP 403 FORBIDDEN e uma mensagem explicando a restrição violada.
Se um LimitRange for ativado em um namespace para recursos computacionais como
cpu e memória , os usuários deverão especificar solicitações ou limites para esses
valores. Caso contrário, o sistema pode rejeitar a criação do pod.
As validações de LimitRange ocorrem apenas no estágio de Admissão de Pod, não em
Pods em Execução.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 2/178
5/14/22, 11:15 AM Conceitos | Kubernetes

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.

Nem a contenção nem as alterações em um LimitRange afetarão os recursos já criados.

Próximos passos
Consulte o documento de design LimitRanger para obter mais informações.

Para exemplos de uso de limites, leia:

Como configurar restrições mínimas e máximas de CPU por namespace.


Como configurar restrições de memória mínima e máxima por namespace.
como configurar solicitações e limites de CPU padrão por namespace.
como configurar solicitações e limites de memória padrão por namespace.
como configurar o consumo mínimo e máximo de armazenamento por namespace.
Um exemplo detalhado de configuração de cota por namespace.

https://kubernetes.io/pt-br/docs/concepts/_print/ 3/178
5/14/22, 11:15 AM Conceitos | Kubernetes

2 - Cotas de Recursos
Quando vários usuários ou equipes compartilham um cluster com um número fixo de nós,

uma preocupação de que uma equipe possa usar mais do que é justo durante o
compartilhamento de recursos.

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.

As cotas de recursos funcionam assim:

Diferentes equipes trabalham em diferentes namespaces. Atualmente, isso é voluntário,


mas o suporte para tornar isso obrigatório por meio de ACLs está planejado.

O administrador cria uma ResourceQuota para cada namespace.

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.

Veja o passo a passo


para um exemplo de como evitar este problema.

O nome de um objeto ResourceQuota deve ser um nome do subdomínio DNS válido.

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.

Nem a contenção nem as alterações na cota afetarão os recursos já criados.

Ativando a cota de recursos


O suporte à cota de recursos é ativado por padrão para muitas distribuições do Kubernetes.
Isto é
ativado quando a flag API server --enable-admission-plugins= tem ResourceQuota
como
um de seus argumentos.

Uma cota de recurso é aplicada em um namespace específico quando há um ResourceQuota


nesse namespace.

Cota de recursos computacionais


https://kubernetes.io/pt-br/docs/concepts/_print/ 4/178
5/14/22, 11:15 AM Conceitos | Kubernetes

Você pode limitar a soma total de recursos computacionais que pode ser solicitado em um
determinado namespace.

Os seguintes tipos de recursos são suportados:

Nome do
Recurso Descrição

limits Em todos os pods em um estado não terminal, a soma dos limites de CPU
.cpu não pode exceder esse valor.

limits. Em todos os pods em um estado não terminal, a soma dos limites de


memory memória não pode exceder esse valor.

request Em todos os pods em um estado não terminal, a soma das solicitações da


s.cpu CPU não pode exceder esse valor.

request Em todos os pods em um estado não terminal, a soma das solicitações de


s.memor memória não pode exceder esse valor.
y

hugepag Em todos os pods em um estado não terminal, o número de solicitações de


es- grandes páginas do tamanho especificado não pode exceder esse valor.
<size>

cpu O mesmo que requests.cpu

memory O mesmo que requests.memory

Cota de recursos para recursos estendidos


Além dos recursos mencionados acima, na versão 1.10, suporte a cotas para recursos
estendidos foi adicionado.

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

Veja como visualizar e definir cotas para mais informações.

Cota de recursos de armazenamento


Você pode limitar a soma total de recursos de armazenamento que podem ser solicitados em
um determinado namespace.

Além disso, você pode limitar o consumo de recursos de armazenamento com base na classe
de armazenamento associada.

Nome do recurso Descrição

requests.storage Em todas as solicitações de volume persistentes, a soma


das solicitações de armazenamento não pode exceder
esse valor.

https://kubernetes.io/pt-br/docs/concepts/_print/ 5/178
5/14/22, 11:15 AM Conceitos | Kubernetes

Nome do recurso Descrição

persistentvolumeclaims O número total de PersistentVolumeClaims que podem


existir no namespace.

<storage-class- Em todas as solicitações de volume persistentes


name>.storageclass.stor associadas ao <storage-class-name> , a soma das
age.k8s.io/requests.sto solicitações de armazenamento não pode exceder esse
rage valor.

<storage-class- Em todas as declarações de volume persistentes


name>.storageclass.stor associadas ao storage-class-name, o número total de
age.k8s.io/persistentvo declarações de volume persistente que podem existir no
lumeclaims namespace.

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

Na versão 1.8, o suporte de cota para armazenamento temporário local foi adicionado como
um recurso alfa:

Nome do Recurso Descrição

requests.ephem Em todos os pods no namespace, a soma das solicitações de


eral-storage armazenamento local efêmero não pode exceder esse valor.

limits.ephemer Em todos os pods no namespace, a soma dos limites de


al-storage armazenamento temporário local não pode exceder esse valor.

ephemeral- O mesmo que requests.ephemeral-storage .


storage

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.

Cota de contagem de objetos


Você pode definir cotas para o número total de determinados recursos de todos os padrões,
tipos de recursos com namespace usando a seguinte sintaxe:

count/<resource>.<group> para recursos de grupos não principais


count/<resource> para recursos do grupo principal

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 6/178
5/14/22, 11:15 AM Conceitos | Kubernetes

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:

Nome do
Recurso Descrição

config O número total de ConfigMaps que podem existir no namespace.


maps

persist O número total de PersistentVolumeClaims que podem existir no


entvolum namespace.
eclaims

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.

replica O número total de ReplicationControllers que podem existir no


tioncont namespace.
rollers

resourc O número total de ResourceQuotas que podem existir no namespace.


equotas

servic O número total de Serviços que podem existir no namespace.


es

service O número total de serviços do tipo LoadBalancer que podem existir no


s.loadba namespace.
lancers

service O número total de serviços do tipo NodePort que podem existir no


s.nodep namespace.
orts

secret O número total de segredos que podem existir no namespace.


s

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 7/178
5/14/22, 11:15 AM Conceitos | Kubernetes

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

Terminating Pods correspondentes onde


.spec.activeDeadlineSeconds >= 0

NotTerminating Pods correspondentes onde


.spec.activeDeadlineSeconds is nil

BestEffort Pods correspondentes que tenham a qualidade de serviço de


melhor esforç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.

CrossNamespacePodA Corresponde a pods que tenham termos de (anti)afinidade de


ffinity namespace cruzado.

O escopo BestEffort restringe uma cota ao rastreamento do seguinte recurso:

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.

O scopeSelector suporta os seguintes valores no campo operator :

In

NotIn

Exists

DoesNotExist

Ao usar um dos seguintes valores como o scopeName ao definir o scopeSelector , o


operator deve ser Exists .

Terminating

https://kubernetes.io/pt-br/docs/concepts/_print/ 8/178
5/14/22, 11:15 AM Conceitos | Kubernetes

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.

Cota de recursos por classe de prioridade


FEATURE STATE: Kubernetes v1.17 [stable]

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.

Salve o seguinte YAML em um arquivo quota.yml .

apiVersion: v1

kind: List

items:

- apiVersion: v1

kind: ResourceQuota

metadata:

name: pods-high

spec:

hard:

cpu: "1000"

memory: 200Gi

pods: "10"

https://kubernetes.io/pt-br/docs/concepts/_print/ 9/178
5/14/22, 11:15 AM Conceitos | Kubernetes

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"]

Aplique o YAML usando kubectl create .

kubectl create -f ./quota.yml

resourcequota/pods-high created

resourcequota/pods-medium created

resourcequota/pods-low created

Verifique se a cota Used é 0 usando kubectl describe quota .

kubectl describe quota

https://kubernetes.io/pt-br/docs/concepts/_print/ 10/178
5/14/22, 11:15 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

Applique com kubectl create .

kubectl create -f ./high-priority-pod.yml

Verifique se as estatísticas "Used" para a cota de prioridade "high", pods-high foram


alteradas e se
as outras duas cotas permanecem inalteradas.

kubectl describe quota

https://kubernetes.io/pt-br/docs/concepts/_print/ 11/178
5/14/22, 11:15 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

Cota de afinidade de pod entre namespaces


FEATURE STATE: Kubernetes v1.22 [beta]

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:

apiVersion: apiserver.config.k8s.io/v1

kind: AdmissionConfiguration

plugins:

https://kubernetes.io/pt-br/docs/concepts/_print/ 12/178
5/14/22, 11:15 AM Conceitos | Kubernetes

- 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.

Solicitações comparadas aos limites


Ao alocar recursos computacionais, cada contêiner pode especificar uma solicitação e um
valor limite para CPU ou memória. A cota pode ser configurada para cotar qualquer valor.

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.

Como visualizar e definir cotas


O Kubectl é compatível com a criação, atualização e visualização de cotas:

kubectl create namespace myspace

cat <<EOF > compute-resources.yaml

apiVersion: v1

kind: ResourceQuota

metadata:

name: compute-resources

spec:
hard:

requests.cpu: "1"

requests.memory: 1Gi

limits.cpu: "2"

limits.memory: 2Gi

requests.nvidia.com/gpu: 4

EOF

kubectl create -f ./compute-resources.yaml --namespace=myspace

cat <<EOF > object-counts.yaml

apiVersion: v1

kind: ResourceQuota

metadata:

name: object-counts

spec:
hard:

configmaps: "10"

https://kubernetes.io/pt-br/docs/concepts/_print/ 13/178
5/14/22, 11:16 AM Conceitos | Kubernetes

persistentvolumeclaims: "4"

pods: "4"

replicationcontrollers: "20"

secrets: "10"

services: "10"

services.loadbalancers: "2"

EOF

kubectl create -f ./object-counts.yaml --namespace=myspace

kubectl get quota --namespace=myspace

NAME AGE

compute-resources 30s

object-counts 32s

kubectl describe quota compute-resources --namespace=myspace

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

kubectl describe quota object-counts --namespace=myspace

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> :

kubectl create namespace myspace

kubectl create quota test --hard=count/deployments.apps=2,count/replicasets.apps=

https://kubernetes.io/pt-br/docs/concepts/_print/ 14/178
5/14/22, 11:16 AM Conceitos | Kubernetes

kubectl create deployment nginx --image=nginx --namespace=myspace --replicas=2

kubectl describe quota --namespace=myspace

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

Capacidade e cota de Cluster


ResourceQuotas são independentes da capacidade do cluster. Eles estão expresso em
unidades absolutas. Portanto, se você adicionar nós ao cluster, isso não
dá automaticamente
a cada namespace a capacidade de consumir mais recursos.

Às vezes, políticas mais complexas podem ser necessárias, como:

Divida proporcionalmente os recursos totais do cluster entre várias equipes.


Permita que cada locatário aumente o uso de recursos conforme necessário, mas tenha
um generoso limite para evitar o esgotamento acidental de recursos.
Detecte a demanda de um namespace, adicione nós e aumente a cota.

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ó.

Limite de consumo de classe de prioridade por


padrão
Pode ser desejado que os pods com uma prioridade particular, por exemplo. "cluster-
services",
deve ser permitido em um namespace, se, e somente se, existir um objeto de cota
correspondente.

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:

apiVersion: apiserver.config.k8s.io/v1

kind: AdmissionConfiguration

plugins:

- name: "ResourceQuota"

configuration:

apiVersion: apiserver.config.k8s.io/v1

kind: ResourceQuotaConfiguration

limitedResources:

- resource: pods

matchScopes:

https://kubernetes.io/pt-br/docs/concepts/_print/ 15/178
5/14/22, 11:16 AM Conceitos | Kubernetes

- scopeName: PriorityClass

operator: In

values: ["cluster-services"]

Em seguida, crie um objeto de cota de recurso no namespace kube-system :

policy/priority-class-resourcequota.yaml

apiVersion: v1

kind: ResourceQuota

metadata:

name: pods-cluster-services

spec:

scopeSelector:

matchExpressions:

- operator : In

scopeName: PriorityClass

values: ["cluster-services"]

kubectl apply -f https://k8s.io/examples/policy/priority-class-resourcequota.yaml

resourcequota/pods-cluster-services created

Nesse caso, a criação de um pod será permitida se:

1. O priorityClassName do pod não foi especificado.


2. O priorityClassName do pod é especificado com um valor diferente de cluster-
services .
3. O priorityClassName do pod está definido como cluster-services , ele deve ser
criado no namespace kube-system e passou na verificação de cota de recursos.

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/ 16/178
5/14/22, 11:16 AM Conceitos | Kubernetes

3 - Visão Geral
Obtenha uma visão em alto-nível do Kubernetes e dos componentes a partir
dos quais ele é construído.

3.1 - O que é Kubernetes?


Kubernetes é um plataforma de código aberto, portável e extensiva para o
gerenciamento de cargas de trabalho e serviços distribuídos em contêineres,
que facilita tanto a configuração declarativa quanto a automação. Ele possui
um ecossistema grande, e de rápido crescimento. Serviços, suporte, e
ferramentas para Kubernetes estão amplamente disponíveis.

Essa página é uma visão geral do Kubernetes.

Kubernetes é um plataforma de código aberto, portável e extensiva para o gerenciamento de


cargas de trabalho e serviços distribuídos em contêineres, que facilita tanto a configuração
declarativa quanto a automação. Ele possui um ecossistema grande, e de rápido crescimento.
Serviços, suporte, e ferramentas para Kubernetes estão amplamente disponíveis.

O Google tornou Kubernetes um projeto de código-aberto em 2014. O Kubernetes combina


mais de 15 anos de experiência do Google executando cargas de trabalho produtivas em
escala, com as melhores idéias e práticas da comunidade.

O nome Kubernetes tem origem no Grego, significando timoneiro ou piloto. K8s é a


abreviação derivada pela troca das oito letras "ubernete" por "8", se tornado K"8"s.

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.

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
https://kubernetes.io/pt-br/docs/concepts/_print/ 17/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Por que você precisa do Kubernetes e o que


ele pode fazer
Os contêineres são uma boa maneira de agrupar e executar suas aplicações. Em um
ambiente de produção, você precisa gerenciar os contêineres que executam as aplicações e
garantir que não haja tempo de inatividade. Por exemplo, se um contêiner cair, outro
contêiner precisa ser iniciado. Não seria mais fácil se esse comportamento fosse controlado
por um sistema?

É assim que o Kubernetes vem ao resgate! O Kubernetes oferece uma estrutura para
executar sistemas distribuídos de forma resiliente. Ele cuida do escalonamento e do
recuperação à falha de sua aplicação, fornece padrões de implantação e muito mais. Por
exemplo, o Kubernetes pode gerenciar facilmente uma implantação no método canário para
seu sistema.

O Kubernetes oferece a você:

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 18/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 controlada. 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.
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.

O que o Kubernetes não é


O Kubernetes não é um sistema PaaS (plataforma como serviço) tradicional e completo.
Como o Kubernetes opera no nível do contêiner, e não no nível do hardware, ele fornece
alguns recursos geralmente aplicáveis comuns às ofertas de PaaS, como implantação,
escalonamento, balanceamento de carga, e permite que os usuários integrem suas soluções
de logging, monitoramento e alerta. No entanto, o Kubernetes não é monolítico, e essas
soluções padrão são opcionais e conectáveis. O Kubernetes fornece os blocos de construção
para a construção de plataformas de desenvolvimento, mas preserva a escolha e flexibilidade
do usuário onde é importante.

Kubernetes:

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 19/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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/ 20/178
5/14/22, 11:16 AM Conceitos | Kubernetes

3.2 - Componentes do Kubernetes


Um cluster Kubernetes consiste de componentes que representam a camada
de gerenciamento, e um conjunto de máquinas chamadas nós.

Ao implantar o Kubernetes, você obtém um cluster.

Um cluster Kubernetes consiste em um conjunto de servidores de processamento, chamados


nós, que executam aplicações containerizadas. Todo cluster possui ao menos um servidor de
processamento (worker node).

O servidor de processamento hospeda os Pods que são componentes de uma aplicação. O


ambiente de gerenciamento gerencia os nós de processamento e os Pods no cluster. Em
ambientes de produção, o ambiente de gerenciamento geralmente executa em múltiplos
computadores e um cluster geralmente executa em múltiplos nós (nodes) , provendo
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.

Esse é o diagrama de um cluster Kubernetes com todos os componentes interligados.

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

kubelet kubelet kubelet kube-proxy


etcd k-proxy

sched
sched
sched

Scheduler
sched

Control Plane k-proxy k-proxy k-proxy


Control plane

Node

Componentes da camada de gerenciamento


Os componentes da camada de gerenciamento tomam decisões globais sobre o cluster (por
exemplo, agendamento de pods), bem como detectam e respondem aos eventos do cluster
(por exemplo, iniciando um novo pod quando o campo replicas de um Deployment não está
atendido).

Os componentes da camada de gerenciamento podem ser executados em qualquer máquina


do cluster. Contudo, para simplificar, os scripts de configuração normalmente iniciam todos
os componentes da camada de gerenciamento na mesma máquina, e não executa
contêineres de usuário nesta máquina. Veja Construindo clusters de alta disponibilidade para
um exemplo de configuração de múltiplas VMs para camada de gerenciamento (multi-main-
VM).

kube-apiserver
O servidor de API é um componente da Camada de gerenciamento do Kubernetes que expõe
a API do Kubernetes.
O servidor de API é o front end para a camada de gerenciamento do
Kubernetes.

A principal implementação de um servidor de API do Kubernetes é kube-apiserver.


O kube-
apiserver foi projetado para ser escalonado horizontalmente — ou seja, ele pode ser
escalado com a implantação de mais instâncias.
Você pode executar várias instâncias do
kube-apiserver e balancear (balanceamento de carga, etc) o tráfego entre essas instâncias.

https://kubernetes.io/pt-br/docs/concepts/_print/ 21/178
5/14/22, 11:16 AM Conceitos | Kubernetes

etcd
Armazenamento do tipo Chave-Valor consistente e em alta-disponibilidade usado como
repositório de apoio do Kubernetes para todos os dados do cluster.

Se o seu cluster Kubernetes usa etcd como seu armazenamento de apoio, certifique-se de ter
um plano de back up para seus dados.

Você pode encontrar informações detalhadas sobre o etcd na seção oficial da documentação.

kube-scheduler
Componente da camada de gerenciamento que observa os pods recém-criados sem nenhum
nó atribuído, e seleciona um nó para executá-los.

Os fatores levados em consideração para as decisões de agendamento incluem:


requisitos de
recursos individuais e coletivos, hardware/software/política de restrições, 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.

Alguns tipos desses controladores são:

Controlador de nó: responsável por perceber e responder quando os nós caem.


Controlador de Job: Observa os objetos Job que representam tarefas únicas e, em
seguida, cria pods para executar essas tarefas até a conclusão.
Controlador de endpoints: preenche o objeto Endpoints (ou seja, junta os Serviços e os
pods).
Controladores de conta de serviço e de token: crie contas padrão e tokens de acesso de
API para novos namespaces.

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 escalar horizontalmente (executar mais de uma cópia)
para melhorar o desempenho ou para auxiliar na tolerância a falhas.

Os seguintes controladores podem ter dependências de provedor de nuvem:

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 22/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Node Components
Os componentes de 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 node no cluster. Ele garante que os contêineres estejam
sendo executados em um Pod.

O kubelet utiliza um conjunto de PodSpecs que são fornecidos por vários mecanismos e
garante que os contêineres descritos nesses PodSpecs estejam funcionando corretamente. O
kubelet não gerencia contêineres que não foram criados pelo Kubernetes.

kube-proxy
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.

Container runtime
O agente de execução (runtime) de contêiner é o software responsável por executar os
contêineres.

O Kubernetes suporta diversos agentes de execução de contêineres: Docker, containerd,


CRI-O, e qualquer implementação do Kubernetes CRI (Container Runtime Interface).

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 addons que necessitem ser criados dentro de um namespace pertencem ao
namespace kube-system .

Alguns addons selecionados são descritos abaixo; para uma lista estendida dos addons
disponíveis, por favor consulte Addons.

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)
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.

Monitoramento de recursos do contêiner


https://kubernetes.io/pt-br/docs/concepts/_print/ 23/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Monitoramento de recursos do contêiner registra métricas de série temporal genéricas sobre


os contêineres em um banco de dados central e fornece uma interface de usuário para
navegar por esses dados.

Logging a nivel do cluster


Um mecanismo de logging a nível do cluster é responsável por guardar os logs dos
contêineres em um armazenamento central de logs com um interface para
navegação/pesquisa.

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/ 24/178
5/14/22, 11:16 AM Conceitos | Kubernetes

3.3 - Objetos do Kubernetes


3.3.1 - Nomes
Cada objeto em um cluster possui um Nome que é único para aquele tipo de recurso.
Todo
objeto do Kubernetes também possui um UID que é único para todo o cluster.

Por exemplo, você pode ter apenas um Pod chamado "myapp-1234", porém você pode ter
um Pod
e um Deployment ambos com o nome "myapp-1234".

Para atributos não únicos providenciados por usuário, Kubernetes providencia labels e
annotations.

Nomes
Recursos Kubernetes podem ter nomes com até 253 caracteres. Os caracteres permitidos em
nomes são: dígitos (0-9), letras minúsculas (a-z), - , e . .

A seguir, um exemplo para um Pod chamado nginx-demo .

apiVersion: v1

kind: Pod

metadata:

name: nginx-demo

spec:

containers:

- name: nginx

image: nginx:1.7.9

ports:

- containerPort: 80

Nota: Alguns tipos de recursos possuem restrições adicionais em seus nomes.

UIDs
Kubernetes UIDs são identificadores únicos universais (também chamados de UUIDs).
UUIDs
utilizam padrões ISO/IEC 9834-8 e ITU-T X.667.

Próximos passos
Leia sobre labels em Kubernetes.
Consulte o documento de design Identificadores e Nomes em Kubernetes.

https://kubernetes.io/pt-br/docs/concepts/_print/ 25/178
5/14/22, 11:16 AM Conceitos | Kubernetes

3.3.2 - 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).

Quando Utilizar Múltiplos Namespaces


Namespaces devem ser utilizados em ambientes com múltiplos usuários espalhados por
diversos times ou projetos. Para clusters com poucos ou até algumas dezenas de usuários,
você não deveria precisar criar ou pensar a respeito de namespaces. Comece a utilizar
namespaces quando você precisar das funcionalidades que eles oferecem.

Namespaces oferecem escopo para nomes. Nomes de recursos precisam ser únicos dentro
de um namespace, porém não em diferentes namespaces. Namespaces não podem ser
aninhados dentro de outros namespaces e cada recurso Kubernetes pode pertencer à
apenas um namespace.

Namespaces nos permitem dividir os recursos do cluster entre diferentes usuários (via
resource quota).

Não é necessário utilizar múltiplos namespaces para separar recursos levemente diferentes,
como diferentes versões de um mesmo software: use labels para distinguir recursos dentro
de um mesmo namespace.

Trabalhando com Namespaces


Criação e eliminação de namespaces estão descritas na
documentação de namespaces do
guia de administradores.

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:

kubectl get namespace

NAME STATUS AGE

default Active 1d

kube-node-lease Active 1d

kube-public Active 1d

kube-system Active 1d

O Kubernetes é inicializado com quatro namespaces:

default O namespace padrão para objetos sem namespace


kube-system O namespace para objetos criados pelo sistema Kubernetes
kube-public Este namespace é criado automaticamente e é legível por todos os
usuários (incluindo usuários não autenticados). Este namespace é reservado
principalmente para uso do cluster, no caso de alguns recursos que precisem ser
visíveis e legíveis publicamente por todo o cluster. O aspecto público deste namespace é
apenas uma convenção, não um requisito.
https://kubernetes.io/pt-br/docs/concepts/_print/ 26/178
5/14/22, 11:16 AM Conceitos | Kubernetes

kube-node-lease Este namespace contém os objetos de Lease associados com cada


node. Node leases permitem que o kubelet envie heartbeats para que a camada de
gerenciamento detecte falhas nos nodes.

Preparando o namespace para uma requisição


Para preparar o namespace para a requisição atual, utilize o parâmetro --namespace . Por
exemplo:

kubectl run nginx --image=nginx --namespace=<insert-namespace-name-here>

kubectl get pods --namespace=<insert-namespace-name-here>

Configurando a preferência de namespaces


Você pode salvar permanentemente o namespace para todos os comandos kubectl
subsequentes no mesmo contexto:

kubectl config set-context --current --namespace=<insert-namespace-name-here>

# Validando

kubectl config view --minify | grep namespace:

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ç. Se você quiser acessar múltiplos
namespaces, precisará utilizar um Fully Qualified Domain Name (FQDN).

Nem todos os objetos pertencem a algum


Namespace
A maior parte dos recursos Kubernetes (como Pods, Services, controladores de replicação e
outros) pertencem a algum namespace. Entretanto, recursos de namespaces não pertencem
a nenhum namespace. Além deles, recursos de baixo nível, como nodes e persistentVolumes,
também não pertencem a nenhum namespace.

Para visualizar quais recursos Kubernetes pertencem ou não a algum namespace, utilize:

# Em um namespace

kubectl api-resources --namespaced=true

# Sem namespace

kubectl api-resources --namespaced=false

Rotulamento Automático
FEATURE STATE: Kubernetes 1.21 [beta]

A camada de gerenciamento Kubernetes configura um label imutável


kubernetes.io/metadata.name em todos os namespaces se a
feature gate
NamespaceDefaultLabelName estiver habilitada. O valor do label é o nome do namespace.

https://kubernetes.io/pt-br/docs/concepts/_print/ 27/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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/ 28/178
5/14/22, 11:16 AM Conceitos | Kubernetes

3.3.3 - Seletores de Campos


Os Seletores de Campos permitem que você selecione recursos do Kubernetes baseado no
valor de um ou mais campos de um recurso. Seguem alguns exemplos de buscas utilizando
seletores de campos:

metadata.name=my-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 :

kubectl get pods --field-selector 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:

kubectl get ingress --field-selector foo.bar=baz

Error from server (BadRequest): Unable to find "ingresses" that match label selec

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 :

kubectl get services --all-namespaces --field-selector metadata.namespace!=defau

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

kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always

https://kubernetes.io/pt-br/docs/concepts/_print/ 29/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Múltiplos tipos de recursos


Você pode utilizar seletores de campos através de múltiplos tipos de recursos. Por exemplo,
o comando kubectl a seguir seleciona todos Statefulsets e Services que não estão presentes
no namespace default .

kubectl get statefulsets,services --all-namespaces --field-selector metadata.name

https://kubernetes.io/pt-br/docs/concepts/_print/ 30/178
5/14/22, 11:16 AM Conceitos | Kubernetes

4 - Volumes Persistentes
Esse documento descreve o estado atual dos volumes persistentes no Kubernetes. Sugerimos
que esteja familiarizado com volumes.

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.

Veja os exemplos de passo a passo de forma detalhada.

Requisição e ciclo de vida de um volume


PVs são recursos dentro um cluster. PVCs são requisições para esses recursos e também
atuam como uma validação da solicitação desses recursos. O ciclo de vida da interação entre
PVs e PVCs funcionam da seguinte forma:

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 31/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

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.

Proteção de Uso de um Objeto de Armazenamento


O propósito da funcionalidade do Objeto de Armazenamento em Proteção de Uso é garantir
que as PersistentVolumeClaims (PVCs) que estejam sendo utilizadas por um Pod e
PersistentVolume (PVs) que pertençam aos PVCs não sejam removidos do sistema, pois isso
pode resultar numa perda de dados.

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 :

https://kubernetes.io/pt-br/docs/concepts/_print/ 32/178
5/14/22, 11:16 AM Conceitos | Kubernetes

kubectl describe pvc hostpath

Name: hostpath

Namespace: default

StorageClass: example-hostpath

Status: Terminating

Volume:

Labels: <none>

Annotations: volume.beta.kubernetes.io/storage-class=example-hostpath

volume.beta.kubernetes.io/storage-provisioner=example.com/hostpath
Finalizers: [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:

kubectl describe pv task-pv-volume

Name: task-pv-volume

Labels: type=local

Annotations: <none>

Finalizers: [kubernetes.io/pv-protection]

StorageClass: standard

Status: Terminating

Claim:

Reclaim Policy: Delete

Access Modes: RWO

Capacity: 1Gi

Message:

Source:

Type: HostPath (bare host directory volume)

Path: /tmp/data

HostPathType:

Events: <none>

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
https://kubernetes.io/pt-br/docs/concepts/_print/ 33/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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:

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: "k8s.gcr.io/busybox"

command: ["/bin/sh", "-c", "test -e /scrub && rm -rf /scrub/..?* /scrub/.[!.]


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:

https://kubernetes.io/pt-br/docs/concepts/_print/ 34/178
5/14/22, 11:16 AM Conceitos | Kubernetes

storageClassName: "" # Empty string must be explicitly set otherwise default S


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

...

Isso é útil se você deseja utilizar PersistentVolumes que possuem suas claimPolicy
configuradas para Retain , incluindo situações onde você estiver reutilizando um PV
existente.

Expandindo Requisições de Volumes Persistentes


FEATURE STATE: Kubernetes v1.11 [beta]

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 35/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Expansão de volume CSI


FEATURE STATE: Kubernetes v1.16 [beta]

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.

Redimensionando um volume que contém um sistema de arquivo


Só podem ser redimensionados os volumes que contém os seguintes sistemas de arquivo:
XFS, Ext3 ou Ext4.

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.

Redimensionamento de uma PersistentVolumeClaim em uso


FEATURE STATE: Kubernetes v1.15 [beta]

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.

Recuperação em caso de falha na expansão de volumes


Se a expansão do respectivo armazenamento falhar, o administrador do cluster pode
recuperar manualmente o estado da Persistent Volume Claim (PVC) e cancelar as solicitações
de redimensionamento. Caso contrário, as tentativas de solicitação de redimensionamento
ocorrerão de forma contínua pelo controlador sem nenhuma intervenção do administrador.

1. Marque o PersistentVolume(PV) que estiver atrelado à PersistentVolumeClaim(PVC) com


a política de recuperação Retain .

https://kubernetes.io/pt-br/docs/concepts/_print/ 36/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Tipos de volumes persistentes


Tipos de PersistentVolume são implementados como plugins. Atualmente o Kubernetes
suporta os plugins abaixo:

awsElasticBlockStore - AWS Elastic Block Store (EBS)

azureDisk - Azure Disk

azureFile - Azure File

cephfs - CephFS volume

cinder - Cinder (OpenStack block storage)


(depreciado)

csi - Container Storage Interface (CSI)

fc - Fibre Channel (FC) storage

flexVolume - FlexVolume

flocker - Flocker storage

gcePersistentDisk - GCE Persistent Disk

glusterfs - Glusterfs volume

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

local - storage local montados nos nós.

nfs - Network File System (NFS) 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

quobyte - Volume Quobyte

rbd - Volume Rados Block Device (RBD)

scaleIO - Volume ScaleIO


(depreciado)

storageos - Volume StorageOS

vsphereVolume - Volume vSphere VMDK

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:
https://kubernetes.io/pt-br/docs/concepts/_print/ 37/178
5/14/22, 11:16 AM Conceitos | Kubernetes

- 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
FEATURE STATE: Kubernetes v1.18 [stable]

O Kubernetes suporta dois volumeModes de PersistentVolumes: Filesystem e Block .

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.

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.

Os modos de acesso são:

ReadWriteOnce -- o volume pode ser montado como leitura-escrita por um nó único


ReadOnlyMany -- o volume pode ser montado como somente-leitura por vários nós
ReadWriteMany -- o volume pode ser montado como leitura-escrita por vários nós

Na linha de comando, os modos de acesso ficam abreviados:

RWO - ReadWriteOnce
ROX - ReadOnlyMany
RWX - ReadWriteMany

https://kubernetes.io/pt-br/docs/concepts/_print/ 38/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Plugin de
Volume ReadWriteOnce ReadOnlyMany ReadWriteMany

AWSElasticBloc ✓ - -
kStore

AzureFile ✓ ✓ ✓

AzureDisk ✓ - -

CephFS ✓ ✓ ✓

Cinder ✓ - -

CSI depende do depende do depende do driver


driver driver

FC ✓ ✓ -

FlexVolume ✓ ✓ depende do driver

Flocker ✓ - -

GCEPersistentD ✓ ✓ -
isk

Glusterfs ✓ ✓ ✓

HostPath ✓ - -

iSCSI ✓ ✓ -

Quobyte ✓ ✓ ✓

NFS ✓ ✓ ✓

RBD ✓ ✓ -

VsphereVolum ✓ - (funcionam quando os Pods são


e do tipo collocated)

PortworxVolum ✓ - ✓
e

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.
https://kubernetes.io/pt-br/docs/concepts/_print/ 39/178
5/14/22, 11:16 AM Conceitos | Kubernetes

No passado, a notação volume.beta.kubernetes.io/storage-class era utilizada no lugar do


atributo storageClassName . Essa notação ainda funciona. Contudo, ela será totalmente
depreciada numa futura versão do Kubernetes.

Política de Retenção
Atualmente as políticas de retenção são:

Retain -- recuperação manual


Recycle -- limpeza básica ( rm -rf /thevolume/* )
Delete -- o volume de armazenamento associado, como AWS EBS, GCE PD, Azure Disk
ou OpenStack Cinder é deletado

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ó.

Nota: Nem todos os tipos de Volume Persistente suportam opções de montagem.

Seguem os tipos de volumes que suportam opções de montagem.

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 volumes do
tipo local.

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ó.

https://kubernetes.io/pt-br/docs/concepts/_print/ 40/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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

A CLI mostrará o nome do PV que foi atrelado à PVC

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:

matchLabels - o volume deve ter um rótulo com esse valor


matchExpressions - uma lista de requisitos, como chave, lista de valores e operador
relacionado aos valores e chaves. São operadores válidos: In, NotIn, Exists e
DoesNotExist.

https://kubernetes.io/pt-br/docs/concepts/_print/ 41/178
5/14/22, 11:16 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.

Requisições como Volumes


Os Pods podem ter acesso ao armazenamento utilizando a requisição como um volume. Para
isso, a requisição tem que estar no mesmo namespace que o Pod. Ao localizar a requisição
no namespace do Pod, o cluster passa o PersistentVolume para a requisição.

apiVersion: v1

kind: Pod

metadata:

name: mypod

spec:

containers:

- name: myfrontend

image: nginx

volumeMounts:

- mountPath: "/var/www/html"

https://kubernetes.io/pt-br/docs/concepts/_print/ 42/178
5/14/22, 11:16 AM Conceitos | Kubernetes

name: mypd

volumes:

- name: mypd

persistentVolumeClaim:

claimName: myclaim

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.

PersistentVolumes do tipo hostPath


Um PersistentVolume do tipo hostPath utiliza um arquivo ou diretório no nó para emular
um network-attached storage (NAS). Veja um exemplo de volume do tipo hostPath .

Suporte a Volume de Bloco Bruto


FEATURE STATE: Kubernetes v1.18 [stable]

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

Utilização de PersistentVolume com Volume de Bloco Bruto

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

Requisição de PersistentVolumeClaim com Volume de Bloco


Bruto

apiVersion: v1

https://kubernetes.io/pt-br/docs/concepts/_print/ 43/178
5/14/22, 11:16 AM Conceitos | Kubernetes

kind: PersistentVolumeClaim

metadata:

name: block-pvc

spec:

accessModes:

- ReadWriteOnce

volumeMode: Block

resources:

requests:

storage: 10Gi

Especificação de Pod com Dispositivo de Bloco Bruto no


contêiner

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.

Bind de Volumes de Bloco


Se um usuário solicita um volume de bloco bruto através do campo volumeMode na spec da
PersistentVolumeClaim, as regras de bind agora têm uma pequena diferença em relação às
versões anteriores que não consideravam esse modo como parte da spec .
A tabela abaixo
mostra as possíveis combinações que um usuário e um administrador pode especificar para
requisitar um dispositivo de bloco bruto. A tabela indica se o volume será ou não atrelado
com base nas combinações:
Matriz de bind de volume para provisionamento estático de
volumes:

PV volumeMode PVC volumeMode Result

unspecified unspecified BIND

unspecified Block NO BIND

unspecified Filesystem BIND

Block unspecified NO BIND

Block Block BIND

Block Filesystem NO BIND

Filesystem Filesystem BIND

https://kubernetes.io/pt-br/docs/concepts/_print/ 44/178
5/14/22, 11:16 AM Conceitos | Kubernetes

PV volumeMode PVC volumeMode Result

Filesystem Block NO BIND

Filesystem unspecified BIND

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.

Snapshot de Volume e Restauração de Volume


a partir de um Snapshot
FEATURE STATE: Kubernetes v1.20 [stable]

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.

Criar uma PersistentVolumeClaim a partir de um Snapshot 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.

Criação de PersistentVolumeClaim a partir de uma PVC já


existente

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

name: cloned-pvc

spec:

storageClassName: my-csi-plugin

dataSource:

name: existing-src-pvc-name

kind: PersistentVolumeClaim

accessModes:

- ReadWriteOnce

https://kubernetes.io/pt-br/docs/concepts/_print/ 45/178
5/14/22, 11:16 AM Conceitos | Kubernetes

resources:

requests:

storage: 10Gi

Boas Práticas de Configuração


Se você está criando templates ou exemplos que rodam numa grande quantidade de clusters
e que precisam de armazenamento persistente, recomendamos que utilize o padrão abaixo:

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/ 46/178
5/14/22, 11:16 AM Conceitos | Kubernetes

5 - Arquitetura do Kubernetes
5.1 - Comunicação entre Nó e Control
Plane
Este documento cataloga os caminhos de comunicação entre o control plane (o
apiserver) e o
cluster Kubernetes. A intenção é permitir que os usuários
personalizem sua instalação para
proteger a configuração de rede
então o cluster pode ser executado em uma rede não
confiável (ou em IPs totalmente públicos em um
provedor de nuvem).

Nó para o Control Plane


Todos os caminhos de comunicação do cluster para o control plane terminam no
apiserver
(nenhum dos outros componentes do control plane são projetados para expor
Serviços
remotos). Em uma implantação típica, o apiserver é configurado para escutar
conexões
remotas em uma porta HTTPS segura (443) com uma ou mais clientes autenticação
habilitado.
Uma ou mais formas de autorização
deve ser habilitado, especialmente se
requisições anônimas
ou tokens da conta de serviço
são autorizados.

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.

Control Plane para o nó


Existem dois caminhos de comunicação primários do control plane (apiserver) para os nós.
O
primeiro é do apiserver para o processo do kubelet que é executado em
cada nó no cluster.
O segundo é do apiserver para qualquer nó, pod,
ou serviço através da funcionalidade de
proxy do apiserver.

apiserver para o kubelet


As conexões do apiserver ao kubelet são usadas para:

Buscar logs para pods.


Anexar (através de kubectl) pods em execução.
Fornecer a funcionalidade de encaminhamento de porta do kubelet.

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.
https://kubernetes.io/pt-br/docs/concepts/_print/ 47/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

apiserver para nós, pods e serviços


As conexões a partir do apiserver para um nó, pod ou serviço padrão para simples
conexões
HTTP não são autenticadas nem criptografadas. Eles
podem ser executados em uma conexão
HTTPS segura prefixando https: no nó,
pod, ou nome do serviço no URL da API, mas eles
não validarão o certificado
fornecido pelo ponto de extremidade HTTPS, nem fornece
credenciais de cliente, enquanto
a conexão será criptografada, não fornecerá nenhuma
garantia de integridade.
Estas conexões não são atualmente seguras para serem usados
por redes não confiáveis ​e/ou públicas.

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
FEATURE STATE: 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.

Veja a tarefa do Konnectivity para configurar o serviço Konnectivity no seu cluster.

https://kubernetes.io/pt-br/docs/concepts/_print/ 48/178
5/14/22, 11:16 AM Conceitos | Kubernetes

5.2 - Conceitos sobre Cloud Controller


Manager
O conceito do Cloud Controller Manager (CCM) (não confundir com o binário) foi
originalmente criado para permitir que o código específico de provedor de nuvem e o núcleo
do Kubernetes evoluíssem independentemente um do outro. O Cloud Controller Manager é
executado junto com outros componentes principais, como o Kubernetes controller manager,
o servidor de API e o scheduler. Também pode ser iniciado como um addon do Kubernetes,
caso em que é executado em cima do 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.

Aqui está a arquitetura de um cluster Kubernetes sem o Cloud Controller Manager:

Projeto de Arquitetura (Design)


No diagrama anterior, o Kubernetes e o provedor de nuvem são integrados através de vários
componentes diferentes:

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:

Componentes do CCM
https://kubernetes.io/pt-br/docs/concepts/_print/ 49/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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

Na versão 1.9, o CCM executa os seguintes controladores da lista anterior:

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.

1. Kubernetes Controller Manager


A maioria das funções do CCM é derivada do KCM. Conforme mencionado na seção anterior,
o CCM executa os seguintes ciclos de controle:

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:

1. Inicializar um node com labels de região/zona específicos para a nuvem.


2. Inicialize um node com detalhes de instância específicos da nuvem, por exemplo, tipo e
tamanho.
3. Obtenha os endereços de rede e o nome do host do node.
4. No caso de um node não responder, verifique a nuvem para ver se o node foi excluído
da nuvem.
Se o node foi excluído da nuvem, exclua o objeto Node do Kubernetes.

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.
https://kubernetes.io/pt-br/docs/concepts/_print/ 50/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Service controller
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:

https://kubernetes.io/pt-br/docs/concepts/_print/ 51/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

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

O RBAC ClusterRole para o CCM se parece com isso:

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 52/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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

Implementações de Provedores de Nuvem


Os seguintes provedores de nuvem implementaram CCMs:

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/ 53/178
5/14/22, 11:16 AM Conceitos | Kubernetes

5.3 - 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.

Um exemplo de ciclo de controle é um termostato de uma sala.

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.

Padrão Controlador (Controller pattern)


Um controlador rastreia pelo menos um tipo de recurso Kubernetes.
Estes objetos
têm um
campo spec que representa o estado desejado.
O(s) controlador(es) para aquele recurso são
responsáveis por trazer o estado atual
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.

Controlador via API server


O controlador Job é um exemplo de um
controlador Kubernetes embutido. Controladores
embutidos gerem estados através da
interação com o cluster API server.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 54/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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)

Estado desejado versus atual


Kubernetes tem uma visão cloud-native de sistemas e é capaz de manipular
mudanças
constantes.

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.

Formas de rodar controladores


O Kubernetes vem com um conjunto de controladores embutidos que correm
dentro do
kube-controller-manager.
Estes controladores embutidos providenciam comportamentos
centrais importantes.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 55/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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/ 56/178
5/14/22, 11:16 AM Conceitos | Kubernetes

6 - 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.

Agente de execução de contêiner


O agente de execução (runtime) de contêiner é o software responsável por executar os
contêineres.

O Kubernetes suporta diversos agentes de execução de contêineres: Docker, containerd,


CRI-O, e qualquer implementação do Kubernetes CRI (Container Runtime Interface).

Próximos passos
Imagens de contêineres
Pods

https://kubernetes.io/pt-br/docs/concepts/_print/ 57/178
5/14/22, 11:16 AM Conceitos | Kubernetes

6.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

Esta página fornece um resumo sobre o conceito de imagem de contêiner.

Nomes das imagens


As imagens de contêiner geralmente recebem um nome como pause ,
exemplo/meuconteiner , ou kube-apiserver .
As imagens também podem incluir um
hostname de algum registro; por exemplo: exemplo.registro.ficticio/nomeimagem ,
e um
possível número de porta; por exemplo: exemplo.registro.ficticio:10443/nomeimagem .

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.

Em vez disso, especifique uma tag significativa, como v1.42.0 .

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:

defina a imagePullPolicy do contêiner para Always .


omita imagePullPolicy e use : latest como a tag para a imagem a ser usada.
omita o imagePullPolicy e a tag da imagem a ser usada.
habilite o AlwaysPullImages controlador de admissão.

Quando imagePullPolicy é definido sem um valor específico, ele também é definido como
Always .

Multiarquitetura de imagens com índice de


imagens

https://kubernetes.io/pt-br/docs/concepts/_print/ 58/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Além de fornecer o binário das imagens, um registro de contêiner também pode servir um
índice de imagem do contêiner. Um índice de imagem pode apontar para múltiplos
manifestos da imagem para versões específicas de arquitetura de um contêiner. A ideia é que
você possa ter um nome para uma imagem (por exemplo: pause , exemple/meuconteiner ,
kube-apiserver ) e permitir que diferentes sistemas busquem o binário da imagem correta
para a arquitetura de máquina que estão usando.

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.

Usando um registro privado


Os registros privados podem exigir chaves para acessar as imagens deles.
As credenciais
podem ser fornecidas de várias maneiras:

Configurando nós para autenticação em um registro privado


todos os pods podem ler qualquer registro privado configurado
requer configuração de nó pelo administrador do cluster
Imagens pré-obtidas
todos os pods podem usar qualquer imagem armazenada em cache em um nó
requer acesso root a todos os nós para configurar
Especificando ImagePullSecrets em um Pod
apenas pods que fornecem chaves próprias podem acessar o registro privado
Extensões locais ou específicas do fornecedor
se estiver usando uma configuração de nó personalizado, você (ou seu provedor
de nuvem) pode implementar seu mecanismo para autenticar o nó ao registro do
contêiner.

Essas opções são explicadas com mais detalhes abaixo.

Configurando nós para autenticação em um registro privado

Se você executar o Docker em seus nós, poderá configurar o contêiner runtime do Docker
para autenticação em um registro de contêiner privado.

Essa abordagem é adequada se você puder controlar a configuração do nó.

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 59/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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

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:

kubectl apply -f - <<EOF

apiVersion: v1

kind: Pod

metadata:

name: private-image-test-1

spec:
containers:

- name: uses-private-image

image: $PRIVATE_IMAGE_NAME

imagePullPolicy: Always

command: [ "echo", "SUCCESS" ]

EOF

pod/private-image-test-1 created

Se tudo estiver funcionando, então, após algum tempo, você pode executar:

kubectl logs private-image-test-1

e veja o resultado do comando:

SUCCESS

Se você suspeitar que o comando falhou, você pode executar:

kubectl describe pods/private-image-test-1 | grep 'Failed'

Em caso de falha, a saída é semelhante a:


https://kubernetes.io/pt-br/docs/concepts/_print/ 60/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {ku

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).

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.

Todos os pods terão permissão de leitura a quaisquer imagens pré-obtidas.

Especificando imagePullSecrets em um pod

Nota: Esta é a abordagem recomendada para executar contêineres com base em


imagens
de registros privados.

O Kubernetes oferece suporte à especificação de chaves de registro de imagem de contêiner


em um pod.

Criando um segredo com Docker config


Execute o seguinte comando, substituindo as palavras em maiúsculas com os valores
apropriados:

kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERV

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 61/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Referenciando um imagePullSecrets em um pod


Agora, você pode criar pods que fazem referência a esse segredo adicionando uma seção
imagePullSecrets
na definição de Pod.

Por exemplo:

cat <<EOF > pod.yaml

apiVersion: v1

kind: Pod

metadata:

name: foo

namespace: awesomeapps

spec:
containers:

- name: foo

image: janedoe/awesomeapp:v1

imagePullSecrets:

- name: myregistrykey

EOF

cat <<EOF >> ./kustomization.yaml

resources:
- pod.yaml
EOF

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.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 62/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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/ 63/178
5/14/22, 11:16 AM Conceitos | Kubernetes

6.2 - Ambiente de Contêiner


Essa página descreve os recursos disponíveis para contêineres no ambiente de contêiner.

Ambiente de contêiner
O ambiente de contêiner do Kubernetes fornece recursos importantes para contêineres:

Um sistema de arquivos, que é a combinação de uma imagem e um ou mais volumes.


Informação sobre o contêiner propriamente.
Informação sobre outros objetos no cluster.

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:

FOO_SERVICE_HOST=<o host em que o serviço está executando>

FOO_SERVICE_PORT=<a porta em que o serviço está executando>

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/ 64/178
5/14/22, 11:16 AM Conceitos | Kubernetes

6.3 - Classes de execução


FEATURE STATE: Kubernetes v1.20 [stable]

Essa página descreve o recurso RuntimeClass e a seleção do mecanismo do agente de


execução.

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.

1. Configure a implementação do CRI nos nós


As configurações disponíveis através do RuntimeClass sáo dependentes da implementação
do
Container Runtime Interface (Container runtime interface (CRI)). Veja a documentação
correspondente abaixo para a
sua implementação CRI para verificar como configurar.

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
- ).

2. Crie o recurso RuntimeClass correspondente


As etapas de configuração no passo 1 devem todas estar associadas a um nome para o
campo handler
que identifica a configuração. Para cada um, crie o objeto RuntimeClass
correspondente.

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:

apiVersion: node.k8s.io/v1 # RuntimeClass é definido no grupo de API node.k8s.io


kind: RuntimeClass

metadata:

name: myclass # O nome que o RuntimeClass será chamado como

# RuntimeClass é um recurso global, e não possui namespace.

handler: myconfiguration # Nome da configuração CRI correspondente

https://kubernetes.io/pt-br/docs/concepts/_print/ 65/178
5/14/22, 11:16 AM Conceitos | Kubernetes

O nome de um objeto RuntimeClass deve ser um


nome de subdomínio DNS válido.

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.

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}]

Veja a documentação de configuração do containerd para maiores detalhes:


https://github.com/containerd/cri/blob/master/docs/config.md

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}"

Veja a documentação de configuração do CRI-O para maiores detalhes.

https://kubernetes.io/pt-br/docs/concepts/_print/ 66/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Associação
FEATURE STATE: 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.

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
FEATURE STATE: 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/ 67/178
5/14/22, 11:16 AM Conceitos | Kubernetes

6.4 - Hooks de Ciclo de Vida do


Contêiner
Essa página descreve como os contêineres gerenciados pelo kubelet podem usar a estrutura
de hook de ciclo de vida do contêiner para executar código acionado por eventos durante seu
ciclo de vida de gerenciamento.

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.

Implementações de manipulador de hook


Os contêineres podem acessar um hook implementando e registrando um manipulador para
esse hook.
Existem dois tipos de manipuladores de hooks que podem ser implementados
para contêineres:

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.

Execução do manipulador de hook


Quando um hook de gerenciamento de ciclo de vida do contêiner é chamado, o sistema de
gerenciamento do Kubernetes executa o manipulador de acordo com a ação do hook,
httpGet e tcpSocket são executados pelo processo kubelet e exec é executado pelo
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
https://kubernetes.io/pt-br/docs/concepts/_print/ 68/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Se um hook PostStart ou PreStop falhar, ele mata o contêiner.

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.

Garantias de entrega de hooks


A entrega do hook é destinada a acontecer pelo menos uma vez,
o que quer dizer que um hook
pode ser chamado várias vezes para qualquer evento,
como para PostStart ou PreStop .
Depende da implementação do hook lidar com isso corretamente.

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.

Depurando manipuladores de hooks


Os logs para um manipulador de hook não são expostos em eventos de Pod.
Se um
manipulador falhar por algum motivo, ele transmitirá um evento.
Para PostStart é o evento
FailedPostStartHook e para PreStop é o evento
FailedPreStopHook .
Você pode ver esses
eventos executando kubectl describe pod <nome_do_pod> .
Aqui está um exemplo de saída
de eventos da execução deste comando:

Events:

FirstSeen LastSeen Count From


--------- -------- ----- ----
1m 1m 1 {default-scheduler }
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siq
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siq

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/ 69/178
5/14/22, 11:16 AM Conceitos | Kubernetes

7 - Serviços, balanceamento de carga e


conectividade
Conceitos e recursos por trás da conectividade no Kubernetes.

A conectividade do Kubernetes trata quatro preocupações:

Contêineres em um Pod se comunicam via interface loopback.


A conectividade do cluster provê a comunicação entre diferentes Pods.
O recurso de Service permite a você expor uma aplicação executando em um Pod,
de
forma a ser alcançável de fora de seu cluster.
Você também pode usar os Services para publicar serviços de consumo interno do
seu
cluster.

https://kubernetes.io/pt-br/docs/concepts/_print/ 70/178
5/14/22, 11:16 AM Conceitos | Kubernetes

7.1 - Políticas de rede


Se você deseja controlar o fluxo do tráfego de rede no nível do endereço IP ou de portas TCP
e UDP
(camadas OSI 3 e 4) então você deve considerar usar Políticas de rede
( NetworkPolicies ) do Kubernetes para aplicações
no seu cluster. NetworkPolicy é um
objeto focado em aplicações/experiência do desenvolvedor
que permite especificar como é
permitido a um pod
comunicar-se com várias "entidades" de rede.

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.

Pods isolados e não isolados


Por padrão, pods não são isolados; eles aceitam tráfego de qualquer origem.

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.

Uma NetworkPolicy de exemplo é similar ao abaixo:

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

name: test-network-policy

namespace: default

spec:

https://kubernetes.io/pt-br/docs/concepts/_print/ 71/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 .

Então a NetworkPolicy acima:


https://kubernetes.io/pt-br/docs/concepts/_print/ 72/178
5/14/22, 11:16 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:

qualquer pod no namespace "default" com a label "role=frontend"


qualquer pod em um namespace que tenha a label "project=myproject" (aqui cabe
ressaltar que o namespace que deve ter a label e não os pods dentro desse
namespace)
IPs dentro das faixas 172.17.0.0–172.17.0.255 e 172.17.2.0–172.17.255.255 (ex.:,
toda 172.17.0.0/16 exceto 172.17.1.0/24)
3. (Regras de saída/egress) permite conexões de qualquer pod no namespace "default"
com a label
"role=db" para a faixa de destino 10.0.0.0/24 na porta TCP 5978.

Veja o tutorial Declarando uma política de redes para mais exemplos.

Comportamento dos seletores to e from


Existem quatro tipos de seletores que podem ser especificados nas sessões ingress.from
ou
egress.to :

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 .

https://kubernetes.io/pt-br/docs/concepts/_print/ 73/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Quando estiver em dúvida, utilize o comando kubectl describe para verificar como o
Kubernetes interpretou a política.

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.

Bloqueio padrão de todo tráfego de entrada


Você pode criar uma política padrão de isolamento para um namespace criando um objeto
NetworkPolicy
que seleciona todos os pods mas não permite o tráfego de entrada para
esses pods.

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.

Permitir por padrão todo tráfego de entrada


Se você deseja permitir todo o tráfego de todos os pods em um namespace (mesmo que
políticas que
sejam adicionadas faça com que alguns pods sejam tratados como "isolados"),
você pode criar
uma política que permite explicitamente todo o tráfego naquele namespace.

service/networking/network-policy-allow-all-ingress.yaml

https://kubernetes.io/pt-br/docs/concepts/_print/ 74/178
5/14/22, 11:16 AM Conceitos | Kubernetes

---

apiVersion: networking.k8s.io/v1

kind: NetworkPolicy

metadata:

name: allow-all-ingress

spec:

podSelector: {}

ingress:

- {}

policyTypes:

- Ingress

Bloqueio padrão de todo tráfego de saída


Você pode criar uma política de isolamento de saída padrão para um namespace criando
uma
política de redes que selecione todos os pods, mas não permita o tráfego de saída a
partir
de nenhum desses pods.

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.

Permitir por padrão todo tráfego de saída


Caso você queira permitir todo o tráfego de todos os pods em um namespace (mesmo que
políticas sejam
adicionadas e cause com que alguns pods sejam tratados como "isolados"),
você pode criar uma
política explicita que permite todo o tráfego de saída no namespace.

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/ 75/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Bloqueio padrão de todo tráfego de entrada e saída


Você pode criar uma política padrão em um namespace que previne todo o tráfego de
entrada
E saída criando a política a seguir no namespace.

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.

Selecionando uma faixa de portas


FEATURE STATE: Kubernetes v1.21 [alpha]

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.

As seguintes restrições aplicam-se ao se utilizar esse campo:

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,... .

O valor de endPort deve ser igual ou maior ao valor do campo port .

https://kubernetes.io/pt-br/docs/concepts/_print/ 76/178
5/14/22, 11:16 AM Conceitos | Kubernetes

O campo endPort só pode ser definido se o campo port também for definido.
Ambos os campos port e endPort devem ser números.

Nota: Seu cluster deve utilizar um plugin CNI


que suporte o campo endPort na
especificação da política de redes.

Selecionando um Namespace pelo seu nome

FEATURE STATE: Kubernetes 1.21 [beta]

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.24 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/ 77/178
5/14/22, 11:16 AM Conceitos | Kubernetes

8 - Configuração
8.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.

Dicas Gerais de Configuração


Ao definir configurações, especifique a versão mais recente estável da API.

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.

"Naked" Pods comparados a ReplicaSets,


Deployments, e Jobs
Se você puder evitar, não use "naked" Pods (ou seja, se você puder evitar, pods não
vinculados a um ReplicaSet ou Deployment).
Os "naked" pods não serão reconfigurados
em caso de falha de um nó.

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:

https://kubernetes.io/pt-br/docs/concepts/_print/ 78/178
5/14/22, 11:16 AM Conceitos | Kubernetes

FOO_SERVICE_HOST=<o host em que o Service está executando>

FOO_SERVICE_PORT=<a porta em que o Service está executando>

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.

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 .

Evite usar hostNetwork pelos mesmos motivos do 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

https://kubernetes.io/pt-br/docs/concepts/_print/ 79/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 a tag da imagem é :latest ou se imagePullPolicy é


omitido é automaticamente definido como Always . Observe que não será utilizado
para ifNotPresent se o valor da tag mudar.

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.

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/ 80/178
5/14/22, 11:16 AM Conceitos | Kubernetes

8.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.

É obrigatório que o nome de um ConfigMap seja um


subdomínio DNS válido.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 81/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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:

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"

# chaves semelhantes a fragmentos de arquivos

game.properties: |

enemy.types=aliens,monsters

player.maximum-lives=5

user-interface.properties: |
color.good=purple

color.bad=yellow

allow.textmode=true

Existem quatro formas diferentes para consumo de um ConfigMap na configuração de um


contêiner dentro de um Pod:

1. Dentro de um comando de contêiner e seus argumentos.


2. Variáveis de ambiente para um contêiner.
3. Criando um arquivo em um volume somente leitura, para consumo pela aplicação.
4. Escrevendo código para execução dentro do Pod que utilize a API do Kubernetes para
ler um ConfigMap.

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:

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


# 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

https://kubernetes.io/pt-br/docs/concepts/_print/ 82/178
5/14/22, 11:16 AM Conceitos | Kubernetes

volumeMounts:

- name: config

mountPath: "/config"

readOnly: true

volumes:

# Volumes são definidos no escopo do Pod, e os pontos de montagem são defini


# 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.

Utilizando ConfigMaps como arquivos em um Pod


Para consumir um ConfigMap em um volume em um Pod:

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 .spec.containers[].volumeMounts[] a cada um dos
contêineres
que precisam do ConfigMap. Especifique
.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 .

Exemplo de um Pod que monta um ConfigMap em um volume:


https://kubernetes.io/pt-br/docs/concepts/_print/ 83/178
5/14/22, 11:16 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

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 montados são atualizados automaticamente


Quando um ConfigMap que está sendo consumido em um volume é atualizado, as chaves
projetadas são
eventualmente atualizadas também. O Kubelet checa se o ConfigMap
montado está atualizado em cada
sincronização periódica.
No entanto, o kubelet utiliza o
cache local para buscar o valor atual do ConfigMap.
O tipo de cache é configurável utilizando
o campo ConfigMapAndSecretChangeDetectionStrategy na
configuração do Kubelet
(KubeletConfiguration).
Um ConfigMap pode ter sua propagação baseada em um watch
(comportamento padrão), que é o sistema
de propagação de mudanças incrementais em
objetos do Kubernetes; baseado em TTL (time to live,
ou tempo de expiração); ou
redirecionando todas as requisições diretamente para o servidor da API.
Como resultado, o
tempo decorrido total entre o momento em que o ConfigMap foi atualizado até o momento
quando as novas chaves são projetadas nos Pods pode ser tão longo quanto o tempo de
sincronização
do kubelet somado ao tempo de propagação do cache, onde o tempo de
propagação do cache depende do
tipo de cache escolhido: o tempo de propagação pode ser
igual ao tempo de propagação do watch,
TTL do cache, ou zero, de acordo com cada um dos
tipos de cache.

ConfigMaps que são consumidos como variáveis de ambiente não atualizam


automaticamente e requerem uma
reinicialização do pod.

ConfigMaps imutáveis
FEATURE STATE: 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

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:

https://kubernetes.io/pt-br/docs/concepts/_print/ 84/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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/ 85/178
5/14/22, 11:16 AM Conceitos | Kubernetes

8.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:

1. Habilite encriptação em disco para Secrets.


2. Habilite ou configure regras de RBAC
que restrinjam o acesso de leitura a Secrets
(incluindo acesso indireto).
3. Quando apropriado, utilize mecanismos como RBAC para limitar quais perfis e
usuários possuem permissão para criar novos Secrets ou substituir Secrets
existentes.

Visão Geral de Secrets


Para utilizar um Secret, um Pod precisa referenciar o Secret.
Um Secret pode ser utilizado em
um Pod de três maneiras diferentes:

Como um arquivo em um
volume montado em um ou mais de
seus contêineres.
Como uma variável de ambiente em um
contêiner.
Pelo kubelet ao baixar imagens de contêiner para o
Pod.

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.

O nome de um Secret deve ser um subdomínio DNS válido.


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 toma a precedência.

Tipos de Secrets
https://kubernetes.io/pt-br/docs/concepts/_print/ 86/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Tipo embutido Caso de uso

Opaque dados arbitrários definidos pelo usuário

kubernetes.io/service-account- token de service account (conta de serviço)


token

kubernetes.io/dockercfg arquivo ~/.dockercfg serializado

kubernetes.io/dockerconfigjson arquivo ~/.docker/config.json


serializado

kubernetes.io/basic-auth credenciais para autenticação básica (basic


auth)

kubernetes.io/ssh-auth credenciais para autenticação SSH

kubernetes.io/tls dados para um cliente ou servidor TLS

bootstrap.kubernetes.io/token dados de token de autoinicialização

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.

Secrets tipo Opaque


Opaque é o tipo predefinido de Secret quando o campo type não é informado
em um
arquivo de configuração. 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 :

kubectl create secret generic empty-secret

kubectl get secret empty-secret

O resultado será semelhante ao abaixo:

NAME TYPE DATA AGE

empty-secret Opaque 0 2m6s

A coluna DATA demonstra a quantidade de dados armazenados no Secret. Neste


caso, 0
significa que este objeto Secret está vazio.

Secrets de token de service account (conta de serviço)


Secrets do tipo kubernetes.io/service-account-token são utilizados para
armazenar um
token que identifica uma service account (conta de serviço). Ao
utilizar este tipo de Secret,
você deve garantir que a anotação
kubernetes.io/service-account.name contém um nome

https://kubernetes.io/pt-br/docs/concepts/_print/ 87/178
5/14/22, 11:16 AM Conceitos | Kubernetes

de uma service account


existente. Um controlador do Kubernetes preenche outros campos,
como por exemplo
a anotação kubernetes.io/service-account.uid e a chave token no
campo data
com o conteúdo do token.

O exemplo de configuração abaixo declara um Secret de token de service account:

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 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.

Secrets de configuração do Docker


Você pode utilizar um dos tipos abaixo para criar um Secret que armazena
credenciais para
accesso a um registro de contêineres compatível com Docker
para busca de imagens:

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.

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.

Um exemplo de um Secret do tipo kubernetes.io/dockercfg :

apiVersion: v1

kind: Secret

metadata:

name: secret-dockercfg

type: kubernetes.io/dockercfg

data:

.dockercfg: |

"<base64 encoded ~/.dockercfg file>"

https://kubernetes.io/pt-br/docs/concepts/_print/ 88/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 compatível
com o Docker, você
pode executar:

kubectl create secret docker-registry secret-tiger-docker \

--docker-username=tiger \

--docker-password=pass113 \

--docker-email=tiger@acme.com \

--docker-server=my-registry.example:5000

Esse comando cria um secret do tipo kubernetes.io/dockerconfigjson , cujo


conteúdo é
semelhante ao exemplo abaixo:

"apiVersion": "v1",

"data": {

".dockerconfigjson": "eyJhdXRocyI6eyJteS1yZWdpc3RyeTo1MDAwIjp7InVzZXJuYW1
},

"kind": "Secret",

"metadata": {

"creationTimestamp": "2021-07-01T07:30:59Z",

"name": "secret-tiger-docker",

"namespace": "default",

"resourceVersion": "566718",

"uid": "e15c1d7b-9071-4100-8681-f3a7a2ce89ca"

},

"type": "kubernetes.io/dockerconfigjson"

Se você extrair o conteúdo da chave .dockerconfigjson , presente no campo


data , e
decodificá-lo do formato base64, você irá obter o objeto JSON abaixo,
que é uma
configuração válida do Docker criada automaticamente:

"auths":{

"my-registry:5000":{

"username":"tiger",

"password":"pass113",

"email":"tiger@acme.com",

"auth":"dGlnZXI6cGFzczExMw=="

}
}

Secret de autenticação básica


O tipo kubernetes.io/basic-auth é fornecido para armazenar credenciais
necessárias para
autenticação básica. Ao utilizar este tipo de Secret, o campo
data do Secret deve conter as
duas chaves abaixo:
https://kubernetes.io/pt-br/docs/concepts/_print/ 89/178
5/14/22, 11:16 AM Conceitos | Kubernetes

username : o usuário utilizado para autenticação;


password : a senha ou token para autenticação.

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.

O arquivo YAML abaixo é um exemplo de configuração para um Secret de autenticação


básica:

apiVersion: v1

kind: Secret

metadata:

name: secret-basic-auth

type: kubernetes.io/basic-auth
stringData:

username: admin

password: t0p-Secret

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 de Secret auxilia a unificação dos formatos das suas
credenciais. O tipo embutido
também fornece verificação de presença das chaves
requeridas pelo servidor da API.

Secret de autenticação SSH


O tipo embutido kubernetes.io/ssh-auth é fornecido para armazenamento de dados
utilizados em autenticação SSH. Ao utilizar este tipo de Secret, você deve
especificar um par
de chave-valor ssh-privatekey no campo data ou no campo
stringData com a credencial
SSH a ser utilizada.

O YAML abaixo é um exemplo de configuração para um Secret de autenticação SSH:

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 auxilia na
unificação dos formatos das suas
credenciais e o servidor da API 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 "machine-in-the-middle", 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. Estes dados
são utilizados primariamente para a
finalização TLS do recurso Ingress, mas podem ser
https://kubernetes.io/pt-br/docs/concepts/_print/ 90/178
5/14/22, 11:16 AM Conceitos | Kubernetes

utilizados 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.

O YAML a seguir tem um exemplo de configuração para um Secret TLS:

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:

kubectl create secret tls my-tls-secret \

--cert=path/to/cert/file \

--key=path/to/key/file

O par de chaves pública/privada deve ser criado separadamente. O certificado


de chave
pública a ser utilizado no argumento --cert deve ser codificado em
formato .PEM (formato
DER codificado em texto base64) e deve corresponder à
chave privada fornecida no
argumento --key .
A chave privada deve estar no formato de chave privada PEM não-
encriptado. Em
ambos os casos, as linhas inicial e final do formato PEM (por exemplo,
------
--BEGIN CERTIFICATE----- e -------END CERTIFICATE---- para um
certificado) não são
incluídas.

Secret de token de autoinicialização


Um Secret de token de autoinicialização pode ser criado especificando o tipo de
um Secret
explicitamente com o valor bootstrap.kubernetes.io/token . Este tipo
de Secret é projetado
para tokens utilizados durante o processo de inicialização
de nós. Este tipo de Secret
armazena tokens utilizados para assinar ConfigMaps
conhecidos.

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.

No formato de manifesto do Kubernetes, um Secret de token de autoinicialização


se
assemelha ao exemplo abaixo:

apiVersion: v1

kind: Secret

metadata:

name: bootstrap-token-5emitj
namespace: kube-system

type: bootstrap.kubernetes.io/token
data:

https://kubernetes.io/pt-br/docs/concepts/_print/ 91/178
5/14/22, 11:16 AM Conceitos | Kubernetes

auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG
expiration: MjAyMC0wOS0xM1QwNDozOToxMFo=

token-id: NWVtaXRq

token-secret: a3E0Z2lodnN6emduMXAwcg==

usage-bootstrap-authentication: dHJ1ZQ==

usage-bootstrap-signing: dHJ1ZQ==

Um Secret do tipo token de autoinicialização possui as seguintes chaves no campo


data :

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 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"

Criando um Secret
Há várias formas diferentes de criar um Secret:

criar um Secret utilizando o comando kubectl


criar um Secret a partir de um arquivo de configuração
criar um Secret utilizando a ferramenta kustomize

Editando um Secret
Um Secret existente no cluster pode ser editado com o seguinte comando:

https://kubernetes.io/pt-br/docs/concepts/_print/ 92/178
5/14/22, 11:16 AM Conceitos | Kubernetes

kubectl edit secrets mysecret

Este comando abrirá o editor padrão configurado e permitirá a modificação dos


valores
codificados em base64 no campo data :

# 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 fil
# 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

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.

Utilizando Secrets como arquivos em um Pod


Para consumir um Secret em um volume em um Pod:

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 .

Este é um exemplo de Pod que monta um Secret em um volume:

apiVersion: v1

kind: Pod

metadata:

name: mypod

spec:

containers:

- name: mypod

https://kubernetes.io/pt-br/docs/concepts/_print/ 93/178
5/14/22, 11:16 AM Conceitos | Kubernetes

image: redis

volumeMounts:

- name: foo

mountPath: "/etc/foo"

readOnly: true

volumes:

- name: foo

secret:

secretName: mysecret

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.

Você pode armazenar vários arquivos em um Secret ou utilizar vários Secrets


distintos, o que
for mais conveniente.

Projeção de chaves de Secrets a caminhos específicos


Você pode também controlar os caminhos dentro do volume onde as chaves do Secret
são
projetadas. Você pode utilizar o campo .spec.volumes[].secret.items para
mudar o
caminho de destino de cada chave:

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:

O valor da chave username é armazenado no arquivo


/etc/foo/my-group/my-username
ao invés de /etc/foo/username .
O valor da chave password não é projetado no sistema de arquivos.

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 . Todas as chaves listadas precisam
existir no Secret
correspondente. Caso contrário, o volume não é criado.

Permissões de arquivos de Secret


Você pode trocar os bits de permissão de uma chave avulsa de Secret.
Se nenhuma
permissão for especificada, 0644 é utilizado por padrão.
Você pode também especificar uma
permissão padrão para o volume inteiro de
Secret e sobrescrever esta permissão por chave,
se necessário.

https://kubernetes.io/pt-br/docs/concepts/_print/ 94/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 .

Note que a especificação JSON não suporta notação octal. Neste caso, utilize o
valor 256 para
permissões equivalentes a 0400. Se você utilizar YAML ao invés
de JSON para o Pod, você
pode utilizar notação octal para especificar permissões
de uma forma mais natural.

Perceba que se você acessar o Pod com kubectl exec , você precisará seguir o
vínculo
simbólico para encontrar a permissão esperada. Por exemplo,

Verifique as permissões do arquivo de Secret no pod.

kubectl exec mypod -it sh

cd /etc/foo

ls -l

O resultado é semelhante ao abaixo:

total 0

lrwxrwxrwx 1 root root 15 May 18 00:18 password -> ..data/password

lrwxrwxrwx 1 root root 15 May 18 00:18 username -> ..data/username

Siga o vínculo simbólico para encontrar a permissão correta do arquivo.

cd /etc/foo/..data

ls -l

O resultado é semelhante ao abaixo:

total 8

-r-------- 1 root root 12 May 18 00:18 password

-r-------- 1 root root 5 May 18 00:18 username

Você pode também utilizar mapeamento, como no exemplo anterior, e especificar


permissões diferentes para arquivos diferentes conforme abaixo:

apiVersion: v1

kind: Pod

metadata:

name: mypod

spec:

https://kubernetes.io/pt-br/docs/concepts/_print/ 95/178
5/14/22, 11:16 AM Conceitos | Kubernetes

containers:

- name: mypod

image: redis

volumeMounts:

- name: foo

mountPath: "/etc/foo"

volumes:

- name: foo

secret:

secretName: mysecret

items:

- key: username

path: my-group/my-username

mode: 0777

Neste caso, o arquivo resultante em /etc/foo/my-group/my-username terá as


permissões
0777 . Se você utilizar JSON, devido às limitações do formato,
você precisará informar as
permissões em base decimal, ou o valor 511 neste
exemplo.

Note que os valores de permissões podem ser exibidos em formato decimal se você
ler essa
informação posteriormente.

Consumindo valores de Secrets em volumes


Dentro do contêiner que monta um volume de Secret, as chaves deste Secret
aparecem
como arquivos e os valores dos Secrets são decodificados do formato
base64 e armazenados
dentro destes arquivos. Ao executar comandos dentro do
contêiner do exemplo anterior,
obteremos os seguintes resultados:

ls /etc/foo

O resultado é semelhante a:

username

password

cat /etc/foo/username

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.

Secrets montados são atualizados automaticamente

https://kubernetes.io/pt-br/docs/concepts/_print/ 96/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Quando um Secret que está sendo consumido a partir de um volume é atualizado, as


chaves
projetadas são atualizadas após algum tempo também. O kubelet verifica
se o Secret
montado está atualizado a cada sincronização periódica. No entanto,
o kubelet utiliza seu
cache local para buscar o valor corrente de um Secret. O
tipo do cache é configurável
utilizando o campo ConfigMapAndSecretChangeDetectionStrategy
na estrutura
KubeletConfiguration.
Um Secret pode ser propagado através de um watch (comportamento
padrão), que
é o sistema de propagação de mudanças incrementais em objetos do
Kubernetes;
baseado em TTL (time to live, ou tempo de expiração); ou redirecionando todas
as requisições diretamente para o servidor da API.

Como resultado, o tempo decorrido total entre o momento em que o Secret foi
atualizado até
o momento em que as novas chaves são projetadas nos Pods pode
ser tão longo quanto o
tempo de sincronização do kubelet somado ao tempo de
propagação do cache, onde o
tempo de propagação do cache depende do tipo de
cache escolhido: o tempo de propagação
pode ser igual ao tempo de propagação
do watch, TTL do cache, ou zero, de acordo com cada
um dos tipos de cache.

Nota: Um contêiner que utiliza Secrets através de um ponto de montagem com a


propriedade
subPath não recebe atualizações
deste Secret.

Utilizando Secrets como variáveis de ambiente


Para utilizar um secret em uma variável de ambiente
em um Pod:

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.

Este é um exemplo de um Pod que utiliza Secrets em variáveis de ambiente:

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

- name: SECRET_PASSWORD

valueFrom:

secretKeyRef:

name: mysecret

key: password

restartPolicy: Never

Consumindo valores de Secret em variáveis de ambiente


Dentro de um contêiner que consome um Secret em variáveis de ambiente, a chave
do Secret
aparece como uma variável de ambiente comum, contendo os dados do
Secret decodificados
do formato base64. Ao executar comandos no contêiner do
exemplo anterior, obteremos os
https://kubernetes.io/pt-br/docs/concepts/_print/ 97/178
5/14/22, 11:16 AM Conceitos | Kubernetes

resultados abaixo:

echo $SECRET_USERNAME

O resultado é semelhante a:

admin

echo $SECRET_PASSWORD

O resultado é semelhante a:

1f2d1e2e67df

Variáveis de ambiente não são atualizadas após uma atualização no


Secret
Se um contêiner já consome um Secret em uma variável de ambiente, uma atualização
dos
valores do Secret não será refletida no contêiner a menos que o contêiner
seja reiniciado.
Existem ferramentas de terceiros que oferecem reinicializações automáticas
quando Secrets
são atualizados.

Secrets imutáveis
FEATURE STATE: Kubernetes v1.21 [stable]

A funcionalidade do Kubernetes Secrets e ConfigMaps imutáveis fornece uma


opção para
marcar Secrets e ConfigMaps individuais como imutáveis. Em clusters
que fazem uso
extensivo de Secrets (pelo menos dezenas de milhares de montagens
únicas de Secrets em
Pods), prevenir alterações aos dados dos Secrets traz as
seguintes vantagens:

protege você de alterações acidentais ou indesejadas que poderiam provocar


disrupções na execução de aplicações;
melhora a performance do seu cluster através da redução significativa de carga
no
kube-apiserver, devido ao fechamento de watches de Secrets marcados como
imutáveis.

Esta funcionalidade é controlada pelo


feature gate ImmutableEphemeralVolumes , que está
habilitado por padrão desde a versão
v1.19. Você pode criar um Secret imutável adicionando
o campo immutable com
o valor true . Por exemplo:

apiVersion: v1

kind: Secret

metadata:

...
data:

...
immutable: true

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 98/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Usando imagePullSecrets
O campo imagePullSecrets é uma lista de referências para Secrets no mesmo
namespace.
Você pode utilizar a lista imagePullSecrets para enviar Secrets
que contém uma senha para
acesso a um registro de contêineres do Docker (ou
outros registros de contêineres) ao
kubelet. O kubelet utiliza essa informação
para baixar uma imagem privada no lugar do seu
Pod.
Veja a API PodSpec
para maiores detalhes sobre o campo imagePullSecrets .

Especificando imagePullSecrets manualmente


Você pode ler sobre como especificar imagePullSecrets em um Pod na
documentação de
imagens de contêiner.

Configurando imagePullSecrets para serem vinculados


automaticamente
Você pode criar manualmente imagePullSecrets e referenciá-los em uma
ServiceAccount.
Quaisquer Pods criados com esta ServiceAccount, especificada
explicitamente ou por padrão,
têm o campo imagePullSecrets populado com os
mesmos valores existentes na service
account.
Veja adicionando imagePullSecrets a uma service account
para uma explicação
detalhada do processo.

Detalhes
Restrições
Referências a Secrets em volumes são validadas para garantir que o objeto
especificado
realmente existe e é um objeto do tipo Secret. Portanto, um Secret
precisa ser criado antes
de quaisquer Pods que dependam deste.

Objetos Secret residem em um namespace.


Secrets podem ser referenciados somente por
Pods no mesmo namespace.

Secrets individuais são limitados ao tamanho de 1MiB. Esta limitação ter por
objetivo
desencorajar a criação de Secrets muito grandes que poderiam exaurir
a memória do
servidor da API e do kubelet. No entanto, a criação de muitos
Secrets pequenos também
pode exaurir a memória. Limites mais completos de uso
de memória em função de Secrets é
uma funcionalidade prevista para o futuro.

O kubelet suporta apenas o uso de Secrets em Pods onde os Secrets são obtidos
do servidor
da API. Isso inclui quaisquer Pods criados usando o comando
kubectl , ou indiretamente
através de um controlador de replicação, mas não
inclui Pods criados como resultado das
flags --manifest-url e --config do
kubelet, ou a sua API REST (estas são formas incomuns
de criar um Pod).
A spec de um Pod estático
não pode se referir a um Secret ou a qualquer
outro objeto da API.

Secrets precisam ser criados antes de serem consumidos em Pods como variáveis de
ambiente, exceto quando são marcados como opcionais. Referências a Secrets que
não
existem provocam falhas na inicialização do Pod.

Referências (campo secretKeyRef ) a chaves que não existem em um Secret nomeado


provocam falhas na inicialização do Pod.

Secrets utilizados para popular variáveis de ambiente através do campo envFrom


que
contém chaves inválidas para utilização como nome de uma variável de ambiente
terão tais
chaves ignoradas. O Pod inicializará normalmente. Porém, um evento
será gerado com a
razão InvalidVariableNames e a mensagem gerada conterá a lista
de chaves inválidas que
foram ignoradas. O exemplo abaixo demonstra um Pod que se
refere ao Secret
default/mysecret, contendo duas chaves inválidas: 1badkey e
2alsobad .

kubectl get events

https://kubernetes.io/pt-br/docs/concepts/_print/ 99/178
5/14/22, 11:16 AM Conceitos | Kubernetes

O resultado é semelhante a:

LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT


0s 0s 1 dapi-test-pod Pod

Interações do ciclo de vida entre Secrets e Pods


Quando um Pod é criado através de chamadas à API do Kubernetes, não há validação
da
existência de um Secret referenciado. Uma vez que um Pod seja agendado, o
kubelet tentará
buscar o valor do Secret. Se o Secret não puder ser encontrado
porque não existe ou porque
houve uma falha de comunicação temporária entre o
kubelet e o servidor da API, o kubelet
fará novas tentativas periodicamente.
O kubelet irá gerar um evento sobre o Pod, explicando
a razão pela qual o Pod
ainda não foi inicializado. Uma vez que o Secret tenha sido
encontrado, o
kubelet irá criar e montar um volume contendo este Secret. Nenhum dos
contêineres
do Pod irá iniciar até que todos os volumes estejam montados.

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

Crie o Secret no seu cluster:

kubectl apply -f mysecret.yaml

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: k8s.gcr.io/busybox

command: [ "/bin/sh", "-c", "env" ]

envFrom:

- secretRef:

name: mysecret

restartPolicy: Never

Caso de uso: Pod com chaves SSH

https://kubernetes.io/pt-br/docs/concepts/_print/ 100/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Crie um Secret contendo chaves SSH:

kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/

O resultado é semelhante a:

secret "ssh-key-secret" created

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. Utilize uma service account que você
deseje 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 service
account caso os
usuários sejam comprometidos.

Agora você pode criar um Pod que referencia o Secret com a chave SSH e consome-o
em um
volume:

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"

Ao rodar o comando do contêiner, as partes da chave estarão disponíveis em:

/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.

Caso de uso: Pods com credenciais de ambientes de produção


ou testes
Este exemplo ilustra um Pod que consome um Secret contendo credenciais de um
ambiente
de produção e outro Pod que consome um Secret contendo credenciais de
um ambiente de
testes.

Você pode criar um manifesto kustomization.yaml com um secretGenerator ou


rodar
kubectl create secret .

https://kubernetes.io/pt-br/docs/concepts/_print/ 101/178
5/14/22, 11:16 AM Conceitos | Kubernetes

kubectl create secret generic prod-db-secret --from-literal=username=produser --f

O resultado é semelhante a:

secret "prod-db-secret" created

Você pode também criar um Secret com credenciais para o ambiente de testes.

kubectl create secret generic test-db-secret --from-literal=username=testuser --f

O resultado é semelhante a:

secret "test-db-secret" created

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:

kubectl create secret generic dev-db-secret --from-literal=username=devuser -

Não é necessário gerar sequências de escape para caracteres especiais em arquivos


(utilizados com a opção --from-file ).

Agora, crie os Pods:

cat <<EOF > pod.yaml

apiVersion: v1

kind: List
items:

- kind: Pod

apiVersion: v1

metadata:

name: prod-db-client-pod

labels:

name: prod-db-client

spec:

volumes:

- name: secret-volume

secret:

secretName: prod-db-secret

containers:

- name: db-client-container

image: myClientImage

volumeMounts:

- name: secret-volume

readOnly: true

mountPath: "/etc/secret-volume"

- kind: Pod

apiVersion: v1

metadata:

name: test-db-client-pod

https://kubernetes.io/pt-br/docs/concepts/_print/ 102/178
5/14/22, 11:16 AM Conceitos | Kubernetes

labels:

name: test-db-client

spec:

volumes:

- name: secret-volume

secret:

secretName: test-db-secret

containers:

- name: db-client-container

image: myClientImage

volumeMounts:

- name: secret-volume

readOnly: true

mountPath: "/etc/secret-volume"

EOF

Adicione os Pods a um manifesto kustomization.yaml :

cat <<EOF >> kustomization.yaml

resources:
- pod.yaml
EOF

Crie todos estes objetos no servidor da API rodando o comando:

kubectl apply -k .

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:

1. prod-user com o Secret prod-db-secret

2. test-user com o Secret test-db-secret

A especificação do Pod é reduzida para:

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

Caso de uso: dotfiles em um volume de Secret

https://kubernetes.io/pt-br/docs/concepts/_print/ 103/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Você pode fazer com que seus dados fiquem "ocultos" definindo uma chave que se
inicia com
um ponto ( . ). Este tipo de chave representa um dotfile, ou
arquivo "oculto". Por exemplo,
quando o Secret abaixo é montado em um volume,
secret-volume :

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: k8s.gcr.io/busybox

command:

- ls

- "-l"

- "/etc/secret-volume"

volumeMounts:

- name: secret-volume

readOnly: true

mountPath: "/etc/secret-volume"

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 ocultos do resultado
do comando ls -l. Você precisa utilizar ls -la para vê-los ao listar o
conteúdo de um
diretório.

Caso de uso: Secret visível somente em um dos contêineres


de um pod
Suponha que um programa necessita manipular requisições HTTP, executar regras
de
negócio complexas e então assinar mensagens com HMAC. Devido à natureza
complexa da
aplicação, pode haver um exploit despercebido que lê arquivos
remotos no servidor e que
poderia expor a chave privada para um invasor.

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.

Melhores práticas
Clientes que utilizam a API de Secrets

https://kubernetes.io/pt-br/docs/concepts/_print/ 104/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Ao instalar aplicações que interajam com a API de Secrets, você deve limitar o
acesso
utilizando políticas de autorização
como RBAC.

Secrets frequentemente contém valores com um espectro de importância, muitos dos


quais
podem causar escalações dentro do Kubernetes (por exemplo, tokens de service
account) e
de sistemas externos. Mesmo que um aplicativo individual possa
avaliar o poder do Secret
com o qual espera interagir, outras aplicações dentro
do mesmo namespace podem tornar
estas suposições inválidas.

Por estas razões, as requisições watch (observar) e list (listar) de


Secrets dentro de um
namespace são permissões extremamente poderosas e devem
ser evitadas, pois a listagem
de Secrets permite a clientes inspecionar os
valores de todos os Secrets presentes naquele
namespace. A habilidade de listar
e observar todos os Secrets em um cluster deve ser
reservada somente para os
componentes mais privilegiados, que fazem parte do nível de
aplicações de sistema.

Aplicações que necessitam acessar a API de Secret devem realizar uma requisição
get nos
Secrets que precisam. Isto permite que administradores restrinjam o
acesso a todos os
Secrets, enquanto
utilizam uma lista de autorização a instâncias individuais
que a aplicação
precise.

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.

Propriedades de segurança
Proteções
Como Secrets podem ser criados de forma independente de Pods que os utilizam,
há menos
risco de um Secret ser exposto durante o fluxo de trabalho de criação,
visualização, e edição
de Pods. O sistema pode também tomar precauções adicionais
com Secrets, como por
exemplo evitar que sejam escritos em disco quando possível.

Um Secret só é enviado para um nó se um Pod naquele nó requerê-lo. O kubelet


armazena o
Secret num sistema de arquivos tmpfs , de forma a evitar que o Secret
seja escrito em
armazenamento persistente. Uma vez que o Pod que depende do
Secret é removido, o
kubelet apaga sua cópia local do Secret também.

Secrets de vários Pods diferentes podem existir no mesmo nó. No entanto, somente
os
Secrets que um Pod requerer estão potencialmente visíveis em seus contêineres.
Portanto,
um Pod não tem acesso aos Secrets de outro Pod.

Um Pod pode conter vários contêineres. Porém, cada contêiner em um Pod precisa
requerer
o volume de Secret nos seus volumeMounts para que este fique visível
dentro do contêiner.
Esta característica pode ser utilizada para construir
partições de segurança ao nível do Pod.

Na maioria das distribuições do Kubernetes, a comunicação entre usuários e o


servidor da
API e entre servidor da API e os kubelets é protegida por SSL/TLS.
Secrets são protegidos
quando transmitidos através destes canais.

FEATURE STATE: Kubernetes v1.13 [beta]

Você pode habilitar encriptação em disco


em dados de Secret para evitar que estes sejam
armazenados em texto plano no
etcd.

Riscos
No servidor da API, os dados de Secret são armazenados no
etcd; portanto:
Administradores devem habilitar encriptação em disco para dados do cluster
(requer Kubernetes v1.13 ou posterior).

https://kubernetes.io/pt-br/docs/concepts/_print/ 105/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Administradores devem limitar o acesso ao etcd somente para usuários


administradores.
Administradores podem desejar apagar definitivamente ou destruir discos
previamente utilizados pelo etcd que não estiverem mais em uso.
Ao executar o etcd em um cluster, administradores devem garantir o uso de
SSL/TLS para conexões ponto-a-ponto do etcd.
Se você configurar um Secret utilizando um arquivo de manifesto (JSON ou
YAML) que
contém os dados do Secret codificados como base64, compartilhar
este arquivo ou
salvá-lo num sistema de controle de versão de código-fonte
compromete este Secret.
Codificação base64 não é um método de encriptação
e deve ser considerada idêntica a
texto plano.
Aplicações ainda precisam proteger o valor do Secret após lê-lo de um volume,
como
por exemplo não escrever seu valor em logs ou enviá-lo para um sistema
não-confiável.
Um usuário que consegue criar um Pod que utiliza um Secret também consegue
ler o
valor daquele Secret. Mesmo que o servidor da API possua políticas para
impedir que
aquele usuário leia o valor do Secret, o usuário poderia criar um
Pod que expõe o
Secret.

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/ 106/178
5/14/22, 11:16 AM Conceitos | Kubernetes

8.4 - Gerenciamento de recursos em


Pods e contêineres
Ao criar a especificação de um Pod, você pode
opcionalmente especificar quanto de cada
recurso um contêiner
precisa. Os recursos mais comuns a serem especificados são CPU e
memória (RAM);
há outros recursos que podem ser especificados.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 107/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Requerimentos de recursos e limites de Pod e


contêiner
Para cada contêiner, você pode especificar limites e requerimentos de recursos,
incluindo os
seguintes recursos:

spec.containers[].resources.limits.cpu

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.

Unidades de recursos no Kubernetes


Unidades de recurso de CPU
Limites e requerimentos de recursos de CPU são mensurados em unidades de cpu.
No
Kubernetes, uma unidade de CPU é equivalente a um núcleo físico de CPU,
ou um núcleo
virtual, dependendo se o nó é uma máquina física ou uma máquina
virtual rodando em uma
máquina física.

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.

Unidades de recurso de memória


Limites e requerimentos de memory são medidos em bytes. Você pode expressar
memória
como um número inteiro ou como um número de ponto fixo, utilizando um
destes sufixos de
quantidade:
E, P, T, G, M, k. Você também pode utilizar os equivalentes de potência de dois:

https://kubernetes.io/pt-br/docs/concepts/_print/ 108/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Ei, Pi, Ti, Gi, Mi, Ki. Por exemplo, as quantidades abaixo representam, a grosso
modo, o
mesmo valor:

128974848, 129e6, 129M, 128974848000m, 123Mi

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 ).

Exemplo de recursos de contêiner


O Pod seguinte tem dois contêineres. Ambos os contêineres têm um requerimento de
0,25
CPU e 64 MiB (ou 226 bytes) de memória. Cada contêiner tem um
limite de 0,5 CPU e 128 MiB
de memória. Você pode dizer que o Pod tem um
requerimento de 0,5 CPU e 128 MiB de
memória, e um limite de 1 CPU e 256 MiB de
memória.

---

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"

Como Pods com requerimentos de recursos


são agendados
Quando você cria um Pod, o escalonador do Kubernetes seleciona um nó para que o
Pod
rode. Cada nó possui uma capacidade máxima para cada um dos tipos de recurso:
a
quantidade de CPU e memória que o nó pode fornecer aos Pods. O escalonador
garante que,
para cada tipo de recurso, a soma dos requerimentos de recursos dos
contêineres
agendados seja menor que a capacidade do nó.
Note que, embora o consumo de memória
ou CPU real nos nós seja muito baixo, o
escalonador ainda irá se recusar a agendar um Pod
em um nó se a verificação de
capacidade falhar. Isso protege contra a falta de um recurso em
um nó quando o
consumo de recursos aumenta com o passar do tempo, como por exemplo
durante o
pico diário de requisições a um serviço.

https://kubernetes.io/pt-br/docs/concepts/_print/ 109/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Como o Kubernetes aplica requisições e


limites de recursos
Quando o kubelet inicia um contêiner como parte de um Pod, o kubelet envia as
requisições
e limites de memória e de CPU ao agente de execução de contêiner.

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.

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.

Monitorando utilização de recursos computacionais e de


memória
O kubelet relata a utilização de recursos de um Pod como parte do
status
do Pod.

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

Armazenamento efêmero local


FEATURE STATE: Kubernetes v1.10 [beta]

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 110/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Configurações para armazenamento local efêmero


O Kubernetes suporta duas formas de configuração para o armazenamento local
efêmero
em um nó:

Sistema de arquivos único Dois sistemas de arquivos

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.

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.

Configurando requerimentos e limites para armazenamento


local efêmero
Você pode especificar o recurso ephemeral-storage para gerenciar o
armazenamento local
efêmero. Cada contêiner de um Pod pode especificar um dos
valores abaixo, ou ambos:

https://kubernetes.io/pt-br/docs/concepts/_print/ 111/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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: {}

Como Pods com requerimentos de ephemeral-storage são


agendados
Quando você cria um Pod, o Kubernetes seleciona um nó para o Pod rodar. Cada nó
tem uma
quantidade máxima de armazenamento efêmero local que pode ser fornecida
aos Pods. Para
mais informações, consulte
Node Allocatable.

O escalonador garante que a soma dos requerimentos de recursos dos contêineres


agendados é menor que a capacidade do nó.

Gerenciamento do consumo do armazenamento efêmero


Se o kubelet estiver gerenciando armazenamento local efêmero como um recurso,
o kubelet
irá medir o consumo de armazenamento em:

https://kubernetes.io/pt-br/docs/concepts/_print/ 112/178
5/14/22, 11:16 AM Conceitos | Kubernetes

volumes emptyDir , com exceção dos volumes do tipo tmpfs

diretórios que armazenem logs a nível de nó


camadas de contêiner graváveis

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.

Veja as configurações suportadas


para armazenamento efêmero local.

O kubelet suporta formas diferentes de medir o uso de armazenamento dos Pods:

Varredura periódica Quota de projeto do sistema de arquivos

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.

A varredura mede quanto espaço está sendo utilizado.

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/ 113/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Gerenciando recursos estendidos

Recursos estendidos a nível de nó


Recursos estendidos a nível de nó são recursos ligados ao nó.

Recursos gerenciados por dispositivos conectados


Veja Device Plugin
para mais informações sobre como anunciar recursos gerenciados por
dispositivos
conectados em cada nó.

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 .

curl --header "Content-Type: application/json-patch+json" \

--request PATCH \

--data '[{"op": "add", "path": "/status/capacity/example.com~1foo", "value": "5


http://k8s-master:8080/api/v1/nodes/k8s-node-1/status

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.

Recursos estendidos a nível de cluster


Recursos estendidos a nível de cluster não são vinculados aos nós. Estes
recursos são
normalmente gerenciados por extensões do escalonador, que manipulam
o consumo e as
quotas de recursos.

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/ 114/178
5/14/22, 11:16 AM Conceitos | Kubernetes

"kind": "Policy",

"apiVersion": "v1",

"extenders": [

{
"urlPrefix":"<extender-endpoint>",

"bindVerb": "bind",
"managedResources": [

"name": "example.com/foo",

"ignoredByScheduler": true

}
]

Consumindo recursos estendidos


Usuários podem consumir recursos estendidos em especificações de Pods como CPU
e
memória. O escalonador controla a contagem de recursos de modo que a
quantidade
alocada simultaneamente a Pods não seja maior que a quantidade
disponível.

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:

O Pod abaixo requisita duas CPUs e um "example.com/foo" (um recurso estendido).

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/ 115/178
5/14/22, 11:16 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:

kubectl describe pod frontend | grep -A 9999999999 Events

Events:

Type Reason Age From Message

---- ------ ---- ---- -------

Warning FailedScheduling 23s default-scheduler 0/42 nodes available: insuf

No exemplo acima, o Pod de nome "frontend" não pôde ser agendado devido à nenhum

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:

Adicione mais nós ao cluster.


Encerre Pods desnecessários para liberar espaço para Pods pendentes.
Verifique se o Pod não é maior que todos os nós. Por exemplo, se todos os nós
têm uma
capacidade de cpu: 1 , um Pod que requisita cpu: 1.1 nunca será
agendado.
Verifique se os nós não possuem taints. Se a maioria dos seus nós possuem
taints, e o
novo Pod não tolera tal taint, o escalonador somente considera
agendar o Pod nos nós
que não possuem aquele taint.

Você pode verificar capacidades de nós e quantidades alocadas com o comando


kubectl
describe nodes . Por exemplo:

kubectl describe nodes e2e-test-node-pool-4lw4

https://kubernetes.io/pt-br/docs/concepts/_print/ 116/178
5/14/22, 11:16 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 Me


--------- ---- ------------ ---------- --
kube-system fluentd-gcp-v1.38-28bv1 100m (5%) 0 (0%) 20
kube-system kube-dns-3297075139-61lj3 260m (13%) 0 (0%) 10
kube-system kube-proxy-e2e-test-... 100m (5%) 0 (0%) 0
kube-system monitoring-influxdb-grafana-v4-z1m12 200m (10%) 200m (10%) 60
kube-system node-problem-detector-v0.1-fj7m3 20m (1%) 200m (10%) 20
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 .

Meu contêiner foi terminado


Seu contêiner pode ser terminado se faltar recursos para que este rode. Para
verificar se um
contêiner está sendo terminado por chegar no limite de algum
recurso, utilize o comando
kubectl describe pod no Pod em questão:

kubectl describe pod simmemleak-hra99

A saída será semelhante a:

https://kubernetes.io/pt-br/docs/concepts/_print/ 117/178
5/14/22, 11:16 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-hr


Normal Pulled 41s kubelet Container image "saadali/simmemleak
Normal Created 41s kubelet Created container simmemleak

Normal Started 40s kubelet Started container simmemleak

Normal Killing 32s kubelet Killing container with id ead3fb35-

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/ 118/178
5/14/22, 11:16 AM Conceitos | Kubernetes

8.5 - Organizando o acesso ao cluster


usando arquivos kubeconfig
Utilize arquivos kubeconfig para organizar informações sobre clusters, usuários, namespaces
e mecanismos de autenticação. A ferramenta de linha de comando kubectl faz uso dos
arquivos kubeconfig para encontrar as informações necessárias para escolher e se comunicar
com o serviço de API de um cluster.

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.

Suportando múltiplos clusters, usuários e


mecanismos de autenticação
Imagine que você possua inúmeros clusters, e seus usuários e componentes se autenticam
de várias formas. Por exemplo:

Um kubelet ativo pode se autenticar utilizando certificados


Um usuário pode se autenticar através de tokens
Administradores podem possuir conjuntos de certificados os quais provém acesso aos
usuários de forma individual.

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.

Para escolher o contexto atual:

kubectl config use-context

A variável de ambiente KUBECONFIG


A variável de ambiente KUBECONFIG possui uma lista dos arquivos kubeconfig. Para Linux e
Mac, esta lista é delimitada por vírgula. No Windows, a lista é delimitada por ponto e vírgula.
A variável de ambiente KUBECONFIG não é um requisito obrigatório - caso ela não exista o
kubectl utilizará o arquivo kubeconfig padrão localizado no caminho $HOME/.kube/config .

https://kubernetes.io/pt-br/docs/concepts/_print/ 119/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 .

Combinando arquivos kubeconfig


Para inspecionar a sua configuração atual, execute o seguinte comando:

kubectl config view

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:

Ignorar arquivos vazios.


Produzir erros para aquivos cujo conteúdo não for possível desserializar.
O primeiro arquivo que definir um valor ou mapear uma chave determinada, será
o escolhido.
Nunca modificar um valor ou mapear uma chave.
Exemplo: Preservar o contexto
do primeiro arquivo que definir current-context .
Exemplo: Se dois arquivos
especificarem um red-user , use apenas os valores do primeiro red-user .
Mesmo se um segundo arquivo possuir entradas não conflitantes sobre a mesma
entrada red-user , estas deverão ser descartadas.
Para um exemplo de definição da variável de ambiente KUBECONFIG veja Definido a
variável de ambiente KUBECONFIG.

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:

1. Usar o conteúdo da flag --context caso ela existir.


2. Usar o current-context a partir da combinação dos arquivos kubeconfig.
Um contexto vazio é permitido neste momento.

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.

1. Utilizar a flag caso ela existir: --user ou --cluster .


2. Se o contexto não estiver vazio, utilizar o cluster ou usuário deste contexto.
O usuário e o cluster poderão estar vazios neste ponto.

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:

1. Usar as flags de linha de comando caso existirem: --server , --certificate-


authority , --insecure-skip-tls-verify .

https://kubernetes.io/pt-br/docs/concepts/_print/ 120/178
5/14/22, 11:16 AM Conceitos | Kubernetes

2. Se algum atributo do cluster existir a partir da combinação de kubeconfigs, estes


deverão ser utilizados.
3. Se não existir informação de localização do servidor falhar.
5. Determinar a informação atual de usuário a ser utilizada. Construir a informação de
usuário utilizando as mesmas regras utilizadas para o caso de informações de cluster,
exceto para a regra de técnica de autenticação que deverá ser única por usuário:

1. Usar as flags, caso existirem: --client-certificate , --client-key , --username ,


--password , --token .

2. Usar os campos user resultado da combinação de arquivos kubeconfig.


3. Se existirem duas técnicas conflitantes, falhar.
6. Para qualquer informação que ainda estiver ausente, utilizar os valores padrão e
potencialmente solicitar informações de autenticação a partir do prompt de comando.

Referências de arquivos
Arquivos e caminhos referenciados em um arquivo kubeconfig são relativos à localização do
arquivo kubeconfig.

Referências de arquivos na linha de comando são relativas ao diretório de trabalho vigente.

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/ 121/178
5/14/22, 11:16 AM Conceitos | Kubernetes

9 - Segurança
9.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.

Os 4C da Segurança Cloud Native


Você pode pensar na segurança em camadas. Os 4C da segurança Cloud Native são a Cloud,
Clusters, Contêineres e Código.

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.

Os 4C da Segurança Cloud Native

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.

Segurança no provedor da Cloud


https://kubernetes.io/pt-br/docs/concepts/_print/ 122/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Se você estiver executando um cluster Kubernetes em seu próprio hardware ou em um


provedor de nuvem diferente,
consulte sua documentação para melhores práticas de
segurança.
Aqui estão os links para as documentações de segurança dos provedores mais
populares de nuvem:

Provedor IaaS Link

Alibaba Cloud https://www.alibabacloud.com/trust-center

Amazon Web Services https://aws.amazon.com/security/

Google Cloud Platform https://cloud.google.com/security/

IBM Cloud https://www.ibm.com/cloud/security

Microsoft Azure https://docs.microsoft.com/en-us/azure/security/azure-


security

Oracle Cloud https://www.oracle.com/security/


Infrastructure

VMWare VSphere https://www.vmware.com/security/hardening-guides.html

Segurança de Infraestrutura
Sugestões para proteger sua infraestrutura em um cluster Kubernetes:

Área de
Interesse para
Infraestrutura
Kubernetes Recomendação

Acesso de rede Todo o acesso ao control plane do Kubernetes publicamente na


ao servidor API Internet não é permitido e é controlado por listas de controle de acesso
(Control plane) à rede restritas ao conjunto de endereços IP necessários para
administrar o cluster.

Acesso de rede Os nós devem ser configurados para só aceitar conexões (por meio de
aos Nós listas de controle de acesso à rede) do control plane nas portas
(nodes) 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 Cada provedor de nuvem precisa conceder um conjunto diferente de


Kubernetes à permissões para o control plane e nós do Kubernetes. É melhor
API do fornecer ao cluster permissão de acesso ao provedor de nuvem que
provedor de segue o princípio do menor privilégio para os recursos que ele precisa
Cloud 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 Sempre que possível, é uma boa prática encriptar todas as unidades de
etcd armazenamento, mas como o etcd mantém o estado de todo o cluster
(incluindo os Secrets), seu disco deve ser criptografado.

https://kubernetes.io/pt-br/docs/concepts/_print/ 123/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Cluster
Existem duas áreas de preocupação para proteger o Kubernetes:

Protegendo os componentes do cluster que são configuráveis.


Protegendo as aplicações que correm no cluster.

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.

Componentes no cluster (sua aplicação)


Dependendo da superfície de ataque de sua aplicação, você pode querer se concentrar em
tópicos específicos de segurança. Por exemplo: se você estiver executando um serviço
(Serviço A) que é crítico
numa cadeia de outros recursos e outra carga de trabalho separada
(Serviço B) que é
vulnerável a um ataque de exaustão de recursos e, por consequência, o
risco de comprometer o Serviço A
é alto se você não limitar os recursos do Serviço B. A tabela
a seguir lista
áreas de atenção na segurança e recomendações para proteger cargas de
trabalho em execução no Kubernetes:

Área de interesse para a segurança do


Workload Recomendação

Autorização RBAC (acesso à API Kubernetes) https://kubernetes.io/docs/reference/acce


ss-authn-authz/rbac/

Autenticação https://kubernetes.io/docs/concepts/securi
ty/controlling-access/

Gerenciamento de segredos na aplicação (e https://kubernetes.io/docs/concepts/confi


encriptando-os no etcd em repouso) guration/secret/
https://kubernetes.io/docs/tasks/administ
er-cluster/encrypt-data/

Políticas de segurança do Pod https://kubernetes.io/docs/concepts/policy


/pod-security-policy/

Qualidade de serviço (e gerenciamento de https://kubernetes.io/docs/tasks/configure


recursos de cluster) -pod-container/quality-service-pod/

Políticas de Rede https://kubernetes.io/docs/concepts/servic


es-networking/network-policies/

TLS para Kubernetes Ingress https://kubernetes.io/docs/concepts/servic


es-networking/ingress/#tls

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:

Área de Interesse
para Contêineres Recomendação

https://kubernetes.io/pt-br/docs/concepts/_print/ 124/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Área de Interesse
para Contêineres Recomendação

Scanners de Como parte da etapa de construção de imagem, você deve usar


Vulnerabilidade de algum scanner em seus contêineres em busca de
Contêiner e Segurança vulnerabilidades.
de Dependência de SO

Assinatura Imagem e Assinatura de imagens de contêineres para manter um sistema


Enforcement de confiança para o conteúdo de seus contêineres.

Proibir Usuários Ao construir contêineres, consulte a documentação para criar


Privilegiados 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 Selecione classes de contêiner runtime com o provedor de


Runtime com 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:

Segurança de código
Área de
Atenção
para o
Código Recomendação

Acesso Se seu código precisar se comunicar por TCP, execute um handshake TLS com
só o cliente antecipadamente. Com exceção de alguns casos, encripte tudo em
através trânsito. Indo um passo adiante, é uma boa ideia encriptar o tráfego de rede
de TLS 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.

Limitand Essa recomendação pode ser um pouco autoexplicativa, mas, sempre que
o possível, você só deve expor as portas em seu serviço que são absolutamente
intervalo essenciais para a comunicação ou coleta de métricas.
s de
porta de
comunic
ação

Seguran É uma boa prática verificar regularmente as bibliotecas de terceiros de sua


ça na aplicação em busca de vulnerabilidades de segurança. Cada linguagem de
Depend programação possui uma ferramenta para realizar essa verificação
ência de automaticamente.
Terceiro
s

https://kubernetes.io/pt-br/docs/concepts/_print/ 125/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Área de
Atenção
para o
Código Recomendação

Análise A maioria das linguagens fornece uma maneira para analisar um extrato do
de código referente a quaisquer práticas de codificação potencialmente
Código inseguras. Sempre que possível, você deve automatizar verificações usando
Estático 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 Existem algumas ferramentas automatizadas que você pode executar contra
de seu serviço para tentar alguns dos ataques mais conhecidos. Isso inclui
sondage injeção de SQL, CSRF e XSS. Uma das ferramentas de análise dinâmica mais
m populares é o OWASP Zed Attack proxy.
dinâmic
a

Próximos passos
Saiba mais sobre os tópicos de segurança do Kubernetes:

Padrões de segurança do Pod


Políticas de rede para Pods
Controle de acesso à API Kubernetes
Protegendo seu cluster
Criptografia de dados em trânsito for the control plane
Criptografia de dados em repouso
Secrets no Kubernetes
Runtime class

https://kubernetes.io/pt-br/docs/concepts/_print/ 126/178
5/14/22, 11:16 AM Conceitos | Kubernetes

10 - Escalonamento
No Kubernetes, agendamento refere-se a garantia de que os pods
correspondam aos nós para que o kubelet possa executá-los. Remoção é o
processo de falha proativa de um ou mais pods em nós com falta de
recursos.

10.1 - Taints e Tolerâncias


Afinidade de nó
é uma propriedade dos Pods que os associa a um conjunto de nós (seja como
uma preferência ou uma exigência). Taints são o oposto -- eles permitem que um nó repudie
um conjunto de pods.

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,

kubectl taint nodes node1 key1=value1:NoSchedule

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:

kubectl taint nodes node1 key1=value1:NoSchedule-

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"

Aqui está um exemplo de um pod que utiliza tolerâncias:

pods/pod-with-toleration.yaml

https://kubernetes.io/pt-br/docs/concepts/_print/ 127/178
5/14/22, 11:16 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 padrão de operator é Equal .

Uma tolerância "casa" um taint se as chaves e efeitos são os mesmos, e:

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.

Um effect vazio "casa" todos os efeitos com a chave key1 .

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).

Por exemplo, imagine que você tem um nó com os seguintes taints

kubectl taint nodes node1 key1=value1:NoSchedule

kubectl taint nodes node1 key1=value1:NoExecute

kubectl taint nodes node1 key2=value2:NoSchedule

https://kubernetes.io/pt-br/docs/concepts/_print/ 128/178
5/14/22, 11:16 AM Conceitos | Kubernetes

E um pod com duas tolerâncias:

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.

Exemplos de Casos de Uso


Taints e tolerâncias são um modo flexível de conduzir pods para fora dos nós ou expulsar
pods que não deveriam estar sendo executados. Alguns casos de uso são

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 129/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Expulsões baseadas em Taint


FEATURE STATE: Kubernetes v1.18 [stable]

O efeito de taint NoExecute , mencionado acima, afeta pods que já estão rodando no nó da
seguinte forma

pods que não toleram o taint são expulsos imediatamente


pods que toleram o taint sem especificar tolerationSeconds em sua especificação de
tolerância, ficam alocados para sempre
pods que toleram o taint com um tolerationSeconds especificado, permanecem
alocados pela quantidade de tempo definida

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 ".
: Nó é inalcançável a partir do controlador de nó. Isso
node.kubernetes.io/unreachable
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:

https://kubernetes.io/pt-br/docs/concepts/_print/ 130/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Taints por condições de nó


A camada de gerenciamento, usando o controlador do nó, cria taints automaticamente com o
efeito NoSchedule para condições de nó.

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

node.kubernetes.io/pid-pressure (1.14 ou superior)


node.kubernetes.io/unschedulable (1.10 ou superior)
node.kubernetes.io/network-unavailable (somente rede do host)

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
https://kubernetes.io/pt-br/docs/concepts/_print/ 131/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Leia sobre Pod Priority

https://kubernetes.io/pt-br/docs/concepts/_print/ 132/178
5/14/22, 11:16 AM Conceitos | Kubernetes

10.2 - Escalonador do Kubernetes


No Kubernetes, escalonamento refere-se a garantir que os Pods
sejam correspondidos aos
Nodes para que o
Kubelet possa executá-los.

Visão geral do Escalonamento


Um escalonador observa Pods recém-criados que não possuem um Node atribuído.
Para
cada Pod que o escalonador descobre, ele se torna responsável por
encontrar o melhor Node
para execução do Pod. O escalonador chega a essa decisão de alocação levando em
consideração os princípios de programação descritos abaixo.

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.

Seleção do Node no kube-scheduler


O kube-scheduler seleciona um Node para o Pod em uma operação que consiste em duas
etapas:

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 133/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Existem duas maneiras suportadas de configurar o comportamento de filtragem e pontuação


do escalonador:

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.

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/ 134/178
5/14/22, 11:16 AM Conceitos | Kubernetes

10.3 - Sobrecarga de Pod


FEATURE STATE: Kubernetes v1.18 [beta]

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.

Habilitando a Sobrecarga de Pod


Terá de garantir que o Feature Gate PodOverhead esteja ativo (está ativo por padrão a partir
da versão 1.18)
em todo o cluster, e uma RuntimeClass utilizada que defina o campo
overhead .

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.

Considere executar a seguinte carga de trabalho de exemplo, test-pod:

apiVersion: v1

kind: Pod

metadata:

name: test-pod

spec:

runtimeClassName: kata-fc

containers:

- name: busybox-ctr

image: busybox

stdin: true

tty: true

resources:

https://kubernetes.io/pt-br/docs/concepts/_print/ 135/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 .

Depois do controlador de admissão RuntimeClass, pode verificar o PodSpec atualizado:

kubectl get pod test-pod -o jsonpath='{.spec.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:

kubectl get pod test-pod -o jsonpath='{.spec.containers[*].resources.limits}'

O total de requisições ao contêiner são 2000m CPU e 200MiB de memória:

map[cpu: 500m memory:100Mi] map[cpu:1500m memory:100Mi]

Verifique isto comparado ao que é observado pelo nó:

kubectl describe node | grep test-pod -B2

https://kubernetes.io/pt-br/docs/concepts/_print/ 136/178
5/14/22, 11:16 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 Memo


--------- ---- ------------ ---------- ----
default test-pod 2250m (56%) 2250m (56%) 320M

Verificar os limites cgroup do Pod


Verifique os cgroups de memória do Pod no nó onde a carga de trabalho está em execução.
No seguinte exemplo, crictl
é usado no nó, que fornece uma CLI para agentes de execução
compatíveis com CRI. Isto é um
exemplo avançado para mostrar o comportamento do
PodOverhead, e não é esperado que os usuários precisem verificar
cgroups diretamente no
nó.

Primeiro, no nó em particular, determine o identificador do Pod:

# Execute no nó onde o Pod está agendado

POD_ID="$(sudo crictl pods --name test-pod -q)"

A partir disto, pode determinar o caminho do cgroup para o Pod:

# Execute no nó onde o Pod está agendado

sudo crictl inspectp -o=json $POD_ID | grep cgroupsPath

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/7ccf55a

Neste caso especifico, o caminho do cgroup do Pod é kubepods/podd7f4b509-cf94-4951-9417-


d1087c92a5b2 . Verifique a configuração cgroup de nível do Pod para a memória:

# Execute no nó onde o Pod está agendado

# Mude também o nome do cgroup para combinar com o cgroup alocado ao Pod.

cat /sys/fs/cgroup/memory/kubepods/podd7f4b509-cf94-4951-9417-d1087c92a5b2/memor

Isto é 320 MiB, como esperado:

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/ 137/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Próximos passos
RuntimeClass
PodOverhead Design

https://kubernetes.io/pt-br/docs/concepts/_print/ 138/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11 - 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.

Antes de escolher um guia, aqui estão algumas considerações:

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.

Autenticação explica a autenticação no Kubernetes, incluindo as várias opções de


autenticação.

Autorização é separado da autenticação e controla como as chamadas HTTP são


tratadas.
https://kubernetes.io/pt-br/docs/concepts/_print/ 139/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Auditoria descreve como interagir com logs de auditoria do Kubernetes.

Protegendo o kubelet
Comunicação Control Plane-Nó
TLS bootstrapping
Autenticação/autorização do kubelet

Serviços Opcionais para o Cluster


Integração com DNS descreve como resolver um nome DNS diretamente para um
serviço Kubernetes.

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/ 140/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.1 - Visão Geral da Administração de


Cluster
A visão geral da administração de cluster é para qualquer um criando ou administrando um
cluster Kubernetes. Assume-se que você tenha alguma familiaridade com os conceitos
centrais do 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.

Antes de escolher um guia, aqui estão algumas considerações.

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.

Familiarize-se com os componentes necessários para rodar um cluster.

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.

Aprender como gerenciar um nó.

Aprender como configurar e gerenciar o recurso de quota para um cluster


compartilhado.

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 141/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Controlando Acesso a API Kubernetes API descreve como configurar


a permissão para
usuários e contas de serviço.

Autenticando explica a autenticação no Kubernetes, incluindo as várias opções de


autenticação.

Autorização é separada da autenticação e controla como as chamadas HTTP são


tratadas.

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.

Auditando
descreve como interagir com os logs de auditoria do Kubernetes.

Protegendo o kubelet
Comunicação Master-Node
TLS bootstrapping
Autenticação/Autorização Kubelet

Serviços Opcionais do Cluster


Integração DNS descreve como resolver um nome DNS diretamente para um serviço do
Kubernetes.

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/ 142/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.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.

1. Baixe, descompacte e inicialize a versão corrigida do easyrsa3.

curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa


tar xzf easy-rsa.tar.gz

cd easy-rsa-master/easyrsa3

./easyrsa init-pki

2. Gerar o CA. ( --batch set automatic mode. --req-cn default CN to use.)

./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass

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

4. Copie pki/ca.crt , pki/issued/server.crt ,e pki/private/server.key para o seu


diretório.

5. Preencha e adicione os seguintes parâmetros aos parâmetros de inicialização do


servidor de API:

--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.

1. Gere um ca.key com 2048bit:

openssl genrsa -out ca.key 2048

2. De acordo com o ca.key, gere um ca.crt (use -days para definir o tempo efetivo do
certificado):

https://kubernetes.io/pt-br/docs/concepts/_print/ 143/178
5/14/22, 11:16 AM Conceitos | Kubernetes

openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 100

3. Gere um server.key com 2048bit:

openssl genrsa -out server.key 2048

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

5. Gere a solicitação de assinatura de certificado com base no arquivo de configuração:

openssl req -new -key server.key -out server.csr -config csr.conf

6. Gere o certificado do servidor usando o ca.key, ca.crt e server.csr:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \

-CAcreateserial -out server.crt -days 10000 \

-extensions v3_ext -extfile csr.conf

7. Veja o certificado:

openssl x509 -noout -text -in ./server.crt

https://kubernetes.io/pt-br/docs/concepts/_print/ 144/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o cfssl

chmod +x cfssl

curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o cfssljson

chmod +x cfssljson

curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o cfssl-certin


chmod +x cfssl-certinfo

2. Crie um diretório para conter os artefatos e inicializar o cfssl:

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 145/178
5/14/22, 11:16 AM Conceitos | Kubernetes

"CN": "kubernetes",

"key": {
"algo": "rsa",

"size": 2048

},

"names":[{

"C": "<country>",

"ST": "<state>",

"L": "<city>",

"O": "<organization>",

"OU": "<organization unit>"

}]

5. Gere a chave CA ( ca-key.pem ) e o certificado ( ca.pem ):

../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca

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

"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:

../cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \

--config=ca-config.json -profile=kubernetes \

server-csr.json | ../cfssljson -bare server

Distribuindo Certificado CA auto assinado

https://kubernetes.io/pt-br/docs/concepts/_print/ 146/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Um nó cliente pode se recusar a reconhecer o certificado CA self-signed como válido.


Para
uma implementação de não produção ou para uma instalação que roda atrás de um firewall,
você pode distribuir certificados auto-assinados para todos os clientes e atualizar a lista de
certificados válidos.

Em cada cliente, execute as seguintes operações:

sudo cp ca.crt /usr/local/share/ca-certificates/kubernetes.crt

sudo update-ca-certificates

Updating certificates in /etc/ssl/certs...

1 added, 0 removed; done.

Running hooks in /etc/ca-certificates/update.d....

done.

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/ 147/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.3 - Conectividade do Cluster


Conectividade é uma parte central do Kubernetes, mas pode ser desafiador
entender
exatamente como é o seu funcionamento esperado. Existem 4 problemas
distintos em
conectividade que devem ser tratados:

1. Comunicações contêiner-para-contêiner altamente acopladas: Isso é resolvido


por Pods
e comunicações através do localhost .
2. Comunicações pod-para-pod: Esse é o foco primário desse documento.
3. Comunicações pod-para-serviço (service): Isso é tratado em Services.
4. Comunicações Externas-para-serviços: Isso é tratado em services.

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 modelo de conectividade e rede do


Kubernetes
Todo Pod obtém seu próprio endereço IP. Isso significa que vocë não precisa
criar links
explícitos entre os Pods e vocë quase nunca terá que lidar com o
mapeamento de portas de
contêineres para portas do host. Isso cria um modelo simples,
retro-compatível onde os
Pods podem ser tratados muito mais como VMs ou hosts
físicos da perspectiva de alocação
de portas, nomes, descobrimento de serviços
(service discovery), balanceamento de carga,
configuração de aplicações e migrações.

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".

Como isso é implementado é um detalhe do agente de execução de contêiner em uso.

https://kubernetes.io/pt-br/docs/concepts/_print/ 148/178
5/14/22, 11:16 AM Conceitos | Kubernetes

É 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.

Como implementar o modelo de


conectividade do Kubernetes
Existe um número de formas de implementar esse modelo de conectividade. Esse
documento não é um estudo exaustivo desses vários métodos, mas pode servir como
uma
introdução de várias tecnologias e serve como um ponto de início.

A conectividade no Kubernetes é fornecida através de plugins de


CNIs

As seguintes opções estão organizadas alfabeticamente e não implicam preferência por


qualquer solução.

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.

AWS VPC CNI para Kubernetes


O AWS VPC CNI oferece conectividade
com o AWS Virtual Private Cloud (VPC) para clusters
Kubernetes. Esse plugin oferece
alta performance e disponibilidade e baixa latência.
Adicionalmente, usuários podem
aplicar as melhores práticas de conectividade e segurança
existentes no AWS VPC
para a construção de clusters Kubernetes. Isso inclui possibilidade de
usar o
VPC flow logs, políticas de roteamento da VPC e grupos de segurança para isolamento
de tráfego.

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.

Azure CNI para o Kubernetes


Azure CNI é um
plugin de código fonte aberto
que integra os Pods do Kubernetes com uma
rede virtual da Azure (também conhecida como VNet)
provendo performance de rede similar
à de máquinas virtuais no ambiente. Os Pods
podem se comunicar com outras VNets e com
ambientes on-premises com o uso de
funcionalidades da Azure, e também podem ter clientes
com origem dessas redes.
Os Pods podem acessar serviços da Azure, como armazenamento
https://kubernetes.io/pt-br/docs/concepts/_print/ 149/178
5/14/22, 11:16 AM Conceitos | Kubernetes

e SQL, que são


protegidos por Service Endpoints e Private Link. Você pode utilizar as políticas
de segurança e roteamento para filtrar o tráfico do Pod. O plugin associa IPs da VNet
para os
Pods utilizando um pool de IPs secundário pré-configurado na interface de rede
do nó
Kubernetes.

O Azure CNI está disponível nativamente no Azure Kubernetes Service (AKS).

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.

Google Compute Engine (GCE)


Para os scripts de configuração do Google Compute Engine, roteamento
avançado é usado
para associar
para cada VM uma sub-rede (o padrão é /24 - 254 IPs). Qualquer tráfico
direcionado
para aquela sub-rede será roteado diretamente para a VM pela rede do GCE. Isso
é
adicional ao IP principal associado à VM, que é mascarado para o acesso à Internet.
Uma
brige Linux (chamada cbr0 ) é configurada para existir naquela sub-rede, e é
configurada no
docker através da opção --bridge .

O Docker é iniciado com:

DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"

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):

iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE

Por fim, o encaminhamento de IP deve ser habilitado no Kernel de forma a processar


os
pacotes vindos dos contêineres:

https://kubernetes.io/pt-br/docs/concepts/_print/ 150/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Redes L2 e bridges Linux


Se você tem uma rede L2 "burra", como um switch em um ambiente "bare-metal",
você deve
conseguir fazer algo similar ao ambiente GCE explicado acima.
Note que essas instruções
foram testadas casualmente - parece funcionar, mas
não foi propriamente testado. Se você
conseguir usar essa técnica e aperfeiçoar
o processo, por favor nos avise!!

Siga a parte "With Linux Bridge devices" desse


tutorial super bacana do
Lars Kellogg-Stedman.

Multus (Plugin multi redes)


Multus é um plugin Multi CNI para
suportar a funcionalidade multi redes do Kubernetes
usando objetos baseados em CRDs.

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.

OVN (Open Virtual Networking)


OVN é uma solução de virtualização de redes de código aberto desenvolvido pela
comunidade Open vSwitch. Permite a criação de switches lógicos, roteadores lógicos,
listas de
acesso, balanceadores de carga e mais, para construir diferences topologias
de redes virtuais.
Esse projeto possui um plugin específico para o Kubernetes e a
documentação em ovn-
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/ 151/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.4 - Arquitetura de Log


Os logs de aplicativos e sistemas podem ajudá-lo a entender o que está acontecendo dentro
do seu cluster. Os logs são particularmente úteis para depurar problemas e monitorar a
atividade do cluster. A maioria das aplicações modernas possui algum tipo de mecanismo de
logs; como tal, a maioria dos mecanismos de contêineres também é projetada para suportar
algum tipo de log. O método de log mais fácil e abrangente para aplicações em contêiner é
gravar nos fluxos de saída e erro padrão.

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.

Log básico no Kubernentes


Nesta seção, você pode ver um exemplo de log básico no Kubernetes que gera dados para o
fluxo de saída padrão(standard output stream). Esta demostração usa uma especificação de
pod com um contêiner que grava algum texto na saída padrão uma vez por segundo.

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']

Para executar este pod, use o seguinte comando:

kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml

A saída será:

pod/counter created

Para buscar os logs, use o comando kubectl logs , da seguinte maneira:

kubectl logs counter

https://kubernetes.io/pt-br/docs/concepts/_print/ 152/178
5/14/22, 11:16 AM Conceitos | Kubernetes

A saída será:

0: Mon Jan 1 00:00:00 UTC 2001

1: Mon Jan 1 00:00:01 UTC 2001

2: Mon Jan 1 00:00:02 UTC 2001

...

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 153/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Logs de componentes do sistema


Existem dois tipos de componentes do sistema: aqueles que são executados em um
contêiner e aqueles que não são executados em um contêiner. Por exemplo:

O scheduler Kubernetes e o kube-proxy são executados em um contêiner.


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.

Arquiteturas de log no nível de cluster


Embora o Kubernetes não forneça uma solução nativa para o log em nível de cluster, há
várias abordagens comuns que você pode considerar. Aqui estão algumas opções:

Use um agente de log no nível do nó que seja executado em todos os nós.


Inclua um contêiner sidecar dedicado para efetuar logging em um pod de aplicativo.
Envie logs diretamente para um back-end de dentro de um aplicativo.

Usando um agente de log de nó

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 154/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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ó.

Usando um contêiner sidecar com o agente de log


Você pode usar um contêiner sidecar de uma das seguintes maneiras:

O container sidecar transmite os logs do aplicativo para seu próprio stdout .


O contêiner do sidecar executa um agente de log, configurado para selecionar logs de
um contêiner de aplicativo.

Streaming sidecar conteiner

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 155/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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: {}

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
https://kubernetes.io/pt-br/docs/concepts/_print/ 156/178
5/14/22, 11:16 AM Conceitos | Kubernetes

volumes:

- name: varlog

emptyDir: {}

Agora, quando você executa este pod, é possível acessar cada fluxo de log separadamente,
executando os seguintes comandos:

kubectl logs counter count-log-1

0: Mon Jan 1 00:00:00 UTC 2001

1: Mon Jan 1 00:00:01 UTC 2001

2: Mon Jan 1 00:00:02 UTC 2001

...

kubectl logs counter count-log-2

Mon Jan 1 00:00:00 UTC 2001 INFO 0

Mon Jan 1 00:00:01 UTC 2001 INFO 1

Mon Jan 1 00:00:02 UTC 2001 INFO 2

...

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.

Contêiner sidecar com um agente de log

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 157/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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

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

apiVersion: v1

kind: Pod

metadata:

name: counter

spec:

containers:

- name: count

image: busybox

args:

- /bin/sh

- -c

- >

i=0;
while true;

https://kubernetes.io/pt-br/docs/concepts/_print/ 158/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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: k8s.gcr.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.

Expondo logs diretamente do 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/ 159/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.5 - Logs de Sistema


Logs de componentes do sistema armazenam eventos que acontecem no cluster, sendo
muito úteis para depuração. Seus níveis de detalhe podem ser ajustados para mais ou para
menos. Podendo se ater, por exemplo, a mostrar apenas os erros que ocorrem no
componente, ou chegando a mostrar cada passo de um evento. (Como acessos HTTP,
mudanças no estado dos pods, ações dos controllers, ou decisões do scheduler).

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.

Um exemplo do formato padrão dos logs da biblioteca:

I1025 00:15:15.525108 1 httplog.go:79] GET /api/v1/namespaces/kube-system/p

Logs Estruturados
FEATURE STATE: 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 formatação e serialização dos logs ainda estão sujeitas a alterações.

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.

Formato dos logs estruturados:

<klog header> "<message>" <key1>="<value1>" <key2>="<value2>" ...

Exemplo:

I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="

Logs em formato JSON


FEATURE STATE: Kubernetes v1.19 [alpha]

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 160/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

O nome dos campos e a serialização JSON ainda estão sujeitos a mudanças.

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"
}

Chaves com significados especiais:

ts - Data e hora no formato Unix (obrigatório, float)


v - Nível de detalhe (obrigatório, int, padrão 0)
err - Mensagem de erro (opcional, string)
msg - Mensagem (obrigatório, string)

Lista dos componentes que suportam o formato JSON atualmente:

kube-controller-manager
kube-apiserver
kube-scheduler
kubelet

Limpeza dos Logs


FEATURE STATE: Kubernetes v1.20 [alpha]

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.

Lista dos componentes que suportam a limpeza de logs atualmente:

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.

Nível de detalhe dos logs


https://kubernetes.io/pt-br/docs/concepts/_print/ 161/178
5/14/22, 11:16 AM Conceitos | Kubernetes

A opção -v controla o nível de detalhe dos logs. Um valor maior aumenta o número de
eventos registrados, começando a registrar também os eventos menos importantes.
Similarmente, um valor menor restringe os logs apenas aos eventos mais importantes. O
valor padrão 0 registra apenas eventos críticos.

Localização dos Logs


Existem dois tipos de componentes do sistema: aqueles que são executados em um
contêiner e aqueles que não são. Por exemplo:

O Kubernetes scheduler e o kube-proxy são executados em um contêiner.


O kubelet e os agentes de execução, como o Docker por exemplo, não são executados
em contêineres.

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/ 162/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.6 - Métricas para componentes do


sistema Kubernetes
Métricas dos componentes do sistema podem dar uma visão melhor do que acontece
internamente. Métricas são particularmente úteis para construir dashboards e alertas.

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 .

Exemplos desses componentes:

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

Ciclo de vida da métrica


Métrica alfa → Métrica estável → Métrica ultrapassada → Métrica oculta → Métrica excluída

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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 163/178
5/14/22, 11:16 AM Conceitos | Kubernetes

Por exemplo:

Antes de se tornar ultrapassado

# HELP some_counter isso conta coisas

# TYPE some_counter contador

some_counter 0

Depois de se tornar ultrapassado

# HELP some_counter (obsoleto desde 1.15.0) isso conta coisas

# TYPE some_counter contador

some_counter 0

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.

Mostrar métricas ocultas


Como descrito anteriormente, administradores podem habilitar métricas ocultas por meio de
uma flag de linha de comando em um binário específico. Isso pode ser usado como uma
saída de emergência para os administradores caso percam a migração das métricas
ultrapassadas na última versão.

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 .

Desativar métricas do accelerator


O kubelet coleta métricas do accelerator por meio do cAdvisor. Para coletar essas métricas,
para accelerator como as GPUs NVIDIA, o kubelet mantinha uma alça aberta no driver. Isso
significava que, para realizar alterações na infraestrutura (por exemplo, atualizar o driver), um
administrador do cluster precisa interromper o agente kubelet.

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).
https://kubernetes.io/pt-br/docs/concepts/_print/ 164/178
5/14/22, 11:16 AM Conceitos | Kubernetes

O DisableAcceleratorUsageMetrics feature gate desabilita as métricas coletadas pelo


kubelet, com uma timeline para habilitar esse recurso por padrão.

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.

Por exemplo, para o GCE as seguintes métricas são chamadas:

cloudprovider_gce_api_request_duration_seconds { request = "instance_list"}

cloudprovider_gce_api_request_duration_seconds { request = "disk_insert"}

cloudprovider_gce_api_request_duration_seconds { request = "disk_delete"}

cloudprovider_gce_api_request_duration_seconds { request = "attach_disk"}

cloudprovider_gce_api_request_duration_seconds { request = "detach_disk"}

cloudprovider_gce_api_request_duration_seconds { request = "list_disk"}

Métricas do kube-scheduler
FEATURE STATE: 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.

https://kubernetes.io/pt-br/docs/concepts/_print/ 165/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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 ).

Aplicação de cardinalidade de métrica


As métricas com dimensões sem limites podem causar problemas de memória nos
componentes que elas instrumentam. Para limitar a utilização de recursos você pode usar a
opção de linha de comando --allow-label-value para dinamicamente configurar uma lista
de permissões de valores de label para uma métrica.

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.

O formato geral se parece com:


--allow-label-value <metric_name>,
<label_name>='<allow_value1>, <allow_value2>...', <metric_name2>,
<label_name>='<allow_value1>, <allow_value2>...', ... .

Por exemplo:
--allow-label-value number_count_metric,odd_number='1,3,5',
number_count_metric,even_number='2,4,6', date_gauge_metric,weekend='Saturday,Sunday'

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/ 166/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.7 - Configurando o Garbage


Collection do kubelet
O Garbage collection(Coleta de lixo) é uma função útil do kubelet que limpa imagens e
contêineres não utilizados. O kubelet executará o garbage collection para contêineres a cada
minuto e para imagens a cada cinco minutos.

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.
https://kubernetes.io/pt-br/docs/concepts/_print/ 167/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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.

Descontinuado
Alguns recursos do Garbage Collection neste documento serão substituídos pelo kubelet
eviction no futuro.

Incluindo:

Flag Existente Nova Flag Fundamentação

--image-gc-high- --eviction-hard os sinais existentes de despejo podem


threshold ou --eviction- acionar o garbage collection da imagem
soft

--image-gc-low- --eviction- recuperações de despejo atinge o


threshold minimum-reclaim mesmo comportamento

--maximum-dead- descontinuado quando os logs antigos


containers forem armazenados fora do contexto
do contêiner

--maximum-dead- descontinuado quando os logs antigos


containers-per- forem armazenados fora do contexto
container do contêiner

--minimum- descontinuado quando os logs antigos


container-ttl- forem armazenados fora do contexto
duration do contêiner

--low-diskspace- --eviction-hard O despejo generaliza os limites do disco


threshold-mb ou eviction-soft para outros recursos

--outofdisk- --eviction- O despejo generaliza a transição da


transition- pressure- pressão do disco para outros recursos
frequency transition-
period

Próximos passos
Consulte Configurando a Manipulação de Recursos Insuficientes para mais detalhes.

https://kubernetes.io/pt-br/docs/concepts/_print/ 168/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.8 - Proxies no Kubernetes


Esta página descreve o uso de proxies com 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:

é um bastion server, construído no servidor de API


conecta um usuário fora do cluster com os IPs do cluster que não podem ser
acessados de outra forma
executa dentro do processo do servidor de API
cliente para proxy usa HTTPS (ou HTTP se o servidor de API for configurado)
proxy para o destino pode usar HTTP ou HTTPS conforme escolhido pelo proxy
usando as informações disponíveis
pode ser usado para acessar um Nó, Pod ou serviço
faz balanceamento de carga quando usado para acessar um Service.
2. O kube proxy:

executa em todos os Nós


atua como proxy para UDP, TCP e SCTP
não aceita HTTP
provém balanceamento de carga
apenas é usado para acessar serviços.
3. Um Proxy/Balanceador de carga na frente de servidores de API(s):

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/ 169/178
5/14/22, 11:16 AM Conceitos | Kubernetes

11.9 - Instalando Complementos


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.

Complementos estendem as funcionalidades do Kubernetes.

Esta página lista alguns dos complementos disponíveis e links com suas respectivas
instruções de instalação.

Rede e Política de Rede


ACI fornece rede integrada de contêineres e segurança de rede com a Cisco ACI.
Antrea opera nas camadas 3 e 4 do modelo de rede OSI para fornecer serviços de rede
e de segurança para o Kubernetes, aproveitando o Open vSwitch como camada de
dados de rede.
Calico é um provedor de serviços de rede e de políticas de rede. Este complemento
suporta um conjunto flexível de opções de rede, de modo a permitir a escolha da opção
mais eficiente para um dado caso de uso, incluindo redes overlay (sobrepostas) e não-
overlay, com ou sem o uso do protocolo BGP. Calico usa o mesmo mecanismo para
aplicar políticas de rede a hosts, pods, e aplicações na camada de service mesh (quando
Istio e Envoy estão instalados).
Canal une Flannel e Calico, fornecendo rede e política de rede.
Cilium é um plug-in de rede de camada 3 e de políticas de rede que pode aplicar
políticas HTTP/API/camada 7 de forma transparente. Tanto o modo de roteamento
quanto o de sobreposição/encapsulamento são suportados. Este plug-in também
consegue operar no topo de outros plug-ins CNI.
CNI-Genie permite que o Kubernetes se conecte facilmente a uma variedade de plug-ins
CNI, como Calico, Canal, Flannel, Romana ou Weave.
Contiv oferece serviços de rede configuráveis para diferentes casos de uso (camada 3
nativa usando BGP, overlay (sobreposição) usando vxlan, camada 2 clássica e Cisco-
SDN/ACI) e também um framework rico de políticas de rede. O projeto Contiv é
totalmente open source. O instalador fornece opções de instalação com ou sem
kubeadm.
Contrail é uma plataforma open source baseada no Tungsten Fabric que oferece
virtualização de rede multi-nuvem e gerenciamento de políticas de rede. O Contrail e o
Tungsten Fabric são integrados a sistemas de orquestração de contêineres, como
Kubernetes, OpenShift, OpenStack e Mesos, e fornecem modos de isolamento para
cargas de trabalho executando em máquinas virtuais, contêineres/pods e servidores
físicos.
Flannel é um provedor de redes overlay (sobrepostas) que pode ser usado com o
Kubernetes.
Knitter é um plug-in para suporte de múltiplas interfaces de rede em Pods do
Kubernetes.
Multus é um plugin para suporte a várias interfaces de rede em Pods no Kubernetes.
Este plug-in pode agir como um "meta-plug-in", ou um plug-in CNI que se comunica com
múltiplos outros plug-ins CNI (por exemplo, Calico, Cilium, Contiv, Flannel), além das
cargas de trabalho baseadas em SRIOV, DPDK, OVS-DPDK e VPP no Kubernetes.
NSX-T Container Plug-in (NCP) fornece integração entre o VMware NSX-T e sistemas de
orquestração de contêineres como o Kubernetes. Além disso, oferece também
integração entre o NSX-T e as plataformas CaaS/PaaS baseadas em contêiner, como o
Pivotal Container Service (PKS) e o OpenShift.
Nuage é uma plataforma de rede definida por software que fornece serviços de rede
baseados em políticas entre os Pods do Kubernetes e os ambientes não-Kubernetes,
com visibilidade e monitoramento de segurança.
https://kubernetes.io/pt-br/docs/concepts/_print/ 170/178
5/14/22, 11:16 AM Conceitos | Kubernetes

OVN-Kubernetes é um provedor de rede para o Kubernetes baseado no OVN (Open


Virtual Network), uma implementação de redes virtuais que surgiu através do projeto
Open vSwitch (OVS). O OVN-Kubernetes fornece uma implementação de rede baseada
em overlay (sobreposição) para o Kubernetes, incluindo uma implementação baseada
em OVS para serviços de balanceamento de carga e políticas de rede.
OVN4NFV-K8S-Plugin é um plug-in controlador CNI baseado no OVN (Open Virtual
Network) que fornece serviços de rede cloud native, como Service Function Chaining (SFC),
redes overlay (sobrepostas) OVN múltiplas, criação dinâmica de subredes, criação
dinâmica de redes virtuais, provedor de rede VLAN e provedor de rede direto, e é
plugável a outros plug-ins multi-rede. Ideal para cargas de trabalho que utilizam
computação de borda cloud native em redes multi-cluster.
Romana é uma solução de rede de camada 3 para redes de pods que também suporta a
API NetworkPolicy. Detalhes da instalação do complemento Kubeadm disponíveis aqui.
Weave Net fornece rede e política de rede, funciona em ambos os lados de uma
partição de rede e não requer um banco de dados externo.

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.

Visualização & Controle


Dashboard é uma interface web para gestão do Kubernetes.
Weave Scope é uma ferramenta gráfica para visualizar contêineres, pods, serviços, entre
outros objetos do cluster. Pode ser utilizado com uma conta Weave Cloud. Como
alternativa, é possível hospedar a interface do usuário por conta própria.

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/ 171/178
5/14/22, 11:16 AM Conceitos | Kubernetes

12 - Extendendo o Kubernetes
12.1 - Extendendo a API do Kubernetes

12.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/ 172/178
5/14/22, 11:16 AM Conceitos | Kubernetes

12.2 - Extensões de Computação,


armazenamento e redes
12.2.1 - Plugins de rede
Plugins de redes no Kubernetes podem ser dos seguintes tipos:

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:

cni-bin-dir : O Kubelet verifica esse diretório por plugins na inicialização


network-plugin : O plugin de rede que deve ser utilizado do diretório configurado em
cni-bin-dir . Deve ser igual ao nome configurado por um plugin no diretório de
plugins.
Para plugins de CNI, isso equivale ao valor cni .

Requisitos de plugins de Rede


Além de prover a interface NetworkPlugin
para configuração da rede do pod, o plugin pode
necessitar de suporte específico ao
kube-proxy.
O proxy iptables obviamente depende do
iptables, e o plugin deve garantir que o
tráfego do contêiner esteja disponível para o iptables.
Por exemplo, se o plugin
conecta os contêineres à Linux bridge, o plugin deve configurar a
diretiva de
sysctl net/bridge/bridge-nf-call-iptables com o valor 1 para garantir que o
proxy iptables opere normalmente. Se o plugin não faz uso da Linux Bridge (mas outro
mecanismo, como Open vSwitch) ele deve garantir que o tráfego do contêiner é roteado
apropriadamente para o proxy.

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

https://kubernetes.io/pt-br/docs/concepts/_print/ 173/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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:

"name": "k8s-pod-network",

"cniVersion": "0.3.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}

}
]

Suporte a controle de banda


Funcionalidade experimental

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.3.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"

},

https://kubernetes.io/pt-br/docs/concepts/_print/ 174/178
5/14/22, 11:16 AM Conceitos | Kubernetes

"type": "bandwidth",

"capabilities": {"bandwidth": true}

}
]

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.

Esse plugin possui alguns requisitos:

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.

Customizando o MTU (com kubenet)


O MTU deve sempre ser configurado corretamente para obter-se a melhor performance de
rede. Os plugins de rede geralmente tentam detectar uma configuração correta de MTU,
porém algumas vezes a lógica não irá resultar em uma configuração adequada. Por exemplo,
se a Docker bridge ou alguma outra interface possuir um MTU pequeno, o kubenet irá
selecionar aquela MTU. Ou caso você esteja utilizando encapsulamento IPSEC, o MTU deve
ser reduzido, e esse cálculo não faz parte do escopo da maioria dos plugins de rede.

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 .
https://kubernetes.io/pt-br/docs/concepts/_print/ 175/178
5/14/22, 11:16 AM Conceitos | Kubernetes

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/ 176/178
5/14/22, 11:16 AM Conceitos | Kubernetes

12.3 - Padrão Operador


Operadores são extensões de software para o Kubernetes que
fazem uso de recursos
personalizados
para gerir aplicações e os seus componentes. Operadores seguem os
princípios do Kubernetes, notavelmente o ciclo de controle.

Motivação
O padrão Operador tem como objetivo capturar o principal objetivo de um operador
humano
que gere um serviço ou um conjunto de serviços. Operadores humanos
responsáveis por
aplicações e serviços específicos têm um conhecimento
profundo da forma como o sistema é
suposto se comportar, como é instalado
e como deve reagir na ocorrência de problemas.

As pessoas que executam cargas de trabalho no Kubernetes habitualmente gostam


de usar
automação para cuidar de tarefas repetitivas. O padrão Operador captura
a forma como
pode escrever código para automatizar uma tarefa para além do que
o Kubernetes fornece.

Operadores no Kubernetes
O Kubernetes é desenhado para automação. Out of the box, você tem bastante
automação
embutida no núcleo do Kubernetes. Pode usar
o Kubernetes para automatizar instalações e
executar cargas de trabalho,
e pode ainda automatizar a forma como o Kubernetes faz isso.

O conceito de controlador no
Kubernetes permite a extensão do comportamento sem
modificar o código do próprio
Kubernetes.
Operadores são clientes da API do Kubernetes que
atuam como controladores para
um dado Custom Resource

Exemplo de um Operador
Algumas das coisas que um operador pode ser usado para automatizar incluem:

instalar uma aplicação a pedido


obter e restaurar backups do estado dessa aplicação
manipular atualizações do código da aplicação juntamente com alterações
como
esquemas de base de dados ou definições de configuração extra
publicar um Service para aplicações que não suportam a APIs do Kubernetes
para as
descobrir
simular uma falha em todo ou parte do cluster de forma a testar a resiliência
escolher um lider para uma aplicação distribuída sem um processo
de eleição de
membro interno

Como deve um Operador parecer em mais detalhe? Aqui está um exemplo em mais
detalhe:

1. Um recurso personalizado (custom resource) chamado SampleDB, que você pode


configurar para dentro do cluster.
2. Um Deployment que garante que um Pod está a executar que contém a
parte
controlador do operador.
3. Uma imagem do container do código do operador.
4. Código do controlador que consulta o plano de controle para descobrir quais
recursos
SampleDB estão configurados.
5. O núcleo do Operador é o código para informar ao servidor da API (API server) como
fazer
a realidade coincidir com os recursos configurados.
Se você adicionar um novo SampleDB, o operador configurará
PersistentVolumeClaims
para fornecer armazenamento de base de dados durável,
um StatefulSet para executar SampleDB e
um Job para lidar com a configuração
inicial.
Se você apagá-lo, o Operador tira um snapshot e então garante que
o StatefulSet e
Volumes também são removidos.
https://kubernetes.io/pt-br/docs/concepts/_print/ 177/178
5/14/22, 11:16 AM Conceitos | Kubernetes

6. O operador também gere backups regulares da base de dados. Para cada recurso
SampleDB,
o operador determina quando deve criar um Pod que possa se conectar
à
base de dados e faça backups. Esses Pods dependeriam de um ConfigMap
e / ou um
Secret que possui detalhes e credenciais de conexão com à base de dados.
7. Como o Operador tem como objetivo fornecer automação robusta para o recurso
que
gere, haveria código de suporte adicional. Para este exemplo,
O código verifica se a base
de dados está a executar uma versão antiga e, se estiver,
cria objetos Job que o
atualizam para si.

Instalar Operadores
A forma mais comum de instalar um Operador é a de adicionar a
definição personalizada de
recurso (Custom Resource Definition) e
o seu Controlador associado ao seu cluster.
O
Controlador vai normalmente executar fora do
plano de controle,
como você faria com
qualquer aplicação containerizada.
Por exemplo, você pode executar o controlador no seu
cluster como um Deployment.

Usando um Operador
Uma vez que você tenha um Operador instalado, usaria-o adicionando, modificando
ou
apagando a espécie de recurso que o Operador usa. Seguindo o exemplo acima,
você
configuraria um Deployment para o próprio Operador, e depois:

kubectl get SampleDB # encontra a base de dados configurada

kubectl edit SampleDB/example-database # mudar manualmente algumas definições

…e é isso! O Operador vai tomar conta de aplicar


as mudanças assim como manter o serviço
existente em boa forma.

Escrevendo o seu próprio Operador


Se não existir no ecosistema um Operador que implementa
o comportamento que pretende,
pode codificar o seu próprio.
Qual é o próximo você vai encontrar
alguns links para
bibliotecas e ferramentas que pode usar
para escrever o seu próprio Operador cloud native.

Pode também implementar um Operador (isto é, um Controlador) usando qualquer


linguagem / runtime
que pode atuar como um cliente da API do Kubernetes.

Próximos passos
Aprenda mais sobre Recursos Personalizados
Encontre operadores prontos em OperatorHub.io para o seu caso de uso
Use ferramentes existentes para escrever os seus Operadores:
usando KUDO (Kubernetes Universal Declarative Operator)
usando kubebuilder
usando Metacontroller juntamente com WebHooks que
implementa você mesmo
usando o Operator Framework
Publique o seu operador para que outras pessoas o possam usar
Leia o artigo original da CoreOS que introduz o padrão Operador
Leia um artigo da Google Cloud sobre as melhores práticas para contruir Operadores

https://kubernetes.io/pt-br/docs/concepts/_print/ 178/178

Você também pode gostar