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
Protegendo um cluster
Protegendo o kubelet
Serviços Opcionais para o Cluster
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
Protegendo o kubelet
Serviços Opcionais do Cluster
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.
Baixe, descompacte e inicialize a versão corrigida do easyrsa3.
curl -LO https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
tar xzf easy-rsa.tar.gz
cd easy-rsa-master/easyrsa3
./easyrsa init-pki
Gerar o CA. (--batch
set automatic mode. --req-cn
default CN to use.)
./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass
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
Copie pki/ca.crt
, pki/issued/server.crt
, e pki/private/server.key
para o seu diretório.
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.
Gere um ca.key com 2048bit:
openssl genrsa -out ca.key 2048
De acordo com o ca.key, gere um ca.crt (use -days para definir o tempo efetivo do certificado):
openssl req -x509 -new -nodes -key ca.key -subj "/CN=${MASTER_IP}" -days 10000 -out ca.crt
Gere um server.key com 2048bit:
openssl genrsa -out server.key 2048
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
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
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
Veja o certificado:
openssl x509 -noout -text -in ./server.crt
Por fim, adicione os mesmos parâmetros nos parâmetros iniciais do Servidor de API.
cfssl
cfssl é outra ferramenta para geração de certificados.
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-certinfo
chmod +x cfssl-certinfo
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
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"
}
}
}
}
Crie um arquivo de configuração JSON para o CA - solicitação de assinatura de certificado (CSR - Certificate Signing Request), por exemplo, ca-csr.json
. Certifique-se de substituir os valores marcados com colchetes angulares por valores reais que você deseja usar.
{
"CN": "kubernetes",
"key": {
"algo": "rsa",
"size": 2048
},
"names":[{
"C": "<country>",
"ST": "<state>",
"L": "<city>",
"O": "<organization>",
"OU": "<organization unit>"
}]
}
Gere a chave CA (ca-key.pem
) e o certificado (ca.pem
):
../cfssl gencert -initca ca-csr.json | ../cfssljson -bare ca
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>"
}]
}
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
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.
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:
- Comunicações contêiner-para-contêiner altamente acopladas: Isso é resolvido
por Pods e comunicações através do
localhost
. - Comunicações pod-para-pod: Esse é o foco primário desse documento.
- Comunicações pod-para-serviço (service): Isso é tratado em Services.
- 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.
É 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 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:
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.
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.
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:
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.
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.
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ó.
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:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
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:
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-1
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log']
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-log-2
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log']
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
emptyDir: {}
Agora, quando você executa este pod, é possível acessar cada fluxo de log separadamente, executando os seguintes comandos:
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.
Se o agente de log no nível do nó não for flexível o suficiente para sua situação, você poderá criar um contêiner secundário com um agente de log separado que você configurou especificamente para executar com seu aplicativo.
Nota: O uso de um agente de log em um contêiner sidecar pode levar a um consumo significativo de recursos. Além disso, você não poderá acessar esses logs usando o comando kubectl logs
, porque eles não são controlados pelo kubelet.
Como exemplo, você pode usar o Stackdriver, que usa fluentd como um agente de log. Aqui estão dois arquivos de configuração que você pode usar para implementar essa abordagem. O primeiro arquivo contém um ConfigMap para configurar o fluentd.
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.
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args:
- /bin/sh
- -c
- >
i=0;
while true;
do
echo "$i: $(date)" >> /var/log/1.log;
echo "$(date) INFO $i" >> /var/log/2.log;
i=$((i+1));
sleep 1;
done
volumeMounts:
- name: varlog
mountPath: /var/log
- name: count-agent
image: 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.
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/pods/metrics-server-v0.3.1-57c75779f-9p8wg: (1.512ms) 200 [pod_nanny/v0.0.0 (linux/amd64) kubernetes/$Format 10.56.1.19:51756]
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="kube-system/kubedns" status="ready"
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.
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:
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:
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
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:
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
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:
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.
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).
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.
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
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:
image-gh-high-threshold
, a porcentagem de uso de disco que aciona o garbage collection da imagem. O padrão é 85%.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:
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.maximum-dead-containers-per-container
, número máximo de instâncias antigas a serem retidas por contêiner. O padrão é 1.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-threshold | --eviction-hard ou --eviction-soft | os sinais existentes de despejo podem acionar o garbage collection da imagem |
--image-gc-low-threshold | --eviction-minimum-reclaim | recuperações de despejo atinge o mesmo comportamento |
--maximum-dead-containers | | descontinuado quando os logs antigos forem armazenados fora do contexto do contêiner |
--maximum-dead-containers-per-container | | descontinuado quando os logs antigos forem armazenados fora do contexto do contêiner |
--minimum-container-ttl-duration | | descontinuado quando os logs antigos forem armazenados fora do contexto do contêiner |
--low-diskspace-threshold-mb | --eviction-hard ou eviction-soft | O despejo generaliza os limites do disco para outros recursos |
--outofdisk-transition-frequency | --eviction-pressure-transition-period | O despejo generaliza a transição da pressão do disco para outros recursos |
Próximos passos
Consulte Configurando a Manipulação de Recursos Insuficientes para mais detalhes.
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:
- 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.
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.
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.
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.
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.
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.
- 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!