Bem-vindo à documentação do Kubernetes em Português
Como você pode ver, a maior parte da documentação ainda está disponível apenas em inglês, mas não se preocupe, há uma equipe trabalhando na tradução para o português.
Se você quiser participar, você pode entrar no canal Slack #kubernetes-docs-pt e fazer parte da equipe por trás da tradução.
Você também pode acessar o canal para solicitar a tradução de uma página específica ou relatar qualquer erro que possa ter sido encontrado. Qualquer contribuição será bem recebida!
1.1 - Versões Suportadas da Documentação do Kubernetes
Este site contém documentação para a versão atual do Kubernetes e as quatro versões anteriores do Kubernetes.
A disponibilidade da documentação para uma versão do Kubernetes é separada dessa versão que é suportada atualmente.
Leia o período de suporte para saber quais versões do Kubernetes são oficialmente suportadas e por quanto tempo.
2 - Instalação
Essa seção lista as diferentes formas de instalar e executar o Kubernetes. Quando você realiza a instalação de um cluster Kubernetes, deve decidir o tipo de instalação baseado em critérios como facilidade de manutenção, segurança, controle, quantidade de recursos disponíveis e a experiência necessária para gerenciar e operar o cluster.
Você pode criar um cluster Kubernetes em uma máquina local, na nuvem, em um datacenter on-premises ou ainda escolher uma oferta de um cluster Kubernetes gerenciado pelo seu provedor de computação em nuvem.
Existem ainda diversos outros tipos de soluções customizadas, que você pode se deparar ao buscar formas de instalação e gerenciamento de seu cluster.
Ambientes de aprendizado
Se você está aprendendo ou pretende aprender mais sobre o Kubernetes, use ferramentas suportadas pela comunidade, ou ferramentas no ecossistema que te permitam criar um cluster Kubernetes em sua máquina virtual.
Ao analisar uma solução para um ambiente de produção, devem ser considerados quais aspectos de operação de um cluster Kubernetes você deseja gerenciar, ou então delegar ao seu provedor.
Temos diversas opções para esse provisionamento, desde o uso de uma ferramenta de deployment de um cluster tal qual o Kubeadm ou o Kubespray quando se trata de um cluster local, ou ainda o uso de um cluster gerenciado por seu provedor de nuvem.
Para a escolha do melhor ambiente e da melhor forma para fazer essa instalação, você deve considerar:
Se você deseja se preocupar com a gestão de backup da sua estrutura do ambiente de gerenciamento
Se você deseja ter um cluster mais atualizado, com novas funcionalidades, ou se deseja seguir a versão suportada pelo fornecedor
Se você deseja ter um cluster com um alto nível de serviço, ou com auto provisionamento de alta disponibilidade
Quanto você deseja pagar por essa produção
2.1 - Instalando a ferramenta kubeadm
Essa página mostra o processo de instalação do conjunto de ferramentas kubeadm.
Para mais informações sobre como criar um cluster com o kubeadm após efetuar a instalação, veja a página Utilizando kubeadm para criar um cluster.
This installation guide is for Kubernetes v1.30. If you want to use a different Kubernetes version, please refer to the following pages instead:
Uma máquina com sistema operacional Linux compatível. O projeto Kubernetes provê instruções para distribuições Linux baseadas em Debian e Red Hat, bem como para distribuições sem um gerenciador de pacotes.
2 GB ou mais de RAM por máquina (menos que isso deixará pouca memória para as suas aplicações).
2 CPUs ou mais.
Conexão de rede entre todas as máquinas no cluster. Seja essa pública ou privada.
Nome de host único, endereço MAC e product_uuid para cada nó. Veja aqui para mais detalhes.
Certas portas estão abertas em suas máquinas. Veja aqui para mais detalhes.
Configuração de swap. O comportamento padrão do kubelet era falhar ao iniciar se a memória swap fosse detectada em um nó.
O suporte a swap foi introduzido a partir da v1.22. E desde a v1.28, o swap é suportado apenas para cgroup v2; o recurso NodeSwap
do kubelet está em beta, mas desativado por padrão.
Você DEVE desabilitar o swap se o kubelet não estiver configurado corretamente para usar swap. Por exemplo, sudo swapoff -a
desabilitará a troca temporariamente. Para tornar essa mudança persistente entre reinicializações, certifique-se de que o swap esteja desabilitado em
arquivos de configuração como /etc/fstab, systemd.swap, dependendo de como foi configurado em seu sistema.
Nota:
A instalação do kubeadm é feita via binários que usam linkagem dinâmica e assume que seu sistema alvo fornece glibc.
Essa é uma suposição razoável em muitas distribuições Linux (incluindo Debian, Ubuntu, Fedora, CentOS, etc.)
mas nem sempre é o caso com distribuições personalizadas e leves que não incluem glibc por padrão, como o Alpine Linux.
A expectativa é que a distribuição inclua glibc ou uma camada de compatibilidade
que forneça os símbolos esperados.
Verifique se o endereço MAC e o product_uuid são únicos para cada nó
Você pode obter o endereço MAC das interfaces de rede usando o comando ip link ou ifconfig -a.
O product_uuid pode ser verificado utilizando o comando sudo cat /sys/class/dmi/id/product_uuid.
É provável que dispositivos físicos possuam endereços únicos. No entanto, é possível que algumas máquinas virtuais possuam endereços iguais. O Kubernetes utiliza esses valores para identificar unicamente os nós em um cluster. Se esses valores não forem únicos para cada nó, o processo de instalação pode falhar.
Verificando os adaptadores de rede
Se você possuir mais de um adaptador de rede, e seus componentes Kubernetes não forem acessíveis através da rota padrão, recomendamos adicionar o IP das rotas para que os endereços do cluster Kubernetes passem pelo adaptador correto.
Verifique as portas necessárias
Essas portas necessárias
precisam estar abertas para que os componentes do Kubernetes se comuniquem entre si.
Você pode usar ferramentas como netcat para verificar se uma porta está aberta. Por exemplo:
nc 127.0.0.1 6443 -v
O plugin de rede de Pods que você usa também pode exigir que certas portas estejam
abertas. Como isso varia com cada plugin de rede de Pods, consulte a
documentação dos plugins sobre quais portas precisam estar abertas.
Se você não especificar um runtime, o kubeadm tentará detectar automaticamente um runtime de contêiner instalado
varrendo uma lista de endpoints conhecidos.
Se múltiplos ou nenhum runtime de contêiner forem detectados, o kubeadm lançará um erro
e solicitará que você especifique qual deles deseja usar.
O Docker Engine não implementa a CRI
que é um requisito para um runtime de contêiner trabalhar com o Kubernetes.
Por essa razão, um serviço adicional cri-dockerd
deve ser instalado. cri-dockerd é um projeto baseado no suporte integrado legado
do Docker Engine que foi removido do kubelet na versão 1.24.
As tabelas abaixo incluem os endpoints conhecidos para sistemas operacionais suportados:
Você instalará esses pacotes em todas as suas máquinas:
kubeadm: o comando para iniciar o cluster.
kubelet: o componente que executa em todas as máquinas do seu cluster
e faz coisas como iniciar Pods e contêiners.
kubectl: o utilitário de linha de comando para interagir com o cluster.
O kubeadm não irá instalar ou gerenciar o kubelet ou o kubectl para você, então você
precisará garantir que eles correspondam à versão da camada de gerenciamento do Kubernetes
que você deseja que o kubeadm instale para você. Caso isso não seja feito, surge o risco de que uma diferença nas versões
leve a bugs e comportamentos inesperados. Dito isso, uma diferença de menor grandeza nas versões entre o kubelet e a
camada de gerenciamento é suportada, mas a versão do kubelet nunca poderá ser superior à versão do servidor da API.
Por exemplo, o kubelet executando 1.7.0 deve ser totalmente compatível com um servidor da API 1.8.0,
mas não o contrário.
Essas instruções removem todos os pacotes Kubernetes de quaisquer atualizações de sistema.
Isso ocorre porque o kubeadm e o Kubernetes requerem alguns cuidados especiais para serem atualizados.
Para mais detalhes sobre compatibilidade entre as versões, veja:
Nota: The legacy package repositories (apt.kubernetes.io and yum.kubernetes.io) have been
deprecated and frozen starting from September 13, 2023.
Using the new package repositories hosted at pkgs.k8s.io
is strongly recommended and required in order to install Kubernetes versions released after September 13, 2023.
The deprecated legacy repositories, and their contents, might be removed at any time in the future and without
a further notice period. The new package repositories provide downloads for Kubernetes versions starting with v1.24.0.
Nota:
Existe um repositório de pacotes dedicado para cada versão menor do Kubernetes. Se você deseja instalar
uma versão menor diferente da v1.30, por favor, veja o guia de instalação para
a sua versão menor desejada.
Atualize o índice de pacotes apt e instale os pacotes necessários para usar o repositório apt do Kubernetes:
sudo apt-get update
# apt-transport-https pode ser um pacote fictício; se for, você pode pular esse pacotesudo apt-get install -y apt-transport-https ca-certificates curl gpg
Baixe a chave pública de assinatura para os repositórios de pacotes do Kubernetes.
A mesma chave de assinatura é usada para todos os repositórios, então você pode ignorar a versão na URL:
# Se o diretório `/etc/apt/keyrings` não existir, ele deve ser criado antes do comando curl, leia a nota abaixo.# sudo mkdir -p -m 755 /etc/apt/keyringscurl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
Nota:
Em lançamentos anteriores ao Debian 12 e Ubuntu 22.04, o diretório /etc/apt/keyrings não existe por padrão, e deve ser criado antes do comando curl.
Adicione o repositório apt apropriado do Kubernetes. Por favor, note que este repositório tem pacotes
apenas para o Kubernetes 1.30; para outras versões menores do Kubernetes, você precisa
mudar a versão menor do Kubernetes na URL para corresponder à sua versão menor desejada
(você também deve verificar se está lendo a documentação para a versão do Kubernetes
que você planeja instalar).
# Isso sobrescreve qualquer configuração existente em /etc/apt/sources.list.d/kubernetes.listecho'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
Atualize o índice de pacotes apt, instale o kubelet, o kubeadm e o kubectl, e fixe suas versões:
(Opcional) Habilite o serviço kubelet antes de executar o kubeadm:
sudo systemctl enable --now kubelet
Configure o SELinux em modo permissivo:
Essas instruções são para o Kubernetes 1.30.
# Configure o SELinux em modo permissivo (efetivamente desabilitando-o)sudo setenforce 0sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
Cuidado:
Configurar o SELinux em modo permissivo ao executar setenforce 0 e sed ...
efetivamente o desabilita. Isso é necessário para permitir que os contêineres acessem o sistema de arquivos do hospedeiro; por exemplo, alguns plugins de rede de cluster requerem isso. Você deve
fazer isso até que o suporte ao SELinux seja melhorado no kubelet.
Você pode manter o SELinux habilitado se souber como configurá-lo, mas pode ser necessário
configurações que não são suportadas pelo kubeadm.
Adicione o repositório yum do Kubernetes. O parâmetro exclude na
definição do repositório garante que os pacotes relacionados ao Kubernetes não
sejam atualizados ao executar yum update, já que existe um procedimento especial que
deve ser seguido para atualizar o Kubernetes. Por favor, note que este repositório
tem pacotes apenas para o Kubernetes 1.30; para outras
versões menores do Kubernetes, você precisa mudar a versão menor do Kubernetes
na URL para corresponder à sua versão menor desejada (você também deve verificar se
está lendo a documentação para a versão do Kubernetes que você planeja instalar).
# Isso sobrescreve qualquer configuração existente em /etc/yum.repos.d/kubernetes.repocat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
Escolha o diretório para baixar os arquivos de comandos.
Nota:
A variável DOWNLOAD_DIR deve ser definida para um diretório que permita escrita.
Se você está executando o Flatcar Container Linux, defina DOWNLOAD_DIR="/opt/bin".
Opcionalmente, habilite o serviço kubelet antes de executar o kubeadm:
sudo systemctl enable --now kubelet
Nota:
A distribuição Flatcar Container Linux monta o diretório /usr como um sistema de arquivos somente leitura.
Antes de iniciar seu cluster, você precisa tomar passos adicionais para configurar um diretório gravável.
Veja o Guia de Solução de Problemas do Kubeadm
para aprender como configurar um diretório gravável.
O kubelet agora ficará reiniciando de alguns em alguns segundos, enquanto espera por instruções vindas do kubeadm.
Configurando um driver cgroup
Tanto o agente de execução quanto o kubelet possuem uma propriedade chamada
"driver cgroup", que é importante
para o gerenciamento dos cgroups em máquinas Linux.
Aviso:
A compatibilidade entre os drivers cgroup e o agente de execução é necessária. Sem ela o processo do kubelet irá falhar.
O kops usa DNS para descoberta, tanto dentro do cluster quanto fora, para que você possa acessar o servidor da API do kubernetes a partir dos clientes.
kops tem uma opinião forte sobre o nome do cluster: deve ser um nome DNS válido. Ao fazer isso, você não confundirá mais seus clusters, poderá compartilhar clusters com seus colegas de forma inequívoca e alcançá-los sem ter de lembrar de um endereço IP.
Você pode e provavelmente deve usar subdomínios para dividir seus clusters. Como nosso exemplo usaremos
useast1.dev.example.com. O endpoint do servidor de API será então api.useast1.dev.example.com.
Uma zona hospedada do Route53 pode servir subdomínios. Sua zona hospedada pode ser useast1.dev.example.com,
mas também dev.example.com ou até example.com. kops funciona com qualquer um deles, então normalmente você escolhe por motivos de organização (por exemplo, você tem permissão para criar registros em dev.example.com,
mas não em example.com).
Vamos supor que você esteja usando dev.example.com como sua zona hospedada. Você cria essa zona hospedada usando o processo normal, ou
com um comando como aws route53 create-hosted-zone --name dev.example.com --caller-reference 1.
Você deve então configurar seus registros NS no domínio principal, para que os registros no domínio sejam resolvidos. Aqui, você criaria registros NS no example.com para dev. Se for um nome de domínio raiz, você configuraria os registros NS em seu registrador de domínio (por exemplo example.com, precisaria ser configurado onde você comprou example.com).
Verifique a configuração do seu domínio route53 (é a causa número 1 de problemas!). Você pode verificar novamente se seu cluster está configurado corretamente se tiver a ferramenta dig executando:
dig NS dev.example.com
Você deve ver os 4 registros NS que o Route53 atribuiu à sua zona hospedada.
(3/5) Crie um bucket do S3 para armazenar o estado dos clusters
O kops permite que você gerencie seus clusters mesmo após a instalação. Para fazer isso, ele deve acompanhar os clusters que você criou, juntamente com suas configurações, as chaves que estão usando etc. Essas informações são armazenadas em um bucket do S3. As permissões do S3 são usadas para controlar o acesso ao bucket.
Vários clusters podem usar o mesmo bucket do S3 e você pode compartilhar um bucket do S3 entre seus colegas que administram os mesmos clusters - isso é muito mais fácil do que transmitir arquivos kubecfg. Mas qualquer pessoa com acesso ao bucket do S3 terá acesso administrativo a todos os seus clusters, portanto, você não deseja compartilhá-lo além da equipe de operações.
Portanto, normalmente você tem um bucket do S3 para cada equipe de operações (e geralmente o nome corresponderá ao nome da zona hospedada acima!)
Em nosso exemplo, escolhemos dev.example.com como nossa zona hospedada, então vamos escolher clusters.dev.example.com como o nome do bucket do S3.
Exporte AWS_PROFILE (se precisar selecione um perfil para que a AWS CLI funcione)
Crie o bucket do S3 usando aws s3 mb s3://clusters.dev.example.com
Você pode rodar export KOPS_STATE_STORE=s3://clusters.dev.example.com e, em seguida, o kops usará esse local por padrão. Sugerimos colocar isso em seu perfil bash ou similar.
(4/5) Crie sua configuração de cluster
Execute kops create cluster para criar sua configuração de cluster:
kops criará a configuração para seu cluster. Observe que ele apenas cria a configuração, na verdade não cria os recursos de nuvem - você fará isso na próxima etapa com um arquivo kops update cluster. Isso lhe dá a oportunidade de revisar a configuração ou alterá-la.
Ele exibe comandos que você pode usar para explorar mais:
Liste seus clusters com: kops get cluster
Edite este cluster com: kops edit cluster useast1.dev.example.com
Edite seu grupo de instâncias de nós: kops edit ig --name=useast1.dev.example.com nodes
Edite seu grupo de instâncias principal: kops edit ig --name=useast1.dev.example.com master-us-east-1c
Se esta é sua primeira vez usando kops, gaste alguns minutos para experimentá-los! Um grupo de instâncias é um conjunto de instâncias que serão registradas como nós do kubernetes. Na AWS, isso é implementado por meio de grupos de auto-scaling.
Você pode ter vários grupos de instâncias, por exemplo, se quiser nós que sejam uma combinação de instâncias spot e sob demanda ou instâncias de GPU e não GPU.
(5/5) Crie o cluster na AWS
Execute kops update cluster para criar seu cluster na AWS:
kops update cluster useast1.dev.example.com --yes
Isso leva alguns segundos para ser executado, mas seu cluster provavelmente levará alguns minutos para estar realmente pronto.
kops update cluster será a ferramenta que você usará sempre que alterar a configuração do seu cluster; ele aplica as alterações que você fez na configuração ao seu cluster - reconfigurando AWS ou kubernetes conforme necessário.
Por exemplo, depois de você executar kops edit ig nodes, em seguida execute kops update cluster --yes para aplicar sua configuração e, às vezes, você também precisará kops rolling-update cluster para implementar a configuração imediatamente.
Sem --yes, kops update cluster mostrará uma prévia do que ele fará. Isso é útil para clusters de produção!
Explore outros complementos
Consulte a lista de complementos para explorar outros complementos, incluindo ferramentas para registro, monitoramento, política de rede, visualização e controle de seu cluster Kubernetes.
Limpeza
Para excluir seu cluster: kops delete cluster useast1.dev.example.com --yes
Contribua para o kOps endereçando ou levantando um problema GitHub Issues.
2.3 - Soluções de Nuvem Prontas para uso
Essa página fornece uma lista de provedores de soluções certificadas do Kubernetes. Na página de cada provedor, você pode aprender como instalar e configurar clusters prontos para produção.
3 - Conceitos
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.
3.1 - Visão Geral
Kubernetes é um plataforma de código aberto, portável e extensiva para o gerenciamento de cargas de trabalho e serviços distribuídos em contêineres, que facilita tanto a configuração declarativa quanto a automação. Ele possui um ecossistema grande, e de rápido crescimento. Serviços, suporte, e ferramentas para Kubernetes estão amplamente disponíveis.
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 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 da recuperação à falha de sua aplicação, fornece padrões de implantação e muito mais. Por exemplo, o Kubernetes pode gerenciar facilmente uma implantação no método canário para seu sistema.
O Kubernetes oferece a você:
Descoberta de serviço e balanceamento de carga
O Kubernetes pode expor um contêiner usando o nome DNS ou seu próprio endereço IP. Se o tráfego para um contêiner for alto, o Kubernetes pode balancear a carga e distribuir o tráfego de rede para que a implantação seja estável.
Orquestração de armazenamento
O Kubernetes permite que você monte automaticamente um sistema de armazenamento de sua escolha, como armazenamentos locais, provedores de nuvem pública e muito mais.
Lançamentos e reversões automatizadas
Você pode descrever o estado desejado para seus contêineres implantados usando o Kubernetes, e ele pode alterar o estado real para o estado desejado em um ritmo controlado. Por exemplo, você pode automatizar o Kubernetes para criar novos contêineres para sua implantação, remover os contêineres existentes e adotar todos os seus recursos para o novo contêiner.
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 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.
Um cluster Kubernetes consiste de componentes que são parte da camada de gerenciamento e de 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(s) servidor(es) de processamento hospeda(m) os
Pods, que são componentes de uma
aplicação. A camada de gerenciamento
gerencia os nós de processamento e os Pods no cluster. Em ambientes de produção,
a camada de gerenciamento geralmente executa em múltiplos computadores e um
cluster geralmente executa múltiplos nós, fornecendo tolerância a falhas e alta
disponibilidade.
Este documento descreve os vários componentes que você precisa ter para implantar
um cluster Kubernetes completo e funcional.
Componentes da camada de gerenciamento
Os componentes da camada de gerenciamento tomam decisões globais sobre o cluster
(por exemplo, alocação de Pods), bem como detectam e respondem aos eventos
do cluster (por exemplo, inicialização de um novo Pod
quando o campo replicas de um Deployment não está atendido).
Os componentes da camada de gerenciamento podem ser executados em qualquer máquina
do cluster. Contudo, para simplificar, os scripts de configuração normalmente
iniciam todos os componentes da camada de gerenciamento na mesma máquina, e
contêineres com cargas de trabalho do usuário não rodam nesta máquina. Veja
Construindo clusters altamente disponíveis com o kubeadm
para um exemplo de configuração da camada de gerenciamento que roda em múltiplas
máquinas.
kube-apiserver
O servidor da API é um componente da camada de gerenciamento
do Kubernetes que expõe a API do Kubernetes.
O servidor da API é o front end para a camada de gerenciamento do Kubernetes.
A principal implementação de um servidor de API do Kubernetes é o
kube-apiserver.
O kube-apiserver foi projetado para ser escalonado horizontalmente — ou seja,
ele pode ser escalonado com a criação de mais instâncias.
Você pode executar várias instâncias do kube-apiserver e distribuir o tráfego
entre essas instâncias.
etcd
Armazenamento do tipo chave-valor consistente e de alta-disponibilidade, usado
como armazenamento de apoio do Kubernetes para todos os dados do cluster.
Se o seu cluster Kubernetes usa o etcd como seu armazenamento de apoio,
certifique-se de ter um plano de
backup
para seus dados.
Você pode encontrar informações detalhadas sobre o etcd na documentação
oficial.
kube-scheduler
Componente da camada de gerenciamento que observa os
Pods recém-criados e que ainda não
foram atribuídos a um nó, e
seleciona um nó para executá-los.
Os fatores levados em consideração para as decisões de alocação incluem:
requisitos de recursos individuais e coletivos, restrições de hardware/software/política,
especificações de afinidade e antiafinidade, localidade de dados, interferência
entre cargas de trabalho, e prazos.
kube-controller-manager
Componente da camada de gerenciamento que executa os processos de
controlador.
Logicamente, cada controlador
está em um processo separado, mas para reduzir a complexidade, eles todos são
compilados num único binário e executam em um processo único.
Alguns tipos desses controladores são:
Controlador de nó: responsável por perceber e responder quando os nós caem.
Controlador de Jobs: observa os objetos Job, que representam tarefas únicas, e em seguida cria Pods para executar essas tarefas até a conclusão.
Controlador de EndpointSlice: preenche o objeto EndpointSlice (conecta os objetos Service e Pod).
Controlador de ServiceAccount: cria a ServiceAccount default 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 escalonar horizontalmente (executar mais
de uma cópia) para melhorar o desempenho ou para auxiliar na tolerância a falhas.
Os seguintes controladores podem ter dependências de provedor de nuvem:
Controlador de nó: para verificar junto ao provedor de nuvem para determinar se um nó foi excluído da nuvem após parar de responder.
Controlador de rota: para configurar rotas na infraestrutura de nuvem subjacente.
Controlador de serviço: para criar, atualizar e excluir balanceadores de carga do provedor de nuvem.
Componentes do nó
Os componentes do nó são executados em todos os nós, mantendo os Pods em execução
e fornecendo o ambiente de execução do Kubernetes.
kubelet
Um agente que é executado em cada nó
no cluster. Ele garante que os contêineres
estejam sendo executados em um Pod.
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.
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.
Complementos (addons) usam recursos do Kubernetes (DaemonSet,
Deployment, etc) para implementar funcionalidades
do cluster. Como fornecem funcionalidades em nível do cluster, recursos de complementos
que necessitem ser criados dentro de um namespace pertencem ao namespace kube-system.
Alguns complementos selecionados são descritos abaixo; para uma lista estendida dos
complementos disponíveis, consulte Instalando Complementos.
DNS
Embora os outros complementos não sejam estritamente necessários, todos os clusters
do Kubernetes devem ter um DNS do cluster,
já que muitos exemplos dependem disso.
O DNS do cluster é um servidor DNS, além de outros servidores DNS em seu ambiente,
que fornece registros DNS para serviços do Kubernetes.
Os contêineres iniciados pelo Kubernetes incluem automaticamente esse servidor DNS em suas pesquisas DNS.
Web UI (Dashboard)
O dashboard é uma interface
de usuário Web, de uso geral, para clusters do Kubernetes. Ele permite que os
usuários gerenciem e solucionem problemas de aplicações em execução no cluster,
bem como o próprio cluster.
Monitoramento de recursos do contêiner
O monitoramento de recursos do contêiner
registra métricas de série temporal genéricas sobre os contêineres em um banco de
dados central e fornece uma interface de usuário para navegar por esses dados.
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 uma interface para navegação/pesquisa.
Esta página explica como os objetos do Kubernetes são representados na API do Kubernetes e como você pode expressá-los no formato .yaml.
Entendendo os objetos do Kubernetes
Os objetos do Kubernetes são entidades persistentes no Kubernetes. Kubernetes utiliza estas entidades para representar o estado do cluster. Especificamente, eles podem descrever:
Quais aplicativos estão sendo executados (e em quais nós).
Os recursos disponíveis para esses aplicativos
As políticas acerca de como esses aplicativos se comportam, como políticas de reinicialização e tolerâncias a falhas.
Um objeto do Kubernetes é um “registro de intenção”-uma vez criado o objeto, o sistema do Kubernetes trabalha constantemente para garantir que este objeto existe. Ao criar um objeto, você está efetivamente falando para o sistema do Kubernetes como você quer que a carga do seu cluster seja. Este é o estado desejado do seu cluster.
Para trabalhar com objetos do Kubernetes seja para criar, modificar ou deletar eles, você precisará usar a API do Kubernetes. Quando você usa a interface de linha de comando do kubectl, por exemplo, o CLI faz as chamadas necessárias na API do Kubernetes para você. Você também pode usar a API do Kubernetes diretamente no seu próprio programa usando uma das Bibliotecas.
Especificação e status do objeto
Quase todos os objetos do Kubernetes incluem dois campos de objetos aninhados que governam a configuração do objeto: a especificação do objeto e o status do objeto. Para objetos que têm especificação, você tem que definir isso quando você cria o objeto, fornecendo uma descrição das características que você quer que o recurso tenha: o seu estado desejado.
O status descreve o estado atual do objeto, fornecido e atualizado pelo Kubernetes e seus componentes. A camada de gerenciamento do Kubernetes gerência continuamente e ativamente o real estado para corresponder ao estado desejado que você forneceu.
Por exemplo, no Kubernetes, o Deployment é um objeto que pode representar uma aplicação executando no seu cluster. Quando você cria o Deployment, você pode alterar a especificaçãopara definir que você quer três réplicas da aplicação em execução simultânea. O Kubernetes lê as especificações do Deployment e inicia três instâncias do seu aplicativo desejado, atualizando o status para corresponder às suas especificações. Se uma dessas instâncias falhar (um status mudar), o Kubernetes responde as diferenças entre as especificações e o status fazendo uma correção-neste caso, iniciando uma instância de substituição.
Para mais informações sobre especificações do objeto, status e metadados, veja Kubernetes API Conventions.
Descrevendo um objeto Kubernetes
Quando se cria um objeto do Kubernetes, deve-se fornecer a especificação do objeto que descreve seu estado desejado, bem como algumas informações básicas sobre o objeto (como um nome, por exemplo). Quando utiliza a API Kubernetes para criar o objeto (diretamente ou via kubectl), essa solicitação de API deve incluir essa informação como JSON no corpo da solicitação. Na maioria das vezes, você fornece as informações ao comando kubectl em um arquivo .yaml. O comandokubectl converte a informação para JSON ao fazer a requisição para a API.
Aqui está um exemplo de arquivo .yaml que mostra os campos necessários e as especificações de objeto para uma implatação Kubernetes:
apiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deploymentspec:selector:matchLabels:app:nginxreplicas:2# diz ao deployment para executar 2 pods que correspondam ao modelotemplate:metadata:labels:app:nginxspec:containers:- name:nginximage:nginx:1.14.2ports:- containerPort:80
Uma maneira de criar um Deployment usando um arquivo .yaml como o representado acima é usar o comando kubectl apply na interface de linha de comando kubectl, passando o arquivo .yaml como argumento. Aqui está um exemplo:
No arquivo .yaml para o objeto Kubernetes que pretende criar, você precisará definir valores para os seguintes campos:
apiVersion - Qual a versão de API do objeto que será usado no Kubernetes para criar esse objeto.
kind - Qual tipo de objeto pretende criar.
metadata - Dados que ajudam a identificar de forma única o objeto, incluindo uma string nome, UID e um namespace.
spec - Que estado deseja para o objeto.
O formato preciso do objeto spec é diferente para cada objeto Kubernetes, e contém campos aninhados específicos para aquele objeto. A documentação de referência da API do Kubernetes pode ajudar a encontrar o formato de especificação para todos os objetos que você pode criar usando Kubernetes.
Por exemplo, veja o campo de spec field para a referência Pod API.
Para cada Pod, o campo .spec especifica o pod e seu estado desejado (como o nome da imagem do contêiner para cada recipiente dentro daquela cápsula).
Outro exemplo de especificação de um objeto é o
campo spec.
Para o StatefulSet, o campo .spec especifica o StatefulSet e seu estado desejado.
Dentro do .spec de um StatefulSet está um template
para objetos de Pod. Esse modelo descreve os Pods que o controlador StatefulSet criará para
satisfazer a especificação do StatefulSet. Diferentes tipos de objetos também podem ter diferentes
.status; novamente, as páginas de referência API detalham a estrutura daquele campo .status,
e seu conteúdo para cada tipo diferente de objeto.
Próximos passos
Aprenda sobre os mais importantes objetos básicos Kubernetes, como o Pod.
Aprenda sobre as controladoras do Kubernetes.
Usando a API Kubernetes explica mais alguns conceitos da API.
3.1.2.2 - Nomes de objetos e IDs
Cada objeto em seu cluster possui um Nome que é único para aquele
tipo de recurso.
Todo objeto do Kubernetes também possui um UID que é único para todo
o cluster.
Por exemplo, você pode ter apenas um Pod chamado myapp-1234 dentro de um
namespace, porém
você pode ter um Pod e um Deployment ambos com o nome myapp-1234.
Para atributos não-únicos definidos pelo usuário, o Kubernetes fornece
labels e
annotations.
Nomes
Uma string fornecida pelo cliente que referencia um objeto em uma URL de
recurso, como por exemplo /api/v1/pods/qualquer-nome.
Somente um objeto de um dado tipo pode ter um certo nome por vez. No entanto,
se você remover o objeto, você poderá criar um novo objeto com o mesmo nome.
Nota:
Em casos em que objetos representam uma entidade física, como no caso de um Nó
representando um host físico, caso o host seja recriado com o mesmo nome mas o
objeto Nó não seja recriado, o Kubernetes trata o novo host como o host antigo,
o que pode causar inconsistências.
Abaixo estão descritos quatro tipos de restrições de nomes comumente utilizadas
para recursos.
Nomes de subdomínio DNS
A maior parte dos recursos do Kubernetes requerem um nome que possa ser
utilizado como um nome de subdomínio DNS, conforme definido na
RFC 1123.
Isso significa que o nome deve:
conter no máximo 253 caracteres
conter somente caracteres alfanuméricos em caixa baixa, traço ('-') ou ponto
('.').
iniciar com um caractere alfanumérico
terminar com um caractere alfanumérico
Nomes de rótulos da RFC 1123
Alguns tipos de recurso requerem que seus nomes sigam o padrão de rótulos DNS
definido na RFC 1123.
Isso significa que o nome deve:
conter no máximo 63 caracteres
conter somente caracteres alfanuméricos em caixa baixa ou traço ('-')
iniciar com um caractere alfanumérico
terminar com um caractere alfanumérico
Nomes de rótulo da RFC 1035
Alguns tipos de recurso requerem que seus nomes sigam o padrão de rótulos DNS
definido na RFC 1035.
Isso significa que o nome deve:
conter no máximo 63 caracteres
conter somente caracteres alfanuméricos em caixa baixa ou traço ('-')
iniciar com um caractere alfanumérico
terminar com um caractere alfanumérico
Nomes de segmentos de caminhos
Alguns tipos de recurso requerem que seus nomes possam ser seguramente
codificados como um segmento de caminho, ou seja, o nome não pode ser "." ou
".." e não pode conter "/" ou "%".
Exemplo de um manifesto para um Pod chamado nginx-demo.
Alguns tipos de recursos possuem restrições adicionais em seus nomes.
UIDs
Uma string gerada pelos sistemas do Kubernetes para identificar objetos de
forma única.
Cada objeto criado durante todo o ciclo de vida do cluster do Kubernetes possui
um UID distinto. O objetivo deste identificador é distinguir ocorrências
históricas de entidades semelhantes.
UIDs no Kubernetes são identificadores únicos universais (também conhecidos como
UUIDs).
UUIDs seguem os padrões ISO/IEC 9834-8 e ITU-T X.667.
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.
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.
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:
Quando você cria um Serviço, ele cria uma
entrada DNS correspondente.
Esta entrada possui o formato: <service-name>.<namespace-name>.svc.cluster.local, de forma que se um contêiner utilizar apenas <service-name> ele será resolvido para um serviço que é local ao namespace.
Isso é útil para utilizar a mesma configuração em vários namespaces, por exemplo em Desenvolvimento, Staging e Produção. Se você quiser acessar múltiplos namespaces, precisará utilizar um Fully Qualified Domain Name (FQDN).
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 namespacekubectl api-resources --namespaced=true# Sem namespacekubectl api-resources --namespaced=false
Rotulamento Automático
ESTADO DA FUNCIONALIDADE: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 gateNamespaceDefaultLabelName estiver habilitada. O valor do label é o nome do namespace.
Os Seletores de Campos permitem que você selecione recursos do Kubernetes baseado no valor de um ou mais campos de um recurso. Seguem alguns exemplos de buscas utilizando seletores de campos:
metadata.name=my-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 selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"
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!=default
Seletores em cadeia
Assim como label e outros tipos de seletores, podem ser utilizados em cadeia através de uma lista separada por vírgula. O comando kubectl a seguir seleciona todos os Pods nos quais status.phase não é igual a Running e spec.restartPolicy é igual a Always
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
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.namespace!=default
3.2 - Arquitetura do Kubernetes
3.2.1 - Nós
O Kubernetes executa sua carga de trabalho colocando contêineres em Pods para serem executados em Nós. Um nó pode ser uma máquina virtual ou física, dependendo do cluster. Cada nó é gerenciado pela camada de gerenciamento e contém os serviços necessários para executar Pods.
Normalmente, você tem vários nós em um cluster; em um ambiente de aprendizado ou limitado por recursos, você pode ter apenas um nó.
Existem duas maneiras principais de adicionar Nós ao Servidor da API:
O kubelet em um nó se registra automaticamente na camada de gerenciamento
Você (ou outro usuário humano) adiciona manualmente um objeto Nó
Depois de criar um objeto Nó, ou o kubelet em um nó se registra automaticamente, a camada de gerenciamento verifica se o novo objeto Nó é válido. Por exemplo, se você tentar criar um nó a partir do seguinte manifesto JSON:
O Kubernetes cria um objeto nó internamente (a representação). O Kubernetes verifica se um kubelet se registrou no servidor da API que corresponde ao campo metadata.name do Nó. Se o nó estiver íntegro (ou seja, todos os serviços necessários estiverem em execução), ele será elegível para executar um Pod. Caso contrário, esse nó é ignorado para qualquer atividade de cluster até que se torne íntegro.
Nota:
O Kubernetes mantém o objeto nó inválido e continua verificando se ele se torna íntegro.
Você, ou um controlador, deve excluir explicitamente o objeto Nó para interromper essa verificação de integridade.
O nome identifica um nó. Dois nós não podem ter o mesmo nome ao mesmo tempo. O Kubernetes também assume que um recurso com o mesmo nome é o mesmo objeto. No caso de um nó, assume-se implicitamente que uma instância usando o mesmo nome terá o mesmo estado (por exemplo, configurações de rede, conteúdo do disco raiz) e atributos como label de nó. Isso pode levar a inconsistências se uma instância for modificada sem alterar seu nome. Se o nó precisar ser substituído ou atualizado significativamente, o objeto Nó existente precisa ser removido do servidor da API primeiro e adicionado novamente após a atualização.
Auto-registro de Nós
Quando a opção --register-node do kubelet for verdadeira (padrão), o kubelet tentará se registrar no servidor da API. Este é o padrão preferido, usado pela maioria das distribuições.
Para auto-registro, o kubelet é iniciado com as seguintes opções:
--kubeconfig - O caminho das credenciais para se autenticar no servidor da API.
--cloud-provider - Como comunicar com um provedor de nuvem
para ler metadados sobre si mesmo.
--register-node - Registrar automaticamente no servidor da API.
--register-with-taints - Registra o nó com a lista fornecida de taints (separadas por vírgula <key>=<value>:<effect>).
Como mencionado na seção de singularidade do nome do nó, quando a configuração do nó precisa ser atualizada, é uma boa prática registrar novamente o nó no servidor da API. Por exemplo, se o kubelet estiver sendo reiniciado com o novo conjunto de --node-labels, mas o mesmo nome de nó for usado, a alteração não entrará em vigor, pois os labels estão sendo definidos no registro do Nó.
Pods já agendados no Nó podem ter um comportamento anormal ou causar problemas se a configuração do Nó for alterada na reinicialização do kubelet. Por exemplo, o Pod já em execução pode estar marcado diferente dos labels atribuídos ao Nó, enquanto outros Pods, que são incompatíveis com esse Pod, serão agendados com base nesse novo label. O novo registro do nó garante que todos os Pods sejam drenados e devidamente reiniciados.
Administração manual de nós
Você pode criar e modificar objetos Nó usando o kubectl.
Quando você quiser manualmente criar objetos Nó, defina a opção do kubelet --register-node=false.
Você pode modificar os objetos Nó, independentemente da configuração de --register-node. Por exemplo, você pode definir labels em um nó existente ou marcá-lo como não disponível.
Você pode usar labels nos Nós em conjunto com seletores de nós nos Pods para controlar a disponibilidade. Por exemplo, você pode restringir um Pod a ser elegível apenas para ser executado em um subconjunto dos nós disponíveis.
Marcar um nó como não disponível impede que o escalonador coloque novos pods nesse nó, mas não afeta os Pods existentes no nó. Isso é útil como uma etapa preparatória antes da reinicialização de um nó ou outra manutenção.
Os Pods que fazem parte de um DaemonSet toleram ser executados em um nó não disponível. Os DaemonSets geralmente fornecem serviços locais de nós que devem ser executados em um Nó, mesmo que ele esteja sendo drenado de aplicativos de carga de trabalho.
Status do Nó
O status de um nó contém as seguintes informações:
Você pode usar o kubectl para visualizar o status de um nó e outros detalhes:
kubectl describe node <insira-nome-do-nó-aqui>
Cada seção da saída está descrita abaixo.
Endereços
O uso desses campos pode mudar dependendo do seu provedor de nuvem ou configuração dedicada.
HostName: O nome do host relatado pelo kernel do nó. Pode ser substituído através do parâmetro kubelet --hostname-override.
ExternalIP: Geralmente, o endereço IP do nó que é roteável externamente (disponível fora do cluster).
InternalIP: Geralmente, o endereço IP do nó que é roteável somente dentro do cluster.
Condições
O campo conditions descreve o status de todos os nós em execução. Exemplos de condições incluem:
Condições do nó e uma descrição de quando cada condição se aplica.
Condições do nó
Descrição
Ready
True Se o nó estiver íntegro e pronto para aceitar pods, False se o nó não estiver íntegro e não estiver aceitando pods, e desconhecido Unknown se o controlador do nó tiver sem notícias do nó no último node-monitor-grace-period (o padrão é de 40 segundos)
DiskPressure
True Se houver pressão sobre o tamanho do disco, ou seja, se a capacidade do disco for baixa; caso contrário False
MemoryPressure
True Se houver pressão na memória do nó, ou seja, se a memória do nó estiver baixa; caso contrário False
PIDPressure
True Se houver pressão sobre os processos, ou seja, se houver muitos processos no nó; caso contrário False
NetworkUnavailable
True Se a rede do nó não estiver configurada corretamente, caso contrário False
Nota:
Se você usar as ferramentas de linha de comando para mostrar os detalhes de um nó isolado, a Condition inclui SchedulingDisabled. SchedulingDisabled não é uma condição na API do Kubernetes; em vez disso, os nós isolados são marcados como Unschedulable em suas especificações.
Na API do Kubernetes, a condição de um nó é representada como parte do .status do recurso do nó. Por exemplo, a seguinte estrutura JSON descreve um nó íntegro:
Se o status da condição Ready permanecer desconhecido (Unknown) ou falso (False) por mais tempo do que o limite da remoção do pod (pod-eviction-timeout) (um argumento passado para o kube-controller-manager), o controlador de nó acionará o remoção iniciado pela API para todos os Pods atribuídos a esse nó. A duração padrão do tempo limite da remoção é de cinco minutos. Em alguns casos, quando o nó está inacessível, o servidor da API não consegue se comunicar com o kubelet no nó. A decisão de excluir os pods não pode ser comunicada ao kubelet até que a comunicação com o servidor da API seja restabelecida. Enquanto isso, os pods agendados para exclusão podem continuar a ser executados no nó particionado.
O controlador de nós não força a exclusão dos pods até que seja confirmado que eles pararam de ser executados no cluster. Você pode ver os pods que podem estar sendo executados em um nó inacessível como estando no estado de terminando (Terminating) ou desconhecido (Unknown). Nos casos em que o Kubernetes não retirar da infraestrutura subjacente se um nó tiver deixado permanentemente um cluster, o administrador do cluster pode precisar excluir o objeto do nó manualmente. Excluir o objeto do nó do Kubernetes faz com que todos os objetos Pod em execução no nó sejam excluídos do servidor da API e libera seus nomes.
Quando ocorrem problemas nos nós, a camada de gerenciamento do Kubernetes cria automaticamente taints que correspondem às condições que afetam o nó. O escalonador leva em consideração as taints do Nó ao atribuir um Pod a um Nó. Os Pods também podem ter tolerations que os permitem funcionar em um nó, mesmo que tenha uma taint específica.
Descreve os recursos disponíveis no nó: CPU, memória e o número máximo de pods que podem ser agendados no nó.
Os campos no bloco de capacidade indicam a quantidade total de recursos que um nó possui. O bloco alocado indica a quantidade de recursos em um nó que está disponível para ser consumido por Pods normais.
Descreve informações gerais sobre o nó, como a versão do kernel, a versão do Kubernetes (versão do kubelet e kube-proxy), detalhes do tempo de execução do contêiner e qual sistema operacional o nó usa. O kubelet coleta essas informações do nó e as publica na API do Kubernetes.
Heartbeats
Os Heartbeats, enviados pelos nós do Kubernetes, ajudam seu cluster a determinar a disponibilidade de cada nó e a agir quando as falhas forem detectadas.
Para nós, existem duas formas de heartbeats:
atualizações para o .status de um Nó
Objetos Lease dentro do namespacekube-node-lease. Cada nó tem um objeto de Lease associado.
Em comparação com as atualizações no .status de um nó, um Lease é um recurso mais leve. O uso de Leases para heartbeats reduz o impacto no desempenho dessas atualizações para grandes clusters.
O kubelet é responsável por criar e atualizar o .status dos Nós e por atualizar suas Leases relacionadas.
O kubelet atualiza o .status do nó quando há mudança de status ou se não houve atualização para um intervalo configurado. O intervalo padrão para atualizações .status para Nós é de 5 minutos, o que é muito maior do que o tempo limite padrão de 40 segundos para nós inacessíveis.
O kubelet cria e atualiza seu objeto Lease a cada 10 segundos (o intervalo de atualização padrão). As atualizações de Lease ocorrem independentemente das atualizações no .status do Nó. Se a atualização do Lease falhar, o kubelet voltará a tentativas, usando um recuo exponencial que começa em 200 milissegundos e limitado a 7 segundos.
Controlador de Nós
O controlador de nós é um componente da camada de gerenciamento do Kubernetes que gerencia vários aspectos dos nós.
O controlador de nó tem várias funções na vida útil de um nó. O primeiro é atribuir um bloco CIDR ao nó quando ele é registrado (se a atribuição CIDR estiver ativada).
O segundo é manter a lista interna de nós do controlador de nós atualizada com a lista de máquinas disponíveis do provedor de nuvem. Ao ser executado em um ambiente de nuvem e sempre que um nó não é íntegro, o controlador de nó pergunta ao provedor de nuvem se a VM desse nó ainda está disponível. Caso contrário, o controlador de nós exclui o nó de sua lista de nós.
O terceiro é monitorar a saúde dos nós. O controlador do nó é responsável por:
No caso de um nó se tornar inacessível, atualizar a condição NodeReady dentro do campo .status do nó. Nesse caso, o controlador do nó define a condição de pronto (NodeReady) como condição desconhecida (ConditionUnknown).
Se um nó permanecer inacessível: será iniciado a remoção pela API para todos os Pods no nó inacessível. Por padrão, o controlador do nó espera 5 minutos entre marcar o nó como condição desconhecida (ConditionUnknown) e enviar a primeira solicitação de remoção.
O controlador de nó verifica o estado de cada nó a cada --node-monitor-period segundos.
Limites de taxa de remoção
Na maioria dos casos, o controlador de nós limita a taxa de remoção a --node-eviction-rate (0,1 por padrão) por segundo, o que significa que ele não removerá pods de mais de 1 nó por 10 segundos.
O comportamento de remoção do nó muda quando um nó em uma determinada zona de disponibilidade se torna não íntegro. O controlador de nós verifica qual porcentagem de nós na zona não são íntegras (a condição NodeReady é desconhecida ConditionUnknown ou falsa ConditionFalse) ao mesmo tempo:
Se a fração de nós não íntegros for ao menos --unhealthy-zone-threshold (padrão 0,55), então a taxa de remoção será reduzida.
Se o cluster for pequeno (ou seja, tiver número de nós menor ou igual ao valor da opção --large-cluster-size-threshold - padrão 50), então as remoções serão interrompidas.
Caso contrário, a taxa de remoção é reduzida para --secondary-node-eviction-rate de nós secundários (padrão 0,01) por segundo.
A razão pela qual essas políticas são implementadas por zona de disponibilidade é porque a camada de gerenciamento pode perder conexão com uma zona de disponibilidade, enquanto as outras permanecem conectadas. Se o seu cluster não abranger várias zonas de disponibilidade de provedores de nuvem, o mecanismo de remoção não levará em conta a indisponibilidade por zona.
Uma das principais razões para espalhar seus nós pelas zonas de disponibilidade é para que a carga de trabalho possa ser transferida para zonas íntegras quando uma zona inteira cair. Portanto, se todos os nós em uma zona não estiverem íntegros, o controlador do nó removerá na taxa normal de --node-eviction-rate. O caso especial é quando todas as zonas estiverem completamente insalubres (nenhum dos nós do cluster será íntegro). Nesse caso, o controlador do nó assume que há algum problema com a conectividade entre a camada de gerenciamento e os nós e não realizará nenhuma remoção. (Se houver uma interrupção e alguns nós reaparecerem, o controlador do nó expulsará os pods dos nós restantes que estiverem insalubres ou inacessíveis).
O controlador de nós também é responsável por remover pods em execução nos nós com NoExecute taints, a menos que esses pods tolerem essa taint. O controlador de nó também adiciona as taints correspondentes aos problemas de nó, como nó inacessível ou não pronto. Isso significa que o escalonador não colocará Pods em nós não íntegros.
Rastreamento de capacidade de recursos
Os objetos do nó rastreiam informações sobre a capacidade de recursos do nó: por exemplo, a quantidade de memória disponível e o número de CPUs. Os nós que se auto-registram relatam sua capacidade durante o registro. Se você adicionar manualmente um nó, precisará definir as informações de capacidade do nó ao adicioná-lo.
O escalonador do Kubernetes garante que haja recursos suficientes para todos os Pods em um nó. O escalonador verifica se a soma das solicitações de contêineres no nó não é maior do que a capacidade do nó. Essa soma de solicitações inclui todos os contêineres gerenciados pelo kubelet, mas exclui quaisquer contêineres iniciados diretamente pelo agente de execução de contêiner e também exclui quaisquer processos executados fora do controle do kubelet.
Se você ativou os [recursos]](/docs/reference/command-line-tools-reference/feature-gates/) de TopologyManager, o kubelet pode usar dicas da topologia ao tomar decisões de atribuição de recursos. Consulte Controle das Políticas de Gerenciamento de Topologia em um Nó para obter mais informações.
Desligamento gracioso do nó
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [beta]
O kubelet tenta detectar o desligamento do sistema do nó e encerra os pods em execução no nó.
O Kubelet garante que os pods sigam o processo normal de término do podpod-lifecycle/#pod-termination) durante o desligamento do nó.
O recurso de desligamento gradual do nó depende do systemd, pois aproveita os bloqueios do inibidor do systemd para atrasar o desligamento do nó com uma determinada duração.
O desligamento gradual do nó é controlado com recursosGracefulNodeShutdown, que é ativado por padrão na versão 1.21.
Observe que, por padrão, ambas as opções de configuração descritas abaixo, shutdownGracePeriod and shutdownGracePeriodCriticalPods estão definidas como zero, não ativando assim a funcionalidade de desligamento gradual do nó. Para ativar o recurso, as duas configurações do kubelet devem ser configuradas adequadamente e definidas como valores diferentes de zero.
Durante um desligamento gradual, o kubelet encerra os pods em duas fases:
O recurso de desligamento gradual do nó é configurado com duas opções KubeletConfiguration:
shutdownGracePeriod:
Especifica a duração total pela qual o nó deve atrasar o desligamento. Este é o período de carência total para o término dos pods regulares e os críticos.
shutdownGracePeriodCriticalPods:
Especifica a duração utlizada para encerrar pods críticos durante um desligamento de nó. Este valor deve ser menor que shutdownGracePeriod.
Por exemplo, se shutdownGracePeriod=30s e shutdownGracePeriodCriticalPods=10s, o kubelet atrasará o desligamento do nó em 30 segundos. Durante o desligamento, os primeiros 20 (30-10) segundos seriam reservados para encerrar gradualmente os pods normais, e os últimos 10 segundos seriam reservados para encerrar pods críticos.
Nota:
Quando os pods forem removidos durante o desligamento gradual do nó, eles serão marcados como desligados. Executar o kubectl get pods para mostrar o status dos pods removidos como Terminated. E o kubectl describe pod indica que o pod foi removido por causa do desligamento do nó:
Reason: Terminated
Message: Pod was terminated in response to imminent node shutdown.
Desligamento gradual do nó baseado em prioridade do Pod
ESTADO DA FUNCIONALIDADE:Kubernetes v1.24 [beta]
Para fornecer mais flexibilidade durante o desligamento gradual do nó em torno da ordem de pods durante o desligamento, o desligamento gradual do nó respeita a PriorityClass dos Pods, desde que você tenha ativado esse recurso em seu cluster. O recurso permite que o cluster defina explicitamente a ordem dos pods durante o desligamento gradual do nó com base em classes de prioridade.
O recurso Desligamento Gradual do Nó, conforme descrito acima, desliga pods em duas fases, pods não críticos, seguidos por pods críticos. Se for necessária flexibilidade adicional para definir explicitamente a ordem dos pods durante o desligamento de uma maneira mais granular, o desligamento gradual baseado na prioridade do pod pode ser usado.
Quando o desligamento gradual do nó respeita as prioridades do pod, isso torna possível fazer o desligamento gradual do nó em várias fases, cada fase encerrando uma classe de prioridade específica de pods. O kubelet pode ser configurado com as fases exatas e o tempo de desligamento por fase.
Assumindo as seguintes classes de prioridade de pod personalizadas em um cluster,
Nome das classes de prioridade
Valor das classes de prioridade
custom-class-a
100000
custom-class-b
10000
custom-class-c
1000
regular/unset
0
Na configuração do kubelet, as configurações para shutdownGracePeriodByPodPriority são semelhantes a:
Valor das classes de prioridade
Tempo de desligamento
100000
10 segundos
10000
180 segundos
1000
120 segundos
0
60 segundos
A configuração correspondente do YAML do kubelet seria:
A tabela acima implica que qualquer pod com valor priority >= 100000 terá apenas 10 segundos para parar qualquer pod com valor >= 10000 e < 100000 e terá 180 segundos para parar, qualquer pod com valor >= 1000 e < 10000 terá 120 segundos para parar. Finalmente, todos os outros pods terão 60 segundos para parar.
Não é preciso especificar valores correspondentes para todas as classes. Por exemplo, você pode usar estas configurações:
Valor das classes de prioridade
Tempo de desligamento
100000
300 segundos
1000
120 segundos
0
60 segundos
No caso acima, os pods com custom-class-b irão para o mesmo bucket que custom-class-c para desligamento.
Se não houver pods em um intervalo específico, o kubelet não irá espera por pods nesse intervalo de prioridades. Em vez disso, o kubelet pula imediatamente para o próximo intervalo de valores da classe de prioridade.
Se esse recurso estiver ativado e nenhuma configuração for fornecida, nenhuma ação de pedido será tomada.
O uso desse recurso requer ativar os recursos GracefulNodeShutdownBasedOnPodPriority e definir o ShutdownGracePeriodByPodPriority da configuração do kubelet para a configuração desejada, contendo os valores da classe de prioridade do pod e seus respectivos períodos de desligamento.
Gerenciamento da memória swap
ESTADO DA FUNCIONALIDADE:Kubernetes v1.22 [alpha]
Antes do Kubernetes 1.22, os nós não suportavam o uso de memória swap, e um kubelet, por padrão, não iniciaria se a troca fosse detectada em um nó. A partir de 1.22, o suporte a memória swap pode ser ativado por nó.
Para ativar a troca em um nó, o recursos NodeSwap deve estar ativado no kubelet, e a configuração de comando de linha --fail-swap-on ou failSwapOn deve ser definida como falsa.
Aviso:
Quando o recurso de memória swap está ativado, os dados do Kubernetes, como o conteúdo de objetos Secret que foram gravados no tmpfs, agora podem ser trocados para o disco.
Opcionalmente, um usuário também pode configurar memorySwap.swapBehavior para especificar como um nó usará memória swap. Por exemplo,
memorySwap:swapBehavior:LimitedSwap
As opções de configuração disponíveis para swapBehavior são:
LimitedSwap: As cargas de trabalho do Kubernetes são limitadas na quantidade de troca que podem usar. Cargas de trabalho no nó não gerenciadas pelo Kubernetes ainda podem ser trocadas.
UnlimitedSwap: As cargas de trabalho do Kubernetes podem usar tanta memória de swap quanto solicitarem, até o limite do sistema.
Se a configuração do memorySwap não for especificada e o recurso estiver ativado, por padrão, o kubelet aplicará o mesmo comportamento que a configuração LimitedSwap.
O comportamento da configuração LimitedSwap depende se o nó estiver sendo executado com v1 ou v2 de grupos de controle (também conhecidos como "cgroups"):
cgroupsv1: As cargas de trabalho do Kubernetes podem usar qualquer combinação de memória e swap, até o limite de memória do pod, se definido.
cgroupsv2: As cargas de trabalho do Kubernetes não podem usar memória swap.
Para obter mais informações e para ajudar nos testes e fornecer feedback, consulte KEP-2400 e sua proposta de design.
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.
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.
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
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [beta]
Como uma substituição aos túneis SSH, o serviço Konnectivity fornece proxy de nível TCP para a comunicação do control plane para o cluster. O serviço Konnectivity consiste em duas partes: o servidor Konnectivity na rede control plane e os agentes Konnectivity na rede dos nós. Os agentes Konnectivity iniciam conexões com o servidor Konnectivity e mantêm as conexões de rede. Depois de habilitar o serviço Konnectivity, todo o tráfego do control plane para os nós passa por essas conexões.
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
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:
Inicializar um node com labels de região/zona específicos para a nuvem.
Inicialize um node com detalhes de instância específicos da nuvem, por exemplo, tipo e tamanho.
Obtenha os endereços de rede e o nome do host do node.
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.
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.
Esta seção divide o acesso necessário em vários objetos da API pelo CCM para executar suas operações.
Node Controller
O Node Controller só funciona com objetos Node. Ele requer acesso total para obter, listar, criar, atualizar, corrigir, assistir e excluir objetos Node.
v1/Node:
Get
List
Create
Update
Patch
Watch
Delete
Rote Controller
O Rote Controller escuta a criação do objeto Node e configura as rotas apropriadamente. Isso requer acesso a objetos Node.
v1/Node:
Get
Service Controller
O Service Controller escuta eventos de criação, atualização e exclusão de objeto de serviço e, em seguida, configura pontos de extremidade para esses serviços de forma apropriada.
Para acessar os Serviços, é necessário listar e monitorar o acesso. Para atualizar os Serviços, ele requer patch e atualização de acesso.
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.
Voce vai encontrar instruções completas para configurar e executar o CCM
aqui.
3.2.4 - Controladores
Em robótica e automação um control loop, ou em português ciclo de controle, é
um ciclo não terminado que regula o estado de um sistema.
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.
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.
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.
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.
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.
Quando imagePullPolicy é definido sem um valor específico, ele também é definido como Always.
Multiarquitetura de imagens com índice de imagens
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
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:
Execute docker login [servidor] para cada conjunto de credenciais que deseja usar. Isso atualiza o $HOME/.docker/config.json em seu PC.
Visualize $HOME/.docker/config.json em um editor para garantir que contém apenas as credenciais que você deseja usar.
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}' )
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:
Fri, 26 Jun 2015 15:36:13 -0700 Fri, 26 Jun 2015 15:39:13 -0700 19 {kubelet node-i2hq} spec.containers{uses-private-image} failed Failed to pull image "user/privaterepo:v1": Error: image user/privaterepo:v1 not found
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:
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.
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.
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.
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.
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.
Mova dados confidenciais para um recurso "secreto", em vez de empacotá-los em uma imagem.
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
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.
ESTADO DA FUNCIONALIDADE: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
Configure a implementação do CRI nos nós (depende do agente de execução)
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.iokind:RuntimeClassmetadata: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
É 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:
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
finalFailed. 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.
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:
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:
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
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [beta]
Você pode especificar os recursos extra que estão associados à execução de um Pod. Declarar esses
recursos extra permite ao cluster (incluindo o agendador/scheduler de pods) contabilizar por
esses recursos quando estiver decidindo sobre Pods e recursos. Para usar a contabilização
desses recursos extras, você deve estar com o feature gate
PodOverhead habilitado (ele já está habilitado por padrão).
Os recursos extras utilizados são especificados no objeto RuntimeClass através do campo overhead.
Ao usar esses campos, você especifica o uso extra de recursos necessários para executar
Pods utilizando-se desse Runtimeclass e assim contabilizar esses recursos para o Kubernetes.
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 hookPreStop 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 hookPreStop 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 hookPostStart, o ENTRYPOINT do contêiner e o hook disparam de forma assíncrona.
No entanto, se o hook demorar muito para ser executado ou travar, o contêiner não consegue atingir o estado running.
Os hooksPreStop 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 hookPreStop 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 hookPreStopexecutar 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 hookPostStart 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 SubObjectPath Type Reason Message
--------- -------- ----- ---- ------------- -------- ------ -------
1m 1m 1 {default-scheduler } Normal Scheduled Successfully assigned test-1730497541-cq1d2 to gke-test-cluster-default-pool-a07e5d30-siqd
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulling pulling image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Created Created container with docker id 5c6a256a2567; Security:[seccomp=unconfined]
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Pulled Successfully pulled image "test:1.0"
1m 1m 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Started Started container with docker id 5c6a256a2567
38s 38s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 5c6a256a2567: PostStart handler: Error executing in Docker Container: 1
37s 37s 1 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Normal Killing Killing container with docker id 8df9fdfd7054: PostStart handler: Error executing in Docker Container: 1
38s 37s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "main" with RunContainerError: "PostStart handler: Error executing in Docker Container: 1"
1m 22s 2 {kubelet gke-test-cluster-default-pool-a07e5d30-siqd} spec.containers{main} Warning FailedPostStartHook
3.4 - 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.
3.4.1 - Ingress
Disponibilize seu serviço de rede HTTP ou HTTPS usando um mecanismo de configuração com reconhecimento de protocolo, que entende conceitos da Web como URIs, nomes de host, caminhos e muito mais. O conceito Ingress permite mapear o tráfego para diferentes backends com base nas regras definidas por meio da API do Kubernetes.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.19 [stable]
Um objeto da API (do inglês "Application Programming Interface") que gerencia o acesso externo aos serviços em um cluster, normalmente HTTP.
Um Ingress pode fornecer balanceamento de carga, terminação SSL e hospedagem
virtual baseada em nomes.
Terminologia
Para fins de clareza, este guia define os seguintes termos:
Nó: Uma máquina de trabalho no Kubernetes, parte de um cluster.
Cluster: Um conjunto de nós que executam aplicações em contêiner gerenciado pelo Kubernetes. Para este exemplo, e nas instalações mais comuns do Kubernetes, os nós no cluster não fazem parte da Internet pública.
Roteador de borda: Um roteador que impõe a política de firewall para o seu cluster. Isso pode ser um gateway gerenciado por um provedor de nuvem ou um hardware físico.
Rede do cluster: Um conjunto de links, lógicos ou físicos, que facilitam a comunicação dentro de um cluster de acordo com o modelo de rede do Kubernetes.
Serviço: Um objeto serviço do Kubernetes que identifica um conjunto de Pods usando seletores de label. Salvo indicação em contrário, assume-se que os Serviços tenham IPs virtuais apenas roteáveis dentro da rede de cluster.
O que é o Ingress?
O Ingress expõe rotas HTTP e HTTPS de fora do cluster para um serviço dentro do cluster.
O roteamento do tráfego é controlado por regras definidas no recurso Ingress.
Aqui está um exemplo simples em que o Ingress envia todo o seu tráfego para um serviço:
Um Ingress pode ser configurado para fornecer URLs acessíveis externamente aos serviços, balanceamento de carga de tráfego, terminação SSL/TLS e oferecer hospedagem virtual baseada em nome.
Um controlador Ingress é responsável por atender o Ingress, geralmente com um balanceador de carga, embora também possa configurar seu roteador de borda ou frontends adicionais para ajudar a lidar com o tráfego.
Um Ingress não expõe portas ou protocolos arbitrários.
Normalmente se usa um serviço do tipo Service.Type=NodePort ou Service.Type=LoadBalancer para expor serviços à Internet que não sejam HTTP e HTTPS.
Pré-requisitos
Você deve ter um controlador Ingress para satisfazer um Ingress.
Apenas a criação de um recurso Ingress não tem efeito.
Idealmente, todos os controladores Ingress devem se encaixar na especificação de referência.
Na realidade, os vários controladores Ingress operam de forma ligeiramente diferente.
Nota:
Certifique-se de revisar a documentação do seu controlador Ingress para entender as ressalvas de escolhê-lo.
Um Ingress precisa dos campos apiVersion, kind, metadata e spec.
O nome de um objeto Ingress deve ser um nome de subdomínio DNS válido.
Para obter informações gerais sobre como trabalhar com arquivos de configuração, consulte como instalar aplicações, como configurar contêineres e como gerenciar recursos.
O Ingress frequentemente usa anotações para configurar opções dependendo do controlador Ingress. Um exemplo deste uso é a anotação rewrite-target.
Diferentes controladores Ingress suportam diferentes anotações.
Revise a documentação do seu controlador Ingress escolhido para saber quais anotações são suportadas.
A especificação Ingress tem todas as informações necessárias para configurar um balanceador de carga ou servidor proxy.
Mais importante ainda, ele contém uma lista de regras correspondentes a todas as solicitações recebidas.
O recurso Ingress suporta apenas regras para direcionar o tráfego HTTP(S).
Existem alguns controladores Ingress que funcionam sem a definição de uma IngressClass padrão.
Por exemplo, o controlador Ingress-NGINX pode ser configurado com uma flag--watch-ingress-without-class.
No entanto, recomenda-se especificar a IngressClass padrão, conforme mostrado abaixo.
Regras do Ingress
Cada regra HTTP contém as seguintes informações:
Um host opcional. Neste exemplo, nenhum host é especificado, portanto, a regra se aplica a todo o tráfego HTTP de entrada através do endereço IP especificado.
Se um host for fornecido (por exemplo, foo.bar.com), as regras se aplicam a esse host.
Uma lista de caminhos (por exemplo, /testpath), cada um com um backend associado definido com um service.name e um service.port.name ou service.port.number.
Tanto o host quanto o caminho devem corresponder ao conteúdo de uma solicitação recebida antes que o balanceador de carga direcione o tráfego para o serviço referenciado.
Um backend é uma combinação de nomes de serviço e porta, conforme descrito na documentação de Services ou um backend de recursos personalizados por meio de um CRD.
As solicitações HTTP e HTTPS para o Ingress que correspondem ao host e ao caminho da regra são enviadas para o backend listado.
Um defaultBackend geralmente é configurado em um controlador Ingress para atender a quaisquer solicitações que não correspondam a um caminho na especificação.
DefaultBackend
Um Ingress sem regras envia todo o tráfego para um único backend padrão e .spec.defaultBackend é o backend que deve lidar com as solicitações nesse caso.
O defaultBackend é convencionalmente uma opção de configuração do controlador Ingress e não é especificado em seus recursos Ingress.
Se nenhum .spec.rules for especificado, o .spec.defaultBackend deve ser especificado.
Se o defaultBackend não for definido, o tratamento de solicitações que não correspondem a nenhuma das regras ficará a cargo do controlador de Ingress (consulte a documentação do seu controlador de Ingress para descobrir como ele lida com esse caso).
Se nenhum dos hosts ou caminhos corresponder à solicitação HTTP nos objetos Ingress, o tráfego será roteado para o seu backend padrão.
Resource backends
Um Resource backend é um ObjectRef para outro recurso Kubernetes dentro do mesmo namespace que o objeto Ingress.
Um Resource é uma configuração mutuamente exclusiva com o serviço, e a validação irá falhar se ambos forem especificados.
Um uso comum para um Resource backend é inserir dados em um backend de armazenamento de objetos com ativos estáticos.
Cada caminho no Ingress deve ter um tipo de caminho correspondente.
Os caminhos que não incluem um pathType explícito falharão na validação.
Existem três tipos de caminho suportados:
ImplementationSpecific: Com esse tipo de caminho, a correspondência depende da IngressClass. As implementações podem tratar isso como um pathType separado ou tratá-lo de forma idêntica aos tipos de caminho Prefix ou Exact.
Exact: Corresponde exatamente ao caminho da URL podendo ser case-sensitive.
Prefix: Corresponde com base em um prefixo de caminho de URL dividido por /. A correspondência faz distinção entre maiúsculas e minúsculas e é feita em um caminho, elemento por elemento. Um elemento de caminho refere-se à lista de labels no caminho dividido pelo separador /. Uma solicitação é uma correspondência para o caminho p se cada p for um prefixo elementar de p do caminho da solicitação.
Nota:
Se o último elemento do caminho for uma substring do último elemento no caminho da solicitação, não é uma correspondência (por exemplo: /foo/bar corresponde a /foo/bar/baz, mas não corresponde a /foo/barbaz).
Exemplos
Tipos
Caminho(s)
Caminho(s) de solicitação
Correspondências?
Prefix
/
(todos os caminhos)
Sim
Exact
/foo
/foo
Sim
Exact
/foo
/bar
Não
Exact
/foo
/foo/
Não
Exact
/foo/
/foo
Não
Prefix
/foo
/foo, /foo/
Sim
Prefix
/foo/
/foo, /foo/
Sim
Prefix
/aaa/bb
/aaa/bbb
Não
Prefix
/aaa/bbb
/aaa/bbb
Sim
Prefix
/aaa/bbb/
/aaa/bbb
Sim, ignora a barra final
Prefix
/aaa/bbb
/aaa/bbb/
Sim, combina com a barra final
Prefix
/aaa/bbb
/aaa/bbb/ccc
Sim, corresponde ao subcaminho
Prefix
/aaa/bbb
/aaa/bbbxyz
Não, não corresponde ao prefixo da string
Prefix
/, /aaa
/aaa/ccc
Sim, corresponde ao prefixo /aaa
Prefix
/, /aaa, /aaa/bbb
/aaa/bbb
Sim, corresponde ao prefixo /aaa/bbb
Prefix
/, /aaa, /aaa/bbb
/ccc
Sim, corresponde ao prefixo /
Prefix
/aaa
/ccc
Não, usa o backend padrão
Mixed
/foo (Prefix), /foo (Exact)
/foo
Sim, prefere o exact
Várias correspondências
Em alguns casos, vários caminhos dentro de uma entrada corresponderão a uma solicitação.
Nesses casos, a precedência será dada primeiro ao caminho correspondente mais longo.
Se dois caminhos ainda estiverem iguais, a precedência será dada aos caminhos com um tipo de caminho exato sobre o tipo de caminho de prefixo.
Hostname curingas
Os hosts podem ter correspondências precisas (por exemplo, “foo.bar.com”) ou um curinga (por exemplo, “*.foo.com”).
Correspondências precisas exigem que o cabeçalho do host HTTP corresponda ao campo host.
As correspondências curinga exigem que o cabeçalho do host HTTP seja igual ao sufixo da regra curinga.
Host
Host header
Corresponde?
*.foo.com
bar.foo.com
Correspondências baseadas no sufixo compartilhado
*.foo.com
baz.bar.foo.com
Sem correspondência, o curinga cobre apenas um único rótulo DNS
*.foo.com
foo.com
Sem correspondência, o curinga cobre apenas um único rótulo DNS
Os Ingress podem ser implementados por diferentes controladores, muitas vezes com diferentes configurações.
Cada Ingress deve especificar uma classe, uma referência a um recurso IngressClass que contém uma configuração adicional, incluindo o nome do controlador que deve implementar a classe.
O campo .spec.parameters de uma classe Ingress permite que você faça referência a outro recurso que fornece a configuração relacionada a essa classe Ingress.
O tipo específico de parâmetros a serem usados depende do controlador Ingress que você especificar no campo .spec.controller da classe Ingress.
Escopo da classe Ingress
Dependendo do seu controlador Ingress, os parâmetros definidos em todo o cluster ou apenas para um namespace poderão ser utilizados.
O escopo padrão para os parâmetros da classe Ingress é em todo o cluster.
Se você definir o campo .spec.parameters e não definir .spec.parameters.scope, ou se você definir .spec.parameters.scope como Cluster, então a classe Ingress se refere a um recurso com escopo de cluster.
O kind (em combinação com o apiGroup) dos parâmetros refere-se a uma API com escopo de cluster (possivelmente um recurso personalizado), e o name dos parâmetros identifica um recurso específico com escopo de cluster para essa API.
Por exemplo:
---apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lb-1spec:controller:example.com/ingress-controllerparameters:# Os parâmetros para esta classe Ingress são especificados em um# ClusterIngressParameter (grupo de API k8s.example.net) nomeado# "external-config-1". Esta definição diz ao Kubernetes para# procurar um recurso de parâmetro com escopo de cluster. scope:ClusterapiGroup:k8s.example.netkind:ClusterIngressParametername:external-config-1
ESTADO DA FUNCIONALIDADE:Kubernetes v1.23 [stable]
Se você definir o campo .spec.parameters e definir .spec.parameters.scope como Namespace, a classe Ingress terá como referência um recurso com escopo de namespace.
Você também deve definir o campo namespace dentro de .spec.parameters para o namespace que contém os parâmetros que deseja usar.
O campo kind (em combinação com o campo apiGroup) dos parâmetros refere-se a uma API com namespace (por exemplo: ConfigMap), e o campo name dos parâmetros identifica um recurso específico no namespace que você especificou no campo namespace.
Os parâmetros com escopo de namespace ajudam o operador de cluster a delegar o controle sobre a configuração (por exemplo: configurações do balanceador de carga, definição de gateway API) que é usada para uma carga de trabalho.
Se você usou um parâmetro com escopo de cluster, então:
A equipe do operador do cluster precisa aprovar as alterações de uma equipe diferente toda vez que houver uma nova alteração de configuração sendo aplicada.
O operador de cluster deve definir controles de acesso específicos, como funções e vínculos RBAC, que permitem que a equipe do aplicativo faça alterações no recurso de parâmetros do escopo do cluster.
A própria API do IngressClass é sempre com escopo de cluster.
Aqui está um exemplo de uma classe Ingress que se refere a parâmetros com namespace:
---apiVersion:networking.k8s.io/v1kind:IngressClassmetadata:name:external-lb-2spec:controller:example.com/ingress-controllerparameters:# The parameters for this IngressClass are specified in an# IngressParameter (API group k8s.example.com) named "external-config",# that's in the "external-configuration" namespace.scope:NamespaceapiGroup:k8s.example.comkind:IngressParameternamespace:external-configurationname:external-config
Anotação obsoleta
Antes que o recurso IngressClass e o campo ingressClassName fossem adicionados no Kubernetes 1.18, as classes Ingress foram especificadas com uma anotação kubernetes.io/ingress.class no Ingress.
Esta anotação nunca foi formalmente definida, mas foi amplamente apoiada pelos controladores Ingress.
O campo ingressClassName mais recente no Ingress é um substituto para essa anotação, mas não é um equivalente direto.
Embora a anotação tenha sido geralmente usada para fazer referência ao nome do controlador Ingress que deve implementar o Ingress, o campo é uma referência a um recurso IngressClass que contém a configuração Ingress adicional, incluindo o nome do controlador Ingress.
Classe Ingress Padrão
Você pode marcar uma classe Ingress específica como padrão para o seu cluster.
Definir a anotação ingressclass.kubernetes.io/is-default-class como true em um recurso IngressClass garantirá que novos Ingress sem um campo ingressClassName especificado sejam atribuídos a esta ingressClassName padrão.
Cuidado:
Se você tiver mais de uma classe Ingress marcada como padrão para o seu cluster, o controlador de admissão impede a criação de novos objetos Ingress que não tenham um ingressClassName especificado.
Você pode resolver isso garantindo que no máximo uma classe Ingress seja marcada como padrão no seu cluster.
Existem alguns controladores Ingress que funcionam sem a definição de uma IngressClass padrão.
Por exemplo, o controlador Ingress-NGINX pode ser configurado com uma flag--watch-ingress-without-class.
No entanto, é recomendável especificar a IngressClass padrão:
No Kubernetes existem conceitos que permitem expor um único serviço (veja alternativas).
Você também pode fazer isso com um Ingress especificando um backend padrão sem regras.
Se você criá-lo usando kubectl apply -f, você deve ser capaz de visualizar o estado do Ingress que você adicionou:
kubectl get ingress test-ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
test-ingress external-lb * 203.0.113.123 80 59s
Onde 203.0.113.123 é o IP alocado pelo controlador Ingress para satisfazer o Ingress.
Nota:
Controladores Ingress e balanceadores de carga podem levar um ou dois minutos para alocar um endereço IP.
Até aquele momento, você costuma ver o endereço listado como <pending>.
Simples fanout
Uma configuração de fanout roteia o tráfego de um único endereço IP para mais de um serviço, com base na URI HTTP que está sendo solicitada.
Um Ingress permite que você mantenha o número de balanceadores de carga no mínimo.
Por exemplo, uma configuração como:
Name: simple-fanout-example
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:4200 (10.8.0.90:4200)
/bar service2:8080 (10.8.0.91:8080)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 22s loadbalancer-controller default/test
O controlador Ingress fornece um balanceador de carga específico de implementação que satisfaz o Ingress, desde que os serviços (service1, service2) existam.
Quando tiver feito isso, você pode ver o endereço do balanceador de carga no campo Address.
Nota:
Dependendo do controlador Ingress que você está usando, talvez seja necessário criar um serviço de backend http padrão.
Hospedagem virtual baseada em nome
Os hosts virtuais baseados em nomes suportam o roteamento de tráfego HTTP para vários nomes de host no mesmo endereço IP.
O Ingress a seguir diz ao balanceador de carga de apoio para rotear solicitações com base no Host header.
Se você criar um recurso de Ingress sem nenhum host definido nas regras, qualquer tráfego da web para o endereço IP do seu controlador de Ingress pode ser correspondido sem que seja necessário um host virtual baseado em nome.
Por exemplo, o Ingress a seguir roteia o tráfego solicitado para first.bar.com para service1, second.bar.com para service2 e qualquer tráfego cujo cabeçalho de host de solicitação não corresponda a first.bar.com e second.bar.com para service3.
Você pode configurar o uso de TLS no Ingress especificando um Secret que contém uma chave privada e um certificado TLS.
O recurso Ingress suporta apenas uma única porta TLS, 443, e assume a terminação TLS no ponto de entrada (o tráfego para o Serviço e seus Pods não está criptografado o que é inseguro).
Se a seção de configuração TLS em um Ingress especificar hosts diferentes, eles serão multiplexados na mesma porta de acordo com o nome do host especificado através da extensão SNI TLS (desde que o controlador Ingress suporte SNI).
O objeto Secret do tipo TLS deve conter chaves chamadas tls.crt e tls.key que contêm o certificado e a chave privada a ser usada para TLS.
Fazer referência a esse segredo em um Ingress diz ao controlador Ingress para proteger o canal do cliente para o balanceador de carga usando TLS.
Você precisa ter certeza de que o objeto Secret do tipo TLS que você criou é originário de um certificado que contém um Nome Comum (Common
Name, CN), também conhecido como Nome de Domínio Totalmente Qualificado (Fully Qualified Domain Name, FQDN), tal como https-example.foo.com.
Nota:
Tenha em mente que o TLS não funcionará na regra padrão porque os certificados teriam que ser emitidos para todos os subdomínios possíveis.
Portanto, os hosts na seção tls precisam corresponder explicitamente ao host na seção rules.
Há uma lacuna entre os recursos TLS suportados por vários controladores Ingress.
Consulte a documentação sobre nginx, GCE ou qualquer outro controlador Ingress específico da plataforma para entender como o TLS funciona em seu ambiente.
Balanceador de carga
Um controlador Ingress é inicializado com algumas configurações de política de balanceamento de carga que se aplicam a todos os Ingress, como o algoritmo de balanceamento de carga, esquema de peso de backend e outros.
Conceitos mais avançados de balanceamento de carga (por exemplo, sessões persistentes, pesos dinâmicos) ainda não estão expostos através do Ingress.
Em vez disso, você pode obter esses recursos através do balanceador de carga usado para um serviço.
Também vale a pena notar que, embora as verificações de integridade não sejam expostas diretamente através do Ingress, existem conceitos paralelos no Kubernetes, como readiness probes, que permitem alcançar o mesmo resultado final.
Revise a documentação específica do controlador para ver como eles lidam com as verificações de integridade (por exemplo: nginx ou GCE).
Atualizando um Ingress
Para atualizar um Ingress existente para adicionar um novo Host, você pode atualizá-lo editando o recurso:
kubectl describe ingress test
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 35s loadbalancer-controller default/test
kubectl edit ingress test
Isso abre um editor com a configuração existente no formato YAML.
Para incluir o novo host modifique:
Depois de salvar suas alterações, o kubectl atualizará o recurso no servidor API, que diz ao controlador Ingress para reconfigurar o balanceador de carga.
Verifique isso:
kubectl describe ingress test
Name: test
Namespace: default
Address: 178.91.123.132
Default backend: default-http-backend:80 (10.8.2.3:8080)
Rules:
Host Path Backends
---- ---- --------
foo.bar.com
/foo service1:80 (10.8.0.90:80)
bar.baz.com
/foo service2:80 (10.8.0.91:80)
Annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ADD 45s loadbalancer-controller default/test
Você pode alcançar o mesmo resultado invocando kubectl replace -f em um arquivo Ingress YAML modificado.
Falha nas zonas de disponibilidade
Técnicas para distribuir o tráfego entre domínios de falha diferem entre os provedores de nuvem.
Verifique a documentação do controlador Ingress para obter detalhes relevantes.
Alternativas
Você pode expor um serviço de várias maneiras que não envolve diretamente o recurso Ingress:
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:
Outros pods que são permitidos (exceção: um pod não pode bloquear a si próprio)
Namespaces que são permitidos
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.
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:
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)
(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)
(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.
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.
namespaceSelectorepodSelector: 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:
contém dois elementos no conjunto from e permite conexões de Pods no namespace local com
a labelrole=client, OU de qualquer outro Pod em qualquer outro namespace que tenha
a label user=alice.
Quando estiver em dúvida, utilize o comando kubectl describe para verificar como o
Kubernetes interpretou a política.
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.
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.
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.
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.
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
ESTADO DA FUNCIONALIDADE: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:
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 gateNetworkPolicyEndPort no kube-apiserver com a flag --feature-gates=NetworkPolicyEndPort=true,....
O valor de endPort deve ser igual ou maior ao valor do campo port.
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
ESTADO DA FUNCIONALIDADE: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.30 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.
Formas de fornecer armazenamento temporário e de longa duração a Pods em seu cluster.
3.5.1 - Volumes
Os arquivos em disco em um contêiner são efêmeros, o que apresenta alguns problemas para
aplicações não triviais quando executadas em contêineres. Um problema é a perda de arquivos
quando um contêiner quebra. O kubelet reinicia o contêiner, mas em um estado limpo. Um segundo
problema ocorre ao compartilhar arquivos entre contêineres que são executados juntos em
um Pod. A abstração de volume
do Kubernetes resolve ambos os problemas. Sugere-se familiaridade com Pods .
Contexto
Docker tem um conceito de volumes, embora seja um pouco mais
simples e menos gerenciado. Um volume Docker é um diretório em disco ou em outro contêiner.
O Docker oferece drivers de volume, mas a funcionalidade é um pouco limitada.
O Kubernetes suporta muitos tipos de volumes. Um Pod é capaz de utilizar qualquer quantidade de tipos de volumes simultaneamente. Os tipos de volume efêmeros têm a mesma vida útil do pod, mas os volumes persistentes existem além da vida útil de um pod. Quando um pod deixa de existir, o Kubernetes destrói volumes efêmeros; no entanto, o Kubernetes não destrói volumes persistentes. Para qualquer tipo de volume em um determinado pod, os dados são preservados entre as reinicializações do contêiner.
Em sua essência, um volume é um diretório, eventualmente com alguns dados dentro dele, que é acessível aos contêineres de um Pod. Como esse diretório vem a ser, o meio que o suporta e o conteúdo do mesmo são determinados pelo tipo particular de volume utilizado.
Para utilizar um volume, especifique os volumes que serão disponibilizados para o Pod em .spec.volumes e declare onde montar esses volumes dentro dos contêineres em .spec.containers[*].volumeMounts. Um processo em um contêiner enxerga uma visualização do sistema de arquivos composta pelo do conteúdo inicial da imagem do contêiner mais os volumes (se definidos) montados dentro do contêiner. O processo enxerga um sistema de arquivos raiz que inicialmente corresponde ao conteúdo da imagem do contêiner. Qualquer gravação dentro dessa hierarquia do sistema de arquivos, se permitida, afetará o que esse processo enxerga quando ele executa um acesso subsequente ao sistema de arquivos. Os volumes são montados nos caminhos especificados dentro da imagem. Para cada contêiner definido em um Pod, você deve especificar independentemente onde montar cada volume utilizado pelo contêiner.
Volumes não podem ser montados dentro de outros volumes (mas você pode consultar Utilizando subPath para um mecanismo relacionado). Além disso, um volume não pode conter um link físico para qualquer outro dado em um volume diferente.
Tipos de Volumes
Kubernetes suporta vários tipos de volumes.
awsElasticBlockStore (descontinuado)
Um volume awsElasticBlockStore monta um volume EBS da Amazon Web Services (AWS) em seu pod. Ao contrário do emptyDirque é apagado quando um pod é removido, o conteúdo de um volume EBS é preservado e o volume é desmontado. Isto significa que um volume EBS pode ser previamente populado com dados e que os dados podem ser compartilhados entre Pods.
Nota:
Você precisa criar um volume EBS usando aws ec2 create-volume ou pela API da AWS antes que você consiga utilizá-lo.
Existem algumas restrições ao utilizar um volume awsElasticBlockStore:
Os nós nos quais os Pods estão sendo executados devem ser instâncias AWS EC2
Estas instâncias devem estar na mesma região e na mesma zona de disponibilidade que o volume EBS
O EBS suporta montar um volume em apenas uma única instância EC2
Criando um volume AWS EBS
Antes de poder utilizar um volume EBS com um pod, precisa criá-lo.
Certifique-se de que a zona corresponde à mesma zona em que criou o cluster. Verifique se o tamanho e o tipo de volume EBS são adequados para a sua utilização.
Exemplo de configuração do AWS EBS
apiVersion:v1kind:Podmetadata:name:test-ebsspec:containers:- image:registry.k8s.io/test-webservername:test-containervolumeMounts:- mountPath:/test-ebsname:test-volumevolumes:- name:test-volume# Esse volume AWS EBS já deve existir.awsElasticBlockStore:volumeID:"<volume id>"fsType:ext4
Se o volume EBS estiver particionado, é possível informar o campo opcional partition: "<partition em number>" para especificar em que partição deve ser montado.
Migração de CSI do AWS EBS
ESTADO DA FUNCIONALIDADE:Kubernetes v1.25 [stable]
Quando o recurso CSIMigration para awsElasticBlockStore está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas para o driver Cointainer Storage Interface (CSI) ebs.csi.aws.com. Para usar esse recurso, o driver CSI AWS EBS deve estar instalado no cluster.
Migração CSI AWS EBS concluída
ESTADO DA FUNCIONALIDADE:Kubernetes v1.17 [alpha]
Para desabilitar o carregamento do plugin de armazenamento awsElasticBlockStore pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginAWSUnregister como true.
azureDisk (descontinuado)
ESTADO DA FUNCIONALIDADE:Kubernetes v1.19 [deprecated]
O tipo de volume azureDisk monta um Disco de Dados Microsoft Azure em um pod.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.24 [stable]
Quando o recurso CSIMigration para azureDisk está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas para o Driver de Cointêiner Storage Interface (CSI) disk.csi.azure.com. Para utilizar este recurso, o Driver CSI Azure Disk deve estar instalado no cluster.
Migração CSI azureDisk concluída
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [alpha]
Para desabilitar o carregamento do plugin de armazenamento azureDisk pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginAzureDiskUnregister como true.
azureFile (descontinuado)
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [deprecated]
O tipo de volume azureFile monta um volume de arquivo Microsoft Azure (SMB 2.1 e 3.0) em um pod.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.26 [stable]
Quando o recurso CSIMigration para azureFile está habilitado, todas as operações de plugin do tipo in-tree são redirecionadas para o Driver de Cointainer Storage Interface (CSI) file.csi.azure.com. Para utilizar este recurso, o Driver CSI do Azure Disk deve estar instalado no cluster e as feature gatesCSIMigration e CSIMigrationAzureFile devem estar habilitadas.
O driver de CSI do Azure File não oferece suporte ao uso do mesmo volume por fsgroups diferentes, se a migração de CSI Azurefile estiver habilitada, o uso do mesmo volume por fsgroups diferentes não será suportado.
Migração do CSI azureFile concluída
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [alpha]
Para desabilitar o carregamento do plugin de armazenamento azureFile pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginAzureFileUnregister como true.
cephfs
Um volume cephfs permite que um volume CephFS existente seja montado no seu Pod. Ao contrário do emptyDir que é apagado quando um pod é removido, o conteúdo de um volume cephfs é preservado e o volume é simplesmente desmontado. Isto significa que um volume cephfs pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods. O volume cephfs pode ser montado por vários gravadores simultaneamente.
Nota:
Você deve ter seu próprio servidor Ceph funcionando com o compartilhamento acessível antes de poder utilizá-lo.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [deprecated]
Nota:
O Kubernetes deve ser configurado com o provedor de nuvem OpenStack.
O tipo de volume cinder é utilizado para montar o volume do OpenStack Cinder no seu pod.
Exemplo de configuração de volume Cinder
apiVersion:v1kind:Podmetadata:name:test-cinderspec:containers:- image:registry.k8s.io/test-webservername:test-cinder-containervolumeMounts:- mountPath:/test-cindername:test-volumevolumes:- name:test-volume# Esse volume OpenStack já deve existir.cinder:volumeID:"<volume id>"fsType:ext4
Migração de CSI OpenStack
ESTADO DA FUNCIONALIDADE:Kubernetes v1.24 [stable]
O recurso CSIMigration para o Cinder é ativado por padrão no Kubernetes 1.21. Ele redireciona todas as operações de plugin do tipo in-tree para o Driver de Cointainer Storage Interface (CSI) cinder.csi.openstack.org. O Driver CSI OpenStack Cinder tem de estar instalado no cluster. Você pode desativar a migração Cinder CSI para o seu cluster definindo a feature gateCSIMigrationOpenStack como false. Se você desativar o recurso CSIMigrationOpenStack, o plugin de volume in-tree do Cinder assume a responsabilidade por todos os aspectos do gerenciamento de armazenamento de volume do Cinder.
configMap
Um ConfigMap oferece uma forma de injetar dados de configuração em Pods. Os dados armazenados em um ConfigMap podem ser referenciados em um volume de tipo configMap e depois consumidos por aplicações conteinerizadas executadas em um pod.
Ao referenciar um ConfigMap, você informa o nome do ConfigMap no volume. Pode personalizar o caminho utilizado para uma entrada específica no ConfigMap. A seguinte configuração mostra como montar o log-config do ConfigMap em um Pod chamado configmap-pod:
apiVersion:v1kind:Podmetadata:name:configmap-podspec:containers:- name:testimage:busybox:1.28command:['sh','-c','echo "The app is running!" && tail -f /dev/null']volumeMounts:- name:config-volmountPath:/etc/configvolumes:- name:config-volconfigMap:name:log-configitems:- key:log_levelpath:log_level
O ConfigMap log-config é montado como um volume e todos os conteúdos armazenados em sua entrada log_level são montados no Pod através do caminho /etc/config/log_level. Observe que esse caminho é derivado do volume mountPathe do path configurado com log_level.
Um contêiner que utiliza ConfigMap através de um ponto de montagem com a propriedade subPath não receberá atualizações deste ConfigMap.
Os dados de texto são expostos como arquivos utilizando a codificação de caracteres UTF-8. Para outras codificações de caracteres, use binaryData.
downwardAPI
Um volume downwardAPI disponibiliza dados da downward API para as aplicações. Ele monta um diretório e grava os dados solicitados em arquivos de texto sem formatação.
Nota:
Um contêiner que utiliza downward API através de um ponto de montagem com a propriedade subPath não receberá atualizações desta downward API.
Um volume emptyDir é criado pela primeira vez quando um Pod é atribuído a um nó e existe enquanto esse Pod estiver sendo executado nesse nó. Como o nome diz, o volume emptyDir está inicialmente vazio. Todos os contêineres no Pod podem ler e gravar os mesmos arquivos no volume emptyDir, embora esse volume possa ser montado no mesmo caminho ou em caminhos diferentes em cada contêiner. Quando um Pod é removido de um nó por qualquer motivo, os dados no emptyDir são eliminados permanentemente.
Nota:
A falha de um contêiner não remove um Pod de um nó. Os dados em um volume emptyDir são mantidos em caso de falha do contêiner.
Alguns usos para um emptyDir são:
espaço temporário, como para uma merge sort baseado em disco
ponto de verificação de um processamento longo para recuperação de falhas
manter arquivos que um contêiner gerenciador de conteúdo busca enquanto um contêiner de webserver entrega os dados
Dependendo do seu ambiente, os volumes emptyDir são armazenados em qualquer mídia que componha o nó, como disco ou SSD, ou armazenamento de rede. No entanto, se você definir o campo emptyDir.medium como "Memory", o Kubernetes monta um tmpfs (sistema de arquivos com suporte de RAM) para você. Embora o tmpfs seja muito rápido, tenha em atenção que, ao contrário dos discos, o tmpfs é limpo na reinicialização do nó e quaisquer arquivos que grave consomem o limite de memória do seu contêiner.
Nota:
Se a feature gateSizeMemoryBackedVolumes estiver habilitada, é possível especificar um tamanho para volumes mantidos em memória. Se nenhum tamanho for especificado, os volumes mantidos em memória são dimensionados para 50% da memória em um host Linux.
Um tipo de volume fc permite que um volume de armazenamento de fibre channel existente seja montado em um Pod. Você pode especificar um ou vários WWNs usando o parâmetro targetWWNs em sua configuração de volume. Se forem especificados vários WWNs, o targetWWNs espera que esses WWNs sejam de conexões multipath.
Nota:
Para que os hosts Kubernetes possam acessá-los, é necessário configurar o zoneamento FC SAN para alocar e mascarar essas LUNs (volumes) para os WWNs de destino.
Flocker é um gerenciador de volumes de dados de contêineres em cluster de código aberto. O Flocker oferece gerenciamento e orquestração de volumes de dados suportados por uma variedade de backends de armazenamento.
Um volume flocker permite que um conjunto de dados Flocker seja montado em um Pod. Se o conjunto de dados ainda não existir no Flocker, ele precisará ser criado primeiro com o CLI do Flocker ou usando a API do Flocker. Se o conjunto de dados já existir, ele será anexado pelo Flocker ao nó que o pod está escalonado. Isto significa que os dados podem ser compartilhados entre os Pods, conforme necessário.
Nota:
Antes de poder utilizá-lo, é necessário ter a sua própria instalação do Flocker em execução.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.17 [deprecated]
Um volume gcePersistentDisk monta um disco persistente (PD) do Google Compute Engine (GCE) no seu Pod. Ao contrário do emptyDir que é apagado quando um pod é removido, o conteúdo de um PD é preservado e o volume é simplesmente desmontado. Isto significa que um PD pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
Nota:
Você dever criar um PD utilizando gcloud, ou via GCE API ou via UI antes de poder utilizá-lo.
Existem algumas restrições ao utilizar um gcePersistentDisk:
Os nós nos quais os Pods estão sendo executados devem ser VMs GCE
Essas VMs precisam estar no mesmo projeto e zona GCE que o disco persistente
Uma característica do disco persistente GCE é o acesso simultâneo somente leitura a um disco persistente. Um volume gcePersistentDisk permite que vários consumidores montem simultaneamente um disco persistente como somente leitura. Isto significa que é possível alimentar previamente um PD com o seu conjunto de dados e, em seguida, disponibilizá-lo em paralelo a quantos Pods necessitar. Infelizmente, os PDs só podem ser montados por um único consumidor no modo de leitura e escrita. Não são permitidos gravadores simultâneos.
O uso de um disco persistente GCE com um Pod controlado por um ReplicaSet falhará, a menos que o PD seja somente leitura ou a contagem de réplica seja 0 ou 1.
Criando um disco persistente GCE
Antes de poder utilizar um disco persistente GCE com um Pod, é necessário criá-lo.
apiVersion:v1kind:Podmetadata:name:test-pdspec:containers:- image:registry.k8s.io/test-webservername:test-containervolumeMounts:- mountPath:/test-pdname:test-volumevolumes:- name:test-volume# Esse Disco Persistente (PD) GCE já deve existir.gcePersistentDisk:pdName:my-data-diskfsType:ext4
Discos persistentes regionais
O recurso de Discos persistentes regionais permite a criação de discos persistentes que estão disponíveis em duas zonas dentro da mesma região. Para usar esse recurso, o volume deve ser provisionado como PersistentVolume; referenciar o volume diretamente a partir de um pod não é uma configuração suportada.
Provisionar manualmente um PersistentVolume PD Regional
O provisionamento dinâmico é possível usando uma StorageClass para GCE PD. Antes de criar um PersistentVolume, você deve criar o disco persistente:
Exemplo de configuração de disco persistente regional
apiVersion:v1kind:PersistentVolumemetadata:name:test-volumespec:capacity:storage:400GiaccessModes:- ReadWriteOncegcePersistentDisk:pdName:my-data-diskfsType:ext4nodeAffinity:required:nodeSelectorTerms:- matchExpressions:# failure-domain.beta.kubernetes.io/zone deve ser usado para versões anteriores à 1.21- key:topology.kubernetes.io/zoneoperator:Invalues:- us-central1-a- us-central1-b
Migração do CSI GCE
ESTADO DA FUNCIONALIDADE:Kubernetes v1.25 [stable]
Quando o recurso CSIMigration para o GCE PD é habilitado, todas as operações de plugin do plugin in-tree existente são redirecionadas para o Driver de Cointainer Storage Interface (CSI) pd.csi.storage.gke.io. Para utilizar este recurso, o Driver CSI GCE PD deve ser instalado no cluster e os recursos beta CSIMigration e CSIMigrationGCE devem estar habilitados.
Migração de CSI GCE concluída
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [alpha]
Para desabilitar o carregamento do plugin de armazenamento gcePersistentDisk pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginGCEUnregister como true.
gitRepo (descontinuado)
Aviso:
O tipo de volume gitRepo foi descontinuado. Para provisionar um contêiner com um repositório git , monte um EmptyDir em um InitContainer que clone o repositório usando git, depois monte o EmptyDir no contêiner do Pod.
Um volume gitRepo é um exemplo de um plugin de volume. Este plugin monta um diretório vazio e clona um repositório git neste diretório para que seu Pod utilize.
O Kubernetes 1.27 não inclui um tipo de volume glusterfs.
O driver de armazenamento in-tree GlusterFS foi descontinuado na versão v1.25 do Kubernetes e, em seguida, removido totalmente na versão v1.26.
hostPath
Aviso:
Os volumes HostPath apresentam muitos riscos de segurança e é uma prática recomendada evitar o uso de HostPaths quando possível. Quando um volume HostPath precisa ser usado, ele deve ser definido com escopo apenas para o arquivo ou diretório necessário e montado como ReadOnly.
Se você restringir o acesso do HostPath a diretórios específicos através da AdmissionPolicy, a propriedade volumeMounts DEVE obrigatoriamente usar pontos de montagem readOnly para que a política seja eficaz.
Um volume hostPath monta um arquivo ou diretório do sistema de arquivos do nó do host em seu Pod. Isto não é algo de que a maioria dos Pods irá precisar, mas oferece uma poderosa alternativa de escape para algumas aplicações.
Por exemplo, alguns usos para um hostPath são:
Executar um contêiner que necessita de acesso aos documentos internos do Docker; utilizar um hostPath apontando para /var/lib/docker
Executando o cAdvisor em um contêiner; use um hostPath apontando para /sys
Permitir que um Pod especifique se um dado hostPath deve existir antes de o Pod ser executado, se deve ser criado e como deve existir
Além da propriedade obrigatória path , você pode opcionalmente definir um type para um volume hostPath.
Os valores suportados para o campo type são:
Valor
Comportamento
A string vazia (padrão) é para compatibilidade com versões anteriores, o que significa que nenhuma verificação será executada antes de montar o volume hostPath.
DirectoryOrCreate
Se nada existir no caminho indicado, um diretório vazio será criado lá, conforme necessário, com permissão definida para 0755, tendo o mesmo grupo e propriedade com a Kubelet.
Directory
Um diretório deve existir no caminho indicado
FileOrCreate
Se não houver nada no caminho indicado, um arquivo vazio será criado lá, conforme necessário, com permissão definida para 0644, tendo o mesmo grupo e propriedade com Kubelet.
File
Um arquivo deve existir no caminho indicado
Socket
Um socket UNIX deve existir no caminho indicado
CharDevice
Deve existir um dispositivo de caracteres no caminho indicado
BlockDevice
Deve existir um dispositivo de bloco no caminho indicado
Tenha cuidado ao utilizar este tipo de volume, porque:
Os HostPaths podem expor as credenciais privilegiadas do sistema (como para o Kubelet) ou APIs privilegiadas (como o container runtime socket), que podem ser usadas para o explorar vulnerabilidades de escape do contêiner ou para atacar outras partes do cluster.
Os Pods com configuração idêntica (como criado a partir de um PodTemplate) podem se comportar de forma diferente em nós diferentes devido a arquivos diferentes nos nós
Os arquivos ou diretórios criados nos hosts subjacentes são graváveis apenas pelo root. Você precisa executar seu processo como root em um contêiner privilegiado ou modificar as permissões de arquivo no host para poder gravar em um volume hostPath
Exemplo de configuração do hostPath
apiVersion:v1kind:Podmetadata:name:test-pdspec:containers:- image:registry.k8s.io/test-webservername:test-containervolumeMounts:- mountPath:/test-pdname:test-volumevolumes:- name:test-volumehostPath:# localização do diretório no hostpath:/data# este campo é opcionaltype:Directory
Cuidado:
O modo FileOrCreate não cria o diretório onde ficará arquivo. Se o caminho de diretório do arquivo montado não existir, o pod não será iniciado. Para garantir que esse modo funcione, você pode tentar montar diretórios e arquivos separadamente, como mostrado em configuração FileOrCreate.
Exemplo de configuração FileOrCreate do hostPath
apiVersion:v1kind:Podmetadata:name:test-webserverspec:containers:- name:test-webserverimage:registry.k8s.io/test-webserver:latestvolumeMounts:- mountPath:/var/local/aaaname:mydir- mountPath:/var/local/aaa/1.txtname:myfilevolumes:- name:mydirhostPath:# Certifique-se de que o diretório foi criado.path:/var/local/aaatype:DirectoryOrCreate- name:myfilehostPath:path:/var/local/aaa/1.txttype:FileOrCreate
iscsi
Um volume iscsi permite que um volume iSCSI (SCSI sobre IP) existente seja montado no seu Pod. Ao contrário do emptyDir que é apagado quando um Pod é removido, o conteúdo de um volume iscsi é preservado e o volume é simplesmente desmontado. Isto significa que um volume iscsi pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
Nota:
Você deve ter seu próprio servidor iSCSI rodando com o volume criado antes de poder utilizá-lo.
Uma característica do iSCSI é que ele pode ser montado como somente leitura por vários consumidores simultaneamente. Isto significa que um volume pode ser previamente populado com seu conjunto de dados e, em seguida, ser disponibilizado em paralelo para tantos Pods quanto necessitar. Infelizmente, os volumes iSCSI só podem ser montados por um único consumidor no modo de leitura-escrita. Não são permitidos gravadores simultâneos.
Um volume local representa um dispositivo de armazenamento local montado, como um disco, partição ou diretório.
Os volumes locais só podem ser usados como um PersistentVolume criado estaticamente. O provisionamento dinâmico não é suportado.
Em comparação com volumes hostPath, os volumes local são usados de forma durável e portátil, sem escalonamento manual dos Pods para os nós. O sistema está ciente das restrições de nós do volume, observando a afinidade do nó com o PersistentVolume.
No entanto, os volumes local estão sujeitos à disponibilidade do nó que o comporta e não são adequados para todas as aplicações. Se um nó não está íntegro, então o volume local torna-se inacessível pelo pod. O pod que utiliza este volume não consegue ser executado. Os aplicativos que usam volumes local devem ser capazes de tolerar essa disponibilidade reduzida, bem como uma possível perda de dados, dependendo das caraterísticas de durabilidade do disco subjacente.
O exemplo a seguir mostra um PersistentVolume usando um volume local e nodeAffinity:
É preciso definir a propriedade nodeAffinity do PersistentVolume ao utilizar volumes local. O escalonador do Kubernetes usa o PersistentVolume nodeAffinity para escalonar esses pods para o nó correto.
A propriedade volumeMode do PersistentVolume pode ser definida como "Block" (ao invés do valor padrão "Filesystem") para expor o volume local como um dispositivo de bloco bruto.
Ao usar volumes locais, é recomendável criar uma StorageClass com a propriedade volumeBindingMode definida como WaitForFirstConsumer. Para obter mais detalhes, consulte o exemplo local StorageClass. A postergação da vinculação do volume garante que a decisão de vinculação da PersistentVolumeClaim também será avaliada com quaisquer outras restrições de nós que o Pod possa ter, tais como requisitos de recursos de nós, seletores de nós, afinidade do Pod e anti afinidade do Pod.
Um provisionador estático externo pode ser executado separadamente para uma melhor gestão do ciclo de vida do volume local. Observe que este provisionador ainda não suporta o provisionamento dinâmico. Para um exemplo sobre como executar um provisionador local externo, veja o manual do usuário do provisionador local do volume.
Nota:
O PersistentVolume local exige que o usuário faça limpeza e remoção manual se o provisionador estático externo não for utilizado para gerenciar o ciclo de vida do volume.
nfs
Um volume nfs permite que um compartilhamento NFS (Network File System) existente seja montado em um Pod. Ao contrário do emptyDir que é apagado quando um Pod é removido, o conteúdo de um volume nfs é preservado e o volume é simplesmente desmontado. Isto significa que um volume NFS pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods. O NFS pode ser montado por vários gravadores simultaneamente.
Você deve ter seu próprio servidor NFS rodando com o compartilhamento acessível antes de poder utilizá-lo.
Note também que você não pode especificar opções de montagem NFS em uma especificação de pod. Você pode definir as opções de montagem do lado do servidor ou usar /etc/nfsmount.conf. Você também pode montar volumes NFS por meio de PersistentVolumes, que permitem definir opções de montagem.
Um volume persistentVolumeClaim é usado para montar um PersistentVolume em um Pod. PersistentVolumeClaims são uma forma de os usuários "solicitarem" armazenamento durável (como um GCE PersistentDisk ou um volume iSCSI) sem conhecerem os detalhes do ambiente de nuvem em particular.
Consulte as informações sobre PersistentVolumes para obter mais detalhes.
portworxVolume (descontinuado)
Um portworxVolume é uma camada de armazenamento em bloco extensível que funciona hiperconvergente com Kubernetes. O Portworx tira as impressões digitais de um armazenamento em um servidor, organiza com base nas capacidades e agrega capacidade em múltiplos servidores. Portworx funciona em máquinas virtuais ou em nós Linux bare-metal.
Um portworxVolume pode ser criado dinamicamente através do Kubernetes ou também pode ser previamente provisionado e referenciado dentro de um Pod. Aqui está um exemplo de um Pod referenciando um volume Portworx pré-provisionado:
apiVersion:v1kind:Podmetadata:name:test-portworx-volume-podspec:containers:- image:registry.k8s.io/test-webservername:test-containervolumeMounts:- mountPath:/mntname:pxvolvolumes:- name:pxvol# Este volume Portworx já deve existir.portworxVolume:volumeID:"pxvol"fsType:"<fs-type>"
Nota:
Certifique-se de ter um PortworxVolume com o nome pxvol antes de usá-lo no Pod.
Para obter mais detalhes, consulte os exemplos de volume Portworx .
projetado
Um volume projetado mapeia várias fontes de volume existentes dentro do mesmo diretório. Para obter mais detalhes, consulte Volumes projetados.
quobyte (descontinuado)
Um Volume quobyte permite que um volume Quobyte existente seja montado no seu Pod.
Nota:
Você deve ter seu próprio Quobyte configurado e funcionando com os volumes criados antes de poder utilizá-lo.
Quobyte oferece suporte para o Container Storage Interface. CSI é o plugin recomendado para usar volumes Quobyte dentro de Kubernetes. O projeto GitHub da Quobyte tem instruções para implantar o Quobyte usando o CSI, acompanhado de exemplos.
rbd
Um volume rbd permite que um volume Rados Block Device (RBD) seja montado em seu Pod. Ao contrário do emptyDir que é apagado quando um pod é removido, o conteúdo de um volume rbd é preservado e o volume é desmontado. Isto significa que um volume RBD pode ser previamente populado com dados e que os dados podem ser compartilhados entre os Pods.
Nota:
Você deve ter uma instalação Ceph em funcionamento antes de poder usar o RBD.
Uma caraterística do RBD é que ele pode ser montado como somente leitura por vários consumidores simultaneamente. Isto significa que um volume pode ser previamente populado com seu conjunto de dados e, em seguida, ser disponibilizado em paralelo para tantos pods quanto necessitar. Infelizmente, os volumes RBD só podem ser montados por um único consumidor no modo de leitura-escrita. Não são permitidos gravadores simultâneos.
Quando o recurso CSIMigration do RBD está ativado, redireciona todas as operações do plugin in-tree existente para o driver CSIrbd.csi.ceph.com. Para utilizar este recurso, o driver Ceph CSI deve estar instalado no cluster e as feature gatesCSIMigration e csiMigrationRBD devem estar habilitadas.
Nota:
Como operador do cluster Kubernetes que administra o armazenamento, aqui estão os pré-requisitos que você deve atender antes de tentar a migração para o driver CSI RBD:
Você deve instalar o driver Ceph CSI (rbd.csi.ceph.com), v3.5.0 ou superior, no cluster Kubernetes.
Considerando que o campo clusterID é um parâmetro necessário para o driver CSI e sua operação , mas o campo in-tree StorageClass tem o parâmetro obrigatório monitors, um administrador de armazenamento Kubernetes precisa criar um clusterID baseado no hash dos monitores (ex.:#echo -n '<monitors_string>' | md5sum) no mapa de configuração do CSI e manter os monitores sob esta configuração de clusterID.
Além disso, se o valor de adminId no Storageclass in-tree for diferente de admin, o adminSecretName mencionado no Storageclass in-tree tem que ser corrigido com o valor base64 do valor do parâmetro adminId, caso contrário esta etapa pode ser ignorada.
secret
Um volume secret é usado para passar informações sensíveis, tais como senhas, para Pods. Você pode armazenar segredos na API Kubernetes e montá-los como arquivos para serem usados por pods sem necessidade de vinculação direta ao Kubernetes. Volumes secret são mantidos pelo tmpfs (um sistema de arquivos com baseado em memória RAM) para que nunca sejam gravados em armazenamento não volátil.
Nota:
Você deve criar um Secret na API Kubernetes antes de poder utilizá-lo.
Um secret é sempre montado como readOnly.
Um contêiner que utiliza um Secret como ponto de montagem para a propriedade subPath não receberá atualizações deste Secret.
Um volume storageos permite que um volume StorageOS existente seja montado em seu Pod.
O StorageOS funciona como um contêiner dentro de seu ambiente Kubernetes, tornando o armazenamento local ou anexado acessível a partir de qualquer nó dentro do cluster Kubernetes. Os dados podem ser replicados para a proteção contra falhas do nó. O provisionamento e a compressão podem melhorar a utilização e reduzir os custos.
Em sua essência, o StorageOS fornece armazenamento em bloco para containers, acessível a partir de um sistema de arquivo.
O Conteiner StorageOS requer Linux de 64 bits e não possui dependências adicionais. Uma licença para desenvolvedores está disponível gratuitamente.
Cuidado:
Você deve executar o container StorageOS em cada nó que deseja acessar os volumes do StorageOS ou que contribuirá com a capacidade de armazenamento para o pool. Para obter instruções de instalação, consulte a documentação do StorageOS.
O exemplo a seguir é uma configuração do Pod com StorageOS:
apiVersion:v1kind:Podmetadata:labels:name:redisrole:mastername:test-storageos-redisspec:containers:- name:masterimage:kubernetes/redis:v1env:- name:MASTERvalue:"true"ports:- containerPort:6379volumeMounts:- mountPath:/redis-master-dataname:redis-datavolumes:- name:redis-datastorageos:# O volume `redis-vol01` já deve existir dentro do StorageOS no namespace `default`.volumeName:redis-vol01fsType:ext4
Para obter mais informações sobre StorageOS, provisionamento dinâmico e PersistentVolumeClaims, consulte os exemplos do StorageOS.
vsphereVolume (descontinuado)
Nota:
Recomendamos usar o driver out-of-tree do vSphere CSI.
Um vsphereVolume é usado para montar um volume VMDK do vSphere em seu Pod. O conteúdo de um volume é preservado quando é desmontado. Ele suporta sistemas de armazenamento de dados tanto do tipo VMFS quanto do tipo VSAN.
Para obter mais informações, consulte os exemplos vSphere volume
Criar um volume VMDK (descontinuado)
Escolha um dos seguintes métodos para criar um VMDK.
vmware-vdiskmanager -c -t 0 -s 40GB -a lsilogic myDisk.vmdk
Exemplo de configuração do VMDK no vSphere
apiVersion:v1kind:Podmetadata:name:test-vmdkspec:containers:- image:registry.k8s.io/test-webservername:test-containervolumeMounts:- mountPath:/test-vmdkname:test-volumevolumes:- name:test-volume# This VMDK volume must already exist.vsphereVolume:volumePath:"[DatastoreName] volumes/myDisk"fsType:ext4
Para obter mais informações, consulte os exemplos de volume do vSphere .
Migração de CSI vSphere
ESTADO DA FUNCIONALIDADE:Kubernetes v1.26 [stable]
No Kubernetes 1.27, todas as operações para o tipo vsphereVolume in-tree são redirecionadas para o driver CSI csi.vsphere.vmware.com.
O driver vSphere CSI deve ser instalado no cluster. Você pode encontrar conteúdos adicionais sobre como migrar o vsphereVolume in-tree na página de documentação do VMware Migrating In-Tree vSphere Volumes to vSphere Container Storage plug-in. Se o vSphere CSI Driver não estiver instalado, as operações de volume não poderão ser executadas no PV criado com o tipo vsphereVolume in-tree.
Você deve executar o vSphere 7.0u2 ou posterior para migrar para o driver vSphere CSI.
Se você estiver executando uma versão do Kubernetes diferente da v1.27, consulte a documentação dessa versão do Kubernetes.
Nota:
Os seguintes parâmetros da StorageClass do plugin integrado vsphereVolume não são suportados pelo driver CSI do vSphere:
diskformat
hostfailurestotolerate
forceprovisioning
cachereservation
diskstripes
objectspacereservation
iopslimit
Os volumes existentes criados usando esses parâmetros serão migrados para o driver CSI do vSphere, mas novos volumes criados pelo driver de CSI do vSphere não estarão respeitando esses parâmetros.
Migração do CSI do vSphere foi concluída
ESTADO DA FUNCIONALIDADE:Kubernetes v1.19 [beta]
Para desativar o carregamento do plugin de armazenamento vsphereVolume pelo gerenciador de controladores e pelo kubelet, defina a flag InTreePluginvSphereUnregister como true. Você precisa instalar o driver csi.vsphere.vmware.comCSI em todos os nós de processamento.
Migração de driver CSI do Portworx
ESTADO DA FUNCIONALIDADE:Kubernetes v1.25 [beta]
O recurso CSIMigration para Portworx foi adicionado, mas desativado por padrão no Kubernetes 1.23 visto que está no estado alfa. Ele redireciona todas as operações de plugin do tipo in-tree para o Driver de Cointainer Storage Interface (CSI) pxd.portworx.com. O driver CSI Portworx deve ser instalado no cluster. Para ativar o recurso, defina CSIMigrationPortworx=true no kube-controller-manager e no kubelet.
Utilizando subPath
Às vezes, é útil compartilhar um volume para múltiplos usos em um único pod. A propriedade volumeMounts[*].subPath especifica um sub caminho dentro do volume referenciado em vez de sua raiz.
O exemplo a seguir mostra como configurar um Pod com um ambiente LAMP (Linux, Apache, MySQL e PHP) usando um único volume compartilhado. Esta exemplo de configuração subPath não é recomendada para uso em produção.
O código e os ativos da aplicação PHP mapeiam para a pasta do volume html e o banco de dados MySQL é armazenado na pasta do volume mysql . Por exemplo:
Usando subPath com variáveis de ambiente expandidas
ESTADO DA FUNCIONALIDADE:Kubernetes v1.17 [stable]
Use o campo subPathExpr para construir nomes de diretório subPath a partir de variáveis de ambiente da downward API. As propriedades subPath e subPathExpr são mutuamente exclusivas.
Neste exemplo, um Pod usa subPathExpr para criar um diretório pod1 dentro do volume hostPath/var/log/pods. O volume hostPathrecebe o nome Pod do downwardAPI. O diretório /var/log/pods/pod1 do host é montado em /logs no contêiner.
apiVersion:v1kind:Podmetadata:name:pod1spec:containers:- name:container1env:- name:POD_NAMEvalueFrom:fieldRef:apiVersion:v1fieldPath:metadata.nameimage:busybox:1.28command:["sh","-c","while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt"]volumeMounts:- name:workdir1mountPath:/logs# A expansão de variáveis usa parênteses (não chaves).subPathExpr:$(POD_NAME)restartPolicy:Nevervolumes:- name:workdir1hostPath:path:/var/log/pods
Recursos
A mídia de armazenamento(como Disco ou SSD) de um volume emptyDir é determinada por meio do sistema de arquivos que mantém o diretório raiz do kubelet (normalmente /var/lib/kubelet). Não há limite para quanto espaço um volume emptyDir ou hostPath podem consumir, e não há isolamento entre contêineres ou entre pods.
Para saber mais sobre como solicitar espaço usando uma especificação de recursos, consulte como gerenciar recursos.
Plugins de volume out-of-tree
Os plugins de volume out-of-tree incluem o Container Storage Interface (CSI) e também o FlexVolume (que foi descontinuado). Esses plugins permitem que os fornecedores de armazenamento criem plugins de armazenamento personalizados sem adicionar seu código-fonte do plugin ao repositório Kubernetes.
Anteriormente, todos os plugins de volume eram "in-tree". Os plugins "in-tree" eram construídos, vinculados, compilados e distribuídos com o código principal dos binários do Kubernetes. Isto significava que a adição de um novo sistema de armazenamento ao Kubernetes (um plugin de volume) exigia uma validação do código no repositório central de código Kubernetes.
Tanto o CSI quanto o FlexVolume permitem que os plugins de volume sejam desenvolvidos independentemente da base de código Kubernetes e implantados (instalados) nos clusters Kubernetes como extensões.
O Cointainer Storage Interface (CSI) define uma interface padrão para sistemas de orquestração de contêineres (como Kubernetes) para expor sistemas de armazenamento arbitrários a suas cargas de trabalho de contêiner.
O suporte para as versões 0.2 e 0.3 da especificação CSI foi descontinuado no Kubernetes v1.13 e será removido em uma versão futura.
Nota:
Os controladores CSI podem não ser compatíveis em todas as versões do Kubernetes. Consulte a documentação específica do driver CSI para ver as etapas de implantação suportadas para cada versão do Kubernetes e uma matriz de compatibilidade.
Uma vez que um driver de volume compatível com CSI seja implantado em um cluster Kubernetes, os usuários podem usar o tipo de volume csi para anexar ou montar os volumes expostos pelo driver CSI.
Um volume csi pode ser utilizado em um Pod de três formas diferentes:
Os seguintes campos estão disponíveis para administradores de armazenamento configurarem um volume persistente de CSI:
driver: Um valor do tipo string que especifica o nome do driver de volume a ser usado. Este valor deve corresponder ao valor retornado no GetPluginInfoResponse pelo driver CSI, conforme definido na especificação CSI. Ele é usado pelo Kubernetes para identificar qual driver CSI chamar, e pelos componentes do driver CSI para identificar quais objetos PV pertencem ao driver CSI.
volumeHandle: Um valor do tipo string que identifica exclusivamente o volume. Este valor deve corresponder ao valor retornado no campo volume.id em CreateVolumeResponse pelo driver CSI, conforme definido na especificação CSI. O valor é passado como volume_id em todas as chamadas para o driver de volume CSI quando se faz referência ao volume.
readOnly: Um valor booleano opcional que indica se o volume deve ser "ControllerPublished" (anexado) como somente leitura. O valor padrão é false. Este valor é passado para o driver CSI através do campo readonly em ControllerPublishVolumeRequest.
fsType: Se o VolumeMode do PV for Filesystem então este campo pode ser usado para especificar o sistema de arquivos que deve ser usado para montar o volume. Se o volume não tiver sido formatado e a formatação for suportada, este valor será utilizado para formatar o volume. Este valor é passado para o driver CSI através do campo VolumeCapability nas propriedades ControllerPublishVolumeRequest, NodeStageVolumeRequest e NodePublishVolumeRequest.
volumeAttributes: Um mapa de valores do tipo string para string que especifica propriedades estáticas de um volume. Este mapa deve corresponder ao mapa retornado no campo volume.attributes do CreateVolumeResponse pelo driver CSI, conforme definido na especificação CSI. O mapa é passado para o driver CSI através do campo volume_context nas propriedades ControllerPublishVolumeRequest, NodeStageVolumeRequest, e NodePublishVolumeRequest.
controllerPublishSecretRef: Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver CSI para completar as chamadas CSI ControllerPublishVolume e ControllerUnpublishVolume. Este campo é opcional e pode estar vazio se não for necessário nenhum segredo. Se o Secret contiver mais de um segredo, todos os segredos serão passados.
nodeStageSecretRef: Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver de CSI para completar a chamada de CSI do NodeStageVolume. Este campo é opcional e pode estar vazio se não for necessário nenhum segredo. Se o Secret contiver mais de um segredo, todos os segredos serão passados.
nodePublishSecretRef: Uma referência ao objeto Secret que contém informações confidenciais para passar ao driver de CSI para completar a chamada de CSI do NodePublishVolume. Este campo é opcional e pode estar vazio se não for necessário nenhum segredo. Se o objeto Secret contiver mais de um segredo, todos os segredos serão passados.
Suporte CSI para volume de bloco bruto
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [stable]
Os fornecedores com drivers CSI externos podem implementar o suporte de volume de blocos brutos nas cargas de trabalho Kubernetes.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.25 [stable]
É possível configurar diretamente volumes CSI dentro da especificação do Pod. Os volumes especificados desta forma são efêmeros e não persistem nas reinicializações do pod. Consulte Volumes efêmeros para obter mais informações.
Migrando para drivers CSI a partir de plugins in-tree
ESTADO DA FUNCIONALIDADE:Kubernetes v1.25 [stable]
Quando o recurso CSIMigration está habilitado, direciona operações relacionadas a plugins in-tree existentes para plugins CSI correspondentes (que devem ser instalados e configurados). Como resultado, os operadores não precisam fazer nenhuma alteração de configuração para Storage Classes, PersistentVolumes ou PersistentVolumeClaims existentes (referindo-se aos plugins in-tree) quando a transição para um driver CSI que substitui um plugin in-tree.
As operações e características que são suportadas incluem: provisionamento/exclusão, anexação/remoção, montargem/desmontagem e redimensionamento de volumes.
Plugins in-tree que suportam CSIMigration e têm um driver CSI correspondente implementado são listados em tipos de volumes.
Os seguintes plug-ins in-tree suportam armazenamento persistente em nós do Windows:
ESTADO DA FUNCIONALIDADE:Kubernetes v1.23 [deprecated]
O FlexVolume é uma interface de plugin out-of-tree que usa um modelo baseado em execução para fazer interface com drivers de armazenamento. Os binários do driver FlexVolume devem ser instalados em um caminho de plugin de volume predefinido em cada nó e, em alguns casos, também nos nós da camada de gerenciamento.
Os Pods interagem com os drivers do FlexVolume através do plugin de volume in-tree flexVolume. Para obter mais detalhes, consulte o documento README do FlexVolume.
Nota:
O FlexVolume foi descontinuado. Usar um driver CSI out-of-tree é a maneira recomendada de integrar o armazenamento externo com Kubernetes.
Os mantenedores do driver FlexVolume devem implementar um driver CSI e ajudar a migrar usuários de drivers FlexVolume para CSI. Os usuários do FlexVolume devem mover suas cargas de trabalho para usar o driver CSI equivalente.
Propagação de montagem
A propagação de montagem permite compartilhar volumes montados por um contêiner para outros contêineres no mesmo pod, ou mesmo para outros pods no mesmo nó.
A propagação de montagem de um volume é controlada pelo campo mountPropagation na propriedade containers[*].volumeMounts. Os seus valores são:
None - Este volume de montagem não receberá do host nenhuma montagem posterior que seja montada para este volume ou qualquer um de seus subdiretórios. De forma semelhante, nenhum ponto de montagem criado pelo contêiner será visível no host. Este é o modo padrão.
HostToContainer - Este volume de montagem receberá todas as montagens posteriores que forem montadas para este volume ou qualquer um de seus subdiretórios.
Em outras palavras, se o host montar qualquer coisa dentro do volume de montagem, o container o visualizará montado ali.
Da mesma forma, se qualquer Pod com propagação de montagem Bidirectional para o mesmo volume montar qualquer coisa lá, o contêiner com propagação de montagem HostToContainer o reconhecerá.
Bidirectional - Esta montagem de volume se comporta da mesma forma que a montagem de volume HostToContainer. Além disso, todas as montagens de volume criadas pelo contêiner serão propagadas de volta ao host e a todos os contêineres de todas os pods que utilizam o mesmo volume.
Um caso de uso típico para este modo é um Pod com um driver FlexVolume ou CSI ou um Pod que precisa montar algo no host utilizando um volume hostPath.
A propagação de montagem Bidirectional pode ser perigosa. Ela pode danificar o sistema operacional do host e, portanto, ela só é permitida em contêineres privilegiados. A familiaridade com o comportamento do kernel Linux é fortemente recomendada. Além disso, quaisquer montagens de volume criadas por contêineres em pods devem ser destruídas ( desmontadas) pelos contêineres ao final.
Configuração
Antes que a propagação da montagem possa funcionar corretamente em algumas distribuições (CoreOS, RedHat/Centos, Ubuntu), o compartilhamento de montagem deve ser configurado corretamente no Docker como mostrado abaixo.
Edite seu arquivo de serviços systemd do Docker. Configure a propriedade MountFlags da seguinte forma:
MountFlags=shared
Ou, se a propriedade MountFlags=slaveexistir, remova-a. Em seguida, reinicie o daemon Docker:
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.
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 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ãoDefaultStorageClass 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:
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:
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.
Limpar os dados de forma manual no armazenamento associado.
Deletar manualmente o armazenamento associado. Caso você queira utilizar o mesmo armazenamento, crie um novo PersistentVolume com esse armazenamento.
Deletar
Para plugins de volume que suportam a política de recuperação Delete, a deleção vai remover o tanto o PersistentVolume do Kubernetes, quanto o armazenamento associado à infraestrutura externa, como AWS EBS, GCE PD, Azure Disk, ou Cinder volume. Volumes que foram provisionados dinamicamente herdam a política de retenção da sua StorageClass, que por padrão é Delete. O administrador precisa configurar a StorageClass de acordo com as necessidades dos usuários. Caso contrário, o PV deve ser editado ou reparado após sua criação. Veja Alterar a política de retenção de um PersistentVolume.
Reciclar
Aviso:
A política de retenção Recycle está depreciada. Ao invés disso, recomendamos a utilização de provisionamento dinâmico.
Em caso do volume plugin ter suporte a essa operação, a política de retenção Recycle faz uma limpeza básica (rm -rf /thevolume/*) no volume e torna ele disponível novamente para outra requisição.
Contudo, um administrador pode configurar um template personalizado de um Pod reciclador utilizando a linha de comando do gerenciamento de controle do Kubernetes como descrito em referência.
O Pod reciclador personalizado deve conter a spec volume como é mostrado no exemplo abaixo:
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:v1kind:PersistentVolumeClaimmetadata:name:foo-pvcnamespace:foospec:storageClassName:""# Empty string must be explicitly set otherwise default StorageClass will be setvolumeName: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.
Isso é útil se você deseja utilizar PersistentVolumes que possuem suas persistentVolumeReclaimPolicy configuradas para Retain, incluindo situações onde você estiver reutilizando um PV existente.
Expandindo Requisições de Volumes Persistentes
ESTADO DA FUNCIONALIDADE:Kubernetes v1.24 [stable]
Agora, o suporte à expansão de PersistentVolumeClaims (PVCs) já é habilitado por padrão. Você pode expandir os tipos de volumes abaixo:
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
ESTADO DA FUNCIONALIDADE:Kubernetes v1.24 [stable]
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
ESTADO DA FUNCIONALIDADE: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.
Marque o PersistentVolume(PV) que estiver atrelado à PersistentVolumeClaim(PVC) com a política de recuperação Retain.
Delete a PVC. Desde que o PV tenha a política de recuperação Retain - nenhum dado será perdido quando a PVC for recriada.
Delete a entrada claimRef da especificação do PV para que uma PVC possa fazer bind com ele. Isso deve tornar o PV Available.
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.
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:
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.)
photonPersistentDisk - Controlador Photon para disco persistente.
(Esse tipo de volume não funciona mais desde a removação do provedor de cloud correspondente.)
Talvez sejam necessários programas auxiliares para um determinado tipo de volume utilizar um PersistentVolume no cluster. Neste exemplo, o PersistentVolume é do tipo NFS e o programa auxiliar /sbin/mount.nfs é necessário para suportar a montagem dos sistemas de arquivos NFS.
Capacidade
Geralmente, um PV terá uma capacidade de armazenamento específica. Isso é configurado usando o atributo capacity do PV. Veja o Modelo de Recurso do Kubernetes para entender as unidades aceitas pelo atributo capacity.
Atualmente, o tamanho do armazenamento é o único recurso que pode ser configurado ou solicitado. Os futuros atributos podem incluir IOPS, throughput, etc.
Modo do Volume
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [stable]
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
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
AWSElasticBlockStore
✓
-
-
AzureFile
✓
✓
✓
AzureDisk
✓
-
-
CephFS
✓
✓
✓
Cinder
✓
-
-
CSI
depende do driver
depende do driver
depende do driver
FC
✓
✓
-
FlexVolume
✓
✓
depende do driver
Flocker
✓
-
-
GCEPersistentDisk
✓
✓
-
Glusterfs
✓
✓
✓
HostPath
✓
-
-
iSCSI
✓
✓
-
Quobyte
✓
✓
✓
NFS
✓
✓
✓
RBD
✓
✓
-
VsphereVolume
✓
-
(funcionam quando os Pods são do tipo collocated)
PortworxVolume
✓
-
✓
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.
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ó.
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:v1kind:PersistentVolumeClaimmetadata:name:myclaimspec:accessModes:- ReadWriteOncevolumeMode:Filesystemresources:requests:storage:8GistorageClassName:slowselector: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.
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ãoDefaultStorageClass 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.
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
ESTADO DA FUNCIONALIDADE: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
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
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
ESTADO DA FUNCIONALIDADE: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
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).
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:
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 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
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 ifNotPresentse 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.
Um ConfigMap é um objeto da API usado para armazenar dados não-confidenciais em pares chave-valor.
Pods podem consumir ConfigMaps como variáveis de ambiente, argumentos de linha de comando ou como arquivos de configuração em um volume.
Um ConfigMap ajuda a desacoplar configurações vinculadas ao ambiente das imagens de contêiner, de modo a tornar aplicações mais facilmente portáveis.
Cuidado:
O ConfigMap não oferece confidencialidade ou encriptação.
Se os dados que você deseja armazenar são confidenciais, utilize
Secret ao invés de um ConfigMap,
ou utilize ferramentas adicionais (de terceiros) para manter seus dados privados.
Motivação
Utilize um ConfigMap para manter a configuração separada do código da aplicação.
Por exemplo, imagine que você esteja desenvolvendo uma aplicação que pode ser executada
no seu computador local (para desenvolvimento) e na nuvem (para manipular tráfego real).
Você escreve código para ler a variável de ambiente chamada DATABASE_HOST.
No seu ambiente local, você configura essa variável com o valor localhost. Na nuvem, você
configura essa variável para referenciar um serviço
do Kubernetes que expõe o componente do banco de dados ao seu cluster.
Isto permite que você baixe uma imagem de contêiner que roda na nuvem e depure exatamente
o mesmo código localmente se necessário.
Um ConfigMap não foi planejado para conter grandes quantidades de dados. Os dados armazenados
em um ConfigMap não podem exceder 1 MiB. Se você precisa armazenar configurações que são maiores
que este limite, considere montar um volume ou utilizar um serviço separado de banco de dados
ou de arquivamento de dados.
Objeto ConfigMap
Um ConfigMap é um objeto
da API que permite o armazenamento de configurações para consumo por outros objetos. Diferentemente
de outros objetos do Kubernetes que contém um campo spec, o ConfigMap contém os campos data e
binaryData. Estes campos aceitam pares chave-valor como valores. Ambos os campos data e binaryData
são opcionais. O campo data foi pensado para conter sequências de bytes UTF-8, enquanto o campo binaryData
foi planejado para conter dados binários em forma de strings codificadas em base64.
Cada chave sob as seções data ou binaryData pode conter quaisquer caracteres alfanuméricos,
-, _ e .. As chaves armazenadas na seção data não podem colidir com as chaves armazenadas
na seção binaryData.
A partir da versão v1.19 do Kubernetes, é possível adicionar o campo immutable a uma definição de ConfigMap
para criar um ConfigMap imutável.
ConfigMaps e Pods
Você pode escrever uma spec para um Pod que se refere a um ConfigMap e configurar o(s) contêiner(es)
neste Pod baseados em dados do ConfigMap. O Pod e o ConfigMap devem estar no mesmo
namespace.
Nota:
A spec de um Pod estático não pode se referir a um
ConfigMap ou a quaisquer outros objetos da API.
Exemplo de um ConfigMap que contém algumas chaves com valores avulsos e outras chaves com valores semelhantes
a fragmentos de arquivos de configuração:
apiVersion:v1kind:ConfigMapmetadata:name:game-demodata:# chaves com valores de propriedades; cada chave mapeia para um valor avulsoplayer_initial_lives:"3"ui_properties_file_name:"user-interface.properties"# chaves semelhantes a fragmentos de arquivosgame.properties:| enemy.types=aliens,monsters
player.maximum-lives=5user-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:
Dentro de um comando de contêiner e seus argumentos.
Variáveis de ambiente para um contêiner.
Criando um arquivo em um volume somente leitura, para consumo pela aplicação.
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:v1kind:Podmetadata:name:configmap-demo-podspec:containers:- name:demoimage:alpinecommand:["sleep","3600"]env:# Define as variáveis de ambiente- name:PLAYER_INITIAL_LIVES# Note que aqui a variável está definida em caixa alta,# diferente da chave no ConfigMap.valueFrom:configMapKeyRef:name:game-demo # O ConfigMap de onde esse valor vem.key:player_initial_lives# A chave que deve ser buscada.- name:UI_PROPERTIES_FILE_NAMEvalueFrom:configMapKeyRef:name:game-demokey:ui_properties_file_namevolumeMounts:- name:configmountPath:"/config"readOnly:truevolumes:# Volumes são definidos no escopo do Pod, e os pontos de montagem são definidos# nos contêineres dentro dos pods.- name:configconfigMap:# 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:
Crie um ConfigMap ou utilize um ConfigMap existente. Múltiplos Pods
podem referenciar o mesmo ConfigMap.
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.
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.
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:
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
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [stable]
A funcionalidade Secrets e ConfigMaps imutáveis do Kubernetes fornece uma opção
para marcar Secrets e ConfigMaps individuais como imutáveis. Para clusters que utilizam
ConfigMaps extensivamente (ao menos centenas de milhares de mapeamentos únicos de
ConfigMaps para Pods), prevenir alterações dos seus dados traz as seguintes vantagens:
protege de atualizações acidentais ou indesejadas que podem causar disrupção na execução
de aplicações
melhora o desempenho do cluster através do fechamento de watches de ConfigMaps marcados
como imutáveis, diminuindo significativamente a carga no kube-apiserver
Essa funcionalidade é controlada pelo feature gateImmutableEphemeralVolumes. É possível criar um ConfigMap imutável adicionando o campo
immutable e marcando seu valor com true.
Por exemplo:
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.
Leia The Twelve-Factor App (em inglês) para entender a motivação da separação de código
e configuração.
3.6.3 - Secrets
Um Secret é um objeto que contém uma pequena quantidade de informação sensível,
como senhas, tokens ou chaves. Este tipo de informação poderia, em outras
circunstâncias, ser colocada diretamente em uma configuração de
Pod ou em uma
imagem de contêiner. O uso de
Secrets evita que você tenha de incluir dados confidenciais no seu código.
Secrets podem ser criados de forma independente dos Pods que os consomem. Isto
reduz o risco de que o Secret e seus dados sejam expostos durante o processo de
criação, visualização e edição ou atualização de Pods. O Kubernetes e as
aplicações que rodam no seu cluster podem também tomar outras precauções com
Secrets, como por exemplo evitar a escrita de dados confidenciais em local de
armazenamento persistente (não-volátil).
Secrets são semelhantes a
ConfigMaps, mas foram
especificamente projetados para conter dados confidenciais.
Cuidado:
Os Secrets do Kubernetes são, por padrão, gravados não-encriptados no sistema
de armazenamento de dados utilizado pelo servidor da API (etcd). Qualquer pessoa
com acesso à API ou ao etcd consegue obter ou modificar um Secret.
Além disso, qualquer pessoa que possui autorização para criar Pods em um namespace
consegue utilizar este privilégio para ler qualquer Secret naquele namespace. Isso
inclui acesso indireto, como por exemplo a permissão para criar Deployments.
Para utilizar Secrets de forma segura, siga pelo menos as instruções abaixo:
Habilite ou configure regras de RBAC
que restrinjam o acesso de leitura a Secrets (incluindo acesso indireto).
Quando apropriado, utilize mecanismos como RBAC para limitar quais perfis e
usuários possuem permissão para criar novos Secrets ou substituir Secrets
existentes.
A camada de gerenciamento do Kubernetes também utiliza Secrets. Por exemplo,
os Secrets de tokens de autoinicialização são um
mecanismo que auxilia a automação do registro de nós.
Alternativas a Secrets
Ao invés de utilizar um Secret para proteger dados confidenciais, você pode
escolher uma maneira alternativa. Algumas das opções são:
se o seu componente cloud native precisa autenticar-se a outra aplicação que
está rodando no mesmo cluster Kubernetes, você pode utilizar uma
ServiceAccount
e seus tokens para identificar seu cliente.
existem ferramentas fornecidas por terceiros que você pode rodar, no seu
cluster ou externamente, que providenciam gerenciamento de Secrets. Por exemplo,
um serviço que Pods accessam via HTTPS, que revelam um Secret se o cliente
autenticar-se corretamente (por exemplo, utilizando um token de ServiceAccount).
para autenticação, você pode implementar um serviço de assinatura de
certificados X.509 personalizado, e utilizar
CertificateSigningRequests
para permitir ao serviço personalizado emitir certificados a pods que os
necessitam.
você pode utilizar um plugin de dispositivo
para expor a um Pod específico um hardware de encriptação conectado a um nó. Por
exemplo, você pode agendar Pods confiáveis em nós que oferecem um Trusted
Platform Module, configurado em um fluxo de dados independente.
Você pode também combinar duas ou mais destas opções, incluindo a opção de
utilizar objetos do tipo Secret.
Por exemplo: implemente (ou instale) um
operador
que solicite tokens de sessão de curta duração a um serviço externo, e crie
Secrets baseado nestes tokens. Pods rodando no seu cluster podem fazer uso de
tokens de sessão, e o operador garante que estes permanecem válidos. Esta
separação significa que você pode rodar Pods que não precisam ter conhecimento
do mecanismo exato para geração e atualização de tais tokens de sessão.
Você pode especificar o campo data e/ou o campo stringData na criação de um
arquivo de configuração de um Secret. Ambos os campos data e stringData são
opcionais. Os valores das chaves no campo data devem ser strings codificadas
no formato base64. Se a conversão para base64 não for desejável, você pode
optar por informar os dados no campo stringData, que aceita strings arbitrárias
como valores.
As chaves dos campos data e stringData devem consistir de caracteres
alfanuméricos, -, _, ou .. Todos os pares chave-valor no campo stringData
são internamente combinados com os dados do campo data. Se uma chave aparece
em ambos os campos, o valor informado no campo stringData tem a precedência.
Limite de tamanho
Secrets individuais são limitados a 1MiB em tamanho. Esta limitação tem por
objetivo desencorajar a criação de Secrets muito grandes que possam exaurir a
memória do servidor da API e do kubelet. No entanto, a criação de vários Secrets
pequenos também pode exaurir a memória. Você pode utilizar uma
cota de recurso a fim de limitar
o número de Secrets (ou outros recursos) em um namespace.
Editando um Secret
Você pode editar um Secret existente utilizando kubectl:
kubectl edit secrets mysecret
Este comando abre o seu editor padrão configurado e permite a modificação dos
valores do Secret codificados em base64 no campo data. Por exemplo:
# Please edit the object below. Lines beginning with a '#' will be ignored,# and an empty file will abort the edit. If an error occurs while saving this file, it will be# reopened with the relevant failures.#apiVersion:v1data:username:YWRtaW4=password:MWYyZDFlMmU2N2Rmkind:Secretmetadata:annotations:kubectl.kubernetes.io/last-applied-configuration:{... }creationTimestamp:2016-01-22T18:41:56Zname:mysecretnamespace:defaultresourceVersion:"164619"uid:cfee02d6-c137-11e5-8d73-42010af00002type:Opaque
Este manifesto de exemplo define um Secret com duas chaves no campo data:
username and password.
Os valores são strings codificadas em formato base64. No entanto, quando um
Secret é utilizado em um Pod, o kubelet fornece os dados decodificados ao Pod
e seus contêineres.
Você pode especificar muitas chaves e valores em um Secret só, ou utilizar
muitos Secrets. Escolha a opção que for mais conveniente para o caso de uso.
Utilizando Secrets
Secrets podem ser montados como volumes de dados ou expostos como
variáveis de ambiente
para serem utilizados num container de um Pod. Secrets também podem ser
utilizados por outras partes do sistema, sem serem diretamente expostos ao Pod.
Por exemplo, Secrets podem conter credenciais que outras partes do sistema devem
utilizar para interagir com sistemas externos no lugar do usuário.
Secrets montados como volumes são verificados para garantir que o nome
referenciado realmente é um objeto do tipo Secret. Portanto, um Secret deve ser
criado antes de quaisquer Pods que dependem deste Secret.
Se um Secret não puder ser encontrado (porque não existe, ou devido a um problema
de conectividade com o servidor da API) o kubelet tenta periodicamente reiniciar
aquele Pod. O kubelet também relata um evento para aquele Pod, incluindo detalhes
do problema ao buscar o Secret.
Secrets Opcionais
Quando você define uma variável de ambiente em um contêiner baseada em um Secret,
você pode especificar que o Secret em questão será opcional. O padrão é o
Secret ser requerido.
Nenhum dos contêineres de um Pod irão inicializar até que todos os Secrets
requeridos estejam disponíveis.
Se um Pod referencia uma chave específica em um Secret e o Secret existe, mas
não possui a chave com o nome referenciado, o Pod falha durante a inicialização.
Utilizando Secrets como arquivos em um Pod
Se você deseja acessar dados de um Secret em um Pod, uma das formas de consumir
esta informação é fazer com que o Kubernetes deixe o valor daquele Secret
disponível como um arquivo dentro do sistema de arquivos de um ou mais dos
contêineres daquele Pod.
Para configurar isso:
Crie um Secret ou utilize um previamente existente. Múltiplos Pods podem
referenciar o mesmo secret.
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.
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.
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 de nome mysecret em um volume:
Cada Secret que você deseja utilizar deve ser referenciado na lista
.spec.volumes.
Se existirem múltiplos contêineres em um Pod, cada um dos contêineres
necessitará seu próprio bloco volumeMounts, mas somente um volume na lista
.spec.volumes é necessário por Secret.
Nota:
Versões do Kubernetes anteriores a v1.22 criavam automaticamente credenciais
para acesso à API do Kubernetes. Este mecanismo antigo era baseado na criação de
Secrets com tokens que podiam então ser montados em Pods em execução.
Em versões mais recentes, incluindo o Kubernetes v1.30,
credenciais para acesso à API são obtidas diretamente através da API
TokenRequest
e são montadas em Pods utilizando um
volume projetado.
Os tokens obtidos através deste método possuem tempo de vida limitado e são
automaticamente invalidados quando o Pod em que estão montados é removido.
Você ainda pode
criar manualmente
um Secret de token de service account se você precisa de um token que não expire,
por exemplo. No entanto, o uso do subrecurso
TokenRequest
é recomendado para obtenção de um token para acesso à API ao invés do uso de
Secrets de token de service account.
Projeção de chaves de Secrets em 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:
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.
Se você listar as chaves explicitamente, então todas as chaves listadas precisam
existir no Secret correspondente. Caso contrário, o volume não é criado.
Permissões de arquivos de Secret
Você pode trocar os bits de permissão POSIX 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.
Por exemplo, você pode especificar uma permissão padrão da seguinte maneira:
Dessa forma, o Secret será montado em /etc/foo e todos os arquivos criados
no volume terão a permissão 0400.
Nota:
Se você estiver definindo um Pod ou um template de Pod utilizando JSON, observe
que a especificação JSON não suporta a notação octal. Você pode utilizar o valor
decimal para o campo defaultMode (por exemplo, 0400 em base octal equivale a
256 na base decimal).
Se você estiver escrevendo YAML, você pode escrever o valor para defaultMode
em octal.
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
Quando um volume contém dados de um Secret, e o Secret referenciado é atualizado,
o Kubernetes rastreia a atualização e atualiza os dados no volume, utilizando
uma abordagem de consistência eventual.
Nota:
Um contêiner que utiliza Secrets através de um volume montado com a propriedade
subPath não recebe
atualizações automatizadas para este Secret.
O kubelet mantém um cache das chaves e valores atuais dos Secrets que são
utilizados em volumes de Pods daquele nó. Você pode configurar a forma que o
kubelet detecta diferenças dos valores armazenados em cache. O campo
configMapAndSecretDetectionStrategy na
configuração do kubelet
controla qual estratégia o kubelet usa. A estratégia padrão é Watch.
Atualizações em Secrets podem ser propagadas por um mecanismo de observação da
API (estratégia padrão), baseado em cache com um tempo de expiração definido
(time-to-live), ou solicitado diretamente ao servidor da API do cluster a cada
iteração do ciclo de sincronização do kubelet.
Como resultado, o atraso total entre o momento em que o Secret foi atualizado
até o momento em que as novas chaves são projetadas no Pod pode ser tão longo
quanto a soma do tempo de sincronização do kubelet somado ao tempo de atraso de
propagação do cache, onde o atraso de propagação do cache depende do tipo de
cache escolhido. Seguindo a mesma ordem listada no parágrafo anterior, estes
valores são: atraso de propagação via watch, tempo de expiração configurado no
cache (time-to-live, ou TTL), ou zero para solicitação direta ao servidor da
API.
Crie um Secret ou utilize um já existente. Múltiplos Pods podem referenciar o
mesmo Secret.
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.
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:v1kind:Podmetadata:name:secret-env-podspec:containers:- name:mycontainerimage:redisenv:- name:SECRET_USERNAMEvalueFrom:secretKeyRef:name:mysecretkey:usernameoptional:false# valor padrão; "mysecret" deve existir# e incluir uma chave com o nome "username"- name:SECRET_PASSWORDvalueFrom:secretKeyRef:name:mysecretkey:passwordoptional:false# valor padrão; "mysecret" deve existir# e incluir uma chave com o nome "password"restartPolicy:Never
Variáveis de ambiente inválidas
Secrets utilizados para popular variáveis de ambiente através do campo envFrom
que possuem chaves consideradas inválidas para nomes de variáveis de ambiente
têm tais chaves ignoradas. O Pod irá iniciar normalmente.
Se você definir um Pod contendo um nome de variável de ambiente inválido, os
eventos de inicialização do Pod incluirão um evento com a razão
InvalidVariableNames e uma mensagem que lista as chaves inválidas ignoradas.
O exemplo abaixo demonstra um Pod que referencia um Secret chamado mysecret,
onde mysecret contém duas chaves inválidas: 1badkey and 2alsobad.
kubectl get events
O resultado é semelhante a:
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.
Consumindo valores de Secret em variáveis de ambiente
Dentro de um contêiner que consome um Secret em variáveis de ambiente, as chaves
do Secret aparecem como variáveis de ambiente comuns, contendo os dados do
Secret decodificados do formato base64. Ao executar comandos no contêiner do
exemplo anterior, obteremos os resultados abaixo:
echo$SECRET_USERNAME
O resultado é semelhante a:
admin
echo$SECRET_PASSWORD
O resultado é semelhante a:
1f2d1e2e67df
Nota:
Se um contêiner já consome um Secret em uma variável de ambiente, uma
atualização do Secret não será detectada pelo contêiner a menos que este seja
reiniciado. Há soluções de terceiros que fornecem a funcionalidade de
reinicialização automática de Pods quando o valor dos Secrets mudam.
Secrets para obtenção de imagens de contêiner
Se você deseja obter imagens de contêiner de um repositório privado, você
precisa fornecer ao kubelet uma maneira de se autenticar a este repositório.
Você pode configurar o campo imagePullSecrets para esta finalidade. Estes
Secrets são configurados a nível de Pod.
O campo imagePullSecrets de um Pod é uma lista de referências a Secrets
no mesmo namespace que o Pod.
Você pode utilizar imagePullSecrets para enviar credenciais para acesso a um
registro de contêineres ao kubelet. O kubelet utiliza essa informação para
baixar uma imagem privada no lugar do seu Pod.
Veja o campo PodSpec na
referência da API de Pods
para maiores detalhes sobre o campo imagePullSecrets.
Usando imagePullSecrets
O campo imagePullSecrets é uma lista de referências a Secrets no mesmo
namespace.
Você pode utilizar o campo imagePullSecrets para enviar um Secret que contém
uma senha para um registro de imagens de contêiner do Docker (ou outro registro
de imagens de contêiner). O kubelet utiliza essa informação para baixar uma
imagem privada no lugar do seu Pod.
Veja a API PodSpec
para mais informações sobre o campo imagePullSecrets.
Configurando imagePullSecrets para serem adicionados 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.
Utilizando Secrets com pods estáticos
Você não pode utilizar ConfigMaps ou Secrets em
Pods estáticos.
Casos de uso
Caso de uso: Como variáveis de ambiente em um contêiner
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.
Você também pode criar um manifesto kustomization.yaml com um campo
secretGenerator contendo chaves SSH.
Cuidado:
Analise cuidadosamente antes de enviar suas próprias chaves SSH: outros usuários
do cluster podem ter acesso a este Secret.
Como alternativa, você pode criar uma chave SSH privada representando a
identidade de um serviço que você deseja que seja acessível a todos os usuários
com os quais você compartilha o cluster do Kubernetes em questão. Desse modo,
você pode revogar esta credencial em caso de comprometimento.
Agora você pode criar um Pod que referencia o Secret com a chave SSH e consome-o
em um volume:
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.
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:
Observe como as specs 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:
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:
Este volume irá conter um único arquivo, chamado .secret-file, e o contêiner
dotfile-test-container terá este arquivo presente no caminho
/etc/secret-volume/.secret-file.
Nota:
Arquivos com nomes iniciados por um caractere de ponto são ocultados do
resultado do comando ls -l. Você precisa utilizar ls -la para vê-los ao
listar o conteúdo de um diretório.
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.
Tipos de Secrets
Ao criar um Secret, você pode especificar o seu tipo utilizando o campo type
do objeto Secret, ou algumas opções de linha de comando equivalentes no comando
kubectl, quando disponíveis. O campo type de um Secret é utilizado para
facilitar a manipulação programática de diferentes tipos de dados confidenciais.
O Kubernetes oferece vários tipos embutidos de Secret para casos de uso comuns.
Estes tipos variam em termos de validações efetuadas e limitações que o
Kubernetes impõe neles.
Tipo embutido
Caso de uso
Opaque
dados arbitrários definidos pelo usuário
kubernetes.io/service-account-token
token de service account (conta de serviço)
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.
Se você estiver definindo um tipo de Secret que seja para uso público, siga a
convenção e estruture o tipo de Secret para conter o seu domínio antes do nome,
separado por uma barra (/).
Por exemplo: cloud-hosting.example.net/cloud-api-credentials.
Para melhor desempenho em uma requisição get repetitiva, clientes podem criar
objetos que referenciam o Secret e então utilizar a requisição watch neste
novo objeto, requisitando o Secret novamente quando a referência mudar.
Além disso, uma API de "observação em lotes"
para permitir a clientes observar recursos individuais também foi proposta e
provavelmente estará disponível em versões futuras do Kubernetes.
Opaque é o tipo predefinido de Secret quando o campo type é omitido em um
arquivo de configuração de Secret. Quando um Secret é criado usando o comando
kubectl, você deve usar o subcomando generic para indicar que um Secret é
do tipo Opaque. Por exemplo, o comando a seguir cria um Secret vazio do tipo
Opaque:
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 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:v1kind:Secretmetadata:name:secret-sa-sampleannotations:kubernetes.io/service-account-name:"sa-name"type:kubernetes.io/service-account-tokendata:# Você pode incluir pares chave-valor adicionais, da mesma forma que faria com# Secrets do tipo Opaqueextra:YmFyCg==
Ao criar um Pod, o Kubernetes
automaticamente cria um Secret de service account e automaticamente atualiza o
seu Pod para utilizar este Secret. O Secret de token de service account contém
credenciais para acessar a API.
A criação automática e o uso de credenciais de API podem ser desativados ou
substituídos se desejado. Porém, se tudo que você necessita é poder acessar o
servidor da API de forma segura, este é o processo recomendado.
Veja a documentação de
ServiceAccount
para mais informações sobre o funcionamento de service accounts. Você pode
verificar também os campos automountServiceAccountToken e serviceAccountName
do Pod
para mais informações sobre como referenciar service accounts em Pods.
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 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:
Se você não desejar fazer a codificação em formato base64, você pode utilizar o
campo stringData como alternativa.
Ao criar estes tipos de Secret utilizando um manifesto (arquivo YAML), o
servidor da API verifica se a chave esperada existe no campo data e se o valor
fornecido pode ser interpretado como um conteúdo JSON válido. O servidor da API
não verifica se o conteúdo informado é realmente um arquivo de configuração do
Docker.
Quando você não tem um arquivo de configuração do Docker, ou quer utilizar o
comando kubectl para criar um Secret de registro de contêineres, você pode
rodar o comando:
Esse comando cria um secret do tipo kubernetes.io/dockerconfigjson. Se você
obtiver o conteúdo do campo .data.dockerconfigjson deste novo Secret e
decodificá-lo do formato base64:
kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d
o resultado será equivalente a este documento JSON (que também é um arquivo de
configuração válido do Docker):
O valor do campo auth no exemplo acima é codificado em base64; ele está
ofuscado mas não criptografado. Qualquer pessoa com acesso a este Secret pode
ler o conteúdo do token bearer.
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:
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:v1kind:Secretmetadata:name:secret-basic-authtype:kubernetes.io/basic-authstringData:username:admin # required field for kubernetes.io/basic-authpassword:t0p-Secret# required field for kubernetes.io/basic-auth
O tipo de autenticação básica é fornecido unicamente por conveniência. Você pode
criar um Secret do tipo Opaque utilizado para autenticação básica. No entanto,
utilizar o tipo embutido e público de Secret (kubernetes.io/basic-auth)
auxilia outras pessoas a compreenderem o propósito do seu Secret, e define uma
convenção de expectativa de nomes de chaves
O tipo embutido também fornece verificação dos campos requeridos pelo servidor
da API.
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 manifesto abaixo é um exemplo de configuração para um Secret de autenticação
SSH com um par de chaves pública/privada:
apiVersion:v1kind:Secretmetadata:name:secret-ssh-authtype:kubernetes.io/ssh-authdata:# os dados estão abreviados neste exemplossh-privatekey:| MIIEpQIBAAKCAQEAulqb/Y ...
O Secret de autenticação SSH é fornecido apenas para a conveniência do usuário.
Você pode criar um Secret do tipo Opaque para credentials utilizadas para
autenticação SSH. No entanto, a utilização do tipo embutido e público de Secret
(kubernetes.io/tls) auxilia outras pessoas a compreenderem o propósito do
seu Secret, e define uma convenção de quais chaves podem ser esperadas.
O tipo embutido também fornece verificação dos campos requeridos em uma
configuração de Secret.
Cuidado:
Chaves privadas SSH não estabelecem, por si só, uma comunicação confiável
entre um cliente SSH e um servidor. Uma forma secundária de estabelecer
confiança é necessária para mitigar ataques man-in-the-middle (MITM), como por
exemplo um arquivo known_hosts adicionado a um ConfigMap.
Secrets TLS
O Kubernetes fornece o tipo embutido de Secret kubernetes.io/tls para
armazenamento de um certificado e sua chave associada que são tipicamente
utilizados para TLS.
Uma utilização comum de Secrets TLS é a configuração de encriptação em trânsito
para um recurso Ingress, mas
este tipo de secret pode também ser utilizado com outros recursos ou diretamente
por uma carga de trabalho.
Ao utilizar este tipo de Secret, as chaves tls.key e tls.crt devem ser
informadas no campo data (ou stringData) da configuração do Secret, embora o
servidor da API não valide o conteúdo de cada uma destas chaves.
O YAML a seguir tem um exemplo de configuração para um Secret TLS:
apiVersion:v1kind:Secretmetadata:name:secret-tlstype:kubernetes.io/tlsdata:# os dados estão abreviados neste exemplotls.crt:| MIIC2DCCAcCgAwIBAgIBATANBgkqh ...tls.key:| MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...
O tipo TLS é fornecido para a conveniência do usuário. Você pode criar um
Secret do tipo Opaque para credenciais utilizadas para o servidor e/ou
cliente TLS. No entanto, a utilização do tipo embutido auxilia a manter a
consistência dos formatos de Secret no seu projeto; o servidor da API
valida se os campos requeridos estão presentes na configuração do Secret.
Ao criar um Secret TLS utilizando a ferramenta de linha de comando kubectl,
você pode utilizar o subcomando tls conforme demonstrado no exemplo abaixo:
O par de chaves pública/privada deve ser criado previamente. O certificado
de chave pública a ser utilizado no argumento --cert deve ser codificado em
formato DER conforme especificado na
seção 5.1 da RFC 7468
e deve corresponder à chave privada fornecida no argumento --key
(PKCS #8 no formato DER;
seção 11 da RFC 7468).
Nota:
Um Secret kubernetes.io/tls armazena o conteúdo de chaves e certificados em
formato DER codificado em base64. Se você tem familiaridade com o formato PEM
para chaves privadas e certificados, o conteúdo é o mesmo do formato PEM,
excluindo-se a primeira e a última linhas.
Por exemplo, para um certificado, você não inclui as linhas
--------BEGIN CERTIFICATE----- e -------END CERTIFICATE----.
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:
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 secreto
do token. Requerido.
description: Uma string contendo uma descrição do propósito para o qual este
token é utilizado. Opcional.
expiration: Um horário absoluto UTC no formato RFC3339 especificando quando
o token deve expirar. Opcional.
usage-bootstrap-<usage>: Um conjunto de flags booleanas indicando outros
usos para este token de autoinicialização.
auth-extra-groups: Uma lista separada por vírgulas de nomes de grupos que
serão autenticados adicionalmente, além do grupo system:bootstrappers.
O YAML acima pode parecer confuso, já que os valores estão todos codificados em
formato base64. Você pode criar o mesmo Secret utilizando este YAML:
apiVersion:v1kind:Secretmetadata:# Observe como o Secret é nomeadoname:bootstrap-token-5emitj# Um Secret de token de inicialização geralmente fica armazenado no namespace# kube-systemnamespace:kube-systemtype:bootstrap.kubernetes.io/tokenstringData:auth-extra-groups:"system:bootstrappers:kubeadm:default-node-token"expiration:"2020-09-13T04:39:10Z"# Esta identificação de token é utilizada no nometoken-id:"5emitj"token-secret:"kq4gihvszzgn1p0r"# Este token pode ser utilizado para autenticaçãousage-bootstrap-authentication:"true"# e pode ser utilizado para assinaturasusage-bootstrap-signing:"true"
Secrets imutáveis
ESTADO DA FUNCIONALIDADE:Kubernetes v1.21 [stable]
O Kubernetes permite que você marque Secrets (e ConfigMaps) específicos como
imutáveis. Prevenir mudanças nos dados de um Secret existente tem os seguintes
benefícios:
protege você de alterações acidentais (ou indesejadas) que poderiam provocar
disrupções em aplicações.
em clusters com uso extensivo de Secrets (pelo menos dezenas de milhares de
montagens únicas de Secrets a Pods), utilizar Secrets imutáveis melhora o
desempenho do seu cluster através da redução significativa de carga no
kube-apiserver. O kubelet não precisa manter um watch em Secrets que são
marcados como imutáveis.
Marcando um Secret como imutável
Você pode criar um Secret imutável adicionando o campo immutable com o valor
true ao manifesto do Secret. Por exemplo:
Você pode também atualizar qualquer Secret mutável existente para torná-lo
imutável.
Nota:
Uma vez que um Secret ou ConfigMap seja marcado como imutável, não é mais
possível reverter esta mudança, nem alterar os conteúdos do campo data. Você
pode somente apagar e recriar o Secret. Pods existentes mantém um ponto de
montagem referenciando o Secret removido - é recomendado recriar tais Pods.
Informações de segurança sobre Secrets
Embora ConfigMaps e Secrets funcionem de formas similares, o Kubernetes aplica
proteções extras aos objetos Secret.
Secrets frequentemente contém valores dentro de um espectro de importância,
muitos dos quais podem provocar escalações de privilégios dentro do Kubernetes
(por exemplo, um token de service account) e em sistemas externos. Mesmo que uma
aplicação individual possa avaliar o poder dos Secrets com os quais espera
interagir, outras aplicações dentro do mesmo namespace podem tornar tais
suposições inválidas.
Um Secret só é enviado a um nó se um Pod naquele nó precisa do Secret em questão.
Para montar Secrets em Pods, o kubelet armazena uma cópia dos dados dentro de um
sistema de arquivos tmpfs, de modo que os dados confidenciais não sejam
escritos em armazenamento durável. Uma vez que o Pod que dependia do Secret seja
removido, o kubelet apaga sua cópia local dos dados confidenciais do Secret.
Um Pod pode possuir vários contêineres. Por padrão, contêineres que você define
têm acesso somente à ServiceAccount padrão e seu Secret relacionado. Você deve
explicitamente definir variáveis de ambiente ou mapear um volume dentro de um
contêiner para ter acesso a qualquer outro Secret.
Podem haver Secrets para vários Pods no mesmo nó. No entanto, somente os Secrets
que um Pod requisitou estão potencialmente visíveis dentro de seus contêineres.
Portanto, um Pod não tem acesso aos Secrets de outro Pod.
Aviso:
Quaisquer contêineres privilegiados em um nó são passíveis de acesso a todos os
Secrets naquele nó.
Recomendações de segurança para desenvolvedores
Aplicações ainda devem proteger o valor da informação confidencial após lê-la
de uma variável de ambiente ou volume. Por exemplo, sua aplicação deve evitar
imprimir os dados do Secret sem encriptação ou transmitir esta informação para
aplicações terceiras de confiabilidade não-estabelecida.
Se você estiver definindo múltiplos contêineres em um Pod, e somente um destes
contêineres necessita acesso a um Secret, defina o volume ou variável de
ambiente de maneira que os demais contêineres não tenham acesso àquele Secret.
Se você configurar um Secret através de um manifesto,
com os dados codificados em formato base64, compartilhar este arquivo ou
salvá-lo em um sistema de controle de versão de código-fonte significa que o
Secret está disponível para qualquer pessoa que pode ler o manifesto. O formato
base64 não é um método de encriptação e não fornece nenhuma confidencialidade
adicional em comparação com texto puro.
Ao instalar aplicações que interagem com a API de Secrets, você deve limitar
o acesso utilizando
políticas de autorização,
como por exemplo RBAC.
Na API do Kubernetes, requisições watch e list em Secrets dentro de um
namespace são extremamente poderosas. Evite fornecer este acesso quando
possível, já que listar Secrets permite aos clientes inspecionar os valores de
todos os Secrets naquele namespace.
Recomendações de segurança para administradores de cluster
Cuidado:
Um usuário que pode criar um Pod que utiliza um Secret pode também ver o valor
daquele Secret. Mesmo que as permissões do cluster não permitam ao usuário ler
o Secret diretamente, o mesmo usuário poderia ter acesso a criar um Pod que
então expõe o Secret.
Restrinja a habilidade de usar as requisições watch e list para listar todos
os Secrets em um cluster (utilizando a API do Kubernetes) de modo que somente
os componentes mais privilegiados e de nível de sistema possam realizar esta
ação.
Ao instalar aplicações que interajam com a API de Secrets, você deve limitar o
acesso utilizando
políticas de autorização,
como por exemplo RBAC.
No servidor da API, objetos (incluindo Secrets) são persistidos no
etcd; portanto:
somente permita a administradores do sistema o acesso ao etcd (incluindo
acesso somente-leitura);
habilite encriptação em disco
para objetos Secret, de modo que os dados de tais Secrets não sejam
armazenados em texto plano no etcd;
considere a destruição do armazenamento durável previamente utilizado pelo
etcd quando não estiver mais em uso;
se houverem múltiplas instâncias do etcd em uso, garanta que o etcd esteja
configurado para utilizar SSL/TLS para comunicação entre instâncias.
3.6.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.
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:
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
quantidade0.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:
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.
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.
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
ESTADO DA FUNCIONALIDADE: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.
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ó:
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.
Você tem um sistema de arquivos no nó que você utiliza para dados efêmeros que
vêm de Pods em execução: logs e volumes do tipo emptyDir. Você pode utilizar
este sistema de arquivos para outros dados (por exemplo, logs de sistema não
relacionados ao Kubernetes); este sistema de arquivos pode até mesmo ser o
sistema de arquivos raiz.
O kubelet também escreve
logs de contêiner a nível de nó
no primeiro sistema de arquivos e os trata de forma semelhante ao armazenamento
local efêmero.
Você também tem um segundo sistema de arquivos, separado, conectado a um
dispositivo lógico de armazenamento distinto. Nesta configuração, o diretório
que você configurou o kubelet para armazenar as camadas de imagens de contêiner
e as camadas graváveis de contêineres em execução estará neste segundo sistema
de arquivos.
O primeiro sistema de arquivos não armazena nenhuma camada de imagens de
contêiner ou camada gravável.
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 gateLocalStorageCapacityIsolation 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:
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.
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:
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:
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.
Quotas de projeto são uma funcionalidade a nível de sistema operacional para
gerenciamento de uso do armazenamento em sistemas de arquivos. Com o Kubernetes,
você pode habilitar quotas de projeto para o monitoramento de armazenamento em
uso. Tenha certeza que o sistema de arquivos do nó que esteja sendo utilizado em
volumes do tipo emptyDir possui suporte a quotas de projeto. Por exemplo,
os sistemas de arquivos XFS e ext4fs oferecem suporte a quotas de projeto.
Nota:
Quotas de projeto permitem o monitoramento do uso de armazenamento, mas não
garantem limites.
O Kubernetes utiliza IDs de projeto iniciando em 1048576. Os IDs em uso estão
registrados nos diretórios /etc/projects e /etc/projid. Se os IDs de projeto
nestes intervalos forem utilizados para outros propósitos no sistema, estes IDs
de projeto deverão estar registrados nos diretórios especificados acima para que
o Kubernetes não os tente utilizar.
Quotas fornecem melhor desempenho e mais precisão do que varredura de diretórios.
Quando um diretório é atribuído a um projeto, todos os arquivos criados no
diretório são também criados no projeto, e o núcleo do sistema pode simplesmente
manter controle de quantos blocos estão em uso por arquivos daquele projeto. Se
um arquivo é criado e apagado, mas possui um descritor de arquivo aberto, ele
continua a consumir espaço. O rastreio de quotas registra este espaço de forma
precisa, enquanto varreduras de diretório ignoram o uso de espaço de
armazenamento por arquivos apagados.
Se você deseja utilizar quotas de projeto, você deve:
Habilitar o feature gateLocalStorageCapacityIsolationFSQuotaMonitoring=true utilizando o campo
featureGates na configuração do kubelet
ou a opção de linha de comando --feature-gates.
Garantir que o sistema de arquivos raiz (ou o sistema de arquivos opcional de
tempo de execução) tem quotas de projeto habilitadas. Todos os sistemas de
arquivos XFS suportam quotas de projeto. Em sistemas de arquivos ext4, você
precisa habilitar a funcionalidade de rastreio de quotas de projeto enquanto
o sistema de arquivos ainda não está montado.
# Para sistema de arquivos ext4, com o volume /dev/block-device não montadosudo tune2fs -O project -Q prjquota /dev/block-device
Garanta que o sistema de arquivos raiz (ou sistema de arquivos opcional de
tempo de execução) esteja montado com quotas de projeto habilitadas. Em ambos
os sistemas XFS e ext4fs, a opção de montagem é chamada prjquota.
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.
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.
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.
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).
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: insufficient cpu
No exemplo acima, o Pod de nome "frontend" não pôde ser agendado devido à nenhum
nó possuir CPU suficiente para suprir seu requerimento de CPU. Mensagens de erro
semelhantes a essa podem sugerir falha devido a falta de memória
(PodExceedsFreeMemory). De maneira geral, se um Pod estiver pendente com uma
mensagem deste tipo, há diversas possibilidades de solução a serem tentadas:
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:
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 ResourceQuotas 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:
Name: simmemleak-hra99
Namespace: default
Image(s): saadali/simmemleak
Node: kubernetes-node-tf0f/10.240.216.66
Labels: name=simmemleak
Status: Running
Reason:
Message:
IP: 10.244.2.75
Containers:
simmemleak:
Image: saadali/simmemleak:latest
Limits:
cpu: 100m
memory: 50Mi
State: Running
Started: Tue, 07 Jul 2019 12:54:41 -0700
Last State: Terminated
Reason: OOMKilled
Exit Code: 137
Started: Fri, 07 Jul 2019 12:54:30 -0700
Finished: Fri, 07 Jul 2019 12:54:33 -0700
Ready: False
Restart Count: 5
Conditions:
Type Status
Ready False
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned simmemleak-hra99 to kubernetes-node-tf0f
Normal Pulled 41s kubelet Container image "saadali/simmemleak:latest" already present on machine
Normal Created 41s kubelet Created container simmemleak
Normal Started 40s kubelet Started container simmemleak
Normal Killing 32s kubelet Killing container with id ead3fb35-5cf5-44ed-9ae1-488115be66c6: Need to kill Pod
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.
3.6.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.
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.
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:
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.
Caso contrário, utilize o arquivo kubeconfig padrão encontrado no diretório $HOME/.kube/config, sem qualquer tipo de combinação.
Determine o contexto a ser utilizado baseado no primeiro padrão encontrado, nesta ordem:
Usar o conteúdo da flag --context caso ela existir.
Usar o current-context a partir da combinação dos arquivos kubeconfig.
Um contexto vazio é permitido neste momento.
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.
Utilizar a flag caso ela existir: --user ou --cluster.
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.
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:
Usar as flags de linha de comando caso existirem: --server, --certificate-authority, --insecure-skip-tls-verify.
Se algum atributo do cluster existir a partir da combinação de kubeconfigs, estes deverão ser utilizados.
Se não existir informação de localização do servidor falhar.
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:
Usar as flags, caso existirem: --client-certificate, --client-key, --username, --password, --token.
Usar os campos user resultado da combinação de arquivos kubeconfig.
Se existirem duas técnicas conflitantes, falhar.
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.
3.6.6 - Gerenciamento de recursos para nós Windows
Esta página descreve as diferenças em como os recursos são gerenciados entre o Linux e o Windows.
Em nós Linux, cgroups são usados como uma divisão para o controle de recursos em Pods.
Os contêineres são criados dentro desse limite para o isolamento de rede, processo e sistema de arquivos.
As APIs de cgroup do Linux podem ser usadas para coletar estatísticas de uso de CPU, E/S e memória.
Em contraste, o Windows usa um objeto de trabalho por contêiner com um filtro de namespace do sistema
para conter todos os processos em um contêiner e fornecer isolamento lógico ao hospedar.
(Os objetos de trabalho são um mecanismo de isolamento de processo do Windows e são diferentes dos
que o Kubernetes chama de Job).
Não há como executar um contêiner do Windows sem a filtragem de namespace.
Isso significa que os privilégios do sistema não podem ser assegurados no contexto do host e,
portanto, os contêineres privilegiados não estão disponíveis no Windows.
Os contêineres não podem assumir uma identidade do host porque o Gerente de Conta de Segurança (Security Account Manager, ou SAM) é separado.
Gerenciamento de memória
O Windows não possui um eliminador de processo por falta de memória como o Linux.
O Windows sempre trata todas as alocações de memória do modo de usuário como
virtuais e os arquivos de paginação são obrigatórios.
Os nós Windows não superdimensionam a memória para os processos. O efeito real
é que o Windows não atingirá as condições de falta de memória
da mesma forma que o Linux, e estará processando a página em disco em vez de estar
sujeito ao encerramento por falta de memória (OOM). Se a memória for
superprovisionada e toda a memória física estiver esgotada, a paginação poderá diminuir o desempenho.
Gerenciamento de CPU
O Windows pode limitar a quantidade de tempo de CPU alocado para diferentes processos,
mas não pode garantir uma quantidade mínima de tempo de CPU.
No Windows, o kubelet oferece suporte a uma flag de linha de comando para definir a
prioridade do escalonador do processo kubelet:
--windows-priorityclass. Essa flag permite que o processo kubelet obtenha
mais fatias de tempo de CPU quando comparado a outros processos em execução no host do Windows.
Mais informações sobre os valores permitidos e os seus significados estão disponíveis em
classes de prioridade do Windows.
Para garantir que os Pods em execução não deixem o kubelet sem ciclos de CPU, defina essa flag como ABOVE_NORMAL_PRIORITY_CLASS ou acima.
Reserva de recursos
Para contabilizar a memória e a CPU usadas pelo sistema operacional, o agente de execução de contêiner
e os processos de host do Kubernetes, como o kubelet, você pode (e deve)
reservar recursos de memória e CPU com as flags --kube-reserved e/ou --system-reserved do kubelet.
No Windows, esses valores são usados apenas para calcular o recursos
alocáveis pelo nó.
Cuidado:
Conforme você implanta cargas de trabalho, defina a memória de recursos e os limites de CPU nos contêineres.
Isso também subtrai de NodeAllocatable e ajuda o escalonador de todo o cluster a determinar quais pods colocar em quais nós.
Alocar pods sem limites pode superprovisionar os nós do Windows e, em casos extremos, fazer com que os nós não sejam íntegros.
No Windows, uma boa prática é reservar pelo menos 2GiB de memória.
Para determinar quanta CPU reservar, identifique a densidade máxima do pod para cada
nó e monitore o uso da CPU dos serviços do sistema em execução, depois escolha um valor que atenda às necessidades das suas cargas de trabalho.
3.7 - Segurança
3.7.1 - Visão Geral da Segurança Cloud Native
Esta visão geral define um modelo para pensar sobre a segurança em Kubernetes no contexto da Segurança em Cloud Native.
Aviso:
Este modelo de segurança no contêiner fornece sugestões, não prova políticas de segurança da informação.
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.
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
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:
Sugestões para proteger sua infraestrutura em um cluster Kubernetes:
Infrastructure security
Área de Interesse para Infraestrutura Kubernetes
Recomendação
Acesso de rede ao servidor API (Control plane)
Todo o acesso ao control plane do Kubernetes publicamente na Internet não é permitido e é controlado por listas de controle de acesso à rede restritas ao conjunto de endereços IP necessários para administrar o cluster.
Acesso de rede aos Nós (nodes)
Os nós devem ser configurados para só aceitar conexões (por meio de listas de controle de acesso à rede) do control plane nas portas especificadas e aceitar conexões para serviços no Kubernetes do tipo NodePort e LoadBalancer. Se possível, esses nós não devem ser expostos inteiramente na Internet pública.
Acesso do Kubernetes à API do provedor de Cloud
Cada provedor de nuvem precisa conceder um conjunto diferente de permissões para o control plane e nós do Kubernetes. É melhor fornecer ao cluster permissão de acesso ao provedor de nuvem que segue o princípio do menor privilégio para os recursos que ele precisa administrar. A documentação do Kops fornece informações sobre as políticas e roles do IAM.
Acesso ao etcd
O acesso ao etcd (o armazenamento de dados do Kubernetes) deve ser limitado apenas ao control plane. Dependendo de sua configuração, você deve tentar usar etcd sobre TLS. Mais informações podem ser encontradas na documentação do etcd.
Encriptação etcd
Sempre que possível, é uma boa prática encriptar todas as unidades de armazenamento, mas como o etcd mantém o estado de todo o cluster (incluindo os Secrets), seu disco deve ser criptografado.
Cluster
Existem duas áreas de preocupação para proteger o Kubernetes:
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:
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
Scanners de Vulnerabilidade de Contêiner e Segurança de Dependência de SO
Como parte da etapa de construção de imagem, você deve usar algum scanner em seus contêineres em busca de vulnerabilidades.
Assinatura Imagem e Enforcement
Assinatura de imagens de contêineres para manter um sistema de confiança para o conteúdo de seus contêineres.
Proibir Usuários Privilegiados
Ao construir contêineres, consulte a documentação para criar usuários dentro dos contêineres que tenham o menor nível de privilégio no sistema operacional necessário para cumprir o objetivo do contêiner.
Use o Contêiner em Runtime com Isolamento mais Forte
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
Code security
Área de Atenção para o Código
Recomendação
Acesso só através de TLS
Se seu código precisar se comunicar por TCP, execute um handshake TLS com o cliente antecipadamente. Com exceção de alguns casos, encripte tudo em trânsito. Indo um passo adiante, é uma boa ideia encriptar o tráfego de rede entre os serviços. Isso pode ser feito por meio de um processo conhecido como mutual ou mTLS, que realiza uma verificação bilateral da comunicação mediante os certificados nos serviços.
Limitando intervalos de porta de comunicação
Essa recomendação pode ser um pouco autoexplicativa, mas, sempre que possível, você só deve expor as portas em seu serviço que são absolutamente essenciais para a comunicação ou coleta de métricas.
Segurança na Dependência de Terceiros
É uma boa prática verificar regularmente as bibliotecas de terceiros de sua aplicação em busca de vulnerabilidades de segurança. Cada linguagem de programação possui uma ferramenta para realizar essa verificação automaticamente.
Análise de Código Estático
A maioria das linguagens fornece uma maneira para analisar um extrato do código referente a quaisquer práticas de codificação potencialmente inseguras. Sempre que possível, você deve automatizar verificações usando ferramentas que podem verificar as bases de código em busca de erros de segurança comuns. Algumas das ferramentas podem ser encontradas em OWASP Source Code Analysis Tools.
Ataques de sondagem dinâmica
Existem algumas ferramentas automatizadas que você pode executar contra seu serviço para tentar alguns dos ataques mais conhecidos. Isso inclui injeção de SQL, CSRF e XSS. Uma das ferramentas de análise dinâmica mais populares é o OWASP Zed Attack proxy.
Próximos passos
Saiba mais sobre os tópicos de segurança do Kubernetes:
Se você não estiver executando o Kubernetes v1.30, verifique a documentação para
sua versão do Kubernetes.
3.7.3 - Segurança para Nós Windows
Esta página descreve considerações de segurança e boas práticas específicas para o sistema operacional Windows.
Proteção para dados Secret nos Nós
No Windows, os dados do Secret são escritos em texto não-encriptado no armazenamento local do nó (em comparação ao uso de tmpfs / sistemas de arquivo em memória no Linux). Como um operador do cluster, você deve tomar as duas medidas adicionais a seguir:
Use ACLs em arquivos para proteger a localização do arquivo Secrets.
Aplique criptografia a nível de volume usando
BitLocker.
Usuários dos Contêineres
RunAsUsername
pode ser utilizado em Pods ou contêineres com Windows para executar os processos do contêiner como usuário específico. Isto é aproximadamente equivalente a
RunAsUser.
Os contêineres Windows oferecem duas contas de usuário padrão, ContainerUser e ContainerAdministrator. As diferenças entre estas duas contas de usuário são descritas em
When to use ContainerAdmin and ContainerUser user accounts
dentro da documentação da Microsoft Secure Windows containers.
Os usuários locais podem ser adicionados às imagens do contêiner durante o processo de criação do mesmo.
Nota:
Imagens baseadas no Nano Server rodam como
ContainerUser por padrão.
Imagens baseadas no Server Core rodam como
ContainerAdministrator por padrão.
Mecanismos de contexto de segurança de Pod específicos para Linux (como SELinux, AppArmor, Seccomp, ou capabilities customizados para POSIX) não são suportados nos nós com Windows.
Contêineres privilegiados não são suportados
no Windows.
Em vez disso, contêineres HostProcess
podem ser usados no Windows para realizar muitas das tarefas realizadas por contêineres privilegiados no Linux.
3.7.4 - Controlando Acesso à API do Kubernetes
Esta página fornece uma visão geral do controle de acesso à API do Kubernetes.
Usuários podem acessar a API do Kubernetes utilizando kubectl,
bibliotecas, ou executando requisições REST. Ambos, usuários humanos e
Contas de serviço do Kubernetes podem ser autorizados
a acessar à API.
Quando uma requisição chega à API, ela passa por diversos estágios,
ilustrados no seguinte diagrama:
Segurança na camada de transporte
Em um cluster Kubernetes típico, a API fica disponível na porta 443, protegida por segurança na camada de transporte (TLS).
O servidor de API apresenta um certificado. Este certificado pode ser assinado utilizando
uma autoridade privada de certificados (CA), ou baseado em uma infraestrutura de chave pública ligada
a uma autoridade de certificados reconhecida publicamente.
Se o seu cluster utiliza uma autoridade privada de certificados, voce precisa de uma cópia do certificado
da autoridade de certificados (CA) dentro do arquivo de configuração ~/.kube/config, no lado do cliente, para que
voce possa confiar na conexão e tenha a garantia de que não há interceptação de tráfego.
O seu cliente pode apresentar o certificado de cliente TLS neste estágio.
Autenticação
Uma vez em que a segurança na camada de transporte (TLS) é estabelecida, a requisição HTTP move para o passo de autenticação.
Isto é demonstrado no passo 1 no diagrama acima.
O script de criação do cluster ou configurações de administração configuram o servidor de API para executar
um ou mais módulos autenticadores.
Autenticadores são descritos em maiores detalhes em
Autenticação.
A entrada para o passo de autenticação é a requisição HTTP completa; no entanto, tipicamente
são verificados os cabeçalhos e/ou o certificado de cliente.
Módulos de autenticação incluem certificados de cliente, senhas, tokens simples,
tokens de auto-inicialização e JSON Web Tokens (utilizados para contas de serviço).
Vários módulos de autenticação podem ser especificados, em que cada um será verificado em sequência,
até que um deles tenha sucesso.
Se a requisição não pode ser autenticada, será rejeitada com o código de status HTTP 401 (não autorizado).
Caso contrário, o usuário é autenticado com um "nome de usuário" específico e o nome de usuário
está disponível para as etapas subsequentes para usar em suas decisões. Alguns autenticadores
também fornecem as associações de grupo do usuário, enquanto outros autenticadores
não o fazem.
Enquanto o Kubernetes usa nomes de usuário para decisões de controle de acesso e no registro de requisições,
ele não possui um objeto user nem armazena nomes de usuários ou outras informações sobre
usuários em sua API.
Autorização
Após a requisição ser autenticada como originada de um usuário específico, a requisição deve ser autorizada. Isso é mostrado no passo 2 no diagrama.
Uma requisição deve incluir o nome do usuário requerente, a ação requisitada e o objeto afetado pela ação. A requisição é autorizada se uma
política existente declarar que o usuário tem as devidas permissões para concluir a ação requisitada.
Por exemplo, se Bob possui a política abaixo, então ele somente poderá ler pods no namespace projectCaribou:
Se Bob fizer uma requisição para escrever (create ou update) em objetos no namespace projectCaribou, sua autorização será negada. Se Bob fizer uma requisição para ler (get) objetos em um namespace diferente, como projectFish, sua autorização será negada.
A autorização do Kubernetes requer que você use atributos comuns a REST para interagir com os sistemas de controle de acesso existentes em toda uma organização ou em todo o provedor de nuvem utilizado. É importante usar a formatação REST porque esses sistemas de controle podem interagir com outras APIs além da API do Kubernetes.
O Kubernetes oferece suporte a vários módulos de autorização, como o modo de controle de acesso baseado em atributos (ABAC), o modo de controle de acesso baseado em função (RBAC) e o modo Webhook. Quando um administrador cria um cluster, ele configura os módulos de autorização que devem ser utilizados no servidor de API. Se mais de um módulo de autorização for configurado, o Kubernetes verificará cada módulo e, se algum módulo autorizar a requisição, a requisição poderá prosseguir. Se todos os módulos negarem a requisição, a requisição será negada (com código de status HTTP 403 - Acesso Proibido).
Para saber mais sobre a autorização do Kubernetes, incluindo detalhes sobre como criar políticas usando os módulos de autorização compatíveis, consulte Visão Geral de Autorização.
Controle de admissão
Os módulos de controle de admissão são módulos de software que podem modificar ou rejeitar requisições.
Além dos atributos disponíveis para os módulos de Autorização, os módulos do controlador de admissão
podem acessar o conteúdo do objeto que está sendo criado ou modificado.
Os controladores de admissão atuam em requisições que criam, modificam, excluem ou age como um proxy para outro objeto.
Os controladores de admissão não agem em requisições que apenas leem objetos.
Quando vários controladores de admissão são configurados, eles são chamados em ordem.
Isso é mostrado como etapa 3 no diagrama.
Ao contrário dos módulos de autenticação e autorização, se algum módulo controlador de admissão
rejeita, a solicitação é imediatamente rejeitada.
Além de rejeitar objetos, os controladores de admissão também podem definir valores padrão complexos para
campos.
Após uma requisição passar por todos os controladores de admissão, ela é validada usando as rotinas de validação
para o objeto de API correspondente e, em seguida, gravados no armazenamento de objetos (mostrado como etapa 4 no diagrama).
Auditoria
A auditoria do Kubernetes fornece um conjunto de registros cronológicos relevantes para a segurança que documentam a sequência de ações em um cluster.
O cluster audita as atividades geradas pelos usuários, pelos aplicativos que usam a API do Kubernetes e pela própria camada de gerenciamento.
A discussão anterior se aplica a requisições enviadas para a porta segura do servidor de API
(o caso típico). O servidor de API pode realmente servir em 2 portas.
Por padrão, o servidor da API Kubernetes atende HTTP em 2 portas:
Porta localhost:
destina-se a testes e auto-inicialização e a outros componentes do nó mestre
(scheduler, controller-manager) para falar com a API
sem segurança na camada de transporte (TLS)
o padrão é a porta 8080
IP padrão é localhost, mude com a flag --insecure-bind-address.
a requisição ignora os módulos de autenticação e autorização .
requisição tratada pelo(s) módulo(s) de controle de admissão.
protegido pela necessidade de ter acesso ao host
“Porta segura”:
utilize sempre que possível
utiliza segurança na camada de transporte (TLS). Defina o certificado com --tls-cert-file e a chave com a flag --tls-private-key-file.
o padrão é a porta 6443, mude com a flag --secure-port.
IP padrão é a primeira interface de rede não localhost, mude com a flag --bind-address.
requisição tratada pelos módulos de autenticação e autorização.
requisição tratada pelo(s) módulo(s) de controle de admissão.
módulos de autenticação e autorização executados.
Próximos passos
Consulte mais documentação sobre autenticação, autorização e controle de acesso à API:
como os pods podem usar Secrets para obter credenciais de API.
3.8 - Políticas
Políticas que você pode configurar e que afetam grupos de recursos.
3.8.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 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.
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.
Quando vários usuários ou equipes compartilham um cluster com um número fixo de nós,
há 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.
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
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.cpu
Em todos os pods em um estado não terminal, a soma dos limites de CPU não pode exceder esse valor.
limits.memory
Em todos os pods em um estado não terminal, a soma dos limites de memória não pode exceder esse valor.
requests.cpu
Em todos os pods em um estado não terminal, a soma das solicitações da CPU não pode exceder esse valor.
requests.memory
Em todos os pods em um estado não terminal, a soma das solicitações de memória não pode exceder esse valor.
hugepages-<size>
Em todos os pods em um estado não terminal, o número de solicitações de grandes páginas do tamanho especificado não pode exceder esse valor.
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:
Em todas as solicitações de volume persistentes associadas ao <storage-class-name>, a soma das solicitações de armazenamento não pode exceder esse valor.
Em todas as declarações de volume persistentes associadas ao storage-class-name, o número total de declarações de volume persistente que podem existir no 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:
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.ephemeral-storage
Em todos os pods no namespace, a soma das solicitações de armazenamento local efêmero não pode exceder esse valor.
limits.ephemeral-storage
Em todos os pods no namespace, a soma dos limites de armazenamento temporário local não pode exceder esse valor.
ephemeral-storage
O mesmo que requests.ephemeral-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
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
configmaps
O número total de ConfigMaps que podem existir no namespace.
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.
replicationcontrollers
O número total de ReplicationControllers que podem existir no namespace.
resourcequotas
O número total de ResourceQuotas que podem existir no namespace.
services
O número total de Serviços que podem existir no namespace.
services.loadbalancers
O número total de serviços do tipo LoadBalancer que podem existir no namespace.
services.nodeports
O número total de serviços do tipo NodePort que podem existir no namespace.
secrets
O número total de segredos que podem existir no namespace.
Por exemplo, a cota de pods conta e impõe um número máximo de pods criados em um único namespace que não é terminal. Você pode querer definir uma cota podsem um namespace para evitar o caso em que um usuário cria muitos pods pequenos e esgota o fornecimento de IPs de pod do cluster.
Escopos de cota
Cada cota pode ter um conjunto associado de scopes. Uma cota só medirá o uso de um recurso se corresponder
a interseção de escopos enumerados.
Quando um escopo é adicionado à cota, ele limita o número de recursos aos quais ele dá suporte a aqueles que pertencem ao escopo. Os recursos especificados na cota fora do conjunto permitido resultam em um erro de validação.
Escopo
Descrição
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.
O escopo BestEffort restringe uma cota ao rastreamento do seguinte recurso:
pods
Os escopos Termination, NotTerminate, NotBestEffort e PriorityClassrestringem 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 NotTerminatena mesma cota, e você também não pode especificar o BestEffort eNotBestEffort 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 oscopeSelector, o operator deve ser Exists.
Terminating
NotTerminating
BestEffort
NotBestEffort
Se o operator for In ou NotIn, o campo values deve ter pelo menos um valor. Por exemplo:
Se o operator for Exists ou DoesNotExist, o campo valuesNÃO deve ser especificado.
Cota de recursos por classe de prioridade
ESTADO DA FUNCIONALIDADE: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".
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
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:v1kind:Podmetadata:name:high-priorityspec:containers:- name:high-priorityimage:ubuntucommand:["/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
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
ESTADO DA FUNCIONALIDADE: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:
Se os operadores quiserem proibir o uso de namespaces e namespaceSelector por padrão, e
permitir apenas para namespaces específicos, eles podem configurar CrossNamespaceAffinitycomo um recurso limitado definindo o sinalizador kube-apiserver --admission-control-config-file
para o caminho do seguinte arquivo de configuração:
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 gatePodAffinityNamespaceSelector 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:
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:
Nesse caso, a criação de um pod será permitida se:
O priorityClassName do pod não foi especificado.
O priorityClassName do pod é especificado com um valor diferente de cluster-services.
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.
Para dar suporte a cargas de trabalho com latência crítica e altas taxas de transferência, o Kubernetes oferece um conjunto de gerenciadores de recursos. Os gerenciadores visam coordenar e otimizar o alinhamento de recursos do nó(s) para Pods configurados com um requisito específico para CPUs, dispositivos e recursos de memória (hugepages).
O gerenciador principal, o gerenciador de topologia, é um componente do Kubelet que coordena o processo geral de gerenciamento de recursos por meio da sua política.
A configuração de gerenciadores individuais é discutida em documentos dedicados:
No Kubernetes, escalonamento refere-se à certeza de que os Pods correspondam aos nós para que o kubelet possa executá-los. Preempção é o processo de finalizar Pods com menor prioridade, para que os Pods com maior prioridade possam ser escalonados nos nós. Remoção é o processo de finalização proativa de um ou mais Pods em nós com poucos recursos.
No Kubernetes, escalonamento refere-se à certeza de que Pods
correspondam aos nós para que o
Kubelet possa executá-los. Preempção é o processo de finalizar Pods com menor prioridade
para que os Pods com maior prioridade possam ser escalonados nos nós. Remoção é o processo de finalização de um ou mais Pods em nós.
Disrupção do Pod é o processo pelo qual Pods ou nós são interrompidos de forma voluntária ou involuntária.
Disrupções voluntárias são iniciadas intencionalmente pelos donos das aplicações ou administradores dos clusters. Disrupções involuntárias não são intencionais e podem ser encadeadas por problemas inevitáveis como Nós com poucos recursos, ou por exclusões acidentais.
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:
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
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,
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.
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
ESTADO DA FUNCIONALIDADE: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".
node.kubernetes.io/unreachable: Nó é inalcançável a partir do controlador de nó. Isso corresponde ao NodeCondition Ready com o valor "Unknown".
node.kubernetes.io/memory-pressure: Nó possui pressão de memória.
node.kubernetes.io/disk-pressure: Nó possui pressão de disco.
node.kubernetes.io/pid-pressure: Nó possui pressão de PID.
node.kubernetes.io/network-unavailable: A rede do nó está indisponível.
node.kubernetes.io/unschedulable: Nó não é alocável.
node.cloudprovider.kubernetes.io/uninitialized: Quando o kubelet é iniciado com um provedor de nuvem "externo", esse taint é adicionado ao nó para que ele seja marcado como não utilizável. Após o controlador do cloud-controller-manager inicializar o nó, o kubelet remove esse taint.
No caso de um nó estar prestes a ser expulso, o controlador de nó ou kubelet adicionam os taints relevantes com o efeito NoExecute. Se a condição de falha retorna ao normal, o kubelet ou controlador de nó podem remover esses taints.
Nota:
A camada de gerenciamento limita a taxa de adição de novos taints aos nós. Esse limite gerencia o número de expulsões que são disparadas quando muitos nós se tornam inalcançáveis ao mesmo tempo (por exemplo: se ocorre uma falha na rede).
Você pode especificar tolerationSeconds em um Pod para definir quanto tempo ele ficará alocado em um nó que está falhando ou está sem resposta.
Por exemplo, você talvez queira manter uma aplicação com vários estados salvos localmente alocado em um nó por um longo período na ocorrência de uma divisão na rede, esperando que essa divisão se recuperará e assim a expulsão do pod pode ser evitada.
A tolerância que você define para esse Pod poderia ficar assim:
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.
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:
Filtragem
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.
Existem duas maneiras suportadas de configurar o comportamento de filtragem e pontuação
do escalonador:
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.
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 GatePodOverhead 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:
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:
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:
Verifique isto comparado ao que é observado pelo nó:
kubectl describe node | grep test-pod -B2
A saída mostra que 2250m CPU e 320MiB de memória são solicitados, que inclui PodOverhead:
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE
--------- ---- ------------ ---------- --------------- ------------- ---
default test-pod 2250m (56%) 2250m (56%) 320Mi (1%) 320Mi (1%) 36m
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á agendadoPOD_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á agendadosudo 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.
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/memory.limit_in_bytes
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.
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.
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.
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.
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.
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
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
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.
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.
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
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.
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.10.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.
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.
Essa bridge é criada pelo Kubelet (controlada pela opção --network-plugin=kubenet)
de acordo com a informação .spec.podCIDR do Nó.
O Docker irá agora alocar IPs do bloco cbr-cidr. Contêineres podem alcançar
outros contêineres e nós através da interface cbr0. Esses IPs são todos roteáveis
dentro da rede do projeto do GCE.
O GCE mesmo não sabe nada sobre esses IPs, então não irá mascará-los quando tentarem
se comunicar com a internet. Para permitir isso uma regra de IPTables é utilizada para
mascarar o tráfego para IPs fora da rede do projeto do GCE (no exemplo abaixo, 10.0.0.0/8):
Por fim, o encaminhamento de IP deve ser habilitado no Kernel de forma a processar
os pacotes vindos dos contêineres:
sysctl net.ipv4.ip_forward=1
O resultado disso tudo é que Pods agora podem alcançar outros Pods e podem também
se comunicar com a Internet.
Kube-router
Kube-router é uma solução construída
que visa prover alta performance e simplicidade operacional. Kube-router provê um
proxy de serviços baseado no LVS/IPVS,
uma solução de comunicação pod-para-pod baseada em encaminhamento de pacotes Linux e sem camadas
adicionais, e funcionalidade de políticas de redes baseadas no IPTables/IPSet.
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.
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.
3.10.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.
Para buscar os logs, use o comando kubectl logs, da seguinte maneira:
kubectl logs counter
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ó.
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:
apiVersion:v1kind:Podmetadata:name:counterspec:containers:- name:countimage:busyboxargs:- /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;
donevolumeMounts:- name:varlogmountPath:/var/logvolumes:- name:varlogemptyDir:{}
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:
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.
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:v1kind:ConfigMapmetadata:name:fluentd-configdata: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.
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.
3.10.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.
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.
I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"
Logs em formato JSON
ESTADO DA FUNCIONALIDADE: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):
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:
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.
3.10.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.
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/v1kind:ClusterRolemetadata:name:prometheusrules:- nonResourceURLs:- "/metrics"verbs:- get
A métrica alfa não tem garantias de estabilidade. Essas métricas podem ser modificadas ou deletadas a qualquer momento.
Métricas estáveis possuem a garantia de que não serão alteradas. Isso significa:
Uma métrica estável sem uma assinatura ultrapassada não será deletada ou renomeada
O tipo de uma métrica estável não será modificado
As métricas ultrapassadas estão programadas para exclusão, mas ainda estão disponíveis para uso.
Essas métricas incluem uma anotação sobre a versão em que se tornarão ultrapassadas.
Por exemplo:
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 flagshow-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).
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:
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'
3.10.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
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.
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.
3.10.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!
3.10.10 - Prioridade e imparcialidade da API
ESTADO DA FUNCIONALIDADE:Kubernetes v1.20 [beta]
Controlar o comportamento do servidor da API Kubernetes em uma situação de sobrecarga
é uma tarefa chave para administradores de cluster. O kube-apiserver tem alguns controles disponíveis
(ou seja, as flags--max-requests-inflight e --max-mutating-requests-inflight)
para limitar a quantidade de trabalho pendente que será aceito,
evitando que uma grande quantidade de solicitações de entrada sobrecarreguem, e
potencialmente travando o servidor da API, mas essas flags não são suficientes para garantir
que as solicitações mais importantes cheguem em um período de alto tráfego.
O recurso de prioridade e imparcialidade da API (do inglês API Priority and Fairness, APF) é uma alternativa que melhora
as limitações mencionadas acima. A APF classifica
e isola os pedidos de uma forma mais refinada. Também introduz
uma quantidade limitada de filas, para que nenhuma solicitação seja rejeitada nos casos
de sobrecargas muito breves. As solicitações são despachadas das filas usando uma
técnica de filas justa para que, por exemplo, um
controller não precise
negar as outras requisições (mesmo no mesmo nível de prioridade).
Esse recurso foi projetado para funcionar bem com controladores padrão, que
usam informantes e reagem a falhas de solicitações da API com exponencial
back-off, e outros clientes que também funcionam desta forma.
Cuidado:
Solicitações classificadas como "de longa duração" — principalmente watches — não são
sujeitas ao filtro da prioridade e imparcialidade da API. Isso também é verdade para
a flag--max-requests-inflight sem o recurso da APF ativado.
Ativando/Desativando a prioridade e imparcialidade da API
O recurso de prioridade e imparcialidade da API é controlado por um feature gate
e está habilitado por padrão. Veja Portões de Recurso
para uma explicação geral dos portões de recursos e como habilitar e
desativá-los. O nome da porta de recurso para APF é
"APIPriorityAndFairness". Este recurso também envolve um API Group com: (a) um
Versão v1alpha1, desabilitada por padrão, e (b) v1beta1 e
Versões v1beta2, habilitadas por padrão. Você pode desativar o feature gate
e versões beta do grupo de APIs adicionando a seguinte
flag para sua invocação kube-apiserver:
kube-apiserver \
--feature-gates=APIPriorityAndFairness=false\
--runtime-config=flowcontrol.apiserver.k8s.io/v1beta1=false,flowcontrol.apiserver.k8s.io/v1beta2=false\
# …and other flags as usual
Como alternativa, você pode habilitar a versão v1alpha1 do grupo de APIs
com --runtime-config=flowcontrol.apiserver.k8s.io/v1alpha1=true.
A flag--enable-priority-and-fairness=false desabilitará o
recurso de prioridade e imparcialidade da API, mesmo que outras flags o tenha ativado.
Conceitos
Existem vários recursos distintos envolvidos na APF.
As solicitações recebidas são classificadas por atributos da solicitação usando
FlowSchemas e atribuídos a níveis de prioridade. Os níveis de prioridade adicionam um grau de
isolamento mantendo limites de simultaneidade separados, para que as solicitações atribuídas
a diferentes níveis de prioridade não travem outros. Dentro de um nível de prioridade,
um algoritmo de fair queuing impede que solicitações de diferentes flows fiquem sem energia
entre si, e permite que os pedidos sejam enfileirados para evitar que um alto tráfego
cause falhas nas solicitações quando a carga média é aceitavelmente baixa.
Níveis de prioridade
Sem o APF ativado, a simultaneidade geral no servidor de API é limitada pelo
kube-apiserver as flags--max-requests-inflight e
--max-mutating-requests-inflight. Com o APF ativado, os limites de simultaneidade
definidos por esses sinalizadores são somados e, em seguida, a soma é dividida entre um
conjunto configurável de níveis de prioridade. Cada solicitação recebida é atribuída a um
nível de prioridade único, e cada nível de prioridade só despachará tantos
solicitações simultâneas conforme sua configuração permite.
A configuração padrão, por exemplo, inclui níveis de prioridade separados para
solicitações de eleição de líder, solicitações de controladores integrados e solicitações de
Pods. Isso significa que um pod mal-comportado que inunda o servidor da API com
solicitações não podem impedir a eleição do líder ou ações dos controladores integrados
de ter sucesso.
Enfileiramento
Mesmo dentro de um nível de prioridade pode haver um grande número de fontes distintas de
tráfego. Em uma situação de sobrecarga, é importante evitar um fluxo de
pedidos de outros serviços (em particular, no caso relativamente comum de um
único cliente buggy inundando o kube-apiserver com solicitações, esse cliente buggy
idealmente não teria muito impacto em outros clientes). Isto é
tratadas pelo uso de um algoritmo de fair queuing para processar solicitações que são atribuídas
ao mesmo nível de prioridade. Cada solicitação é atribuída a um flow, identificado pelo
nome do FlowSchema correspondente mais um flow distincter — que
é o usuário solicitante, o namespace do recurso de destino ou nada — e o
sistema tenta dar peso aproximadamente igual a solicitações em diferentes
fluxos do mesmo nível de prioridade.
Para habilitar o tratamento distinto de instâncias distintas, os controladores que
muitas instâncias devem ser autenticadas com nomes de usuário distintos
Depois de classificar uma solicitação em um fluxo, a APF
pode então atribuir a solicitação a uma fila. Esta atribuição usa
uma técnica conhecida como shuffle sharding, que faz uso relativamente eficiente de
filas para isolar fluxos de baixa intensidade de fluxos de alta intensidade.
Os detalhes do algoritmo de enfileiramento são ajustáveis para cada nível de prioridade e
permitem que os administradores troquem o uso de memória, justiça (a propriedade que
fluxos independentes irão progredir quando o tráfego total exceder a capacidade),
tolerância para tráfego e a latência adicionada induzida pelo enfileiramento.
Solicitações de isenção
Alguns pedidos são considerados suficientemente importantes para que não estejam sujeitos a
qualquer uma das limitações impostas por este recurso. Estas isenções impedem uma
configuração de controle de fluxo mal configurada de desabilitar totalmente um servidor da API.
Recursos
A API de controle de fluxo envolve dois tipos de recursos.
PriorityLevelConfigurations
define as classes de isolamento disponíveis, a parte da concorrência disponível
que cada um pode tratar e permite o ajuste fino do comportamento das filas.
FlowSchemas
são usados para classificar solicitações de entrada individuais, correspondendo cada uma a um
único PriorityLevelConfiguration. Há também uma versão v1alpha1
do mesmo grupo de APIs e tem os mesmos tipos com a mesma sintaxe e
semântica.
PriorityLevelConfiguration
Um PriorityLevelConfiguration representa uma única classe de isolamento. Cada
PriorityLevelConfiguration tem um limite independente no número de solicitações de pendências
e limitações no número de solicitações enfileiradas.
Os limites de simultaneidade para PriorityLevelConfigurations não são especificados no número absoluto
de solicitações, mas sim em "compartilhamentos de simultaneidade". A simultaneidade limite total
para o servidor da API é distribuído entre os PriorityLevelConfigurations existentes
em proporção com esses compartilhamentos. Isso permite um
administrador de cluster aumentar ou diminuir a quantidade total de tráfego para um
servidor reiniciando kube-apiserver com um valor diferente para
--max-requests-inflight (ou --max-mutating-requests-inflight), e todos os
PriorityLevelConfigurations verá sua simultaneidade máxima permitida aumentar (ou
abaixar) pela mesma proporção.
Cuidado:
Com o recurso prioridade e imparcialidade ativado, o limite total de simultaneidade para
o servidor é definido como a soma de --max-requests-inflight e
--max-mutating-requests-inflight. Já não há distinção
entre solicitações mutantes e não mutantes; se você quiser tratá-las
separadamente para um determinado recurso, faça FlowSchemas separados que correspondam ao
verbos mutantes e não mutantes, respectivamente.
Quando o volume de solicitações de entrada atribuídas a um único
PriorityLevelConfiguration é maior do que o permitido por seu nível de simultaneidade, o
O campo type de sua especificação determina o que acontecerá com solicitações extras.
Um tipo de 'Reject' significa que o excesso de tráfego será imediatamente rejeitado com
um erro HTTP 429 (Too Many Requests). Um tipo de Queue significa que as solicitações
acima do limite será enfileirado, com as técnicas de
shuffle sharding e fair queuing usadas
para equilibrar o progresso entre os fluxos de solicitação.
A configuração de enfileiramento permite ajustar o algoritmo de fair queuing para um
nível de prioridade. Os detalhes do algoritmo podem ser lidos no
proposta de melhoria, mas resumindo:
Aumentar as 'filas' reduz a taxa de colisões entre diferentes fluxos,
o custo do aumento do uso de memória. Um valor de 1 aqui efetivamente desabilita a
lógica de fair queuing, mas ainda permite que as solicitações sejam enfileiradas.
Aumentar o queueLengthLimit permite que tráfegos maiores sejam
sustentados sem deixar de lado nenhum pedido, ao custo de aumento
latência e uso de memória.
Alterar handSize permite ajustar a probabilidade de colisões entre
fluxos diferentes e a simultaneidade geral disponível para um único fluxo em um
situação de sobrecarga.
Nota:
Um 'handSize' maior torna menos provável que dois fluxos individuais colidam
(e, portanto, um bloqueie a solicitação do outro), mas é mais provável que
um pequeno número de fluxos pode dominar o apiserver. Um handSize maior também
aumenta potencialmente a quantidade de latência que um único fluxo de alto tráfego
pode causar. O número máximo de solicitações enfileiradas possíveis de um
fluxo único é handSize * queueLengthLimit.
A seguir está uma tabela mostrando uma coleção interessante de configurações do
shuffle sharding, mostrando para cada uma a probabilidade de que um
determinado rato (fluxo de baixa intensidade) é esmagado pelos elefantes (fluxo de alta intensidade) para
uma coleção ilustrativa de números de elefantes. Veja
https://play.golang.org/p/Gi0PLgVHiUg , que calcula esta tabela.
Example Shuffle Sharding Configurations
HandSize
Filas
1 elefante
4 elefantes
16 elefantes
12
32
4.428838398950118e-09
0.11431348830099144
0.9935089607656024
10
32
1.550093439632541e-08
0.0626479840223545
0.9753101519027554
10
64
6.601827268370426e-12
0.00045571320990370776
0.49999929150089345
9
64
3.6310049976037345e-11
0.00045501212304112273
0.4282314876454858
8
64
2.25929199850899e-10
0.0004886697053040446
0.35935114681123076
8
128
6.994461389026097e-13
3.4055790161620863e-06
0.02746173137155063
7
128
1.0579122850901972e-11
6.960839379258192e-06
0.02406157386340147
7
256
7.597695465552631e-14
6.728547142019406e-08
0.0006709661542533682
6
256
2.7134626662687968e-12
2.9516464018476436e-07
0.0008895654642000348
6
512
4.116062922897309e-14
4.982983350480894e-09
2.26025764343413e-05
6
1024
6.337324016514285e-16
8.09060164312957e-11
4.517408062903668e-07
FlowSchema
Um FlowSchema corresponde a algumas solicitações de entrada e as atribui a um
nível de prioridade. Cada solicitação de entrada é testada em relação a cada
FlowSchema, por sua vez, começando com aqueles com valores numericamente mais baixos ---
que consideramos ser o logicamente mais alto --- matchingPrecedence e
trabalhando adiante. A primeira correspondência ganha.
Cuidado:
Somente o primeiro FlowSchema correspondente para uma determinada solicitação é importante. Se vários
FlowSchemas correspondem a uma única solicitação de entrada, ela será atribuída com base na
com o maior em matchingPrecedence. Se vários FlowSchemas com igual
matchingPrecedence corresponde ao mesmo pedido, aquele com menor
name lexicográfico vencerá, mas é melhor não confiar nisso e, em vez disso,
certifique-se de que dois FlowSchemas não tenham o mesmo matchingPrecedence.
Um FlowSchema corresponde a uma determinada solicitação se pelo menos uma de suas regras
são correspondidas. Uma regra corresponde se pelo menos um de seus assuntose pelo menos
uma de suas resourceRules ou nonResourceRules (dependendo se a
solicitação de entrada é para um recurso ou URL de não-recurso) corresponde à solicitação.
Para o campo name em assuntos, e os campos verbs, apiGroups, resources,
namespaces e nonResourceURLs de regras de recursos e não recursos,
o wildcard* pode ser especificado para corresponder a todos os valores do campo fornecido,
efetivamente removendo-o de consideração.
O distinguisherMethod.type de um FlowSchema determina como as solicitações correspondentes a esse
esquema será separado em fluxos. Pode ser
ou ByUser, caso em que um usuário solicitante não poderá ser bloqueado por outros,
ou ByNamespace, caso em que solicitações de recursos
em um namespace não será capaz de privar os pedidos de recursos em outros
namespaces de capacidade, ou pode estar em branco (ou distinguisherMethod pode ser
omitido inteiramente), caso em que todas as solicitações correspondidas por este FlowSchema serão
considerados parte de um único fluxo. A escolha correta para um determinado FlowSchema
depende do recurso e do seu ambiente específico.
Padrões
Cada kube-apiserver mantém dois tipos de objetos de configuração APF:
obrigatória e sugerida.
Objetos de configuração obrigatórios
Os quatro objetos de configuração obrigatórios refletem no
comportamento do guardrail embutido. Este é o comportamento que os servidores tinham antes
desses objetos existirem e, quando esses objetos existem, suas especificações refletem
esse comportamento. Os quatro objetos obrigatórios são os seguintes.
O nível de prioridade obrigatório exempt é usado para solicitações que são
não sujeito a controle de fluxo: eles sempre serão despachados
imediatamente. O FlowSchema obrigatório exempt classifica todos
solicitações do grupo system:masters para este nível de prioridade.
Você pode definir outros FlowSchemas que direcionam outras solicitações
a este nível de prioridade, se apropriado.
O nível de prioridade obrigatório catch-all é usado em combinação com
o FlowSchema catch-all obrigatório para garantir que todas as solicitações
recebam algum tipo de classificação. Normalmente você não deve confiar
nesta configuração catch-all, e deve criar seu próprio FlowSchema catch-all
e PriorityLevelConfiguration (ou use o
nível de prioridade global-default que é instalado por padrão) como
apropriado. Como não se espera que seja usado normalmente, o
o nível de prioridade obrigatório catch-all tem uma simultaneidade muito pequena
compartilha e não enfileira solicitações.
Objetos de configuração sugeridos
Os FlowSchemas e PriorityLevelConfigurations sugeridos constituem uma
configuração padrão razoável. Você pode modificá-los e/ou criar
objetos de configuração adicionais, se desejar. Se o seu cluster tiver a
probabilidade de experimentar carga pesada, então você deve considerar qual
configuração funcionará melhor.
A configuração sugerida agrupa as solicitações em seis níveis de prioridade:
O nível de prioridade node-high é para atualizações de integridade dos nós.
O nível de prioridade system é para solicitações não relacionadas à integridade do
grupo system:nodes, ou seja, Kubelets, que deve ser capaz de contatar
o servidor de API para que as cargas de trabalho possam ser agendadas
eles.
O nível de prioridade leader-election é para solicitações de eleição de líder de
controladores embutidos (em particular, solicitações para endpoints, configmaps,
ou leases vindo do system:kube-controller-manager ou
usuários system:kube-scheduler e contas de serviço no namespace kube-system).
Estes são importantes para isolar de outro tráfego porque as falhas
na eleição do líder fazem com que seus controladores falhem e reiniciem, o que por sua vez
causa tráfego mais caro à medida que os novos controladores sincronizam seus informantes.
O nível de prioridade workload-high é para outras solicitações de controladores built-in.
O nível de prioridade workload-low é para solicitações de qualquer outra conta de serviço,
que normalmente incluirá todas as solicitações de controladores em execução
Pods.
O nível de prioridade global-default trata de todos os outros tráfegos, por exemplo,
comandos kubectl interativos executados por usuários não privilegiados.
Os FlowSchemas sugeridos servem para direcionar as solicitações para os
níveis de prioridade acima, e não são enumerados aqui.
Manutenção dos Objetos de Configuração Obrigatórios e Sugeridos
Cada kube-apiserver mantém independentemente os requisitos obrigatórios e
objetos de configuração sugeridos, usando comportamento inicial e periódico.
Assim, em uma situação com uma mistura de servidores de diferentes versões
pode haver thrashing desde que servidores diferentes tenham
opiniões sobre o conteúdo adequado desses objetos.
Para os objetos de configuração obrigatórios, a manutenção consiste em
garantir que o objeto existe e, se existir, tem a especificação adequada.
O servidor se recusa a permitir uma criação ou atualização com uma especificação que é
inconsistente com o comportamento do guarda-corpo do servidor.
A manutenção de objetos de configuração sugeridos é projetada para permitir
que suas especificações sejam substituídas. A exclusão, por outro lado, não é
respeitada: a manutenção restaurará o objeto. Se você não quer um
objeto de configuração sugerido, então você precisa mantê-lo por perto, mas defina
sua especificação para ter consequências mínimas. Manutenção de objetos
sugeridos também é projetada para suportar a migração automática quando uma nova
versão do kube-apiserver é lançada, embora potencialmente com
thrashing enquanto há uma população mista de servidores.
A manutenção de um objeto de configuração sugerido consiste em cria-lo
--- com a especificação sugerida pelo servidor --- se o objeto não
existir. OTOH, se o objeto já existir, o comportamento de manutenção
depende se os kube-apiservers ou os usuários controlam o
objeto. No primeiro caso, o servidor garante que a especificação do objeto
é o que o servidor sugere; no último caso, a especificação é deixada
sozinho.
A questão de quem controla o objeto é respondida primeiro olhando
para uma anotação com a chave apf.kubernetes.io/autoupdate-spec. Se
existe tal anotação e seu valor é true então o
kube-apiservers controlam o objeto. Se houver tal anotação
e seu valor for false, os usuários controlarão o objeto. Se
nenhuma dessas condições é satisfeita entaão a metadata.generation do
objeto é consultado. Se for 1, o kube-apiservers controla
o objeto. Caso contrário, os usuários controlam o objeto. Essas regras foram
introduzido na versão 1.22 e sua consideração de
metadata.generation é para migrar do mais simples
comportamento anterior. Usuários que desejam controlar um objeto de configuração sugerido
deve definir sua anotação apf.kubernetes.io/autoupdate-spec
para 'falso'.
A manutenção de um objeto de configuração obrigatório ou sugerido também
inclui garantir que ele tenha uma anotação apf.kubernetes.io/autoupdate-spec
que reflete com precisão se os kube-apiservers
controlam o objeto.
A manutenção também inclui a exclusão de objetos que não são obrigatórios
nem sugeridos, mas são anotados
apf.kubernetes.io/autoupdate-spec=true.
Isenção de simultaneidade da verificação de integridade
A configuração sugerida não dá nenhum tratamento especial a checagem de saúde das requisições
verifique solicitações em kube-apiservers de seus kubelets locais --- que
tendem a usar a porta segura, mas não fornecem credenciais. Com o
configuração sugerida, essas solicitações são atribuídas ao global-default
FlowSchema e o nível de prioridade "global-default" correspondente,
onde outro tráfego pode bloqueá-los.
Se você adicionar o seguinte FlowSchema adicional, isso isenta aquelas
solicitações de limitação de taxa.
Cuidado:
Fazer essa alteração também permite que qualquer parte hostil envie
solicitações de verificação de integridade que correspondam a este FlowSchema, em qualquer volume.
Se você tiver um filtro de tráfego da Web ou outro mecanismo de segurança externa semelhante
para proteger o servidor de API do seu cluster do trafego geral de internet,
você pode configurar regras para bloquear qualquer solicitação de verificação de integridade
que se originam de fora do seu cluster.
Cada resposta HTTP de um servidor da API com o recurso de prioridade e justiça
ativado tem dois cabeçalhos extras: X-Kubernetes-PF-FlowSchema-UID e
X-Kubernetes-PF-PriorityLevel-UID, observando o esquema de fluxo que corresponde à solicitação
e o nível de prioridade ao qual foi atribuído, respectivamente. Os nomes dos objetos da API
não são incluídos nesses cabeçalhos caso o usuário solicitante não
tenha permissão para visualizá-los, então ao depurar você pode usar um comando como
kubectl get flowschemas -o custom-columns="uid:{metadata.uid},name:{metadata.name}"kubectl get prioritylevelconfigurations -o custom-columns="uid:{metadata.uid},name:{metadata.name}"
para obter um mapeamento de UIDs de nomes para FlowSchemas e
PriorityLevelConfigurations.
Observabilidade
Metricas
Nota:
Nas versões do Kubernetes anteriores à v1.20, as labelsflow_schema e
priority_level foram nomeados de forma inconsistente como flowSchema e priorityLevel,
respectivamente. Se você estiver executando versões do Kubernetes v1.19 ou anteriores, você
deve consultar a documentação da sua versão.
Quando você ativa o APF, o kube-apiserver
exporta métricas adicionais. Monitorá-los pode ajudá-lo a determinar se a sua
configuração está limitando indevidamente o tráfego importante, ou encontrar
cargas de trabalho mal comportadas que podem estar prejudicando a integridade do sistema.
apiserver_flowcontrol_rejected_requests_total é um vetor de contador
(cumulativo desde o início do servidor) de solicitações que foram rejeitadas,
dividido pelos rótulos flow_schema (indicando aquele que
correspondeu ao pedido), priority_level (indicando aquele para o qual
a solicitação foi atribuída) e reason. A labelreason pode
ter um dos seguintes valores:
queue-full, indicando que muitos pedidos já foram enfileirados,
concurrency-limit, indicando que o
PriorityLevelConfiguration está configurado para rejeitar em vez de
enfileirar solicitações em excesso ou
time-out, indicando que a solicitação ainda estava na fila
quando seu limite de tempo de fila expirou.
apiserver_flowcontrol_dispatched_requests_total é um vetor contador
(cumulativo desde o início do servidor) de solicitações que começaram
executando, dividido pelos rótulos flow_schema (indicando o
um que corresponda à solicitação) e priority_level (indicando o
aquele ao qual o pedido foi atribuído).
apiserver_current_inqueue_requests é um vetor de medidor de
limites máximos do número de solicitações enfileiradas, agrupadas por uma
label chamado request_kind cujo valor é mutating ou readOnly.
Essas marcas d'água altas descrevem o maior número visto em uma
segunda janela concluída recentemente. Estes complementam o mais antigo
vetor medidor apiserver_current_inflight_requests que contém o
marca d'água alta da última janela de número de solicitações sendo ativamente
servido.
apiserver_flowcontrol_read_vs_write_request_count_samples é um
vetor de histograma de observações do número atual de
solicitações, divididas pelos rótulos phase (que assume o
valores waiting e executing) e request_kind (que assume
os valores mutating e readOnly). As observações são feitas
periodicamente a uma taxa elevada.
apiserver_flowcontrol_read_vs_write_request_count_watermarks é um
vetor de histograma de marcas d'água altas ou baixas do número de
solicitações divididas pelos rótulos phase (que assume o
valores waiting e executing) e request_kind (que assume
os valores mutating e readOnly); o rótulo mark assume
valores high e low. As marcas d'água são acumuladas ao longo de
janelas delimitadas pelos tempos em que uma observação foi adicionada a
apiserver_flowcontrol_read_vs_write_request_count_samples. Esses
marcas d'água mostram o intervalo de valores que ocorreram entre as amostras.
apiserver_flowcontrol_current_inqueue_requests é um vetor de medidor
mantendo o número instantâneo de solicitações enfileiradas (não em execução),
dividido pelos rótulos priority_level e flow_schema.
apiserver_flowcontrol_current_executing_requests é um vetor de medidor
segurando o número instantâneo de execução (não esperando em uma
queue), divididas pelos rótulos priority_level e
flow_schema.
apiserver_flowcontrol_request_concurrency_in_use é um vetor de medidor
ocupando o número instantâneo de assentos ocupados, diferenciados pelas
labelspriority_level e flow_schema.
apiserver_flowcontrol_priority_level_request_count_samples é um
vetor de histograma de observações do número atual de
solicitações divididas pelas labelsphase (que assume o
valores waiting e executing) e priority_level. Cada
histograma obtém observações feitas periodicamente, até a última
atividade do tipo relevante. As observações são feitas em nota alta.
apiserver_flowcontrol_priority_level_request_count_watermarks é um
vetor de histograma de marcas d'água altas ou baixas do número de
solicitações divididas pelas labelsphase (que assume o
valores waiting e executing) e priority_level; a labelmark assume valores high e low. As marcas da água são
acumulada em janelas delimitadas pelos tempos em que uma observação
foi adicionado a
apiserver_flowcontrol_priority_level_request_count_samples. Esses
marcas d'água mostram o intervalo de valores que ocorreram entre as amostras.
apiserver_flowcontrol_request_queue_length_after_enqueue é um
vetor de histograma de comprimentos de fila para as filas, dividido pelas
labelspriority_level e flow_schema, conforme mostrado pelas
solicitações enfileiradas. Cada solicitação enfileirada contribui com uma
amostra para seu histograma, relatando o comprimento da fila imediatamente
depois que o pedido foi adicionado. Observe que isso produz diferentes
estatísticas do que uma pesquisa imparcial faria.
Nota:
Um valor discrepante em um histograma aqui significa que é provável que um único fluxo
(ou seja, solicitações de um usuário ou de um namespace, dependendo da
configuração) está inundando o servidor de API e sendo limitado. Por contraste,
se o histograma de um nível de prioridade mostrar que todas as filas para essa prioridade
são mais longos do que os de outros níveis de prioridade, pode ser apropriado
aumentar os compartilhamentos de simultaneidade desse PriorityLevelConfiguration.
apiserver_flowcontrol_request_concurrency_limit é um vetor de medidor
mantendo o limite de simultaneidade calculado (com base no limite total de simultaneidade do servidor da API
e na simultaneidade de PriorityLevelConfigurations share), divididos pela labelpriority_level.
apiserver_flowcontrol_request_wait_duration_seconds é um vetor de histograma
de quanto tempo as solicitações ficaram na fila, divididas pelas labelsflow_schema (indicando qual corresponde à solicitação),
priority_level (indicando aquele para o qual o pedido foi
atribuído) e execute (indicando se a solicitação foi iniciada
executando).
Nota:
Como cada FlowSchema sempre atribui solicitações a um único
PriorityLevelConfiguration, você pode adicionar os histogramas para todos os
FlowSchemas para um nível de prioridade para obter o histograma efetivo para
solicitações atribuídas a esse nível de prioridade.
apiserver_flowcontrol_request_execution_seconds é um vetor de histograma
de quanto tempo as solicitações levaram para realmente serem executadas, divididas pelas
labelsflow_schema (indicando qual corresponde à solicitação)
e priority_level (indicando aquele para o qual o pedido foi
atribuído).
Debug endpoints
Quando você ativa A APF, o kube-apiserver
serve os seguintes caminhos adicionais em suas portas HTTP[S].
/debug/api_priority_and_fairness/dump_priority_levels - uma lista de
todos os níveis de prioridade e o estado atual de cada um. Você pode buscar assim:
kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
Para obter informações básicas sobre detalhes de design para prioridade e justiça da API, consulte
a proposta de aprimoramento.
Você pode fazer sugestões e solicitações de recursos por meio do SIG API Machinery
ou do canal do slack.
3.11 - Extendendo o Kubernetes
3.11.1 - Extendendo a API do Kubernetes
3.11.1.1 - Extendendo a API do Kubernetes com a camada de agregação
A camada de agregação permite ao Kubernetes ser estendido com APIs adicionais,
para além do que é oferecido pelas APIs centrais do Kubernetes.
As APIs adicionais podem ser soluções prontas tal como o
catálogo de serviços,
ou APIs que você mesmo desenvolva.
A camada de agregação 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 funcionalidadeEnableAggregatedDiscoveryTimeout=false no kube-apiserver para desativar
a restrição de intervalo. Esta portal de funcionalidade deprecado será removido
num lançamento futuro.
3.11.2 - Extensões de Computação, armazenamento e redes
3.11.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
sysctlnet/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
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:
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).
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.
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
3.11.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 está gerenciando um serviço ou conjunto de serviços. Operadores humanos que cuidam de aplicativos e serviços específicos possuem um conhecimento profundo de como o sistema deve se comportar, como implantá-lo e como reagir se houver problemas.
As pessoas que executam cargas de trabalho no Kubernetes muitas vezes gostam de usar automação para cuidar de tarefas repetitivas. O padrão do operador captura como você pode escrever código para automatizar uma tarefa além do que o próprio Kubernetes fornece.
Operadores no Kubernetes
O Kubernetes é projetado para automação. Por padrão, você tem bastante automação integrada ao núcleo do Kubernetes. Você pode usar o Kubernetes para automatizar a implantação e execução de cargas de trabalho, e pode automatizar como o Kubernetes faz isso.
O conceito de padrão operador do Kubernetes permite a extensão do comportamento sem modificar o código do próprio Kubernetes, vinculando controladores a um ou mais recursos personalizados.
Os operadores são clientes da API do Kubernetes que atuam como controladores para um recurso personalizado.
Exemplo de um operador
Algumas das coisas que você pode automatizar usando um operador incluem:
implantação sob demanda de uma aplicação
fazer e restaurar backups do estado dessa aplicação
lidar com atualizações do código da aplicação junto com mudanças relacionadas, como esquemas de banco de dados ou configurações adicionais
publicar um Service para que aplicações que não suportam as APIs do Kubernetes possam descobrí-los
simular falhas em todo ou parte do seu cluster para testar resiliência
escolher um líder para uma aplicação distribuída sem um processo de eleição interna de membros
Como seria um operador com mais detalhes? Aqui está um exemplo:
Um recurso personalizado (custom resource) chamado SampleDB, que você pode configurar dentro do cluster.
Um Deployment que garante que um Pod esteja em execução contendo a parte do controlador do operador.
Uma imagem de contêiner do código do operador.
Código do controlador que consulta a camada de gerenciamento para descobrir quais recursos SampleDB estão configurados.
O núcleo do Operador é o código que informa ao servidor da API como fazer com que a realidade corresponda aos recursos configurados.
Se você adicionar um novo SampleDB, o operador configura PersistentVolumeClaims para fornecer armazenamento durável da base de dados, um StatefulSet para executar o SampleDB e um Job para lidar com a configuração inicial.
Se você excluir um SampleDB, o operador cria um instantâneo e em seguida, garante que o StatefulSet e os Volumes também sejam removidos.
O operador também gerencia backups regulares da base de dados. Para cada recurso SampleDB, o operador determina quando criar um Pod que pode se conectar ao banco de dados e fazer backups. Esses Pods dependeriam de um ConfigMap e/ou um Secret que tenha detalhes da conexão e credenciais do banco de dados.
Considerando que o Operador tem como objetivo fornecer automação robusta para o recurso que gerencia, haveria código de suporte adicional. Para este exemplo, o código verifica se o banco de dados está a executando uma versão antiga e, se estiver, cria objetos Job que fazem a atualização para você.
Implantando operadores
A maneira mais comum de implantar um operador é adicionar a definição personalizada de recurso (Custom Resource Definition) e o Controlador associado ao seu cluster.
O Controlador normalmente é executado fora da camada de gerenciamento, assim como você executaria qualquer aplicação que rode em contêineres.
Por exemplo, você pode executar o controlador no seu cluster como um Deployment.
Usando um operador
Depois de implantar um operador, você o usaria adicionando, modificando ou excluindo o tipo de recurso que o operador usa. Seguindo o exemplo acima,
você configuraria um Deployment para o próprio operador, e depois:
kubectl get SampleDB # encontrar banco de dados configuradoskubectl edit SampleDB/example-database # alterar manualmente algumas configurações
…e é isso! O Operador cuidará de aplicar as alterações, bem como manter o serviço existente em bom estado.
Escrevendo o seu próprio operador
Se não houver um operador no ecossistema que implemente o comportamento desejado, você pode programar o seu próprio.
Você também pode implementar um operador (ou seja, um Controlador) usando qualquer linguagem/agente de execução que possa atuar como um cliente para a API do Kubernetes.
A seguir estão algumas bibliotecas e ferramentas que você pode usar para escrever seu próprio operador nativo de nuvem.
Nota: Esta seção tem links para projetos de terceiros que fornecem a funcionalidade exigida pelo Kubernetes. Os autores do projeto Kubernetes não são responsáveis por esses projetos. Esta página obedece as diretrizes de conteúdo do site CNCF, listando os itens em ordem alfabética. Para adicionar um projeto a esta lista, leia o guia de conteúdo antes de enviar sua alteração.
Configure as ferramentas do Kubernetes no seu computador.
kubectl
A ferramenta de linha de comando do Kubernetes, kubectl, permite que você execute comandos nos clusters Kubernetes.
Você pode usar o kubectl para instalar aplicações, inspecionar e gerenciar recursos de cluster e visualizar os logs.
Para obter mais informações, incluindo uma lista completa de operações kubectl, consulte a documentação de referência kubectl.
Kubectl é instalável em uma variedade de plataformas tais como Linux, macOS e Windows.
Encontre seu sistema operacional preferido abaixo.
Assim como o kind, o minikube é uma ferramenta que permite executar o Kubernetes localmente.
O minikube executa um cluster Kubernetes local com tudo-em-um ou com vários nós no seu computador pessoal (incluindo PCs Windows, macOS e Linux) para que você possa experimentar o Kubernetes ou para o trabalho de desenvolvimento diário.
Depois de instalar o minikube, você pode usá-lo para executar uma aplicação exemplo.
kubeadm
Você pode usar a ferramenta kubeadm para criar e gerenciar clusters Kubernetes.
Ela executa as ações necessárias para obter um cluster mínimo viável e seguro em funcionamento de maneira amigável ao usuário.
Você deve usar uma versão do kubectl que esteja próxima da versão do seu cluster. Por exemplo, um cliente v1.26 pode se comunicar com as versões v1.25, v1.26 e v1.27 da camada de gerenciamento. Usar a versão compatível mais recente do kubectl ajuda a evitar problemas inesperados.
Instale o kubectl no Linux
Existem os seguintes métodos para instalar o kubectl no Linux:
Para fazer o download de uma versão específica, substitua a parte $(curl -L -s https://dl.k8s.io/release/stable.txt) do comando pela versão específica.
Por exemplo, para fazer download da versão 1.30.0 no Linux, digite:
Em versões anteriores ao Debian 12 e Ubuntu 22.04, o /etc/apt/keyrings não existe por padrão.
Você pode criar este diretório se precisar, tornando-o visível para todos, mas com permissão de escrita apenas aos administradores.
Se você estiver no Ubuntu ou em outra distribuição Linux que suporte o gerenciador de pacotes snap, o kubectl está disponível como um aplicativo snap.
snap install kubectl --classic
kubectl version --client
Se você estiver no Linux e usando o gerenciador de pacotes Homebrew, o kubectl está disponível para instalação.
brew install kubectl
kubectl version --client
Verifique a configuração kubectl
Para que o kubectl encontre e acesse um cluster Kubernetes, ele precisa de um arquivo kubeconfig, que é criado automaticamente quando você cria um cluster usando kube-up.sh ou instala com sucesso um cluster Minikube. Por padrão, a configuração kubectl está localizada em ~/.kube/config.
Verifique se o kubectl está configurado corretamente obtendo o estado do cluster:
kubectl cluster-info
Se você receber uma URL de resposta, o kubectl está configurado corretamente para acessar seu cluster.
Se você receber uma mensagem semelhante à seguinte, o kubectl não está configurado corretamente ou não consegue se conectar a um cluster Kubernetes.
The connection to the server <server-name:port> was refused - did you specify the right host or port?
Por exemplo, se você pretende executar um cluster Kubernetes no seu laptop (localmente), precisará que uma ferramenta como o Minikube seja instalada primeiro, para em seguida executar novamente os comandos indicados acima.
Se o kubectl cluster-info retornar a URL de resposta, mas você não conseguir acessar seu cluster, para verificar se ele está configurado corretamente, use:
kubectl cluster-info dump
Configurações e plugins opcionais do kubectl
Ative o autocompletar no shell
O kubectl oferece recursos de autocompletar para Bash, Zsh, Fish e PowerShell, o que pode economizar muita digitação.
Abaixo estão os procedimentos para configurar o autocompletar para Bash, Fish e Zsh.
O script de autocompletar do kubectl para Bash pode ser gerado com o comando kubectl completion bash. O script permite habilitar o autocompletar do kubectl no seu shell.
No entanto, o script autocompletar depende do bash-completion, o que significa que você precisa instalar este software primeiro (executando type _init_completion você pode testar se tem o bash-completion instalado).
Instale bash-completion
O bash-completion é fornecido por muitos gerenciadores de pacotes (veja aqui). Você pode instalar com apt-get install bash-completion ou yum install bash-completion, etc.
Os comandos acima criam /usr/share/bash-completion/bash_completion, que é o script principal de bash-completion. Dependendo do seu gerenciador de pacotes, você tem que adicionar manualmente ao seu arquivo ~/.bashrc.
Para descobrir, recarregue seu shell e execute type _init_completion. Se o comando for bem-sucedido, já está definido, caso contrário, adicione o seguinte ao seu arquivo ~/.bashrc:
source /usr/share/bash-completion/bash_completion
Recarregue o seu shell e verifique se o bash-completion está instalado corretamente digitando type _init_completion.
Ative o autocompletar do kubectl
Bash
Agora você precisa garantir que o autocompletar do kubectl esteja ativo em todas as suas sessões shell. Existem duas maneiras pelas quais você pode fazer isso:
Se você tiver um alias para kubectl, você pode estender o autocompletar do shell para trabalhar com esse alias:
echo'alias k=kubectl' >>~/.bashrc
echo'complete -o default -F __start_kubectl k' >>~/.bashrc
Nota:
bash-completion fornece todos os scripts de autocompletar em /etc/bash_completion.d.
Todas as abordagens são equivalentes. Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando. Para ativar o autocompletar do bash na sessão atual do shell, execute exec bash:
exec bash
Nota:
O autocompletar para Fish requer kubectl 1.23 ou posterior.
O script de autocompletar do kubectl para Fish pode ser gerado com o comando kubectl completion fish. O script permite habilitar o autocompletar do kubectl no seu shell.
Para fazer isso em todas as suas sessões do shell, adicione a seguinte linha ao seu arquivo ~/.config/fish/config.fish:
kubectl completion fish | source
Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
O script de autocompletar do kubectl para Zsh pode ser gerado com o comando kubectl completion zsh. Este script habilita o autocompletar do kubectl no seu shell.
Para fazer isso em todas as suas sessões de shell, adicione a seguinte linha no arquivo ~/.zshrc:
source <(kubectl completion zsh)
Se você tiver um alias para kubectl, o autocompletar funcionará automaticamente com ele.
Depois de recarregar seu shell, o autocompletar do kubectl deve estar funcionando.
Se você ver um erro similar a 2: command not found: compdef, adicione o seguinte bloco ao início do seu arquivo ~/.zshrc:
autoload -Uz compinit
compinit
Instale o plugin kubectl convert
Um plugin para a ferramenta Kubernetes de linha de comando kubectl, que permite converter manifestos entre diferentes versões da API.
Isso pode ser particularmente útil para migrar manifestos para uma versão não obsoleta com a versão mais recente da API Kubernetes.
Para mais informações, visite Migrar para APIs não obsoletas
Faça download da versão mais recente com o comando:
Gerenciando dados de configurações usando Secrets.
4.2.1 - Gerenciando Secret usando kubectl
Criando objetos Secret usando a linha de comando kubectl.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Um Secret pode conter credenciais de usuário requeridas por Pods para acesso a um banco de dados.
Por exemplo, uma string de conexão de banco de dados é composta por um usuário e senha.
Você pode armazenar o usuário em um arquivo ./username.txt e a senha em um
arquivo ./password.txt na sua máquina local.
A opção -n nos comandos acima garante que os arquivos criados não vão conter
uma nova linha extra no final do arquivo de texto. Isso é importante porque
quando o kubectl lê um arquivo e codifica o conteúdo em uma string base64,
o caractere da nova linha extra também é codificado.
O comando kubectl create secret empacota os arquivos em um Secret e cria um
objeto no API server.
Você não precisa escapar o caractere especial em senhas a partir de arquivos (--from-file).
Você também pode prover dados para Secret usando a tag --from-literal=<key>=<value>.
Essa tag pode ser especificada mais de uma vez para prover múltiplos pares de chave-valor.
Observe que caracteres especiais como $, \, *, =, e ! vão ser interpretados
pelo seu shell e precisam ser escapados.
Na maioria dos shells, a forma mais fácil de escapar as senhas é usar aspas simples (').
Por exemplo, se sua senha atual é S!B\*d$zDsb=, você precisa executar o comando dessa forma:
Os comandos kubectl get e kubectl describe omitem o conteúdo de um Secret por padrão.
Isso para proteger o Secret de ser exposto acidentalmente para uma pessoa não autorizada,
ou ser armazenado em um log de terminal.
Decodificando o Secret
Para ver o conteúdo de um Secret que você criou, execute o seguinte comando:
kubectl get secret db-user-pass -o jsonpath='{.data}'
4.2.2 - Gerenciando Secret usando Arquivo de Configuração
Criando objetos Secret usando arquivos de configuração de recursos.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você pode criar um Secret primeiramente em um arquivo, no formato JSON ou YAML, e depois
criar o objeto. O recurso Secret
contém dois mapas: data e stringData.
O campo data é usado para armazenar dados arbitrários, codificados usando base64. O
campo stringData é usado por conveniência, e permite que você use dados para um Secret
como strings não codificadas.
As chaves para data e stringData precisam ser compostas por caracteres alfanuméricos,
_, - ou ..
Por exemplo, para armazenar duas strings em um Secret usando o campo data, converta
as strings para base64 da seguinte forma:
echo -n 'admin' | base64
A saída deve ser similar a:
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
A saída deve ser similar a:
MWYyZDFlMmU2N2Rm
Escreva o arquivo de configuração do Secret, que será parecido com:
Os valores serializados dos dados JSON e YAML de um Secret são codificados em strings
base64. Novas linhas não são válidas com essas strings e devem ser omitidas. Quando
usar o utilitário base64 em Darwin/MacOS, os usuários devem evitar usar a opção -b
para separar linhas grandes. Por outro lado, usuários de Linux devem adicionar a opção
-w 0 ao comando base64 ou o pipebase64 | tr -d '\n' se a opção w não estiver disponível
Para cenários específicos, você pode querer usar o campo stringData ao invés de data.
Esse campo permite que você use strings não-base64 diretamente dentro do Secret,
e a string vai ser codificada para você quando o Secret for criado ou atualizado.
Um exemplo prático para isso pode ser quando você esteja fazendo deploy de uma aplicação
que usa um Secret para armazenar um arquivo de configuração, e você quer popular partes desse
arquivo de configuração durante o processo de implantação.
Por exemplo, se sua aplicação usa o seguinte arquivo de configuração:
O campo stringData é um campo de conveniência apenas de leitura. Ele nunca vai ser exibido
ao buscar um Secret. Por exemplo, se você executar o seguinte comando:
Os comandos kubectl get e kubectl describe omitem o conteúdo de um Secret por padrão.
Isso para proteger o Secret de ser exposto acidentalmente para uma pessoa não autorizada,
ou ser armazenado em um log de terminal.
Para verificar o conteúdo atual de um dado codificado, veja decodificando secret.
Se um campo, como username, é especificado em data e stringData,
o valor de stringData é o usado. Por exemplo, dada a seguinte definição do Secret:
Criando objetos Secret usando o arquivo kustomization.yaml
Desde o Kubernetes v1.14, o kubectl provê suporte para gerenciamento de objetos usando Kustomize.
O Kustomize provê geradores de recursos para criar Secrets e ConfigMaps.
Os geradores Kustomize devem ser especificados em um arquivo kustomization.yaml dentro
de um diretório. Depois de gerar o Secret, você pode criar o Secret com kubectl apply.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você pode criar um Secret definindo um secretGenerator em um
arquivo kustomization.yaml que referencia outros arquivos existentes.
Por exemplo, o seguinte arquivo kustomization referencia os
arquivos ./username.txt e ./password.txt:
Você também pode definir o secretGenerator no arquivo kustomization.yaml
por meio de alguns literais.
Por exemplo, o seguinte arquivo kustomization.yaml contém dois literais
para username e password respectivamente:
Observe que nos dois casos, você não precisa codificar os valores em base64.
Criando o Secret
Aplique o diretório que contém o arquivo kustomization.yaml para criar o Secret.
kubectl apply -k .
A saída deve ser similar a:
secret/db-user-pass-96mffmfh4k created
Observe que quando um Secret é gerado, o nome do segredo é criado usando o hash
dos dados do Secret mais o valor do hash. Isso garante que
um novo Secret é gerado cada vez que os dados são modificados.
Verifique o Secret criado
Você pode verificar que o secret foi criado:
kubectl get secrets
A saída deve ser similar a:
NAME TYPE DATA AGE
db-user-pass-96mffmfh4k Opaque 2 51s
Os comandos kubectl get e kubectl describe omitem o conteúdo de um Secret por padrão.
Isso para proteger o Secret de ser exposto acidentalmente para uma pessoa não autorizada,
ou ser armazenado em um log de terminal.
Para verificar o conteúdo atual de um dado codificado, veja decodificando secret.
Realizar tarefas comuns de configuração de Pods e contêineres
4.3.1 - Configurando GMSA Para Pods e Contêineres Windows
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [stable]
Esta página mostra como configurar Contas de serviço gerenciadas em grupo (GMSA)
para Pods e contêineres que vão executar em nós Windows. Contas de serviço gerenciadas em grupo
são um tipo específico de conta do Active Directory que provê gerenciamento automático
de senhas, gerenciamento simplificado de service principal name (SPN), e a habilidade
de delegar o gerenciamento a outros administradores através de múltiplos servidores.
No Kubernetes, especificações de credenciais GMSA são configuradas dentro do escopo
do cluster Kubernetes como recursos personalizados. Os Pods Windows, assim como contêineres
individuais dentro de um Pod, podem ser configurados para usar as funções GMSA
baseadas em domínio (exemplo: autenticação Kerberos) quando interagirem com outros
serviços Windows.
Antes de você começar
Você precisa ter um cluster Kubernetes, e a ferramenta de linha de comando kubectl
precisa estar configurada para comunicar-se com seu cluster.
O cluster deve possuir nós de carga de trabalho Windows.
Esta seção cobre o conjunto inicial de passos requeridos para cada cluster:
Instale o CRD GMSACredentialSpec
Uma CustomResourceDefinition (CRD) para a especificação de recursos de credencial GMSA precisa ser configurada no cluster, para definir o tipo de recurso do cliente GMSACredentialSpec. Faça o download do YAML do CRD de GMSA
e salve como gmsa-crd.yaml.
A seguir, instale o CRD com kubectl apply -f gmsa-crd.yaml.
Instale webhooks para validar usuários GMSA
Dois webhooks precisam ser configurados no cluster Kubernetes para popular e validar
as referências de especificação de credenciais GMSA no nível do Pod ou contêiner:
Um webhook de mutação que expanda as referências para as GMSAs,
(por nome a partir de uma especificação de Pod) em uma especificação de credencial completa
em formato JSON dentro da especificação do Pod.
Um webhook de validação garante que todas as referências para GMSAs estão
autorizadas a serem usadas pela conta de serviço do Pod.
A instalação dos webhooks acima e dos objetos associados requer as etapas abaixo:
Crie um par de chaves de certificado (que será usado para permitir que o
contêiner do webhook se comunique com o cluster)
Instale um Secret com o certificado acima.
Crie um Deployment para a lógica principal do webhook.
Crie as configurações de webhook de validação e de mutação, referentes ao Deployment.
Um script
pode ser usado para implantar e configurar os webhooks GMSA e objetos associados
mencionados acima. O script pode ser executado com a opção --dry-run=server
para possibilitar que você possa revisar as alterações antes que sejam aplicadas
no seu cluster.
O template YAML
usado pelo script também pode ser usado para implantar os webhooks e objetos
associados manualmente (com as substituições apropriadas para os parâmetros).
Configurar GMSAs e nós Windows em Active Directory
Antes que os Pods no Kubernetes possam ser configurados para usar GMSAs, as GMSAs apropriadas precisam ser provisionadas no Active Directory como descrito na
documentação de GMSA do Windows.
Nós de carga de trabalho Windows (que são parte do cluster Kubernetes) precisam ser configurados no
Active Directory para acessar as credenciais secretas associadas com a GMSA apropriada,
como descrito na documentação de GMSA do Windows.
Crie recursos de especificação de GMSA
Com o CRD GMSACredentialSpec instalado (como descrito anteriormente),
recursos customizados contendo recursos de especificação de credenciais GMSA podem
ser configurados. A especificação de credencial GMSA não contém dados secretos nem
sensíveis. É informação que o agente de execução de contêiner pode usar para descrever a apropriada
GMSA de um contêiner para o Windows. Especificações de credenciais GMSA podem
ser geradas em formato YAML com o utilitário PowerShell script.
A seguir são os passos para gerar a especificação de credencial GMSA YAML
manualmente, em formato JSON e então convertê-la para YAML:
Crie a especificação da credencial em formato JSON usando New-CredentialSpec.
Para criar a especificação da credencial GMSA nomeada WebApp1,
execute New-CredentialSpec -Name WebApp1 -AccountName WebApp1 -Domain $(Get-ADDomain -Current LocalComputer)
Use Get-CredentialSpec para mostrar o caminho do arquivo JSON.
Converta o arquivo credspec de JSON para o formato YAML e aplique os campos
de cabeçalho necessários apiVersion, kind, metadata e credspec para transformá-lo em
uma instância do recurso customizado GMSACredentialSpec que pode ser configurado no Kubernetes.
A configuração YAML a seguir descreve as especificações de credencial GMSA nomeada
gmsa-WebApp1:
apiVersion:windows.k8s.io/v1kind:GMSACredentialSpecmetadata:name:gmsa-WebApp1 #Este é um nome arbitrário, mas será usado como referênciacredspec:ActiveDirectoryConfig:GroupManagedServiceAccounts:- Name:WebApp1 #Nome de usuário da conta GMSAScope:CONTOSO #Nome de Domínio NETBIOS- Name:WebApp1 #Nome de usuário da conta GMSAScope:contoso.com #Nome de domínio DNSCmsPlugins:- ActiveDirectoryDomainJoinConfig:DnsName:contoso.com #Nome de domínio DNSDnsTreeName:contoso.com #Nome de domínio DNS raizGuid:244818ae-87ac-4fcd-92ec-e79e5252348a #GUIDMachineAccountName:WebApp1#Nome de usuário da conta GMSANetBiosName:CONTOSO #Nome de domínio NETBIOSSid:S-1-5-21-2126449477-2524075714-3094792973#SID da GMSA
O recurso de especificação de credencial acima deve ser salvo como
gmsa-Webapp1-credspec.yaml e aplicado no cluster usando:
kubectl apply -f gmsa-Webapp1-credspec.yml
Configure um ClusterRole para habilitar RBAC nas especificações de credenciais GMSA específicas
Uma ClusterRole precisa ser definida para cada recurso de especificação
de credencial GMSA. Isto autoriza o verbo use em um recurso GMSA específico
por um sujeito, geralmente uma conta de serviço. O exemplo a seguir mostra
um ClusterRole que autoriza o uso de credencial gmsa-WebApp1
acima. Salve o arquivo como gmsa-webapp1-role.yaml e aplique
usando kubectl apply -f gmsa-webapp1-role.yaml
#Criando um Role para ler o credspecapiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:webapp1-rolerules:- apiGroups:["windows.k8s.io"]resources:["gmsacredentialspecs"]verbs:["use"]resourceNames:["gmsa-WebApp1"]
Atribua o Role às contas de serviço para usar especificações de credencial GMSA específicas
Uma conta de serviço (com a qual os Pods virão configurados), precisa ser vinculada
ao ClusterRole criado acima. Isto autoriza a conta de serviço a usar a especificação apropriada
de recurso de credencial GMSA. O trecho a seguir mostra a conta de serviço padrão vinculada ao ClusterRole webapp1-role, para usar a especificação
de recurso de credencial gmsa-WebApp1 criada acima.
Configure a especificação de recurso de credencial GMSA em uma especificação de Pod
O campo securityContext.windowsOptions.gmsaCredentialSpecName do Pod, é usado de referência para recursos customizados, em especificações
de certificado GMSA apropriadas em especificações do Pod.
Isto configura todos contêineres do Pod para usar GMSA.
Uma amostra da anotação populada para referir-se a gmsa-WebApp1:
Contêineres individuais em uma especificação de Pod podem também indicar
a credencial GMSA apropriada, usando o campo securityContext.windowsOptions.gmsaCredentialSpecName por contêiner. Por exemplo:
Assim que as especificações do Pod com os campos GMSA preenchidos
(como descrito acima) são aplicadas em um cluster, ocorre a seguinte sequência de eventos:
O webhook de mutação resolve e expande todas as referências aos recursos de
especificações de credenciais GMSA para o conteúdo das especificações de credenciais GMSA.
O webhook de validação garante que a conta de serviço associada ao Pod, seja autorizada
para o verbo use na especificação GMSA especificada.
O agente de execução de contêiner configura cada contêiner do Windows com a especificação
de credencial GMSA especificada, para que o contêiner possa assumir a identidade
do GMSA no Active Directory, e tenha acesso aos serviços no domínio usando essa identidade.
Autenticando para compartilhamentos de rede usando hostname ou FQDN
Se você estiver enfrentando problemas ao se conectar aos compartilhamentos SMB
de Pods usando o hostname ou o FQDN, mas conseguindo acessar os compartilhamentos
por meio de seu endereço IPv4, verifique se a chave do registro a seguir
está definida nos nós Windows.
Os Pods em execução precisarão ser recriados para pegar as mudanças de comportamento.
Mais informações sobre como essa chave de registro é usada podem ser encontradas aqui
Solução de problemas
Se você estiver tendo dificuldades para fazer com que o GMSA funcione em seu ambiente,
existem algumas etapas de solução de problemas que você pode tentar.
Primeiro, verifique se a especificação de credencial foi passada para o Pod. Para fazer isso,
você precisará rodar kubectl exec em um de seus Pods e verificar
a saída do comando nltest.exe /parentdomain.
No exemplo abaixo, o Pod não recebeu a especificação de credencial corretamente:
nltest.exe /parentdomain resulta no seguinte erro:
Getting parent domain failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE
Se o seu Pod obteve a especificação de credencial corretamente, o próximo passo é
verificar a comunicação com o domínio. Primeiro, de dentro do seu Pod,
execute rapidamente um nslookup para encontrar a raiz do seu domínio.
Isso vai nos dizer 3 coisas:
O Pod pode chegar ao DC
O DC pode chegar ao Pod
O DNS está funcionando corretamente.
Se o DNS e o teste de comunicação passarem, em seguida,
você precisará verificar se o Pod estabeleceu um canal de comunicação segura
com o domínio. Para fazer isso, novamente, em seu Pod
execute o comando nltest.exe /query.
nltest.exe /query
Resulta na seguinte saída:
I_NetLogonControl failed: Status = 1722 0x6ba RPC_S_SERVER_UNAVAILABLE
Isso nos diz que, por algum motivo, o Pod não conseguiu se logar no domínio
usando a conta definida na especificação de credencial. Você pode tentar reparar
o canal seguro executando o seguinte:
nltest /sc_reset:domain.example
Se o comando for bem sucedido, você verá uma saída semelhante a esta:
Flags: 30 HAS_IP HAS_TIMESERV
Trusted DC Name \\dc10.domain.example
Trusted DC Connection Status Status = 0 0x0 NERR_Success
The command completed successfully
Se o excerto acima corrigir o erro, você poderá automatizar a etapa adicionando
o seguinte lifecycle hook à sua especificação de Pod. Se não corrigiu o erro, você
precisará examinar sua especificação de credencial novamente e confirmar que ela está correta e completa.
Se você adicionar a seção lifecycle, mostrada acima à sua especificação de Pod,
o Pod irá executar os comandos listados para reiniciar o serviço netlogon
até que o comando nltest.exe /query execute sem erro.
4.3.2 - Configurando RunAsUserName Para Pods e Contêineres Windows
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [stable]
Esta página mostra como usar a configuração runAsUserName para Pods
e contêineres que serão executados em nós Windows. Isso é aproximadamente
equivalente à configuração runAsUser específica do Linux, permitindo a você
executar aplicativos em um contêiner com um nome de usuário diferente do padrão.
Antes de você começar
Você precisa ter um cluster Kubernetes, e a ferramenta de linha de comando Kubectl
deve ser configurada para se comunicar com o seu cluster. Espera-se que o cluster
tenha nós de carga de trabalho Windows, onde os Pods com contêineres executando as cargas de trabalho do Windows,
serão agendados.
Defina o nome de usuário para um Pod
Para especificar o nome de usuário com o qual executar os processos de contêiner do Pod,
inclua o campo securityContext (PodSecurityContext)
na especificação do Pod, e dentro dela, o campo WindowsOptions (WindowsSecurityContextOptions)
contendo o campo runAsUserName.
As opções de contexto de segurança do Windows que você especificar para um Pod,
se aplicam a todos os contêineres do Pod, inclusive os de inicialização.
Veja abaixo um arquivo de configuração para um Pod do Windows que possui o campo
runAsUserName definido:
Verifique se o shell está executando com o nome de usuário correto:
echo $env:USERNAME
A saída deve ser:
ContainerUser
Defina o nome de usuário para o contêiner
Para especificar o nome de usuário com o qual executar os processos de um contêiner,
inclua o campo SecurityContext (SecurityContext)
no manifesto do contêiner, e dentro dele, o campo WindowsOptions
(WindowsSecurityContextOptions)
contendo o campo runAsUserName.
As opções de contexto de segurança do Windows que você especificar para um contêiner,
se aplicam apenas a esse contêiner individual, e substituem as configurações feitas
no nível do Pod.
Aqui está o arquivo de configuração para um pod que possui um contêiner,
e o campo runAsUserName está definido no nível do Pod e no nível do contêiner:
Verifique se o shell está executando o usuário correto, (aquele definido no nível do contêiner):
echo $env:USERNAME
A saída deve ser:
ContainerAdministrator
Limitações de nomes de usuários no Windows
Para usar esse recurso, o valor definido no campo runAsUserName deve ser um nome
de usuário válido. Deve ter o seguinte formato: DOMAIN\USER, onde DOMAIN\
é opcional. Os nomes de usuário do Windows não diferenciam letras maiúsculas
e minúsculas. Além disso, existem algumas restrições em relação ao DOMAIN e USER:
O campo runAsUserName: não pode estar vazio, e não pode conter caracteres
de controle (Valores ASCII : 0x00-0x1F, 0x7F)
O nome de DOMAIN NetBios, ou um nome de DNS, cada um com suas próprias restrições:
Nomes NetBios: máximo de 15 caracteres, não podem iniciar com . (ponto),
e não podem conter os seguintes caracteres: \ / : * ? " < > |
Nomes DNS: máximo de 255 caracteres, contendo apenas caracteres alfanuméricos,
pontos, e traços, e não podem iniciar ou terminar com um . (ponto) ou - (traço).
O USER: deve ter no máximo 20 caracteres, não pode conter somente pontos ou espaços,
e não pode conter os seguintes caracteres: " / \ [ ] : ; | = , + * ? < > @.
Exemplos de valores aceitáveis para o campo runAsUserName: ContainerAdministrator,
ContainerUser, NT AUTHORITY\NETWORK SERVICE, NT AUTHORITY\LOCAL SERVICE.
Para mais informações sobre estas limitações, verifique aqui e aqui.
4.3.3 - Configurando Qualidade do Serviço Para Pods
Esta página mostra como configurar os Pods para que, a eles sejam atribuídos particularmente classes de
Qualidade de Serviço (QoS). O Kubernetes usa classes QoS para tomar decisões sobre
agendamento e despejo de Pods.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Quando o Kubernetes cria um Pod, ele atribui uma dessas classes de QoS ao Pod:
Guaranteed
Burstable
BestEffort
Crie um namespace
Crie um namespace, assim os seus recursos criados neste exercício estarão
isolados do resto do seu cluster.
kubectl create namespace qos-example
Crie um Pod ao qual seja atribuída uma classe de QoS Guaranteed
Para que um Pod receba uma classe de QoS Guaranteed:
Todo contêiner no Pod deve ter um limite de memória e um requisito de memória.
Para cada contêiner no Pod, o limite de memória deve ser igual ao requisito de memória.
Todo contêiner no Pod deve ter um limite de CPU e um requisito de CPU.
Para cada contêiner no Pod, o limite de CPU deve ser igual ao requisito de CPU.
Essas restrições se aplicam igualmente a contêineres de inicialização bem como de aplicativos.
Aqui está o arquivo de configuração para um pod que possui um contêiner. O contêiner tem um limite de memória e um requisito de memória, ambos iguais a 200 MiB. O contêiner tem um limite de CPU e uma solicitação de CPU, ambos iguais a 700 miliCPU:
kubectl get pod qos-demo --namespace=qos-example --output=yaml
A saída mostra que o Kubernetes forneceu ao pod uma classe de QoS Guaranteed. A saída também
verifica se o contêiner do Pod tem um requisito de memória que corresponde ao seu limite de memória, e possui
um requisito de CPU que corresponde ao seu limite de CPU.
Se um contêiner especificar seu próprio limite de memória, mas não especificar um requisito de memória, o Kubernetes
automaticamente atribui um requisito de memória que corresponda ao limite. Similarmente, se um contêiner especifica o seu próprio
limite de CPU, mas não especifica um requisito de CPU, o Kubernetes atribui automaticamente uma solicitação de CPU que corresponde
ao limite.
Apague seu Pod:
kubectl delete pod qos-demo --namespace=qos-example
Crie um Pod ao qual seja atribuída uma classe de QoS Burstable
Um Pod recebe uma classe de QoS Burstable se:
O Pod não atende aos critérios para a classe de QoS Guaranteed.
Pelo menos um contêiner no Pod tem um requisito ou limite de memória ou CPU.
Aqui está o arquivo de configuração para um Pod que possui um contêiner. O contêiner tem um limite de memória de 200 MiB
e um requisito de memória de 100 MiB.
kubectl delete pod qos-demo-3 --namespace=qos-example
Crie um Pod que tenha dois contêineres
Aqui está o arquivo de configuração para um Pod que possui dois contêineres. Um contêiner especifica um requisito de memória de 200 MiB. O outro contêiner não especifica nenhum requisito ou limite.
Observe que este Pod atende aos critérios para a classe de QoS Burstable. Isto é, ele não atende aos
critérios para a classe de QoS Guaranteed, e um de seus contêineres tem um requisito de memória.
4.3.4 - Atribuindo Recursos Estendidos a um Contêiner
ESTADO DA FUNCIONALIDADE:Kubernetes v1.30 [stable]
Esta página mostra como atribuir recursos estendidos a um Contêiner.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Antes de fazer este exercício, faça o exercício em
Anunciar recursos estendidos para um Nó.
Isso configurará um de seus nós para anunciar um recurso de dongle.
Atribua um recurso estendido a um Pod
Para solicitar um recurso estendido, inclua o campo resources:requests no seu
manifesto do contêiner. Recursos estendidos são totalmente qualificados
com qualquer domínio fora do *.kubernetes.io/. Nomes de recursos estendidos válidos
tem a forma de example.com/foo, onde example.com é substituído pelo domínio
da sua organização e foo é um nome descritivo de recurso.
Aqui está o arquivo de configuração para um pod que possui um contêiner:
A saída mostra que o pod não pode ser agendado, porque não há nó que tenha
2 dongles disponíveis:
Conditions:
Type Status
PodScheduled False
...
Events:
...
... Warning FailedScheduling pod (extended-resource-demo-2) failed to fit in any node
fit failure summary on nodes : Insufficient example.com/dongle (1)
Veja o status do pod:
kubectl get pod extended-resource-demo-2
A saída mostra que o Pod foi criado, mas não está programado para ser executado em um nó.
Tem um status de pendente:
NAME READY STATUS RESTARTS AGEextended-resource-demo-2 0/1 Pending 0 6m
Limpeza
Exclua os Pods que você criou para este exercício:
kubectl delete pod extended-resource-demo
kubectl delete pod extended-resource-demo-2
4.3.5 - Configurando um Pod Para Usar um Volume Para Armazenamento
Esta página mostra como configurar um Pod para usar um Volume para armazenamento.
O sistema de arquivos de um contêiner apenas existe enquanto o contêiner existir.
Então, quando um contêiner termina e reinicia, as alterações do sistema de arquivos
são perdidas.
Para um armazenamento mais consistente, independente do contêiner, você pode usar um
Volume. Isso é especialmente importante para aplicações
stateful, tal como armazenamentos chave-valor (tal como Redis) e bancos de dados.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Neste exercício, você cria um Pod que executa um contêiner. Este Pod tem um
Volume do tipo emptyDir
que persiste durante a existência do Pod, mesmo que o contêiner termine e
reinicie. Aqui está o arquivo de configuração para o pod:
Além do armazenamento de disco local fornecido por emptyDir, o Kubernetes
suporta muitas soluções de armazenamento diferentes, conectadas via rede, incluindo PD na
GCE e EBS na EC2, que são preferidos para dados críticos e vão lidar com os
detalhes, como montar e desmontar os dispositivos nos Nós. Veja
Volumes para mais detalhes.
4.3.6 - Configurando um Pod Para Usar um Volume Persistente Para armazenamento
Esta página mostra como configurar um Pod para usar um
PersistentVolumeClaim
para armazenamento.
Aqui está o resumo do processo:
Você, como administrador do cluster, faz a criação de um Volume Persistente suportado por armazenamento físico. Você não associa o volume a nenhum Pod.
Você, agora assumindo o papel de desenvolvedor/usuário do cluster, faz a criação
de um PersistentVolumeClaim que é automaticamente vinculado ao Volume Persistente adequado.
Você cria um Pod que usa o PersistentVolumeClaim acima para armazenamento.
Antes de você começar
Você precisa ter um cluster Kubernetes que tenha apenas um nó, e a ferramenta de linha de comando
kubectl configurada para se comunicar com seu cluster. Se você
ainda não tem um cluster de um único nó, você pode criar um usando o
Minikube.
Abra um shell no único nó do seu cluster. A maneira de abrir um shell vai depender de como
você inicializou seu cluster. Por exemplo, se você estiver usando o Minikube,
você pode abrir um shell para o seu nó digitando minikube ssh.
No seu shell desse nó, crie um diretótio /mnt/data:
# Assumindo que o seu nó use "sudo" para executar comandos # como superusuáriosudo mkdir /mnt/data
content/pt-br/docs/tasks/configure-pod-container/configure-service-account.md
No diretório /mnt/data, crie o arquivo index.html:
# Novamente assumindo que seu nó use "sudo" para executar comandos# como superusuáriosudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"
Nota:
Se o seu nó usa uma ferramenta para acesso como superusuário que não sudo, você pode
geralmente fazer isso funcionar substituindo sudo pelo nome da outra ferramenta.
Teste se o arquivo index.html existe:
cat /mnt/data/index.html
A saída deve ser:
Hello from Kubernetes storage
Você agora pode fechar o shell do seu nó.
Crie um Volume Persistente
Neste exercício, você cria um Volume Persistente hostPath. O Kubernetes suporta
hostPath para desenvolvimento e teste em um cluster com apenas um nó. Um Volume Persistente
hostPath usa um arquivo ou diretório no nó, para emular um armazenamento conectado pela rede.
Em um cluster de produção, você não usaria hostPath. Em vez disso um administrador
de cluster provisionaria um recurso de rede, como um disco persistente do
Google Compute Engine, um NFS compartilhado, ou um volume do
Amazon Elastic Block Store. Administradores podem também usar classes de armazenamento
para incializar provisionamento dinâmico.
Aqui está o arquivo de configuração para o Volume Persistente hostPath:
O arquivo de configuração especifica que o volume está no diretório /mnt/data do nó do cluster.
A configuração também especifica um tamanho de 10 gibibytes e um modo de acesso
ReadWriteOnce, o que significa que o volume pode ser montado como leitura-escrita
pelo único nó. Define o nome da classe de armazenamentomanual para o Volume Persistente, que será usado para vincular requisições
PersistentVolumeClaim à esse Volume Persistente.
A saída mostra que o Volume Persistente tem um STATUS de Available. Isto
significa que ainda não foi vinculado a um PersistentVolumeClaim.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Available manual 4s
Crie um PersistentVolumeClaim
O próximo passo é criar um PersistentVolumeClaim. Pods usam PersistentVolumeClaims
para requisitar armazenamento físico. Neste exercício, você vai criar
um PersistentVolumeClaim que requisita um volume com pelo menos três
gibibytes, com acesso de leitura-escrita para pelo menos um nó.
Aqui está o arquivo de configuração para oPersistentVolumeClaim:
Após criar o PersistentVolumeClaim, o Kubernetes control plane procura por um
Volume Persistente que satisfaça os requerimentos reivindicados. Se o control plane
encontrar um Volume Persistente adequado, com a mesma classe de armazenamento,
ele liga o volume requisitado.
Olhe novamente o Volume Persistente:
kubectl get pv task-pv-volume
Agora a saída mostra um STATUS de Bound.
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m
Olhe para o PersistentVolumeClaim:
kubectl get pvc task-pv-claim
A saída mostra que oPersistentVolumeClaim está vinculado ao seu Volume Persistente,
task-pv-volume.
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s
Crie um Pod
O próximo passo é criar um Pod que usa o seu PersistentVolumeClaim como um volume.
Note que o arquivo de configuração do Pod especifica um PersistentVolumeClaim, mas não
especifica um Volume Persistente. Do ponto de vista do Pod, a reivindicação é de um volume.
No seu shell, verifique se o nginx está servindo o arquivo index.html do volume
do hostPath:
# Certifique-se de executar esses 3 comandos dentro do shell, na raiz que vem da# execução "kubectl exec" do passo anteriorapt update
apt install curl
curl http://localhost/
A saída mostra o texto que você escreveu no arquivo index.html no volume do
hostPath:
Hello from Kubernetes storage
Se você vir essa mensagem, configurou com sucesso um pod para
usar o armazenamento de um PersistentVolumeClaim.
Limpeza
Exclua o Pod, o PersistentVolumeClaim e o Volume Persistente:
Se você ainda não tem um shell aberto no nó em seu cluster,
Abra um novo shell da mesma maneira que você fez antes.
No shell do seu nó, remova o arquivo e o diretório que você criou:
# Pressupondo que seu nó usa "sudo" para executar comandos# como superusuáriosudo rm /mnt/data/index.html
sudo rmdir /mnt/data
Você pode agora fechar o shell do seu nó.
Montando o mesmo Volume Persistente em dois lugares
apiVersion:v1kind:Podmetadata:name:testspec:containers:- name:testimage:nginxvolumeMounts:# a mount for site-data- name:configmountPath:/usr/share/nginx/htmlsubPath:html# another mount for nginx config- name:configmountPath:/etc/nginx/nginx.confsubPath:nginx.confvolumes:- name:configpersistentVolumeClaim:claimName:test-nfs-claim
Você pode realizar a montagem de 2 volumes no seu contêiner nginx:
/usr/share/nginx/html para o website estático
/etc/nginx/nginx.conf para a configuração padrão
Controle de accesso
Armazenamento configurado com um group ID (GID) possibilita a escrita somente pelos
Pods usando a mesma GID. GIDs incompatíveis ou perdidos causam erros de negação
de permissão. Para reduzir a necessidade de coordenação de usuários, um administrador
pode anotar um Volume Persistente com uma GID. Então a GID é automaticamente
adicionada a qualquer Pod que use um Volume Persistente.
Use a anotação pv.beta.kubernetes.io/gid como a seguir:
Quando um Pod consome um Volume Persistente que tem uma anotação GID, o GID anotado
é aplicado à todos os contêiners no Pod, da mesma forma que as GIDs especificadas no
contexto de segurança em que o Pod está. Cada GID, se é originário de uma anotação
de Volume Persistente ou da especificação do Pod,
é aplicada ao primeiro processo executando em cada contêiner.
Nota:
Quando um Pod consome um Volume Persistente, os GIDs associados ao Volume Persistente
não estiverem presentes no próprio recurso do Pod.
Esta página mostra como atribuir um Pod Kubernetes a um nó particular em um
cluster Kubernetes.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Liste os nós em seu cluster,
juntamente com seus rótulos:
kubectl get nodes --show-labels
A saída é similar a esta:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Escolha um de seus nós, e adicione um rótulo a ele:
kubectl label nodes <your-node-name> disktype=ssd
onde <your-node-name> é o nome do seu nó escolhido.
Verifique se seu nó escolhido tem o rótulo disktype=ssd:
kubectl get nodes --show-labels
A saída é similiar a esta:
NAME STATUS ROLES AGE VERSION LABELS
worker0 Ready <none> 1d v1.13.0 ...,disktype=ssd,kubernetes.io/hostname=worker0
worker1 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker1
worker2 Ready <none> 1d v1.13.0 ...,kubernetes.io/hostname=worker2
Na saída anterior, você pode ver que o nó worker0 tem o rótulo disktype=ssd.
Crie um pod que é agendado em seu nó escolhido
Este arquivo de configuração de pod descreve um pod que tem um seletor de nó,
disktype: ssd. Isto significa que o pod será agendado em um nó que tem o rótulo disktype=ssd.
apiVersion:v1kind:Podmetadata:name:nginxspec:nodeName:foo-node# schedule pod to specific nodecontainers:- name:nginximage:nginximagePullPolicy:IfNotPresent
Use o arquivo de configuração para criar um pod que será agendado somente no nó foo-node.
4.3.8 - Configurando um Pod Para Usar um ConfigMap
Muitas aplicações dependem da configuração que é usada durante a inicialização do aplicativo ou do agente de execução.
Na maioria das vezes, há um requisito para ajustar os valores atribuídos aos parâmetros de configuração.
O objeto ConfigMap é a maneira usada no Kubernetes para injetar dados de configuração em Pods de aplicativos. O ConfigMap permite que você desacople os artefatos de configuração do conteúdo da imagem, para manter os aplicativos de contêiner portáveis. Esta página fornece uma série de exemplos de uso, demonstrando como criar ConfigMaps e configurar Pods usando dados armazenados em ConfigMaps.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você pode usar kubectl create configmap ou um gerador de ConfigMap, em um arquivo kustomization.yaml para criar um ConfigMap. Perceba que o kubectl começou a suportar o kustomization.yaml desde a versão 1.14.
Onde <map-name> é o nome que você quer atribuir ao ConfigMap e <data-source> é o diretório, arquivo, ou o valor literal de onde buscar os dados.
O nome de um objeto ConfigMap precisa ser um nome de subdomínio DNS válido.
Quando você estiver criando um ConfigMap baseado em um arquivo, a chave no <data-source> é por padrão o nome-base do arquivo, e o valor é por padrão o conteúdo do arquivo.
Você pode usar kubectl create configmap para criar um ConfigMap a partir de vários arquivos no mesmo diretório. Quando você está criando um ConfigMap baseado em um diretório, o kubectl identifica arquivos cujo nome-base é uma chave válida no diretório e empacota cada um desses arquivos no novo ConfigMap. Quaisquer entradas existentes no diretório que não sejam arquivos regulares são ignoradas (ex. subdiretórios, links simbólicos, dispositivos, pipes, etc).
Por exemplo:
# Criando o diretório localmkdir -p configure-pod-container/configmap/
# Baixe os arquivos de amostra no diretório `configure-pod-container/configmap/` wget https://kubernetes.io/examples/configmap/game.properties -O configure-pod-container/configmap/game.properties
wget https://kubernetes.io/examples/configmap/ui.properties -O configure-pod-container/configmap/ui.properties
# Crie o ConfigMapkubectl create configmap game-config --from-file=configure-pod-container/configmap/
O comando acima empacota cada arquivo, neste caso, game.properties e ui.properties no diretório configure-pod-container/configmap/ dentro do ConfigMap de nome game-config. Você pode exibir detalhes do ConfigMap usando o seguinte comando:
Quando o kubectl cria um ConfigMap a partir de entradas que não são ASCII ou UTF-8, a ferramenta os coloca no campo binaryData do ConfigMap, e não no campo data. Fontes de dados de texto e binário podem ser combinadas em um ConfigMap.
Se você quiser ver o campo binaryData (e seus valores) em um ConfigMap, você pode executar kubectl get configmap -o jsonpath='{.binaryData}' <name>.
Use a opção --from-env-file para criar um ConfigMap a partir de um arquivo de ambiente, por exemplo:
# Os arquivos de ambiente contêm uma lista de variáveis de ambiente.# Essas regras de sintaxe se aplicam:# Cada linha em um arquivo de ambiente deve estar em formato VAR=VAL.# Linhas começando com # (ex. comentários) são ignoradas.# Linhas em branco são ignoradas.# Não há manuseio especial de aspas (ex. eles farão parte dos valores do ConfigMap).# Baixe os arquivos de amostra no diretório `configure-pod-container/configmap/`wget https://kubernetes.io/examples/configmap/game-env-file.properties -O configure-pod-container/configmap/game-env-file.properties
wget https://kubernetes.io/examples/configmap/ui-env-file.properties -O configure-pod-container/configmap/ui-env-file.properties
# O arquivo de ambiente `game-env-file.properties` se parece como o abaixocat configure-pod-container/configmap/game-env-file.properties
enemies=aliens
lives=3allowed="true"# Este comentário e a linha vazia acima dela são ignorados
A partir do Kubernetes v1.23, o kubectl suporta múltiplas ocorrências do argumento --from-env-file para
criar um ConfigMap para múltiplas fontes de dados.
Onde <my-key-name> é a chave que você deseja usar no ConfigMap e <path-to-file> é a localização do arquivo fonte de dados, que você deseja que a chave represente.
Você pode passar vários pares de chave-valor. Cada par fornecido na linha de comando é representado como uma entrada separada na seção data do ConfigMap.
Você também pode criar um ConfigMap a partir de geradores e então aplicá-lo no cluster
para criar objetos no servidor da API.
Você deve especificar os geradores em um arquivo kustomization.yaml dentro de um diretório.
Gere o ConfigMap a partir de arquivos
Por exemplo, para gerar um ConfigMap a partir de arquivos configure-pod-container/configmap/game.properties
# Crie um arquivo kustomization.yaml com um ConfigMapGeneratorcat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-4
files:
- configure-pod-container/configmap/game.properties
EOF
Aplique o diretório de kustomization para criar o objeto ConfigMap.
kubectl apply -k .
configmap/game-config-4-m9dm2f92bt created
Você pode verificar se o ConfigMap foi criado, assim:
Observe que o nome gerado para o ConfigMap tem um sufixo anexado, que é o hash do conteúdo. Isso garante que um
novo ConfigMap é gerado cada vez que o seu conteúdo é modificado.
Defina a chave a ser usada ao gerar um ConfigMap a partir de um arquivo
Você pode definir uma chave que não seja o nome do arquivo para usar no gerador do ConfigMap.
Por exemplo, para gerar um ConfigMap a partir de arquivos configure-pod-container/configmap/game.properties
com a chave game-special-key
# Criando um arquivo kustomization.yaml com o ConfigMapGeneratorcat <<EOF >./kustomization.yaml
configMapGenerator:
- name: game-config-5
files:
- game-special-key=configure-pod-container/configmap/game.properties
EOF
Aplicar o diretório kustomization para criar o objeto ConfigMap.
kubectl apply -k .
configmap/game-config-5-m67dt67794 created
Gere ConfigMap a partir de literais
Este exemplo mostra como criar um ConfigMap a partir de dois literais chave/valor:
special.type=charm e special.how=very, usando Kustomize e kubectl. Para alcançar isso, você pode especificar o gerador
ConfigMap. Crie (ou sobreponha) o arquivo
kustomization.yaml para que ele tenha os seguintes conteúdos:
---# Conteúdos de um aruivo kustomization.yaml para criar um ConfigMap a partir de literaisconfigMapGenerator:- name:special-config-2literals:- special.how=very- special.type=charm
Aplique o diretório kustomization para criar o objeto ConfigMap.
kubectl apply -k .
configmap/special-config-2-c92b5mmcf2 created
Limpeza provisória
Antes de prosseguir, limpe alguns dos ConfigMaps que você fez:
apiVersion:v1kind:Podmetadata:name:dapi-test-podspec:containers:- name:test-containerimage:registry.k8s.io/busyboxcommand:["/bin/sh","-c","env"]env:# Defina a variável de ambiente- name:SPECIAL_LEVEL_KEYvalueFrom:configMapKeyRef:# O ConfigMap contendo o valor que você deseja atribuir ao SPECIAL_LEVEL_KEYname:special-config# Especifique a chave associada ao valorkey:special.howrestartPolicy:Never
Use envFrom para definir todos os dados do ConfigMap como variáveis de ambiente do contêiner. A chave do ConfigMap torna-se o nome da variável de ambiente no Pod.
Agora, a saída do Pod inclui as variáveis de ambiente SPECIAL_LEVEL=very e SPECIAL_TYPE=charm.
Use variáveis de ambiente definidas no ConfigMap em comandos do Pod
Você pode usar variáveis de ambiente definidas no ConfigMap no command e args de um contêiner usando a sintaxe de substituição do Kubernetes $(VAR_NAME).
produz a seguinte saída no contêiner test-container:
kubectl logs dapi-test-pod
very charm
Adicione dados do ConfigMap em um Volume
Conforme explicado Criando um ConfigMap a partir de arquivos, quando você cria um ConfigMap usando --from-file, o nome do arquivo se torna uma chave armazenada na seção data do ConfigMap. O conteúdo do arquivo se torna o valor da chave.
Os exemplos nesta seção se referem a um ConfigMap de nome' special-config, mostrado abaixo.
Preencher um volume com dados armazenados em um ConfigMap
Adicione o nome do ConfigMap debaixo da seção volumes das especificações do Pod.
Isso adiciona os dados do ConfigMap ao diretório especificado como volumeMounts.mountPath (nesse caso, /etc/config).
A seção command lista arquivos do diretório com nomes que correspondem às chaves no ConfigMap.
apiVersion:v1kind:Podmetadata:name:dapi-test-podspec:containers:- name:test-containerimage:registry.k8s.io/busyboxcommand:["/bin/sh","-c","ls /etc/config/"]volumeMounts:- name:config-volumemountPath:/etc/configvolumes:- name:config-volumeconfigMap:# Forneça o nome do ConfigMap que contém os arquivos # que você deseja adicionar ao contêinername:special-configrestartPolicy:Never
Quando o Pod executa, o comando ls /etc/config/ produz a saída abaixo:
SPECIAL_LEVEL
SPECIAL_TYPE
Cuidado:
Se houver alguns arquivos no diretório /etc/config/, eles serão excluídos.
Nota:
Os dados de texto são expostos como arquivos, usando a codificação de caracteres UTF-8. Para usar outra codificação de caracteres, use binaryData.
Adicione dados ConfigMap para um caminho específico no volume
Use o campo path para especificar o caminho de arquivo desejado para ítens específicos do ConfigMap.
Nesse caso, o item SPECIAL_LEVEL será montado no volume config-volume em /etc/config/keys.
Quando o Pod executar, o comando cat /etc/config/keys produz a saída abaixo:
very
Cuidado:
Como antes, todos os arquivos préviamente existentes no diretório /etc/config/ serão apagados.
Projete chaves para caminhos específicos e permissões de arquivos
Você pode projetar chaves para caminhos específicos e permissões específicas em uma base por-arquivo.
O guia do usuário Segredos explica a sintaxe.
Referências Opcionais
Uma referência de ConfigMap pode ser marcada opcional. Se o ConfigMap for inexistente, o volume montado estará vazio. Se o ConfigMap existir, mas a chave referenciada
é inexistente, o caminho estará ausente no ponto de montagem.
ConfigMaps montados são atualizados automaticamente
Quando um ConfigMap montado é atualizado, o conteúdo projetado é eventualmente atualizado também. Isso se aplica no caso em que um ConfigMap referenciado opcionalmente passe a existir após o Pod ser iniciado.
O Kubelet verifica se o ConfigMap montado está atualizado em cada sincronização periódica. No entanto, ele usa seu cache local baseado em TTL para obter o valor atual do ConfigMap. Como resultado, o atraso total, desde o momento em que o ConfigMap foi atualizado até o momento em que novas chaves são projetadas para o pod, pode ser tão longo quanto o
período de sincronização do Kubelet (1 minuto por padrão) + TTL de cache do ConfigMap (1 minuto por padrão) no kubelet.
Nota:
Um contêiner que esteja utilizando um ConfigMap como um subPath de volume não receberá atualizações de ConfigMaps.
Compreendendo ConfigMap e Pods
O recurso da API ConfigMap armazena dados de configuração como pares de chave-valor. Os dados podem ser consumidos em Pods, ou fornecidos para componentes do sistema, como controladores. O ConfigMap é similar ao Secret, mas fornece um meio de trabalhar com strings que não contêm informações confidenciais. Usuários e componentes do sistema podem armazenar dados de configuração em ConfigMaps.
Nota:
Os mapas de configuração devem fazer referência a arquivos de propriedades, não substituí-los. Pense no ConfigMap como representando algo semelhante ao diretório /etc do Linux e seus conteúdos. Por exemplo, se você criar um Volume Kubernetes a partir de um ConfigMap, cada item de dados no ConfigMap é representado por um arquivo individual no volume.
O campo data do ConfigMap contém os dados de configuração. Como mostrado no exemplo abaixo, estes podem ser simples (como propriedades individuais definidas usando --from-literal) ou complexos (como arquivos de configuração ou blobs JSON definidos usando --from-file).
apiVersion:v1kind:ConfigMapmetadata:creationTimestamp:2016-02-18T19:14:38Zname:example-confignamespace:defaultdata:# exemplo de uma propriedade simples definida usando --from-literalexample.property.1:helloexample.property.2:world# exemplo de uma propriedade complexa definida usando --from-fileexample.property.file:|- property.1=value-1
property.2=value-2
property.3=value-3
Restrições
Você deve criar um ConfigMap antes de referenciá-lo em uma especificação de Pod (a menos que você marque o ConfigMap como optional). Se você referenciar um ConfigMap que não existe, O Pod não vai iniciar. Da mesma forma, referências a chaves que não existem no ConfigMap impedirão o Pod de iniciar.
Se você usar envFrom para definir variáveis de ambiente do ConfigMap, chaves que são consideradas inválidas serão ignoradas. O Pod poderá iniciar, mas os nomes inválidos serão registrados no log de eventos (InvalidVariableNames). A mensagem de log lista cada chave ignorada. Por exemplo:
kubectl get events
A saída é semelhante a esta:
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON SOURCE MESSAGE
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames {kubelet, 127.0.0.1} Keys [1badkey, 2alsobad] from the EnvFrom configMap default/myconfig were skipped since they are considered invalid environment variable names.
O ConfigMap reside em um Namespace específico. Um ConfigMap só pode ser referenciado por Pods residentes no mesmo namespace.
Você não pode usar um ConfigMap para Pods estáticos, porque o kubelet não oferece suporte a isso.
4.3.9 - Compartilhando o Namespace de Processo Entre Contêineres em um Pod
Esta página mostra como configurar o compartilhamento de namespace de processos para um Pod. Quando
O compartilhamento de namespace de processos está ativado, os processos em um Contêiner são visíveis
para todos os outros Contêineres no mesmo Pod.
Você pode usar este recurso para configurar Contêineres de cooperação, como um manipulador de log
sidecar de contêiner, ou para solucionar problemas em imagens de contêiner que não
incluem utilitários de depuração como um shell.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Conecte ao shell do contêiner e execute o comando ps:
kubectl attach -it nginx -c shell
Se você não vir um prompt de comando, tente pressionar Enter. No shell do Contêiner execute:
# execute este comando dentro do "shell" do contêinerps ax
A saída é semelhante a esta:
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
14 101 0:00 nginx: worker process
15 root 0:00 sh
21 root 0:00 ps ax
Você pode sinalizar processos em outros Contêineres. Por exemplo, mandando SIGHUP ao
nginx para restartar o processo worker. Isso requer a capacidade SYS_PTRACE.
# execute este comando dentro do "shell" do contêinerkill -HUP 8# substitua o "8" pelo PID do processo principal do nginx, se necessáriops ax
A saída é semelhante a esta:
PID USER TIME COMMAND
1 root 0:00 /pause
8 root 0:00 nginx: master process nginx -g daemon off;
15 root 0:00 sh
22 101 0:00 nginx: worker process
23 root 0:00 ps ax
É até possível acessar o sistema de arquivos de outro contêiner usando o link
/proc/$pid/root.
# execute este comando dentro do "shell" do contêiner# substitua o "8" pelo PID do processo Nginx, se necessariohead /proc/8/root/etc/nginx/nginx.conf
Compreendendo o compartilhamento de namespace de processos
Os Pods compartilham muitos recursos, por isso faz sentido que eles também compartilhem um namespace de processo.
Alguns Contêineres podem esperar serem isolados de outros, no entanto,
por isso, é importante entender as diferenças:
O processo de contêiner não tem mais o PID 1. Alguns Contêineres recusam
começar sem o PID 1 (por exemplo, contêineres usando systemd) ou executando comandos
como kill -HUP 1 para sinalizar o processo de Contêiner. Em pods com um
namespace de processos compartilhado, kill -HUP 1 irá sinalizar a sandbox
(/pause no exemplo acima).
Os processos são visíveis para outros contêineres no Pod. Isso inclui todas
informações visíveis em /proc, como senhas que foram passadas como argumentos
ou variáveis de ambiente. Estes são protegidos apenas por permissões regulares do Unix.
Sistema de arquivos do Contêiner são visíveis para outros Contêineres do pod através do link
/proc/$pid/root. Isso facilita a depuração, mas também significa
que os segredos do sistema de arquivos, são protegidos apenas por permissões de sistema de arquivos.
4.3.10 - Criando Pods Estáticos
Pods Estáticos são gerenciados diretamente pelo daemon kubelet em um nó específico,
sem o servidor de API
observando-os.
Ao contrário dos pods que são gerenciados pelo Control Plane (por exemplo, uma
Implantação);
em vez disso, o kubelet observa cada Pod estático
(e reinicia-os se falharem).
Pods estáticos estão sempre ligados a um Kubelet em um nó específico.
O Kubelet tenta automaticamente criar um mirror Pod
no servidor de API do Kubernetes para cada Pod estático.
Isso significa que os pods em execução em um nó são visíveis no servidor de API,
mas não podem ser controlados a partir daí.
Aos nomes de Pods será sufixados com o nome de host do nó, com um hífem a esquerda.
Nota:
Se você está executando um cluster Kubernetes, usando Pods estáticos para executar um Pod em cada Nó,
provávelmente você deveria estar usando um DaemonSet em substituição.
Nota:
A especificação de um Pod estático não pode referir-se à outros objetos da API
(ex., ServiceAccount,
ConfigMap,
Secret, etc).
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Esta página assume que você está usando um CRI-O para executar os Pods,
e que seus nós estão executando o sistema operacional Fedora.
Instruções para outras distribuições, ou instalações de Kubernetes, podem variar.
Manifesto do Pod estático hospedado no sistema de arquivos
Os manifestos, são definições de Pod padrão em formato JSON ou YAML em um diretório específico. Use o campo staticPodPath: <diretório> no
arquivo de configuração do kubelet,
que periodicamente varre o diretório e cria/exclui Pods estáticos conforme os arquivos YAML/JSON aparecem/desaparecem.
Observe que o Kubelet ignorará os arquivos começando com pontos ao varrer o diretório especificado.
Por exemplo, como iniciar um servidor Web simples como um Pod estático
Escolha um nó onde você deseja executar um Pod estático. Neste exemplo, é my-node1.
ssh my-node1
Escolha um diretório, digamos /etc/kubernetes/manifests e coloque uma definição de pod para um servidor web lá, por exemplo /etc/kubernetes/manifests/static-web.yaml:
# Execute este comando no nó onde o Kubelet está funcionandomkdir -p /etc/kubernetes/manifests/
cat <<EOF >/etc/kubernetes/manifests/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
name: static-web
labels:
role: myrole
spec:
containers:
- name: web
image: nginx
ports:
- name: web
containerPort: 80
protocol: TCP
EOF
Configure seu kubelet no nó para usar este diretório executando-o com o argumento --pod-manifest-path=/etc/kubernetes/manifests/. No Fedora, edite o arquivo /etc/kubernetes/kubelet para incluir esta linha:
Reinicie o kubelet. No Fedora, você poderia executar:
# Execute este comando no nó onde o kubelet está funcionandosystemctl restart kubelet
Manifesto do Pod estático hospedado na Web
O Kubelet baixa periodicamente um arquivo especificado pelo argumento --manifest-url=<URL>
e interpreta-o como um arquivo JSON/YAML que contém as definições do Pod.
Similar ao que manifestos hospedados no sistema de arquivos fazem, o kubelet
reexamina o manifesto em um agendamento. Se houver alterações na lista de Pods estáticos, o kubelet aplica-os.
Para usar esta abordagem:
Crie um arquivo YAML e armazene-o em um servidor da Web, para que você possa passar o URL desse arquivo para o Kubelet.
Configure o kubelet no seu nó selecionado para usar este manifesto da Web, executando-o com --manifest-url=<manifest-url>. No Fedora, edite /etc/kubernetes/kubelet para incluir esta linha:
# Execute este comando no nó onde o kubelet está funcionandosystemctl restart kubelet
Observe o comportamento do Pod estático
Quando o kubelet começa, inicia automaticamente todos os pods estáticos definidos.
Como você definiu um Pod estático e reiniciou o kubelet, o novo pod estático deveria
já estar em execução.
Você pode ver os Contêineres em execução (incluindo os Pods estáticos) ao executar (no Nó):
# Execute este comando no nó onde o kubelet está funcionandocrictl ps
A saída pode ser algo como:
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
129fd7d382018 docker.io/library/nginx@sha256:... 11 minutes ago Running web 0 34533c6729106
Nota:
crictl mostra a URI da imagem e o checksum SHA-256. O NAME vai parecer mais como:
docker.io/library/nginx@sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31.
Você pode ver o Pod espelho no servidor de API:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web 1/1 Running 0 2m
Os Rótulos dos pods estáticos são
propagados no Pod espelho. Você pode usar esses rótulos como
seletores via normal, etc.
Se você tentar usar o kubectl para excluir o Pod espelho do servidor de API,
o kubelet não remove o Pod estático:
kubectl delete pod static-web
pod "static-web" deleted
Você pode ver que o Pod ainda está funcionando:
kubectl get pods
NAME READY STATUS RESTARTS AGE
static-web 1/1 Running 0 4s
De volta ao seu nó, onde o kubelet está funcionando, você pode tentar parar o Contêiner manualmente.
Você verá que, depois de algum tempo, o Kubelet notará e reiniciará o Pod
automaticamente:
# Execute esses comandos no nó onde o Kubelet está funcionandocrictl stop 129fd7d382018 # substitua pelo ID do seu contêinersleep 20crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
89db4553e1eeb docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
Adição e remoção dinâmica de Pods estáticos
O Kubelet em execução varre periodicamente o diretório configurado (/etc/kubernetes/manifests em nosso exemplo) por alterações, e adiciona/remove os pods à medida que os arquivos aparecem/desaparecem neste diretório.
# Pressupondo que você esteja usando a configuração de Pod estático hospedada no sistema de arquivos# Execute esses comandos no nó onde o Kubelet está funcionando#mv /etc/kubelet.d/static-web.yaml /tmp
sleep 20crictl ps
# Você vê que nenhum contêiner nginx está funcionando#mv /tmp/static-web.yaml /etc/kubelet.d/
sleep 20crictl ps
CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID
f427638871c35 docker.io/library/nginx@sha256:... 19 seconds ago Running web 1 34533c6729106
4.3.11 - Aplicando os Padrões de Segurança do Pod Através da Configuração do Controlador de Admissão Embutido
Após uma release alfa no Kubernetes v1.22, o controlador de admissão
Pod Security Admission tornou-se disponível por padrão no Kubernetes v1.23,
no estado beta. Da versão 1.25 em diante o controlador de admissão Pod Security
Admission está publicamente disponível.
Para verificar a versão, digite kubectl version.
Se você não estiver utilizando o Kubernetes 1.30, você
pode verificar a documentação da versão do Kubernetes que você está utilizando.
Configure o Controlador de Admissão
Nota:
A configuração pod-security.admission.config.k8s.io/v1 requer o Kubernetes v1.25
ou superior.
Para as versões v1.23 e v1.24, utilize v1beta1.
Para a versão v1.22, utilize v1alpha1.
apiVersion:apiserver.config.k8s.io/v1# veja a nota de compatibilidadekind:AdmissionConfigurationplugins:- name:PodSecurityconfiguration:apiVersion:pod-security.admission.config.k8s.io/v1beta1kind:PodSecurityConfiguration# Padrões aplicados quando o label de modo não é especificado.## O valor para o label Level deve ser uma das opções abaixo:# - "privileged" (padrão)# - "baseline"# - "restricted"## O valor para o label Version deve ser uma das opções abaixo:# - "latest" (padrão)# - versão específica no formato "v1.30"defaults:enforce:"privileged"enforce-version:"latest"audit:"privileged"audit-version:"latest"warn:"privileged"warn-version:"latest"exemptions:# Lista de usuários autenticados a eximir.usernames:[]# Lista de RuntimeClasses a eximir.runtimeClasses:[]# Lista de namespaces a eximir.namespaces:[]
Nota:
O manifesto acima precisa ser especificado através da opção de linha de comando
--admission-control-config-file do kube-apiserver.
4.3.12 - Aplicando Padrões de Segurança de Pod com `Labels` em Namespace
Exigindo o padrão de segurança baseline de pod com rótulos em namespace
Este manifesto define um Namespace my-baseline-namespace que:
Bloqueia quaisquer Pods que não satisfazem os requisitos da política baseline.
Gera um aviso para o usuário e adiciona uma anotação de auditoria, a qualquer
pod criado que não satisfaça os requisitos da política restricted.
Fixa as versões das políticas baseline e restricted à v1.30.
apiVersion:v1kind:Namespacemetadata:name:my-baseline-namespacelabels:pod-security.kubernetes.io/enforce:baselinepod-security.kubernetes.io/enforce-version:v1.30# Estamos definindo-os para o nosso nível _desejado_ `enforce`.pod-security.kubernetes.io/audit:restrictedpod-security.kubernetes.io/audit-version:v1.30pod-security.kubernetes.io/warn:restrictedpod-security.kubernetes.io/warn-version:v1.30
Adicionar Rótulos aos Namespaces Existentes com kubectl label
Nota:
Quando um rótulo de política enforce (ou version) é adicionada ou modificada,
O plugin de admissão testará cada Pod no namespace contra a nova política.
Violações são devolvidas ao usuário como avisos.
É útil aplicar a flag --dry-run ao avaliar inicialmente as alterações
do perfil de segurança para namespaces. As verificações padrão de segurança
do pod ainda serão executadas em modo dry run, dando-lhe informações sobre
como a nova política trataria os pods existentes, sem realmente atualizar a política.
Se você está apenas começando com os padrões de segurança de pod, um primeiro passo
adequado seria configurar todos namespaces com anotações de auditoria para um
nível mais rigoroso, como baseline:
Observe que isso não está aplicando as definições de nível, para que os namespaces
que não foram explicitamente avaliados possam ser distinguidos. Você pode listar
os namespaces sem um nível aplicado, explicitamente definido, usando este comando:
kubectl get namespaces --selector='!pod-security.kubernetes.io/enforce'
Aplicando a um único namespace
Você pode atualizar um namespace específico também. Este comando adiciona a política
enforce=restricted ao my-existing-namespace, fixando a política que restringe
à versão v1.30.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Inicie o minikube, a versão mínima exigida é >= v1.5.2, com os seguintes argumentos:
minikube version
minikube version: v1.5.2
minikube start --network-plugin=cni
Para o minikube, você poderá instalar o Cilium utilizando a ferramenta de linha de comando (CLI). Para isso, primeiro faça o download da última versão do CLI com o seguinte comando:
Em seguida extraia o arquivo baixado para o diretório /usr/local/bin com os comandos:
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz
Após executar os passos acima, você poderá instalar o Cilium utilizando o comando abaixo:
cilium install
O Cilium irá detectar as configurações do cluster automaticamente, criará e instalará os componentes apropriados para que a instalação seja bem sucedida.
Os componentes são:
Certificate Authority (CA) no Secret cilium-ca e os certificados para o Hubble (camada de observabilidade do Cilium).
Service accounts.
Cluster roles.
ConfigMap.
Um agente DaemonSet e um Operator Deployment.
Após a instalação, você poderá visualizar o status geral do Deployment do Cilium com o comando cilium status.
Confira a saída esperada da opção statusaqui.
O restante do guia de primeiros passos utiliza como base uma aplicação de exemplo para explicar como aplicar políticas de segurança tanto para L3/L4 (como endereço de IP + porta), quanto para L7 (como HTTP).
Essa documentação inclui detalhes sobre os requisitos, instruções e exemplos de DaemonSet para produção.
Entendendo os componentes do Cilium
Ao realizar o deploy do Cilium no cluster, Pods são adicionados ao namespace kube-system. Para ver essa lista de Pods execute:
kubectl get pods --namespace=kube-system -l k8s-app=cilium
Você verá uma lista de Pods similar a essa:
NAME READY STATUS RESTARTS AGE
cilium-kkdhz 1/1 Running 0 3m23s
...
Um Pod cilium roda em cada um dos nós do seu cluster e garante as políticas de rede no tráfego de/para Pods naquele nó usando o Linux BPF.
Próximos passos
Uma vez que seu cluster estiver rodando, você pode seguir o artigo Declarar uma Network Policy (em inglês) para testar as políticas de NetworkPolicy do Kubernetes com o Cilium.
Divirta-se! Se tiver dúvidas, nos contate usando o Canal Slack do Cilium.
4.5 - Depurando Contêineres de Inicialização
Esta página mostra como investigar problemas relacionados à execução de contêineres de inicialização.
As linhas de comando de exemplo abaixo referem-se ao pod como <pod-name> e aos contêineres de inicialização como <init-container-1> e
<init-container-2>.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Você também pode acessar programaticamente os status dos contêineres de inicialização,
lendo o campo status.initContainerStatuses nas especificações do pod:
kubectl get pod nginx --template '{{.status.initContainerStatuses}}'
Este comando retornará as mesmas informações acima em JSON bruto.
Acessando logs de contêineres de inicialização
Passe o nome do contêiner de inicialização junto com o nome do Pod
para acessar seus logs.
kubectl logs <pod-name> -c <init-container-2>
Contêineres de inicialização que executam comandos de script de shell imprimem
à medida que são executados. Por exemplo, você pode fazer isso no Bash executando set -x no início do script.
Entendendo sobre o status do pod
Um status do Pod começando com Init: resume o status da execução de contêineres de inicialização.
A tabela abaixo descreve alguns valores de status de exemplo que você pode ver durante a depuração de contêineres de inicialização.
Status
Significado
Init:N/M
O pod tem contêineres de inicialização M e N que foram concluídas até agora.
Init:Error
Um contêiner de inicialização falhou ao executar.
Init:CrashLoopBackOff
Um contêiner de inicialização falhou repetidamente.
Pending
O pod ainda não começou a executar o contêiner de inicialização.
PodInitializing ou Running
O pod já concluiu a execução dos contêineres de inicialização.
4.6 - Acessando Aplicações em um Cluster
Configurar balanceamento de carga, redirecionamento de porta, ou configuração de firewall ou DNS para acessar aplicativos em um cluster.
4.6.1 - Acessando clusters
Esse tópico fala sobre diversas maneiras de interagir com clusters.
Acessando pela primeira vez com kubectl
Se estiver acessando o Kubernetes API pela primeira vez, recomendamos usar a CLI do Kubernetes, kubectl.
Para acessar um cluster, você precisa saber a localização do cluster e ter credenciais para acessá-lo. Geralmente, isso é configurado automaticamente quando você trabalha com um Guia de instalação ou outra pessoa configurou o cluster e forneceu a você credenciais e uma localização.
Verifique o local e as credenciais que o kubectl conhece com esse comando:
O Kubectl lida com a localização e a autenticação no servidor de API.
Se você quiser acessar diretamente a API REST com um cliente http como
curl ou wget, ou um navegador, há várias maneiras de localizar e autenticar:
Executar o kubectl no modo proxy.
Método recomendado.
Usa a localização previamente armazenada do servidor da API.
Verifica a identidade do apiserver usando um certificado autoassinado. Não há possibilidade de ataque MITM (Man-In-The-Middle).
Autentica-se no servidor da API.
No futuro, poderá fazer balanceamento de carga inteligente no lado do cliente, e transferência em caso de falha.
Forneça o local e as credenciais diretamente para o cliente http.
Método alternativo.
Funciona com alguns tipos de código de cliente que são confundidos pelo uso de um proxy.
É necessário importar um certificado raiz em seu navegador para se proteger contra ataque MITM (Man-In-The-Middle).
Usando o kubectl proxy
O comando a seguir executa o kubectl em um modo em que ele atua como um proxy reverso. Ele lida com
localização do apiserver e da autenticação.
Execute-o desta forma:
Os exemplos acima usam a opção --insecure. Isso deixa o cluster sujeito a ataques MITM.
Quando o kubectl acessa o cluster, ele usa um certificado raiz guardado
e certificados de cliente para acessar o servidor. (Esses certificados são instalados no diretório
~/.kube). Como os certificados do cluster normalmente são autoassinados, pode ser necessária uma
configuração especial para que seu cliente http use o certificado raiz.
Em alguns clusters, o servidor da API não requer autenticação; ele pode servir
no localhost ou estar protegido por um firewall. Não há um padrão
para isso. A página Controlando Acesso à API do Kubernetes
descreve como um administrador de cluster pode configurar isso.
Acesso programático à API
O Kubernetes suporta oficialmente as bibliotecas de clientes Go e Python.
Cliente Go
Para obter a biblioteca, execute o seguinte comando: go get k8s.io/client-go@kubernetes-<kubernetes-version-number>,
consulte INSTALL.md
para obter instruções detalhadas de instalação. Consulte
https://github.com/kubernetes/client-go
para ver quais versões são compatíveis.
Escreva um aplicativo utilizando o cliente Go. Observe que ela define seus próprios objetos de API,
portanto, se necessário, importe as definições de API do cliente Go em vez de importá-las do repositório principal.
Por exemplo, import "k8s.io/client-go/kubernetes" está correto.
O cliente Go pode usar o mesmo arquivo kubeconfig
como a CLI do kubectl faz, para localizar e autenticar ao apiserver. Veja esse
exemplo.
Se o aplicativo for disponibilizado como um pod no cluster, consulte a próxima seção.
O cliente Python pode usar o mesmo arquivo kubeconfig
que a ferramenta kubectl utiliza para localizar e autenticar ao servidor da API. Veja esse
exemplo.
Outras bibliotecas
Existem bibliotecas de clientes para acessar a API utilizando outras linguagens.
Consulte a documentação de outras bibliotecas para saber como elas se autenticam.
Acessando a API a partir de um pod
Ao acessar a API a partir de um pod, a localização e a autenticação
para o servidor de API são um pouco diferentes.
A seção anterior descreve como se conectar ao servidor da API do Kubernetes.
Para obter informações sobre como se conectar a outros serviços em execução em um cluster do Kubernetes, consulte
Acessando serviços em execução em clusters.
Solicitação de redirecionamentos
Os recursos de redirecionamento foram descontinuados e removidos. Em vez disso, use um proxy (veja abaixo).
Tantos proxies
Há vários proxies diferentes que você pode encontrar ao usar o Kubernetes:
Um Proxy/balanceador de carga na frente do(s) servidor(es) da API:
a existência e a implementação variam de cluster para cluster (por exemplo, nginx)
fica entre todos os clientes e um ou mais servidores da API
atua como um balanceador de carga se houver vários servidores da API.
Balanceadores de carga de provedor de nuvem em serviços externos:
são fornecidos por alguns provedores de nuvem computacional (por exemplo, AWS ELB, Google Cloud Load Balancer)
são criados automaticamente quando o serviço Kubernetes tem o tipo LoadBalancer
usam somente UDP/TCP
a implementação varia de acordo com o provedor de nuvem.
Normalmente, os usuários do Kubernetes não precisam se preocupar com nada além dos dois primeiros tipos. O administrador do cluster
normalmente garantirá que os últimos tipos sejam configurados corretamente.
4.6.2 - Configurar o acesso a múltiplos clusters
Esta página mostra como configurar o acesso a vários clusters usando arquivos de configuração. Depois que os clusters, os usuários e os contextos forem definidos em um ou mais arquivos de configuração, você pode alternar rapidamente entre os clusters usando o comando kubectl config use-context.
Nota:
Um arquivo usado para configurar o acesso a um cluster às vezes é chamado de arquivo kubeconfig. Essa é uma forma genérica de se referir a arquivos de configuração. Isso não significa que exista um arquivo chamado kubeconfig.
Aviso:
Use somente arquivos kubeconfig de fontes confiáveis. O uso de um arquivo kubeconfig artificialmente criado, pode resultar em execução de código malicioso ou exposição de arquivos. Se você preciso usar um arquivo kubeconfig não-confiável, inspecione-o cuidadosamente antes, da mesma forma que faria com um script de shell.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Para verificar se kubectl está instalado,
execute kubectl version --client. A versão do kubectl deve ter no máximo uma versão menor de diferença da versão do servidor de API do seu cluster.
Defina clusters, usuários e contextos
Suponha que você tenha dois clusters, um para o trabalho de desenvolvimento, chamado development, e outro para o trabalho de teste, chamado test.
No cluster development, seus desenvolvedores de front-end trabalham em um namespace chamado frontend,
e os desenvolvedores de armazenamento trabalham em um namespace chamado storage. Em seu cluster test,
os desenvolvedores trabalham no namespace padrão ou criam namespaces auxiliares conforme
acharem adequado. O acesso ao cluster de desenvolvimento requer autenticação por certificado. O acesso
ao cluster de teste requer autenticação por nome de usuário e senha.
Crie um diretório chamado config-exercise. Em seu diretório
config-exercise, crie um arquivo chamado config-demo com este conteúdo:
Um arquivo de configuração descreve clusters, usuários e contextos. Seu arquivo config-demo
tem a estrutura para descrever dois clusters, dois usuários e três contextos.
Vá para o diretório config-exercise. Digite estes comandos para adicionar detalhes do cluster ao
seu arquivo de configuração:
kubectl config --kubeconfig=config-demo set-cluster development --server=https://1.2.3.4 --certificate-authority=fake-ca-file
kubectl config --kubeconfig=config-demo set-cluster test --server=https://5.6.7.8 --insecure-skip-tls-verify
Adicione detalhes do usuário ao seu arquivo de configuração:
Cuidado:
O armazenamento de senhas na configuração do cliente do Kubernetes é arriscado. Uma alternativa melhor seria usar um plug-in de credenciais e salvá-las separadamente. Veja: plugins de credenciais client-go
Abra seu arquivo config-demo para ver os detalhes adicionados. Como alternativa para abrir o arquivo config-demo, você pode usar o comando config view
kubectl config --kubeconfig=config-demo view
O resultado mostra os dois clusters, dois usuários e três contextos:
apiVersion:v1clusters:- cluster:certificate-authority:fake-ca-fileserver:https://1.2.3.4name:development- cluster:insecure-skip-tls-verify:trueserver:https://5.6.7.8name:testcontexts:- context:cluster:developmentnamespace:frontenduser:developername:dev-frontend- context:cluster:developmentnamespace:storageuser:developername:dev-storage- context:cluster:testnamespace:defaultuser:experimentername:exp-testcurrent-context:""kind:Configpreferences:{}users:- name:developeruser:client-certificate:fake-cert-fileclient-key:fake-key-file- name:experimenteruser:# Nota de documentação (este comentário NÃO faz parte da saída do comando).# Armazenar senhas na configuração do cliente Kubernetes é arriscado.# Uma alternativa melhor seria usar um plugin de credenciais# e armazenar as credenciais separadamente.# Veja https://kubernetes.io/pt-br/docs/reference/access-authn-authz/authentication/#plugins-de-credenciais-client-gopassword:some-passwordusername:exp
O fake-ca-file, o fake-cert-file e o fake-key-file acima são os espaços reservados
para a localização dos arquivos de certificado. Você precisa alterá-los para a localização real
dos arquivos de certificado em seu ambiente.
Às vezes, você pode querer usar dados codificados em Base64 incorporados aqui, em vez de arquivos de certificado separados.
Nesse caso, é necessário adicionar o sufixo data às chaves, por exemplo,
certificate-authority-data, client-certificate-data, client-key-data.
Cada contexto é uma tripla (cluster, usuário, namespace). Por exemplo, o contexto
dev-frontend diz: "Use as credenciais do usuário developer
para acessar o namespace frontend do cluster development".
Agora, sempre que você use um comando kubectl, a ação será aplicada ao cluster,
e ao namespace listados no contexto dev-frontend. E o comando usará
as credenciais do usuário listado no contexto dev-frontend.
Para ver apenas as informações de configuração associadas ao
o contexto atual, use a opção --minify.
Agora, qualquer comando kubectl que você usar, será aplicado ao namespace padrão do cluster test. E o comando usará as credenciais do usuário
listado no contexto exp-test.
Ver a configuração associada ao novo contexto atual, exp-test.
O arquivo de configuração anterior define um novo contexto chamado dev-ramp-up.
Defina a variável de ambiente KUBECONFIG
Verifique se você tem uma variável de ambiente chamada KUBECONFIG. Em caso afirmativo, salve o valor atual da variável de ambiente KUBECONFIG para que você possa restaurá-lo posteriormente.
Por exemplo:
Linux
exportKUBECONFIG_SAVED="$KUBECONFIG"
Windows PowerShell
$Env:KUBECONFIG_SAVED=$ENV:KUBECONFIG
A variável de ambiente KUBECONFIG é uma lista de caminhos para arquivos de configuração. A lista é
delimitada por dois pontos para Linux e Mac, e delimitada por ponto e vírgula para Windows. Se você tiver
uma variável de ambiente KUBECONFIG, familiarize-se com os arquivos de configuração
na lista.
Anexe temporariamente duas localizações à sua variável de ambiente KUBECONFIG. Por exemplo:
Em seu diretório config-exercise, digite este comando:
kubectl config view
O resultado mostra informações mescladas de todos os arquivos listados em sua variável de ambiente KUBECONFIG. Em particular, observe que as informações mescladas têm o contexto dev-ramp-up do arquivo config-demo-2 e os três contextos do arquivo config-demo:
Se você já tiver um cluster e puder usar o kubectl para interagir com o
o cluster, então provavelmente você tem um arquivo chamado config no diretório $HOME/.kube.
Vá para $HOME/.kube e veja quais arquivos estão lá. Normalmente, há um arquivo chamado
config. Também pode haver outros arquivos de configuração nesse diretório. Em um breve momento
familiarize-se com o conteúdo desses arquivos.
Acrescente $HOME/.kube/config à sua variável de ambiente KUBECONFIG
Se você tiver um arquivo $HOME/.kube/config e ele ainda não estiver listado em sua variável de ambiente
KUBECONFIG, acrescente-o à sua variável de ambiente KUBECONFIG agora.
Por exemplo:
Visualize as informações de configuração mescladas de todos os arquivos que agora estão listados
em sua variável de ambiente KUBECONFIG. Em seu diretório config-exercise, digite:
kubectl config view
Limpar
Retorne sua variável de ambiente KUBECONFIG ao seu valor original. Por exemplo:
Linux
exportKUBECONFIG="$KUBECONFIG_SAVED"
Windows PowerShell
$Env:KUBECONFIG=$ENV:KUBECONFIG_SAVED
Verificar o sujeito representado pelo kubeconfig
Nem sempre é óbvio quais atributos (nome de usuário, grupos) você obterá após a autenticação no cluster.
Isso pode ser ainda mais desafiador se você estiver gerenciando mais de um cluster ao mesmo tempo.
Há um subcomando de kubectl para verificar os atributos do sujeito, como o nome de usuário, para o Kubernetes contexto selecionado: kubectl auth whoami.
4.6.3 - Use o redirecionamento de porta para acessar aplicativos em um cluster.
Esta página mostra como usar o kubectl port-forward para se conectar a um servidor MongoDB em execução em um cluster Kubernetes. Esse tipo de conexão pode ser útil para depuração de bancos de dados.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
A saída de um comando bem-sucedido verifica que o serviço foi criado:
service/mongo criado
Verifique o serviço criado::
kubectl get service mongo
A saída exibe o serviço criado:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
mongo ClusterIP 10.96.41.183 <none> 27017/TCP 11s
Verifique se o servidor MongoDB está sendo executado no Pod e ouvindo a porta 27017:
# Altere mongo-75f59d57f4-4nd6q para o nome do Podkubectl get pod mongo-75f59d57f4-4nd6q --template='{{(index (index .spec.containers 0).ports 0).containerPort}}{{"\n"}}'
A saída exibe a porta para o MongoDB nesse Pod:
27017
27017 é a porta TCP alocada ao MongoDB na internet.
Encaminhe uma porta local para uma porta no Pod
kubectl port-forward permite usar o nome do recurso, como o nome do pod, para selecionar um pod correspondente para encaminhar a porta.
# Altere mongo-75f59d57f4-4nd6q para o nome do Podkubectl port-forward mongo-75f59d57f4-4nd6q 28015:27017
Qualquer um dos comandos acima funciona. A saída é semelhante a esta:
Encaminhamento de 127.0.0.1:28015 -> 27017
Encaminhamento de [::1]:28015 -> 27017
Nota:
kubectl port-forward não retorna. Para continuar com os exercícios, você precisará abrir outro terminal.
Inicie a interface de linha de comando do MongoDB:
mongosh --port 28015
No prompt de comando do MongoDB, digite o comando ping:
db.runCommand( { ping: 1 } )
Uma solicitação de ping bem-sucedida retorna:
{ ok: 1 }
Opcionalmente, deixe kubectl escolher a porta local
Se você não precisa de uma porta local específica, pode permitir que o kubectl escolha e reserve a porta local e, assim, evitar ter que gerenciar conflitos de porta local, com a sintaxe ligeiramente mais simples:
kubectl port-forward deployment/mongo :27017
A ferramenta kubectl encontra um número de porta local que não está em uso (evitando números de porta baixos, porque esses podem ser usados por outras aplicações). A saída é semelhante a:
Encaminhamento de 127.0.0.1:63753 -> 27017
Encaminhamento de [::1]:63753 -> 27017
Discussão
As conexões feitas à porta local 28015 são encaminhadas para a porta 27017 do Pod que está executando o servidor MongoDB. Com esta conexão em vigor, você pode usar seu local de trabalho para depurar o banco de dados que está sendo executado no Pod.
Nota:
kubectl port-forward é implementado apenas para portas TCP.
O suporte ao protocolo UDP é rastreado em
issue 47862.
4.6.4 - Conectando um Frontend a um Backend usando Serviços
Esta tarefa mostra como criar um microserviço frontend e um microserviço backend. O microserviço backend é um serviço que envia uma mensagem de saudação. O frontend expõe o backend usando o nginx e um objeto Service do Kubernetes.
Objetivos
Crie e execute um microserviço de backend de amostra chamado hello usando um objeto Deployment.
Use um objeto de serviço (Service) para enviar tráfego para as várias réplicas do microserviço de backend.
Crie e execute um microserviço de frontend chamado nginx, também usando um objeto Deployment.
Configure o microserviço de frontend para enviar tráfego para o microserviço de backend.
Use um objeto Service do tipo LoadBalancer para expor o microserviço de frontend fora do cluster.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Name: backend
Namespace: default
CreationTimestamp: Mon, 24 Oct 2016 14:21:02 -0700
Labels: app=hello
tier=backend
track=stable
Annotations: deployment.kubernetes.io/revision=1
Selector: app=hello,tier=backend,track=stable
Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 1 max unavailable, 1 max surge
Pod Template:
Labels: app=hello
tier=backend
track=stable
Containers:
hello:
Image: "gcr.io/google-samples/hello-go-gke:1.0"
Port: 80/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: hello-3621623197 (3/3 replicas created)
Events:
...
Criando o objeto Service hello
A chave para enviar solicitações do frontend para o backend é o Service do backend. Um Service cria um endereço IP persistente e uma entrada de nome DNS, para que o microserviço do backend possa ser sempre acessado. Um Service usa seletores para encontrar os Pods para os quais ele roteia o tráfego.
Primeiro, explore o arquivo de configuração do Service:
No arquivo de configuração, você pode ver que o Service, chamado de hello, roteia o tráfego para Pods que possuem as labels app: hello e tier: backend.
Neste ponto, você possui um Deployment chamado backend executando três réplicas do seu aplicativo hello e possui um Service que pode rotear o tráfego para eles. No entanto, esse serviço ainda não pode ser acessado ou resolvido fora do cluster.
Criando o frontend
Agora que o seu backend está em execução, você pode criar um frontend que seja acessível fora do cluster e se conecte ao backend por meio de solicitações de proxy.
O frontend envia solicitações para os worker Pods do backend usando o nome DNS fornecido ao Serviço do backend. O nome DNS é hello, que é o valor do campo name no arquivo de configuração examples/service/access/backend-service.yaml.
Os Pods no Deployment do frontend executam uma imagem nginx que é configurada para fazer proxy de solicitações para o Serviço de backend hello. Aqui está o arquivo de configuração nginx:
# The identifier Backend is internal to nginx, and used to name this specific upstream
upstream Backend {
# hello is the internal DNS name used by the backend Service inside Kubernetes
server hello;
}
server {
listen 80;
location / {
# The following statement will proxy traffic to the upstream named Backend
proxy_pass http://Backend;
}
}
Similarmente ao backend, o frontend possui um Deployment e um Service. Uma diferença importante a ser notada entre os serviços de backend e frontend é que a configuração do serviço de frontend tem o parâmetro type: LoadBalancer, o que significa que o serviço usa um balanceador de carga fornecido pelo provedor de nuvem e será acessível de fora do cluster.
A saída mostra que ambos os recursos foram criados:
deployment.apps/frontend created
service/frontend created
Nota:
A configuração do nginx está incorporada à imagem do contêiner. Uma maneira melhor de fazer isso seria usar um ConfigMap, para que seja possível alterar a configuração com mais facilidade.
Interagindo com o Service frontend
Depois de criar um Service do tipo LoadBalancer, você pode usar este comando para encontrar o IP externo:
kubectl get service frontend --watch
Isso exibe a configuração do Service frontend e fica monitorando por mudanças. Inicialmente, o IP externo é exibido como <pending>:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 <pending> 80/TCP 10s
Assim que um IP externo é provisionado, a configuração é atualizada para incluir o novo IP na seção EXTERNAL-IP:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
frontend LoadBalancer 10.51.252.116 XXX.XXX.XXX.XXX 80/TCP 1m
Esse IP agora pode ser usado para interagir com o serviço frontend de fora do cluster.
Enviando tráfego por meio do frontend
Agora que o frontend e o backend estão conectados, você pode acessar o endpoint usando o comando curl no IP externo do seu serviço frontend:
curl http://${EXTERNAL_IP}# substitua isto pelo `EXTERNAL-IP` que você viu antes
A saída mostra a mensagem gerada pelo backend:
{"message":"Hello"}
Limpando
Para excluir os Services, digite este comando:
kubectl delete services frontend backend
Para excluir os Deployments, ReplicaSets e `Pods que estão executando as aplicações frontend e backend, digite este comando:
Esta página mostra como criar um balanceador de carga externo para um service em execução em um cluster Kubernetes.
Criando um Service, você tem a opção de criar automaticamente um balanceador de carga em nuvem. Isso fornece um endereço IP acessível externamente que envia tráfego para a porta correta nos nós do seu cluster, desde que seu cluster seja executado em um ambiente suportado e esteja configurado com o pacote do provedor de balanceador de carga em nuvem correto.
Você também pode usar um Ingress no lugar de Service.
Para obter mais informações, verifique a documentação do Ingress.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O endereço IP do balanceador de carga é listado ao lado de LoadBalancer Ingress.
Nota:
Se você estiver executando seu service no Minikube, poderá encontrar o endereço IP e a porta designados com:
minikube service example-service --url
Preservando o IP de origem do cliente
Por padrão, o IP de origem visto no contêiner de destino não é o IP de origem original do cliente. Para permitir a preservação do IP do cliente, os seguintes
campos podem ser configurados no .spec do Service:
.spec.externalTrafficPolicy - indica se este Service deseja rotear o tráfego externo para endpoints locais do nó ou em todo o cluster. Existem duas opções disponíveis: Cluster (padrão) e Local. Cluster oculta o IP de origem do cliente e pode causar um segundo salto para outro nó, mas deve ter uma boa distribuição geral de carga. Local preserva o IP de origem do cliente e evita um segundo salto para Service do tipo LoadBalancer e NodePort, mas corre o risco de uma distribuição de tráfego potencialmente desequilibrada.
.spec.healthCheckNodePort - especifica a porta de verificação de integridade
(número de porta numérico) para o service. Se você não especificar
healthCheckNodePort, o controlador de service alocará uma porta do intervalo NodePort do seu cluster.
Você pode configurar esse intervalo definindo uma opção de linha de comando do servidor de API,
--service-node-port-range. O Service usará o valor healthCheckNodePort especificado pelo usuário, se você o especificar, desde que o tipo do Service esteja definido como LoadBalancer e externalTrafficPolicy esteja definido como Local.
A definição externalTrafficPolicy: Local no manifesto do Service ativa esse recurso. Por exemplo:
Os service de balanceamento de carga de alguns provedores de nuvem não permitem configurar pesos diferentes para cada destino.
Como cada destino recebe o mesmo peso no balanceamento de tráfego para os Nós, o tráfego externo não é distribuído igualmente entre os Pods. Isso ocorre porque o balanceador de carga externo não considera o número de Pods por Nó.
Quando NumServicePods << NumNodes ou NumServicePods >> NumNodes, uma distribuição relativamente próxima da igualdade será observada, mesmo sem pesos.
O tráfego interno Pod-a-Pod deve apresentar um comportamento similar aos services ClusterIP, com a mesma probabilidade entre todos os Pods.
Limpeza de balanceadores de carga
ESTADO DA FUNCIONALIDADE:Kubernetes v1.17 [stable]
Em um caso normal, ao excluir um Service do tipo LoadBalancer, os recursos de balanceamento de carga no provedor de nuvem são automaticamente removidos. Porém, existem casos onde esses recursos permanecem ativos, mesmo após a exclusão do Service. Para resolver esse problema, foi introduzida a Proteção por Finalizadores para LoadBalancers de Service. Essa proteção utiliza finalizadores, que são mecanismos que impedem a exclusão de um Serviço até que os recursos de balanceamento de carga associados também sejam removidos.
Para Service do tipo LoadBalancer, o controlador de service utiliza um finalizador chamado service.kubernetes.io/load-balancer-cleanup. Esse finalizador funciona como um mecanismo de segurança, impedindo a exclusão do Service até que o recurso de balanceamento de carga associado seja removido. Essa medida evita a existência de recursos de balanceamento de carga órfãos, mesmo em situações inesperadas, como a falha do controlador de service.
Provedores de balanceamento de carga externo
É importante ressaltar que o roteamento e distribuição do tráfego para essa funcionalidade são realizados por um balanceador de carga que não faz parte do cluster Kubernetes.
Quando um Serviço é configurado como LoadBalancer, o Kubernetes garante o acesso interno aos pods do Serviço (como no tipo ClusterIP) e também integra o Serviço com um balanceador de carga externo. A camada de gerenciamento do Kubernetes é responsável por criar o balanceador de carga externo no provedor de nuvem, configurar as verificações de integridade (quando necessárias) e as regras de filtragem de pacotes (quando necessárias). Assim que o provedor de nuvem aloca um endereço IP ao balanceador de carga, a camada de gerenciamento o adiciona ao objeto de Serviço, tornando-o acessível externamente.
4.6.6 - Comunicação entre contêineres no mesmo pod usando um volume compartilhado
Esta página mostra como usar um Volume para realizar a comunicação entre dois contêineres rodando
no mesmo Pod. Veja também como permitir que processos se comuniquem por
compartilhamento de namespace do processo
entre os contêineres.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Neste exercício, você cria um Pod que executa dois contêineres. Os dois contêineres
compartilham um volume que eles podem usar para se comunicar. Aqui está o arquivo de configuração
para o Pod:
apiVersion:v1kind:Podmetadata:name:two-containersspec:restartPolicy:Nevervolumes:- name:shared-dataemptyDir:{}containers:- name:nginx-containerimage:nginxvolumeMounts:- name:shared-datamountPath:/usr/share/nginx/html- name:debian-containerimage:debianvolumeMounts:- name:shared-datamountPath:/pod-datacommand:["/bin/sh"]args:["-c","echo Hello from the debian container > /pod-data/index.html"]
No arquivo de configuração, você pode ver que o Pod tem um shared-data chamado
shared-data.
O primeiro contêiner listado no arquivo de configuração executa um servidor nginx.
O caminho de montagem para o volume compartilhado é /usr/share/nginx/html.
O segundo contêiner é baseado na imagem debian e tem um caminho de montagem
/pod-data. O segundo contêiner executa o seguinte comando e é encerrado.
echo Hello from the debian container > /pod-data/index.html
Observe que o segundo contêiner grava o arquivo index.html no diretório raiz do servidor nginx.
USER PID ... STAT START TIME COMMAND
root 1 ... Ss 21:12 0:00 nginx: master process nginx -g daemon off;
Lembre-se de que o contêiner debian criou o arquivo index.html no diretório raiz do nginx.
Use curl para enviar uma solicitação GET para o servidor nginx:
root@two-containers:/# curl localhost
A saída mostra que o nginx responde com uma página da web escrita pelo contêiner debian:
Hello from the debian container
Discussão
O principal motivo pelo qual os pods podem ter vários contêineres é oferecer suporte a aplicações extras que apoiam uma aplicação principal.
Exemplos típicos de aplicativos auxiliares são extratores de dados, aplicações para envio de dados e proxies.
Aplicativos auxiliares e primários geralmente precisam se comunicar uns com os outros.
Normalmente, isso é feito por meio de um sistema de arquivos compartilhado, conforme mostrado neste exercício,
ou por meio da interface de rede de loopback, localhost.
Um exemplo desse padrão é um servidor web junto com um programa auxiliar que consulta um repositório Git para novas atualizações.
O volume neste exercício fornece uma maneira dos contêineres se comunicarem durante
a vida útil do Pod. Se o Pod for excluído e recriado, todos os dados armazenados no volume compartilhado serão perdidos.
4.6.7 - Configurando o Ingress no Minikube com o NGINX Ingress Controller Config
O Ingress é um objeto da API que define regras
que permitem acesso externo a serviços em um cluster. Um
Ingress controller
cumpre as regras estabelecidas no Ingress.
Essa página mostra como configurar um Ingress simples que redireciona as requisições para o Service "web" ou "web2" dependendo do URI HTTP.
Antes de você começar
Esse tutorial assume que você está usando minikube para rodar um cluster Kubernetes local.
Visite Install tools para aprender como instalar o minikube.
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O seu servidor Kubernetes deve estar numa versão igual ou superior a 1.19.
Para verificar a versão, digite kubectl version.
Se você estiver usando uma versão mais antiga do Kubernetes, veja a documentação para essa versão.
Criando um cluster minikube
Se você ainda não configurou um cluster local, rode minikube start para criar um cluster.
Ativando o Ingress controller
Para ativar o NGINX Ingress controller, rode os seguintes comandos:
minikube addons enable ingress
Verifique que o NGINX Ingress controller está rodando
kubectl get pods -n ingress-nginx
Nota:
Os pods podem levar até um minuto para estarem rodando corretamente.
O resultado deve ser similar a:
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create-g9g49 0/1 Completed 0 11m
ingress-nginx-admission-patch-rqp78 0/1 Completed 1 11m
ingress-nginx-controller-59b45fb494-26npt 1/1 Running 0 11m
Instale uma aplicação hello world
Crie um Deployment usando o seguinte comando:
kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
O resultado deve ser:
deployment.apps/web created
Exponha o Deployment:
kubectl expose deployment web --type=NodePort --port=8080
O resultado deve ser:
service/web exposed
Verifique que o Service está criado e disponível em uma porta do nó:
kubectl get service web
O resultado deve ser similar:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.104.133.249 <none> 8080:31637/TCP 12m
Você agora pode acessar a aplicação de exemplo através do endereço IP do Minikube e NodePort.
No próximo passo, você irá acessar a aplicação usando o recurso Ingress.
Criando um Ingress
O manifesto a seguir define um Ingress que envia tráfego para seu Serviço via
hello-world.info.
O Kubernetes oferece um complemento de DNS para os clusters, que a maioria dos ambientes suportados habilitam por padrão. Na versão do Kubernetes 1.11 e posterior, o CoreDNS é recomendado e instalado por padrão com o kubeadm.
Para mais informações sobre como configurar o CoreDNS para um cluster Kubernetes, veja Personalização do Serviço de DNS. Para ver um exemplo que demonstra como usar o DNS do Kubernetes com o kube-dns, consulte Plugin de exemplo para DNS.
4.6.9 - Acessando serviços em execução em clusters
Esta página mostra como se conectar aos serviços em execução no cluster Kubernetes.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
No Kubernetes, todos nós, Pods e serviços têm seus próprios IPs. Em muitos casos, os IPs dos nós, dos Pods e alguns dos IPs de serviço em um cluster não serão
roteáveis, portanto, não estarão acessíveis a partir de uma máquina fora do cluster, como seu computador.
Maneiras de se conectar
Você tem várias opções para se conectar a nós, Pods e serviços de fora do cluster:
Acesse serviços através de IPs públicos.
Use um serviço com tipo NodePort ou LoadBalancer para tornar o serviço acessível fora do cluster. Consulte a documentação de serviços e
kubectl expose.
Dependendo do ambiente do cluster, isso pode expor o serviço apenas para a rede corporativa, ou pode expô-lo para a Internet. Pense se o serviço que está sendo exposto é seguro. Ele faz sua própria autenticação?
Coloque Pods atrás de serviços. Para acessar um Pod específico de um conjunto de réplicas, como para depurar, coloque uma label exclusiva no Pod e crie um novo serviço que selecione esta label.
Na maioria dos casos, não deve ser necessário para o desenvolvedor de aplicativos acessar diretamente nós através de seus endereços IP.
Acesse serviços, nós ou Pods usando o Verbo Proxy.
Faz autenticação e autorização do servidor de API antes de acessar o serviço remoto. Use isto se os serviços não forem seguros o suficiente para expor à Internet, ou para obter acesso a portas no IP do nó, ou para depuração.
Proxies podem causar problemas para algumas aplicações web.
Execute um Pod e, em seguida, conecte-se a um shell nele usando kubectl exec. Conecte-se a outros nós, Pods e serviços a partir desse shell.
Alguns clusters podem permitir que você faça ssh para um nó no cluster. De lá, você pode conseguir acessar os serviços do cluster. Este é um método que não é padrão e funcionará em alguns clusters, mas não em outros. Navegadores e outras ferramentas podem ou não estar instalados. O DNS do cluster pode não funcionar.
Descobrindo serviços integrados
Normalmente, existem vários serviços que são iniciados em um cluster pelo kube-system. Obtenha uma lista desses serviços com o comando kubectl cluster-info:
kubectl cluster-info
A saída é semelhante a esta:
Kubernetes master is running at https://192.0.2.1
elasticsearch-logging is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy
kibana-logging is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/kibana-logging/proxy
kube-dns is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/kube-dns/proxy
grafana is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/monitoring-grafana/proxy
heapster is running at https://192.0.2.1/api/v1/namespaces/kube-system/services/monitoring-heapster/proxy
Isso mostra a URL referente ao verbo proxy para acessar cada serviço. Por exemplo, este cluster tem os logs a nível de cluster habilitados (usando o Elasticsearch), que pode ser acessado em https://192.0.2.1/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/ se as credenciais adequadas forem passadas ou através do comando kubectl proxy, como por exemplo: http://localhost:8080/api/v1/namespaces/kube-system/services/elasticsearch-logging/proxy/.
Construindo manualmente URLs de proxy do servidor da API
Como mencionado acima, você usa o comando kubectl cluster-info para recuperar a URL do proxy do serviço. Para criar URLs de proxy que incluem endpoints, sufixos e parâmetros de serviço, você adiciona à URL do proxy do serviço:
http://endereço_do_mestre_do_kubernetes/api/v1/namespaces/nome_do_namespace/services/[https:]nome_do_serviço[:nome_da_porta]/proxy
Se você não especificou um nome para a porta, não é necessário especificar nome_da_porta na URL. Você também pode usar o número da porta no lugar do nome_da_porta para portas nomeadas e não nomeadas.
Por padrão, o servidor da API usa um proxy para o seu serviço através de HTTP. Para usar HTTPS, adicione o prefixo https: ao nome do serviço:
http://<endereço_do_mestre_do_kubernetes>/api/v1/namespaces/<nome_do_namespace>/services/<nome_do_serviço>/proxy
Os formatos suportados para o segmento <nome_do_serviço> da URL são:
<nome_do_serviço> - usa um proxy para a porta padrão ou não nomeada usando http
<nome_do_serviço>:<nome_da_porta> - usa um proxy para a porta nomeada ou número da porta especificado usando http
https:<nome_do_serviço>: - usa um proxy para a porta padrão ou não nomeada usando https (observe o dois-pontos no final)
https:<nome_do_serviço>:<nome_da_porta> - usa um proxy para a porta nomeada ou número da porta especificado usando https
Exemplos
Para acessar o endpoint de serviço Elasticsearch _search?q=user:kimchy, você usaria:
Usando navegadores da web para acessar serviços em execução no cluster
Você pode conseguir de colocar um URL de proxy do servidor da API na barra de endereço de um navegador. No entanto:
Os navegadores da web geralmente não podem passar tokens, portanto, você pode precisar usar autenticação básica (senha). O servidor da API pode ser configurado para aceitar autenticação básica, mas o seu cluster pode não estar configurado para aceitar autenticação básica.
Algumas aplicações da web podem não funcionar, principalmente aqueles com javascript do lado do cliente que constroem URLs com um mecanismo que não está ciente do prefixo do caminho do proxy.
4.7 - Configurar um provedor de credenciais de imagem para o kubelet
Configure o plugin de provedor de credenciais de imagem do kubelet
ESTADO DA FUNCIONALIDADE:Kubernetes v1.26 [stable]
A partir do Kubernetes v1.20, o kubelet pode obter dinamicamente as credenciais para um registro de imagem de contêiner usando plugins executáveis. O kubelet e o plugin executável se comunicam por meio de stdio (stdin, stdout e stderr) usando APIs versionadas do Kubernetes. Esses plugins permitem que o kubelet solicite credenciais para um registro de contêiner dinamicamente, em vez de armazenar credenciais estáticas no disco. Por exemplo, o plugin pode se comunicar com um servidor de metadados local para recuperar credenciais de curta duração para uma imagem que está sendo baixada pelo kubelet.
Você pode estar interessado em usar essa funcionalidade se alguma das condições abaixo for verdadeira:
Chamadas de API para um serviço de provedor de nuvem são necessárias para recuperar informações de autenticação para um registro.
As credenciais têm tempos de expiração curtos e é necessário solicitar novas credenciais com frequência.
Armazenar credenciais de registro no disco ou em imagePullSecrets não é aceitável.
Este guia demonstra como configurar o mecanismo de plugin do provedor de credenciais de imagem do kubelet.
Antes de você começar
Você precisa de um cluster Kubernetes com nós que suportem plugins de provedor de credenciais do kubelet. Esse suporte está disponível no Kubernetes 1.30; As versões v1.24 e v1.25 do Kubernetes incluíram isso como um recurso beta, ativado por padrão.
Uma implementação funcional de um plugin executável de provedor de credenciais. Você pode criar seu próprio plugin ou usar um fornecido por provedores de nuvem.
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.26.
Para verificar a versão, digite kubectl version.
Instalando Plugins nos Nós
Um plugin de provedor de credenciais é um binário executável que será executado pelo kubelet. Certifique-se de que o binário do plugin exista em cada nó do seu cluster e esteja armazenado em um diretório conhecido. O diretório será necessário posteriormente ao configurar as flags do kubelet.
Configurando o Kubelet
Para usar esse recurso, o kubelet espera que duas flags sejam definidas:
--image-credential-provider-config - o caminho para o arquivo de configuração do plugin de provedor de credenciais.
--image-credential-provider-bin-dir - o caminho para o diretório onde estão localizados os binários do plugin de provedor de credenciais.
Configurar um provedor de credenciais do kubelet
O arquivo de configuração passado para --image-credential-provider-config é lido pelo kubelet para determinar quais plugins executáveis devem ser invocados para quais imagens de contêiner. Aqui está um exemplo de arquivo de configuração que você pode acabar usando se estiver usando o plugin baseado no ECR:
apiVersion:kubelet.config.k8s.io/v1kind:CredentialProviderConfig# providers é uma lista de plug-ins auxiliares do provedor de credenciais que serão habilitados pelo kubelet.# Vários provedores podem corresponder a uma única imagem, caso em que as credenciais# de todos os provedores serão devolvidos ao kubelet. Se vários provedores forem chamados# para uma única imagem, os resultados são combinados. Se os provedores retornarem # chaves de autenticação sobrepostas, o valor do provedor anterior da lista é usado.providers:# name é o nome necessário do provedor de credenciais. Deve corresponder ao nome do# executável do provedor visto pelo kubelet. O executável deve estar no # diretório bin do kubelet (definido pela flag --image-credential-provider-bin-dir).- name:ecr# matchImages é uma lista obrigatória de strings usadas para corresponder às imagens para# determinar se este provedor deve ser invocado. Se uma das strings corresponder à# imagem solicitada do kubelet, o plug-in será invocado e terá uma chance# para fornecer credenciais. Espera-se que as imagens contenham o domínio de registro# e caminho da URL.## Cada entrada em matchImages é um padrão que pode opcionalmente conter uma porta e um caminho.# Globs podem ser usados no domínio, mas não na porta ou no caminho. Globs são suportados# como subdomínios como '*.k8s.io' ou 'k8s.*.io' e domínios de nível superior como 'k8s.*'.# A correspondência de subdomínios parciais como 'app*.k8s.io' também é suportada. Cada glob só pode corresponder# a um único segmento de subdomínio, então `*.io` **não** corresponde a `*.k8s.io`.## Existe uma correspondência entre uma imagem e uma matchImage quando todas as opções abaixo são verdadeiras:# - Ambos contêm o mesmo número de partes de domínio e cada parte faz correspondência.# - O caminho da URL de um matchImages deve ser um prefixo do caminho do URL da imagem de destino.# - Se matchImages contiver uma porta, a porta também deverá corresponder à imagem.## Valores de exemplo de matchImages:# - 123456789.dkr.ecr.us-east-1.amazonaws.com# - *.azurecr.io# - gcr.io# - *.*.registry.io# - Registry.io:8080/pathmatchImages:- "*.dkr.ecr.*.amazonaws.com"- "*.dkr.ecr.*.amazonaws.cn"- "*.dkr.ecr-fips.*.amazonaws.com"- "*.dkr.ecr.us-iso-east-1.c2s.ic.gov"- "*.dkr.ecr.us-isob-east-1.sc2s.sgov.gov"# defaultCacheDuration é a duração padrão em que o plug-in armazenará as credenciais na memória# se a duração do cache não for fornecida na resposta do plug-in. Este campo é obrigatório.defaultCacheDuration:"12h"# Versão de entrada necessária do exec CredentialProviderRequest. O CredentialProviderResponse retornado# DEVE usar a mesma versão de codificação da entrada. Os valores atualmente suportados são:# - credentialprovider.kubelet.k8s.io/v1apiVersion:credentialprovider.kubelet.k8s.io/v1# Argumentos para passar ao comando quando for executá-lo.# +optionalargs:- get-credentials# Env define variáveis de ambiente adicionais para expor ao processo. Esses valores# são combinados com o ambiente do host, bem como as variáveis que o client-go usa# para passar o argumento para o plugin.# +optionalenv:- name:AWS_PROFILEvalue:example_profile
O campo providers é uma lista de plugins habilitados usados pelo kubelet. Cada entrada tem alguns campos obrigatórios:
name: o nome do plugin que DEVE corresponder ao nome do binário executável que existe no diretório passado para --image-credential-provider-bin-dir.
matchImages: uma lista de strings usadas para comparar com imagens, a fim de determinar se este provedor deve ser invocado. Mais sobre isso abaixo.
defaultCacheDuration: a duração padrão em que o kubelet armazenará em cache as credenciais em memória, caso a duração de cache não tenha sido especificada pelo plugin.
apiVersion: a versão da API que o kubelet e o plugin executável usarão ao se comunicar.
Cada provedor de credenciais também pode receber argumentos opcionais e variáveis de ambiente. Consulte os implementadores do plugin para determinar qual conjunto de argumentos e variáveis de ambiente são necessários para um determinado plugin.
Configurar a correspondência de imagens
O campo matchImages de cada provedor de credenciais é usado pelo kubelet para determinar se um plugin deve ser invocado
para uma determinada imagem que um Pod está usando. Cada entrada em matchImages é um padrão de imagem que pode opcionalmente conter uma porta e um caminho.
Globs podem ser usados no domínio, mas não na porta ou no caminho. Globs são suportados como subdomínios como *.k8s.io ou k8s.*.io,
e domínios de nível superior como k8s.*. Correspondência de subdomínios parciais como app*.k8s.io também é suportada. Cada glob só pode corresponder
a um único segmento de subdomínio, então *.io NÃO corresponde a *.k8s.io.
Uma correspondência existe entre um nome de imagem e uma entrada matchImage quando todos os itens abaixo são verdadeiros:
Ambos contêm o mesmo número de partes de domínio e cada parte corresponde.
O caminho da URL da imagem correspondente deve ser um prefixo do caminho da URL da imagem de destino.
Se o matchImages contiver uma porta, então a porta deve corresponder na imagem também.
Alguns valores de exemplo de padrões matchImages são:
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
O administrador do cluster está operando um cluster em nome de uma população de usuários e o administrador quer controlar quanto armazenamento um único namespace pode consumir para controlar custos.
O administrador gostaria de limitar:
O número de persistent volume claims em um namespace
A quantidade de armazenamento que cada claim pode solicitar
A quantidade total de armazenamento que o namespace pode ter.
LimitRange para limitar solicitações de armazenamento
Adicionar um LimitRange a um namespace impõe tamanhos mínimos e máximos para solicitações de armazenamento. O armazenamento é solicitado através do PersistentVolumeClaim. O controlador de admissão que impõe os limites rejeitará qualquer PVC que esteja acima ou abaixo dos valores definidos pelo administrador.
Neste exemplo, um PVC que solicita 10Gi de armazenamento seria rejeitado porque excede o limite máximo de 2Gi.
As requisições de armazenamento mínimas são usadas quando o provedor de armazenamento subjacente exige certos valores mínimos. Por exemplo, os volumes do AWS EBS têm um requisito mínimo de 1 Gi.
StorageQuota para limitar a quantidade de PVC e a capacidade de armazenamento cumulativa
Os administradores podem limitar o número de PVCs em um namespace, bem como a capacidade cumulativa desses PVCs. Novos PVCs que excedam qualquer um desses valores máximos serão rejeitados.
Neste exemplo, o sexto PVC no namespace seria rejeitado porque excede a contagem máxima de 5. Alternativamente, uma cota máxima de 5Gi, combinada com o limite máximo de 2Gi acima, não pode ter 3 PVCs, cada um com 2Gi. Isso seria um total de 6Gi solicitados para um namespace limitado a 5Gi.
Um LimitRange pode colocar um limite na quantidade de armazenamento solicitado enquanto um ResourceQuota pode efetivamente limitar o armazenamento consumido por um namespace através do número de claims e da capacidade de armazenamento cumulativa. Isso permite que um administrador do cluster planeje o custo de armazenamento do seu cluster sem risco de qualquer projeto exceder sua cota.
4.9 - Personalizando o Serviço DNS
Essa página explica como configurar os seus Pod(s) de DNS
e personalizar o processo de resolução de DNS no seu cluster.
Antes de você começar
Você precisa ter um cluster do Kubernetes e a ferramenta de linha de comando kubectl deve estar configurada para se comunicar com seu cluster. É recomendado executar esse tutorial em um cluster com pelo menos dois nós que não estejam atuando como hosts de camada de gerenciamento. Se você ainda não possui um cluster, pode criar um usando o minikube ou pode usar um dos seguintes ambientes:
Seu cluster deve estar executando o complemento CoreDNS.
O seu servidor Kubernetes deve estar numa versão igual ou superior a v1.12.
Para verificar a versão, digite kubectl version.
Introdução
DNS é um serviço integrado do Kubernetes que é iniciado automaticamente usando o gerenciador de complementoscluster add-on.
Nota:
O Service CoreDNS é chamado de kube-dns no campo metadata.name.
O objetivo é garantir maior interoperabilidade com cargas de trabalho que dependiam do nome de serviço legado kube-dns para resolver endereços internos ao cluster.
Usando o service chamado kube-dns abstrai o detalhe de implementação de qual provedor de DNS está sendo executado por trás desse nome comum.
Se você estiver executando o CoreDNS como um Deployment, ele geralmente será exposto como um service do Kubernetes com o endereço de IP estático.
O kubelet passa informações de resolução de DNS para cada contêiner com a flag --cluster-dns=<dns-service-ip>.
Os nomes DNS também precisam de domínios. Você configura o domínio local no kubelet com a flag --cluster-domain=<default-local-domain>.
O servidor DNS suporta pesquisas de encaminhamento (registros A e AAAA), pesquisas de porta (registros SRV), pesquisas de endereço de IP reverso (registros PTR) e muito mais. Para mais informações, veja DNS para Serviços e Pods.
Se a dnsPolicy de um Pod estiver definida como default, ele herda a configuração de resolução de nome do nó em que o Pod é executado. A resolução de DNS do Pod deve se comportar da mesma forma que o nó.
Veja Problemas conhecidos.
Se você não quiser isso, ou se quiser uma configuração de DNS diferente para os pods, pode usar a flag --resolv-conf do kubelet. Defina essa flag como "" para impedir que os Pods herdem a configuração do DNS. Defina-a como um caminho de arquivo válido para especificar um arquivo diferente de /etc/resolv.conf para a herança de DNS.
CoreDNS
CoreDNS é um servidor oficial de DNS de propósito geral que pode atuar como DNS do cluster,
cumprindo com as especificações DNS.
Opções CoreDNS ConfigMap options
CoreDNS é um servidor DNS que é modular e plugável, com plugins que adicionam novas funcionalidades.
O servidor CoreDNS pode ser configurado por um Corefile,
que é o arquivo de configuração do CoreDNS. Como administrador de cluster, você pode modificar o
ConfigMap que contém o arquivo Corefile do CoreDNS para
mudar como o descoberta de serviços DNS se comporta para esse cluster.
No Kubernetes, o CoreDNS é instalado com a seguinte configuração padrão do Corefile:
health: A integridade do CoreDNS é reportada para
http://localhost:8080/health. Nesta sintaxe estendida, lameduck marcará o processo como não-íntegro, esperando por 5 segundos antes que o processo seja encerrado.
ready: Um endpoint HTTP na porta 8181 retornará 200 OK, quando todos os plugins que são capazes de sinalizar prontidão tiverem feito isso.
kubernetes: O CoreDNS responderá a consultas DNS
baseado no IP dos Serviços e Pods. Você pode encontrar mais detalhes sobre este plugin no site do CoreDNS.
ttl permite que você defina um TTL personalizado para as respostas. O padrão é 5 segundos. O TTL mínimo permitido é de 0 segundos e o máximo é de 3600 segundos. Definir o TTL como 0 impedirá que os registros sejam armazenados em cache.
A opção pods insecure é fornecida para retrocompatibilidade com o kube-dns.
Você pode usar a opção pods verified, que retorna um registro A somente se houver um Pod no mesmo namespace com um IP correspondente.
A opção pods disabled pode ser usada se você não usar registros de Pod.
prometheus: As métricas do CoreDNS ficam disponíveis em http://localhost:9153/metrics seguindo o formato Prometheus, também conhecido como OpenMetrics.
forward: Qualquer consulta que não esteja no domínio do cluster do Kubernetes é encaminhada para resolutores predefinidos (/etc/resolv.conf).
loop: Detecta loops de encaminhamento simples e interrompe o processo do CoreDNS se um loop for encontrado.
reload: Permite a recarga automática de um Corefile que foi alterado.
Depois de editar a configuração do ConfigMap, é necessario dois minutos para que as alterações entrem em vigor.
loadbalance: Este é um balanceador de carga DNS round-robin que randomiza a ordem dos registros A, AAAA e MX na resposta.
Você pode modificar o comportamento padrão do CoreDNS modificando o ConfigMap.
Configuração de domínio Stub e upstream nameserver usando o CoreDNS
O CoreDNS tem a capacidade de configurar domínios Stub e upstream nameservers usando o plugin forward.
Exemplo
Se um operador de cluster possui um servidor de domínio Consul localizado em "10.150.0.1"
e todos os nomes Consul possuem o sufixo ".consul.local". Para configurá-lo no CoreDNS,
o administrador do cluster cria a seguinte entrada no ConfigMap do CoreDNS.
Para forçar explicitamente que todas as pesquisas de DNS fora do cluster passem por um nameserver específico em 172.16.0.1, aponte o forward para o nameserver em vez de /etc/resolv.conf.
forward . 172.16.0.1
O ConfigMap final, juntamente com a configuração padrão do Corefile, é:
O CoreDNS não suporta FQDNs para domínios Stub e nameservers (por exemplo, "ns.foo.com"). Durante a tradução, todos os nameservers FQDN serão omitidos da configuração do CoreDNS.
Essa seção da documentação contém tutoriais. Um tutorial demonstra como realizar
um objetivo mais complexo que uma simples tarefa. Tipicamente,
um tutorial é dividido em várias seções, em que cada seção tem uma sequência de
passos.
Antes de iniciar um tutorial, é interessante que você salve a página do
Glossário Padronizado para futuras referências.
Noções Básicas
Noções Básicas do Kubernetes é um
tutorial interativo que auxilia no entendimento do ecossistema Kubernetes, bem
como permite testar algumas funcionalidades básicas do Kubernetes.
Se você desejar escrever um tutorial, consulte a documentação de
Tipos de Página de Conteúdo
para informações sobre o tipo de página de tutorial.
5.1 - Olá, Minikube!
Este tutorial demonstra como executar uma aplicação exemplo no Kubernetes utilizando
o minikube.
O tutorial fornece uma imagem de contêiner que utiliza o NGINX para repetir todas
as requisições.
Objetivos
Instalar uma aplicação exemplo no minikube.
Executar a aplicação.
Visualizar os logs da aplicação.
Antes de você começar
Este tutorial assume que você já tem uma instância do minikube configurada.
Veja minikube start para instruções
de como instalar.
Você também irá precisar instalar o kubectl.
Veja instalando ferramentas para instruções de como
instalar.
Criando um cluster do minikube
minikube start
Abra o painel (dashboard)
Abra o painel (dashboard) do Kubernetes. Você pode fazer isso de duas formas
distintas:
# Inicie um novo terminal e deixe este comando rodando.minikube dashboard
Agora, retorne para o terminal onde você executou o comando minikube start.
Nota:
O comando dashboard habilita o complemento do painel e abre o proxy no navegador
padrão. Você pode criar recursos do Kubernetes no painel, como Deployment e
Service.
Se você estiver executando num ambiente com o usuário root, veja
Abrir o Painel com URL.
Por padrão, o painel só é acessível pela rede virtual interna do Kubernetes. O
comando dashboard cria um proxy temporário para tornar o painel acessível por
fora da rede virtual do Kubernetes.
Para parar o proxy, utilize o comando Ctrl+C para encerrar o processo.
Após o término do comando, o painel permanece executando no cluster do Kubernetes.
Você pode executar o comando dashboard novamente para criar outro proxy para
acessar o painel.
Se você não deseja que o minikube abra um navegador para você, rode o comando
dashboard com a opção de linha de comando --url. O minikube irá imprimir
uma URL que você poderá abrir no navegador de sua preferência.
Abra um novo terminal e rode o comando:
# Inicie um novo terminal e deixe este comando rodando.minikube dashboard --url
Agora, retorne para o terminal onde você executou o comando minikube start.
Criando um Deployment
Um Pod do Kubernetes consiste em um ou mais
contêineres agrupados para fins de administração e gerenciamento de rede. O Pod
deste tutorial possui apenas um contêiner. Um
Deployment do Kubernetes
verifica a integridade do seu Pod e reinicia o contêiner do Pod caso este seja
finalizado. Deployments são a maneira recomendada de gerenciar a criação e
escalonamento dos Pods.
Usando o comando kubectl create para criar um Deployment que gerencia um Pod.
O Pod executa um contêiner baseado na imagem do Docker disponibilizada.
Por padrão, um Pod só é acessível utilizando o seu endereço IP interno no cluster
Kubernetes. Para dispobiblilizar o contêiner hello-node fora da rede virtual do
Kubernetes, você deve expor o Pod como um
Service do Kubernetes.
O parâmetro --type=LoadBalancer indica que você deseja expor o seu serviço
fora do cluster Kubernetes.
A aplicação dentro da imagem de teste escuta apenas na porta TCP 8080. Se
você usou kubectl expose para expor uma porta diferente, os clientes não
conseguirão se conectar a essa outra porta.
Visualize o serviço que você acabou de criar:
kubectl get services
A saída será semelhante a:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
Em provedores de nuvem que fornecem serviços de balanceamento de carga para
o Kubernetes, um IP externo seria provisionado para acessar o serviço. No
minikube, o tipo LoadBalancer torna o serviço acessível por meio do comando
minikube service.
Execute o comando a seguir:
minikube service hello-node
Este comando abre uma janela do navegador que serve o seu aplicativo e exibe
o retorno da requisição ao aplicativo.
Habilitando Complementos (addons)
A ferramenta minikube inclui um conjunto integrado de complementos
que podem ser habilitados, desabilitados e executados no ambiente Kubernetes local.
Os tutoriais interativos neste website estão sendo encerrados. O projeto
Kubernetes espera oferecer uma experiência interativa de aprendizagem semelhante
no futuro.
O encerramento segue a aquisição
do Katacoda pela O'Reilly Media em 2019.
O projeto Kubernetes é grato à O'Reilly e ao Katacoda pelos vários anos de
auxílio às pessoas dando seus primeiros passos nas suas jornadas de aprendizagem
do Kubernetes.
Este tutorial fornece instruções básicas sobre o sistema de orquestração
de cluster do Kubernetes. Cada módulo contém algumas informações básicas
sobre os principais recursos e conceitos do Kubernetes e inclui um tutorial
online interativo. Esses tutoriais interativos permitem que você mesmo
gerencie um cluster simples e seus aplicativos em contêineres.
Usando os tutoriais interativos, você pode aprender a:
Implantar um aplicativo em contêiner em um cluster.
Dimensionar a implantação.
Atualizar o aplicativo em contêiner com uma nova versão do software.
Depurar o aplicativo em contêiner.
Os tutoriais usam Katacoda para executar um terminal virtual em seu navegador da Web, executado em Minikube, uma implantação local em pequena escala do Kubernetes que pode ser executada em qualquer lugar. Não há necessidade de instalar nenhum software ou configurar nada; cada tutorial interativo é executado diretamente no navegador da web.
O que o Kubernetes pode fazer por você?
Com os serviços da Web modernos, os usuários esperam que os aplicativos estejam disponíveis 24 horas por dia, 7 dias por semana, e os desenvolvedores esperam implantar novas versões desses aplicativos várias vezes ao dia. A conteinerização ajuda a empacotar o software para atender a esses objetivos, permitindo que os aplicativos sejam lançados e atualizados de maneira fácil e rápida, sem tempo de inatividade. O Kubernetes ajuda a garantir que esses aplicativos em contêiner sejam executados onde e quando você quiser e os ajuda a encontrar os recursos e ferramentas de que precisam para funcionar. Kubernetes é uma plataforma de código aberto pronta para produção, projetada com a experiência acumulada do Google em orquestração de contêineres, combinada com as melhores idéias da comunidade.
Aprenda sobre clusters
do Kubernetes e crie um cluster simples utilizando o Minikube.
5.2.1.1 - Usando Minikube para criar um cluster
Aprenda o que é um cluster do Kubernetes.
Aprenda o que é Minikube.
Inicialize um cluster do Kubernetes.
Objetivos
Aprenda o que é um cluster do Kubernetes.
Aprenda o que é Minikube.
Inicialize um cluster Kubernetes no seu computador.
Clusters do Kubernetes
O Kubernetes coordena um cluster de computadores de alta
disponibilidade, conectados para funcionar como uma única unidade.
As abstrações no Kubernetes permitem implantar aplicativos em
contêineres em um cluster sem vinculá-los especificamente à uma
máquina individual. Para fazer uso desse novo modelo de
implantação, os aplicativos precisam ser empacotados de uma
forma que os desacoplem dos hosts individuais: eles
precisam ser empacotados em contêineres. Os aplicativos em
contêineres são mais flexíveis e disponíveis do que nos modelos
de implantação anteriores, nos quais os aplicativos eram
instalados diretamente em máquinas específicas como pacotes
profundamente integrados ao host.
O Kubernetes automatiza a distribuição e o agendamento de
contêineres de aplicativos em um cluster de maneira mais eficiente.
O Kubernetes é uma plataforma de código aberto e está pronto para
produção.
Um cluster Kubernetes consiste em dois tipos de recursos:
A Camada de Gerenciamento (Control Plane)
coordena o cluster
Os Nós (Nodes) são as máquinas de processamento
que executam aplicativos
Resumo:
Cluster do Kubernetes
Minikube
O Kubernetes é uma plataforma de código aberto de nível
de produção que orquestra a alocação e a execução de
contêineres de aplicativos dentro de e entre clusters de
computadores.
Diagrama do Cluster
A camada de gerenciamento é responsável por gerenciar o cluster.
A camada de gerenciamento coordena todas as atividades em seu
cluster, como a alocação de aplicativos, manutenção do estado
desejado dos aplicativos, escalonamento de aplicativos e lançamento
de novas atualizações.
Um nó é uma máquina virtual ou um computador físico que atua
como um nó de processamento em um cluster Kubernetes.
Cada nó tem um Kubelet, que é um agente para gerenciar o nó e
comunicar-se com a camada de gerenciamento do Kubernetes. O nó
também deve ter ferramentas para gerenciar operações de contêiner,
como containerd ou Docker. Um cluster Kubernetes que lida com
o tráfego de produção deve ter no mínimo três nós, pois se um
dos nós tornar-se indisponível, um membro do
etcd
e um nó da camada de gerenciamento serão perdidos, comprometendo
a redundância. Você pode mitigar este risco aumentando o número
de nós da camada de gerenciamento.
A camada de gerenciamento gerencia o cluster e os nós que
são usados para hospedar os aplicativos em execução.
Ao implantar aplicativos no Kubernetes, você solicita que a camada
de gerenciamento inicie os contêineres de aplicativos. A camada
de gerenciamento aloca os contêineres para serem executados nos
nós do cluster.
Os nós se comunicam com a camada de gerenciamento usando a
API do Kubernetes, que a camada de gerenciamento expõe. Os usuários finais
também podem usar a API do Kubernetes diretamente para interagir
com o cluster.
Um cluster do Kubernetes pode ser implantado em máquinas físicas
ou virtuais. Para começar a ambientar-se com desenvolvimento de
aplicações para o Kubernetes, você pode usar o Minikube. O
Minikube é uma implementação leve do Kubernetes que cria uma
VM em sua máquina local e implanta um cluster simples contendo
apenas um nó. O Minikube está disponível para sistemas Linux,
macOS e Windows. O utilitário de linha de comando (CLI)
do Minikube fornece operações básicas de inicialização para
trabalhar com seu cluster, incluindo iniciar, parar, status e
excluir.
Agora que você sabe mais sobre o que é Kubernetes, visite
Olá, Minikube!
para testar as operações no seu computador.
Aprenda sobre objetos Deployment do Kubernetes.
Implante seu primeiro aplicativo no Kubernetes utilizando o kubectl.
Objetivos
Saiba mais sobre implantações de aplicativos.
Implante seu primeiro aplicativo no Kubernetes com o kubectl.
Deployments do Kubernetes
Assim que o seu cluster
Kubernetes estiver em execução você pode implantar seu aplicativo
contêinerizado nele.
Para fazer isso, você precisa criar um objeto Deployment do Kubernetes.
O Deployment instrui o Kubernetes sobre como criar e atualizar instâncias
do seu aplicativo. Depois de criar um Deployment, a camada de gerenciamento
do Kubernetes aloca as instâncias do aplicativo incluídas nesse Deployment
para serem executadas em nós individuais do cluster.
Depois que as instâncias do aplicativo são criadas, o controlador de
Deployment do Kubernetes monitora continuamente essas instâncias.
Se o nó em que uma instância está alocada ficar indisponível ou for
excluído, o controlador de Deployment substituirá a instância por uma
instância em outro nó no cluster.
Isso fornece um mecanismo de autocorreção para lidar com falhas ou
manutenção da máquina.
Em um mundo de pré-orquestração, os scripts de instalação eram utilizados
para iniciar aplicativos, mas não permitiam a recuperação de falha da máquina.
Ao criar suas instâncias de aplicativo e mantê-las em execução entre nós,
os Deployments do Kubernetes fornecem uma abordagem fundamentalmente
diferente para o gerenciamento de aplicativos.
Resumo:
Deployments
Kubectl
O objeto Deployment é responsável por criar e atualizar instâncias
de seu aplicativo
Implante seu primeiro aplicativo no
Kubernetes
Você pode criar e gerenciar uma implantação usando a interface
de linha de comando do Kubernetes, o kubectl.
O kubectl usa a API do Kubernetes para interagir com o cluster.
Neste módulo, você aprenderá os comandos Kubectl mais comuns
necessários para criar Deployments que executam seus aplicativos
em um cluster Kubernetes.
Quando você cria um Deployment, você precisa especificar a imagem
de contêiner para seu aplicativo e o número de réplicas que deseja executar.
Você pode alterar essas informações posteriormente, atualizando seu Deployment;
os Módulos 5
e 6
do bootcamp explicam como você pode dimensionar e atualizar seus Deployments.
Os aplicativos precisam ser empacotados em um dos formatos de
contêiner suportados para serem implantados no Kubernetes
Para criar seu primeiro Deployment, você usará o aplicativo hello-node
empacotado em um contêiner que utiliza o NGINX para repetir todas as requisições.
(Se você ainda não tentou criar o aplicativo hello-node e implantá-lo
usando um contêiner, você pode fazer isso primeiro seguindo as
instruções do tutorial Olá, Minikube!).
Você precisará ter o kubectl instalado também. Se você precisar de
instruções de instalação, veja
instalando ferramentas.
Agora que você já sabe o que são Deployments, vamos implantar
nosso primeiro aplicativo!
Noções básicas do kubectl
O formato comum de um comando kubectl é: kubectl ação recurso
Isto executa a ação especificada (como por exemplo create,
describe ou delete) no recurso
especificado (por exemplo, node ou deployment).
Você pode utilizar --help após o subcomando
para obter informações adicionais sobre parâmetros permitidos
(por exemplo, kubectl get nodes --help).
Verifique que o kubectl está configurado para comunicar-se com seu
cluster rodando o comando kubectl version.
Certifique-se de que o kubectl está instalado e que você consegue ver
as versões do cliente e do servidor.
Para visualizar os nós do cluster, execute o comando kubectl
get nodes.
Você verá os nós disponíveis. Posteriormente, o Kubernetes irá escolher
onde implantar nossa aplicação baseado nos recursos disponíveis nos nós.
Implante uma aplicação
Vamos implantar nossa primeira aplicação no Kubernetes utilizando
o comando kubectl create deployment. Precisaremos
fornecer o nome do Deployment e a localização da imagem de contêiner
do aplicativo (inclua a URL completa do repositório para images
hospedadas fora do Docker Hub).
Excelente! Você acabou de implantar sua primeira aplicação através
da criação de um Deployment. Este comando efetuou algumas ações
para você:
buscou um nó utilizável onde a instância da aplicação pode ser executada
(temos somente um nó disponível)
alocou a aplicação para rodar naquele nó
configurou o cluster para realocar a instância em um novo nó sempre
que necessário
Para listar seus Deployments existentes, utilize o comando
kubectl get deployments:
kubectl get deployments
Podemos observar que há um Deployment rodando uma única instância
da sua aplicação. A instância está executando dentro de um contêiner
no seu nó.
Visualize o aplicativo
Pods que rodam dentro do Kubernetes estão rodando em uma rede privada e isolada.
Por padrão, eles são visíveis a outros Pods e Services dentro do mesmo
cluster do Kubernetes, mas não de fora daquela rede.
Ao usarmos kubectl, estamos interagindo através de um
endpoint de API para comunicar-nos com a nossa aplicação.
Iremos discutir outras opções de como expor sua aplicação fora do
cluster do Kubernetes no Módulo 4.
O comando kubectl pode criar um proxy que encaminha
comunicações para dentro da rede privada que engloba todo o cluster. O
proxy pode ser encerrado utilizando a sequência control-C e não irá
imprimir nenhum tipo de saída enquanto estiver rodando.
Você precisa abrir uma segunda janela do terminal para executar
o proxy.
kubectl proxy
Agora temos uma conexão entre nosso host (o terminal online) e o
cluster do Kubernetes. O proxy habilita acesso direto à API através
destes terminais.
Você pode ver todas as APIs hospedadas através do endpoint do
proxy. Por exemplo, podemos obter a versão diretamente através da API
utilizando o comando curl:
curl http://localhost:8001/version
Nota: se a porta 8001 não estiver acessível, certifique-se
de que o comando kubectl proxy que você iniciou acima está
rodando no segundo terminal.
O servidor da API irá automaticamente criar um endpoint para cada
Pod, baseado no nome do Pod, que também estará acessível através do proxy.
Primeiro, precisaremos obter o nome do Pod. Iremos armazená-lo na
variável de ambiente POD_NAME:
export POD_NAME=$(kubectl get pods -o go-template --template
'{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}') echo Nome do Pod: $POD_NAME
Você pode acessar o Pod através da API encaminhada, rodando o comando:
Aprenda como depurar aplicações do Kubernetes utilizando
kubectl get, kubectl describe, kubectl logs e
kubectl exec.
Objetivos
Aprenda sobre Pods do Kubernetes.
Aprenda sobre Nós do Kubernetes.
Solucione problemas de aplicativos implantados no Kubernetes.
Kubernetes Pods
Quando você criou um Deployment no Módulo
2,
o Kubernetes criou um Pod para hospedar a instância do
seu aplicativo. Um Pod é uma abstração do Kubernetes que representa
um grupo de um ou mais contêineres de aplicativos (como Docker)
e alguns recursos compartilhados para esses contêineres. Esses
recursos incluem:
Armazenamento compartilhado, como Volumes
Rede, como um endereço IP único no cluster
Informações sobre como executar cada contêiner, como a
versão da imagem do contêiner ou portas específicas a serem
usadas
Um Pod define um "host lógico" específico para o aplicativo e
pode conter diferentes contêineres de aplicativos que, na maioria
dos casos, são fortemente acoplados. Por exemplo, um Pod pode
incluir tanto o contêiner com seu aplicativo Node.js quanto um
outro contêiner que alimenta os dados a serem publicados pelo
servidor web do Node.js. Os contêineres de um Pod compartilham
um endereço IP e intervalo de portas, são sempre co-localizados,
co-alocados e executam em um contexto compartilhado no mesmo Nó.
Pods são a unidade atômica na plataforma Kubernetes. Quando
criamos um Deployment no Kubernetes, esse Deployment cria Pods
com contêineres dentro dele (em vez de você criar contêineres
diretamente). Cada Pod está vinculado ao nó onde está alocado
e lá permanece até o encerramento (de acordo com a política de
reinicialização) ou exclusão. Em caso de falha do nó, Pods
idênticos são alocados em outros nós disponíveis no cluster.
Sumário:
Pods
Nós
Principais comandos do Kubectl
Um Pod é um grupo de um ou mais contêineres de
aplicativos (como Docker) que inclui armazenamento
compartilhado (volumes), endereço IP e informações
sobre como executá-los.
Visão geral sobre os Pods
Nós
Um Pod sempre será executado em um Nó. Um Nó é uma
máquina de processamento em um cluster Kubernetes e pode ser
uma máquina física ou virtual. Cada Nó é gerenciado pela
Camada de Gerenciamento. Um Nó pode possuir múltiplos Pods e a
Camada de Gerenciamento do Kubernetes gerencia automaticamente
a alocação dos Pods nos nós do cluster. A alocação automática
dos Pods pela Camada de Gerenciamento leva em consideração os
recursos disponíveis em cada Nó.
Cada Nó do Kubernetes executa pelo menos:
O Kubelet, que é o processo responsável pela comunicação entre a
Camada de Gerenciamento e o Nó; gerencia os Pods e os contêineres
rodando em uma máquina.
Um agente de execução de contêiner (por exemplo, Docker)
responsável por baixar a imagem do contêiner de um registro
de imagens (por exemplo, o Docker Hub),
extrair o contêiner e executar a aplicação.
Os contêineres só devem ser alocados juntos em um único Pod se
estiverem fortemente acoplados e precisarem compartilhar recursos,
como disco, por exemplo.
Visão Geral sobre os Nós
Solucionando problemas usando o comando kubectl
No Módulo 2,
você usou a ferramenta de linha de comando kubectl. Você irá continuar
utilizando o kubectl no Módulo 3 para obter informação sobre aplicações
implantadas e seus recursos. As operações mais comuns podem ser
efetuadas com os comandos abaixo:
kubectl get - listar recursos
kubectl describe - mostrar informações detalhadas sobre um recurso
kubectl logs - mostrar os logs de um contêiner em um Pod
kubectl exec - executar um comando em um contêiner em um Pod
Você pode usar esses comandos para verificar quando o Deployment foi
criado, qual seu status atual, onde os Pods estão rodando e quais são
as suas configurações.
Agora que sabemos mais sobre os componentes de um cluster Kubernetes
e o comando kubectl, vamos explorar a nossa aplicação.
Um nó é uma máquina de processamento do Kubernetes e pode ser
uma VM ou máquina física, dependendo do cluster. Vários Pods
podem ser executados em um nó.
Verifique a configuração da aplicação
Vamos verificar que a aplicação que implantamos no cenário anterior
está executando. Iremos utilizar o comando kubectl get
e procurar por Pods existentes:
kubectl get pods
Se nenhum Pod estiver rodando, aguarde alguns instantes e liste os
Pods novamente. Você pode continuar assim que ver um Pod rodando.
A seguir, para visualizar quais contêineres encontram-se no Pod e quais
imagens foram utilizadas para criar tais contêineres iremos usar o
comando kubectl describe pods:
kubectl describe pods
Vemos aqui detalhes a respeito dos contêineres do Pod: endereço IP,
portas utilizadas e uma lista de eventos relacionados ao ciclo de vida
do Pod.
A saída do subcomando describe é extensa e cobre alguns
conceitos que não foram explicados ainda. Não se preocupe, estes
conceitos serão familiares até o fim deste bootcamp.
Nota: o subcomando describe pode ser utilizado
para obter informações detalhadas sobre a maioria das primitivas do
Kubernetes, incluindo Nós (Nodes), Pods e Deployments. A saída do
subcomando describe é projetada para ser legível por humanos,
não para ser consumida por processos automatizados.
Exiba a aplicação no terminal
Lembre-se que Pods estão executando em uma rede isolada e privada -
portanto, precisaremos de um proxy para acessá-los, a fim de tornar
possível a depuração e a interação com estes objetos. Para inicializar
um proxy, utilizaremos o comando kubectl proxy em um
segundo terminal. Abra uma nova janela do terminal,
e nesta nova janela, execute o comando:
kubectl proxy
Agora iremos novamente obter o nome do Pod e obter informações do Pod
diretamente através do proxy. Para obter o nome do Pod e armazená-lo
na variável de ambiente POD_NAME, utilize o comando:
export POD_NAME="$(kubectl get pods -o go-template --template
'{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')" echo Nome do Pod: $POD_NAME
Para ver a saída da aplicação, execute uma requisição com o comando
curl:
Qualquer mensagem que normalmente seria impressa na saída padrão (stdout)
torna-se parte do log do contêiner dentro do Pod. Podemos obter tais
logs utilizando o comando kubectl logs:
kubectl logs "$POD_NAME"
Nota: não é necessário especificarmos o nome do
contêiner pois temos apenas um contêiner neste Pod.
Executando comandos no contêiner
Podemos executar comandos diretamente no contêiner uma vez que o
Pod esteja criado e rodando. Para isso, utilizaremos o subcomando
exec e o nome do Pod como um parâmetro. Vamos listar
as variáveis de ambiente:
kubectl exec "$POD_NAME" -- env
Novamente, vale a pena mencionar que o nome do contêiner pode ser
omitido pois temos apenas um contêiner no Pod.
A seguir, vamos iniciar uma sessão do bash no contêiner do Pod:
kubectl exec -ti $POD_NAME -- bash
Agora temos um terminal aberto no contêiner onde nossa aplicação
Node.js está executando. O código-fonte da aplicação encontra-se
no arquivo server.js:
cat server.js
Você pode verificar que a aplicação está rodando utilizando uma
requisição com o comando curl:
curl http://localhost:8080
Nota: aqui utilizamos localhost pois
executamos o comando dentro do Pod do Node.js. Se você não conseguir
conectar-se a localhost:8080, certifique-se de que você utilizou
o comando kubectl exec e que está rodando a requisição
curl de dentro do Pod.
Para encerrar sua conexão ao contêiner, digite exit.
5.2.4.1 - Utilizando um serviço para expor seu aplicativo
Aprenda sobre Services no Kubernetes.
Entenda como rótulos (labels) e seletores (selectors) relacionam-se aos Services.
Exponha uma aplicação externamente ao cluster Kubernetes.
Objetivos
Aprenda sobre Services no Kubernetes
Entenda como rótulos (labels) e seletores (selectors) relacionam-se aos Services
Exponha uma aplicação externamente ao cluster Kubernetes usando um Service
Visão Geral dos Services no Kubernetes
Pods do Kubernetes são efêmeros.
Na verdade, Pods possuem um ciclo de vida.
Quando um nó de processamento morre, os Pods executados no nó também são
perdidos. A partir disso, o ReplicaSet
pode dinamicamente retornar o cluster ao estado desejado através da criação
de novos Pods para manter sua aplicação em execução. Como outro exemplo,
considere um backend de processamento de imagens com 3 réplicas. Estas
réplicas são permutáveis; o sistema front-end não deveria se importar
com as réplicas backend ou ainda se um Pod foi perdido ou recriado. Dito
isso, cada Pod em um cluster Kubernetes tem um endereço IP único, incluindo
Pods que estejam rodando no mesmo nó, então há necessidade de ter uma
forma de reconciliar automaticamente mudanças entre Pods de modo que sua
aplicação continue funcionando.
Um objeto Service no Kubernetes é uma abstração que define um conjunto
lógico de Pods e uma política pela qual acessá-los. Serviços permitem um
baixo acoplamento entre os Pods dependentes. Um serviço é definido usando
YAML ou JSON, como todos os manifestos de objetos Kubernetes. O conjunto
de Pods selecionados por um Service é geralmente determinado por um
seletor de rótulos (veja abaixo o motivo pelo qual você poderia
desejar um Service que não inclui um seletor (selector) na
especificação (spec)).
Embora cada Pod tenha um endereço IP único, estes IPs não são expostos
externamente ao cluster sem um objeto Service. Objetos Service permitem
que suas aplicações recebam tráfego. Services podem ser expostos de
formas diferentes especificando um tipo (campo type) na
especificação do serviço (campo spec):
ClusterIP (padrão) - Expõe o serviço sob um endereço IP interno
no cluster. Este tipo de serviço é acessível somente dentro do cluster.
NodePort - Expõe o serviço sob a mesma porta em cada nó
selecionado no cluster usando NAT. Torna o serviço acessível externamente
ao cluster usando o endereço <NodeIP>:<NodePort>.
É um superconjunto do tipo ClusterIP.
LoadBalancer - Cria um balanceador de carga externo no provedor
de nuvem atual (se suportado) e atribui um endereço IP fixo e externo
para o serviço. É um superconjunto do tipo NodePort.
ExternalName - Mapeia o Service para o conteúdo do campo
externalName (por exemplo, foo.bar.example.com),
retornando um registro DNS do tipo CNAME com o seu valor.
Nenhum tipo de proxy é configurado. Este tipo requer a versão 1.7 ou
mais recente do kube-dns, ou o CoreDNS versão 0.0.8 ou
superior.
Adicionalmente, note que existem alguns casos de uso com serviços que
envolvem a ausência de um selector no campo spec.
Services criados sem selector também não criarão objetos
Endpoints correspondentes. Isto permite que usuários mapeiem manualmente
um serviço a endpoints específicos. Outro motivo pelo qual seletores
podem estar ausentes é que você esteja utilizando estritamente
type: ExternalName.
Resumo
Exposição de Pods ao tráfego externo
Balanceamento de carga de tráfego entre múltiplos Pods
Utilização de rótulos (labels)
Um objeto Service do Kubernetes é uma camada de abstração que define
um conjunto lógico de Pods e habilita a exposição ao tráfego externo,
balanceamento de carga e descoberta de serviço para esses Pods.
Serviços e Rótulos
Um Service roteia tráfego entre um conjunto de Pods. Service é a
abstração que permite Pods morrerem e se replicarem no Kubernetes sem
impactar sua aplicação. A descoberta e o roteamento entre Pods
dependentes (tal como componentes frontend e backend dentro de uma
aplicação) são controlados por Services do Kubernetes.
Services relacionam um conjunto de Pods usando
rótulos e seletores,
uma primitiva de agrupamento que permite operações lógicas sobre objetos
do Kubernetes. Rótulos são pares chave/valor anexados à objetos e
podem ser usados de diversas formas:
Designar objetos para desenvolvimento, teste e produção
Adicionar tags de versão
Classificar um objeto usando tags
Rótulos podem ser anexados aos objetos no momento de sua criação ou
posteriormente. Eles podem ser modificados a qualquer momento. Vamos
expor nossa aplicação usando um Service e aplicar alguns rótulos.
Crie um novo Service
Vamos verificar que nossa aplicação está rodando. Utilizaremos o comando
kubectl get e procuraremos por Pods existentes:
kubectl get pods
Se não houver Pods rodando, isso significa que o ambiente interativo
ainda está recarregando o estado anterior. Por favor, aguarde alguns
instantes e liste os Pods novamente. Você poderá prosseguir assim que
vir um Pod rodando.
A seguir, vamos listar os Services existentes no momento no nosso cluster:
kubectl get services
Temos um Service chamado kubernetes que é criado por padrão
quando o minikube inicializa o cluster.
Para criar um novo Service e expô-lo para tráfego externo utilizaremos
o comando expose com o tipo NodePort.
Temos agora um Service chamado kubernetes-bootcamp rodando. Aqui vemos
que o Service recebeu um ClusterIP único, uma porta interna e um IP
externo (o IP do nó).
Para descobrir qual porta foi aberta externamente (para o Service com
tipo NodePort) iremos rodar o subcomando describe service:
kubectl describe services/kubernetes-bootcamp
Crie uma variável de ambiente chamada NODE_PORT que armazena
o número da porta do nó:
export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')" echo "NODE_PORT=$NODE_PORT"
Agora podemos verificar que a aplicação está exposta externamente ao
cluster utilizando curl, o endereço IP do nó e a porta
exposta externamente:
curl http://"$(minikube ip):$NODE_PORT"
E receberemos uma resposta do servidor. O Service está exposto.
Passo 2: Utilizando rótulos (labels)
O Deployment criou automaticamente um rótulo para o nosso Pod. Com o
subcomando describe deployment você pode ver o nome
(a chave) deste rótulo:
kubectl describe deployment
Vamos utilizar este rótulo para filtrar nossa lista de Pods.
Utilizaremos o comando kubectl get pods com o parâmetro
-l, seguido dos valores dos rótulos:
kubectl get pods -l app=kubernetes-bootcamp
Você pode fazer o mesmo para listar os Services existentes:
kubectl get services -l app=kubernetes-bootcamp
Obtenha o nome do Pod e armazene-o na variável de ambiente POD_NAME:
export POD_NAME="$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')" echo "Name of the Pod: $POD_NAME"
Para aplicar um novo rótulo podemos utilizar o subcomando label,
seguido pelo tipo de objeto, nome do objeto e o novo rótulo:
kubectl label pods "$POD_NAME" version=v1
Este comando aplicará um novo rótulo no Pod (nós fixamos a versão
da aplicação ao Pod) e podemos verificar com o comando
describe pod:
kubectl describe pods "$POD_NAME"
Vemos aqui que o rótulo está agora vinculado ao nosso Pod. E agora
podemos pesquisar a lista de Pods utilizando o novo label:
kubectl get pods -l version=v1
E vemos o Pod.
Removendo um Service
Para remover um Service você pode utilizar o subcomando delete service.
Rótulos também podem ser utilizados aqui:
kubectl delete service -l app=kubernetes-bootcamp
Confirme que o Service foi removido com sucesso:
kubectl get services
Isto confirma que nosso Service foi removido. Para confirmar que a rota
não está mais exposta, você pode disparar uma requisição para o endereço
IP e porta previamente expostos através do comando curl:
curl http://"$(minikube ip):$NODE_PORT"
Isto prova que a aplicação não está mais acessível de fora do cluster.
Você pode confirmar que a aplicação ainda está rodando com um curl
de dentro do Pod:
Vemos aqui que a aplicação ainda está rodando. Isto se deve ao fato de
que o Deployment está gerenciando a aplicação. Para encerrar a aplicação,
você precisaria remover o Deployment também.
5.2.5.1 - Executando Múltiplas Instâncias da sua Aplicação
Escalone uma aplicação existente de forma manual utilizando kubectl.
Objetivos
Escalonar uma aplicação usando kubectl.
Escalonando uma aplicação
Nos módulos anteriores, criamos um
Deployment,
e então o expusemos publicamente através de um serviço
(Service).
O Deployment criou apenas um único Pod para executar nossa aplicação.
Quando o tráfego aumentar, precisaremos escalonar a aplicação para
suportar a demanda de usuários.
O escalonamento é obtido pela mudança do número de
réplicas em um Deployment
NOTA Se você estiver seguindo este tutorial após a
seção anterior,
poderá ser necessário refazer a seção criando um cluster,
pois os serviços podem ter sido removidos.
Resumo:
Escalonando um Deployment
Você pode criar desde o início um Deployment com
múltiplas instâncias usando o parâmetro --replicas
do comando kubectl create deployment
Escalonar um Deployment garantirá que novos Pods serão criados
e alocados em nós de processamento com recursos disponíveis. O
escalonamento aumentará o número de Pods para o novo estado
desejado. O Kubernetes também suporta o auto-escalonamento
(autoscaling)
de Pods, mas isso está fora do escopo deste tutorial. Escalonar
para zero também é possível, e encerrará todos os Pods do
Deployment especificado.
Executar múltiplas instâncias de uma aplicação requer uma forma
de distribuir o tráfego entre todas elas. Serviços possuem um
balanceador de carga integrado que distribui o tráfego de rede
entre todos os Pods de um Deployment exposto. Serviços irão
monitorar continuamente os Pods em execução usando endpoints
para garantir que o tráfego seja enviado apenas para Pods
disponíveis.
O escalonamento é obtido pela mudança do número de
réplicas em um Deployment.
Uma vez que você tenha múltiplas instâncias de uma aplicação
em execução será possível realizar atualizações graduais no
cluster sem que ocorra indisponibilidade. Cobriremos isso no
próximo módulo. Agora, vamos ao terminal escalonar nossa aplicação.
Escalonando um Deployment
Para listar seus Deployments, utilize o subcomando
get deployments:
kubectl get deployments
A saída deve ser semelhante a:
NAME READY UP-TO-DATE AVAILABLE AGE
kubernetes-bootcamp 1/1 1 1 11m
Teremos um único Pod. Se nenhum Pod aparecer, tente rodar o
comando novamente.
NAME lista os nomes dos Deployments no cluster.
READY exibe a proporção de réplicas atuais/desejadas
(CURRENT/DESIRED).
UP-TO-DATE exibe o número de réplicas que foram
atualizadas para atingir o estado desejado.
AVAILABLE exibe o número de réplicas da aplicação
que estão disponíveis para seus usuários.
AGE exibe há quanto tempo a aplicação está rodando.
Para ver o ReplicaSet criado pelo Deployment, execute
kubectl get rs
Observe que o nome do ReplicaSet sempre é exibido no formato
[NOME-DO-DEPLOYMENT]-[TEXTO-ALEATÓRIO]. O texto aleatório
é gerado e utiliza o valor do pod-template-hash como semente.
Duas colunas importantes desta saída são:
DESIRED exibe o número desejado de réplicas da aplicação,
que você define quando cria o objeto Deployment. Este é o estado
desejado.
CURRENT exibe quantas réplicas estão em execução atualmente.
A seguir, vamos escalonar o Deployment para 4 réplicas. Utilizaremos
o comando kubectl scale, seguido pelo tipo Deployment,
nome e o número desejado de instâncias:
Para listar seus Deployments mais uma vez, utilize get deployments:
kubectl get deployments
A mudança foi aplicada, e temos 4 instâncias da aplicação disponíveis. A seguir,
vamos verificar se o número de Pods mudou:
kubectl get pods -o wide
Temos 4 Pods agora, com endereços IP diferentes. A mudança foi registrada no log
de eventos do Deployment. Para verificar esta mudança, utilize o subcomando describe:
kubectl describe deployments/kubernetes-bootcamp
Você pode ver na saída deste comando que temos 4 réplicas agora.
Balanceamento de carga
Vamos verificar que o Service está efetuando o balanceamento de carga
do tráfego recebido. Para encontrar o endereço IP exposto e a porta podemos
utilizar o comando para descrever o serviço como aprendemos na seção anterior:
kubectl describe services/kubernetes-bootcamp
Crie uma variável de ambiente chamada NODE_PORT que possui
o valor da porta do nó:
export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"
echo NODE_PORT=$NODE_PORT
A seguir, iremos executar o comando curl para efetuar
uma requisição para o endereço IP e porta expostos. Rode este comando
múltiplas vezes:
curl http://"$(minikube ip):$NODE_PORT"
Cada requisição é atendida por um Pod diferente. Isso demonstra que o
balanceamento de carga está funcionando.
Reduzir o número de réplicas
Para reduzir o número de réplicas do Deployment para 2, execute
o subcomando scale novamente:
5.2.5.2 - Tutorial Interativo - Escalando seu aplicativo
Conteúdo indisponível
O tutorial interativo de como escalonar um aplicativo que está rodando
no seu cluster não está disponível.
Para mais informações, veja o
anúncio de encerramento do Katacoda.
6 - Referência
Esta seção da documentação do Kubernetes contém referências.
kubeadm - Ferramenta CLI para provisionar facilmente um cluster Kubernetes seguro.
Referência de configuração
kubelet - O principal agente do nó que é executado em cada nó. O kubelet usa um conjunto de PodSpecs e garante que os contêineres descritos estejam funcionando e saudáveis.
kube-apiserver - API REST que valida e configura dados para objetos de API, como pods, serviços, controladores de replicação.
kube-controller-manager - Daemon que incorpora os principais loops de controle enviados com o Kubernetes.
kube-proxy - É possível fazer o encaminhamento de fluxo TCP/UDP de forma simples ou utilizando o algoritimo de Round Robin encaminhando através de um conjunto de back-ends.
kube-scheduler - Agendador que gerencia disponibilidade, desempenho e capacidade.
Essa página demonstra uma visão geral sobre autenticação
Usuários no Kubernetes
Todos os clusters Kubernetes possuem duas categorias de usuários: contas de serviço gerenciadas pelo Kubernetes e usuários normais.
Assume-se que um serviço independente do cluster gerencia usuários normais das seguintes formas:
Um administrador distribuindo chaves privadas
Uma base de usuários como Keystone
Keystone é o serviço de identidade usado pelo OpenStack para autenticação (authN) e autorização de alto nível (authZ). Atualmente, ele oferece suporte a authN com base em token e autorização de serviço do usuário. Recentemente, foi reprojetado para permitir a expansão para oferecer suporte a serviços externos de proxy e mecanismos AuthN / AuthZ, como oAuth, SAML e openID em versões futuras.
ou Google Accounts
Um arquivo com uma lista de nomes de usuários e senhas
Neste quesito, Kubernetes não possui objetos que possam representar as contas de um usuário normal. Usuários normais não podem ser adicionados ao cluster através de uma chamada para a API.
Apesar de um usuário normal não poder ser adicionado através de uma chamada para a API, qualquer usuário que apresente um certificado válido e assinado pela autoridade de certificados (CA) do cluster é considerado autenticado. Nesta configuração, Kubernetes determina o nome do usuário baseado no campo de nome comum no sujeito (subject) do certificado (por exemplo: "/CN=bob"). A partir daí, o subsistema de controle de acesso baseado em função (RBAC) determina se o usuário é autorizado a realizar uma operação específica sobre o recurso. Para mais detalhes, veja a referência sobre o tópico de usuários normais dentro de requisição de certificado.
Em contraste a usuários normais, contas de serviço são considerados usuários gerenciados pela API do Kubernetes. Elas estão vinculadas à namespaces específicas e criadas automaticamente pelo servidor de API ou manualmente através de chamadas da API. Contas de serviço estão ligadas a um conjunto de credenciais armazenados como Secrets, aos quais são montados dentro dos pods assim permitindo que processos internos ao cluster comuniquem-se com a API do Kubernetes.
Requisições para a API estão ligadas a um usuário normal, conta de serviço ou serão tratadas como requisições anônimas. Isto significa que cada processo dentro ou fora do cluster, desde um usuário humano utilizando o kubectl de uma estação de trabalho, a kubelets rodando nos nós, a membros da camada de gerenciamento (s/painel de controle) devem autenticar-se ao realizarem suas requisições para o servidor API ou serão tratados como usuário anônimo.
Estratégias de autenticação
Kubernetes usa certificados de clientes, bearer Token, um proxy realizando autenticação, ou uma autenticação básica HTTP para autenticar requisições para o servidor de API através de plugins. Como requisições HTTP são feitas no servidor de API, plugins tentam associar os seguintes atributos junto a requisição:
Username
Um nome de usuário é um nome que identifica exclusivamente alguém em um sistema de computador. Por exemplo, um computador pode ser configurado com várias contas, com nomes de usuário diferentes para cada conta. Muitos sites permitem que os usuários escolham um nome de usuário para que possam personalizar suas configurações ou configurar uma conta online. Por exemplo, seu banco pode permitir que você escolha um nome de usuário para acessar suas informações bancárias. Você pode precisar escolher um nome de usuário para postar mensagens em um determinado quadro de mensagens na web. Os serviços de e-mail, como o Hotmail, exigem que os usuários escolham um nome de usuário para usar o serviço.
Um nome de usuário geralmente é pareado com uma senha. Essa combinação de nome de usuário / senha é conhecida como login e geralmente é necessária para que os usuários façam login em sites. Por exemplo, para acessar seu e-mail pela Web, é necessário inserir seu nome de usuário e senha. Depois de fazer o login, seu nome de usuário pode aparecer na tela, mas sua senha é mantida em segredo. Ao manter sua senha privada, as pessoas podem criar contas seguras para vários sites. A maioria dos nomes de usuário pode conter letras e números, mas não espaços. Quando você escolhe um nome de usuário para uma conta de e-mail, a parte antes de "@" é o seu nome de usuário.
: um valor (String) que identifica o usuário final. Valores comuns podem ser kube-admin ou jane@example.com
UID
Uma string gerada pelos sistemas do Kubernetes para identificar objetos de
forma única.
Cada objeto criado durante todo o ciclo de vida do cluster do Kubernetes possui
um UID distinto. O objetivo deste identificador é distinguir ocorrências
históricas de entidades semelhantes.
: um valor (String) que identifica o usuário final e tenta ser mais consistente e único do que username.
Groups: Um conjunto de valores em que cada item indica a associação de um usuário à uma coleção lógica de usuários. Valores comuns podem ser system:masters ou devops-team.
Campos extras: um mapa que pode conter uma lista de atributos que armazena informações adicionais em que autorizadores podem achar útil.
Todos os valores são transparentes para o sistema de autenticação e somente trazem significado quando interpretados por um autorizador.
É possível habilitar múltiplos métodos de autenticação. Deve-se normalmente usar pelo menos dois métodos:
Tokens para contas de serviço;
Pelo menos um outro método de autenticação para usuários.
Quando múltiplos módulos de autenticação estão habilitados, o primeiro módulo a autenticar com sucesso uma requisição termina, o fluxo de avaliação da mesma.
O servidor de API não garante a ordem em que os autenticadores são processados.
O grupo system:authenticated é incluído na lista de grupos de todos os usuários autenticados.
Integrações com outros protocolos de autenticação, como LDAP
Abreviatura para "Lightweight Directory Access Protocol". Se você deseja disponibilizar informações de diretório na Internet, esta é a maneira de fazê-lo. O LDAP é uma versão simplificada de um padrão de diretório anterior denominado X.500. O que torna o LDAP tão útil é que ele funciona muito bem em redes TCP / IP (ao contrário do X.500), de modo que as informações podem ser acessadas por meio do LDAP por qualquer pessoa com uma conexão à Internet. Também é um protocolo aberto, o que significa que os diretórios podem ser armazenados em qualquer tipo de máquina (por exemplo, Windows 2000, Red Hat Linux, Mac OS X).
Para dar uma ideia de como um diretório LDAP é organizado, aqui estão os diferentes níveis de uma hierarquia de árvore LDAP simples:
O diretório raiz
Países
Organizações
Divisões, departamentos, etc.
Indivíduos
Recursos individuais, como arquivos e impressoras.
A maior parte da conectividade LDAP é feita nos bastidores, então o usuário típico provavelmente não notará ao navegar na web. No entanto, é uma boa tecnologia para se conhecer. Se nada mais, é outro termo para impressionar seus pais.
, SAML
SAML significa Linguagem de Marcação para Asserção de Segurança. É um padrão aberto baseado em XML para transferência de dados de identidade entre duas partes: um provedor de identidade (IdP) e um provedor de serviços (SP).
Provedor de identidade - executa autenticação e passa a identidade do usuário e o nível de autorização para o provedor de serviços.
Provedor de serviços - confia no provedor de identidade e autoriza o usuário fornecido a acessar o recurso solicitado.
A autenticação de logon único SAML normalmente envolve um provedor de serviços e um provedor de identidade. O fluxo do processo geralmente envolve os estágios de estabelecimento de confiança e fluxo de autenticação.
Considere este exemplo:
Nosso provedor de identidade é Auth0
Nosso provedor de serviços é um serviço fictício, Zagadat
Nota: O provedor de identidade pode ser qualquer plataforma de gerenciamento de identidade.
Agora, um usuário está tentando obter acesso ao Zagadat usando a autenticação SAML.
Este é o fluxo do processo:
O usuário tenta fazer login no Zagadat a partir de um navegador.
O Zagadat responde gerando uma solicitação SAML.
, Kerberos
Kerberos é um protocolo de rede que usa criptografia de chave secreta para autenticar aplicativos cliente-servidor. O Kerberos solicita um tíquete criptografado por meio de uma sequência de servidor autenticada para usar os serviços.
Kerberos foi desenvolvido pelo Project Athena - um projeto conjunto entre o Massachusetts Institute of Technology (MIT), Digital Equipment Corporation e IBM que funcionou entre 1983 e 1991.
Um servidor de autenticação usa um tíquete Kerberos para conceder acesso ao servidor e, em seguida, cria uma chave de sessão com base na senha do solicitante e outro valor aleatório. O tíquete de concessão de tíquete (TGT) é enviado ao servidor de concessão de tíquete (TGS), que é necessário para usar o mesmo servidor de autenticação.
O solicitante recebe uma chave TGS criptografada com um registro de data e hora e um tíquete de serviço, que é retornado ao solicitante e descriptografado. O solicitante envia ao TGS essas informações e encaminha a chave criptografada ao servidor para obter o serviço desejado. Se todas as ações forem tratadas corretamente, o servidor aceita o tíquete e realiza o atendimento ao usuário desejado, que deve descriptografar a chave, verificar a data e hora e entrar em contato com o centro de distribuição para obter as chaves de sessão. Essa chave de sessão é enviada ao solicitante, que descriptografa o tíquete.
Se as chaves e o carimbo de data / hora forem válidos, a comunicação cliente-servidor continuará. O tíquete TGS tem carimbo de data / hora, o que permite solicitações simultâneas dentro do período de tempo alocado.
, alternate x509 schemes
X.509 é um formato padrão para certificados de chave pública, documentos digitais que associam com segurança pares de chaves criptográficas a identidades como sites, indivíduos ou organizações.
Introduzido pela primeira vez em 1988 junto com os padrões X.500 para serviços de diretório eletrônico, o X.509 foi adaptado para uso na Internet pelo grupo de trabalho Public-Key Infrastructure (X.509) (PKIX) da IETF. O RFC 5280 define o perfil do certificado X.509 v3, a lista de revogação de certificado X.509 v2 (CRL) e descreve um algoritmo para a validação do caminho do certificado X.509.
As aplicações comuns de certificados X.509 incluem:
- SSL / TLS e HTTPS para navegação na web autenticada e criptografada
- E-mail assinado e criptografado por meio do protocolo S / MIME
- Assinatura de código
- Assinatura de documento
- Autenticação de cliente
- Identificação eletrônica emitida pelo governo
, etc, podem ser alcançadas utilizando-se de um proxy ou webhook de autenticação.
Certificados de cliente X509
Autenticação via certificados de cliente pode ser habilitada ao passar a opção --client-ca-file=ARQUIVO para o servidor de API. O arquivo referenciado deve conter um ou mais autoridades de certificação usadas para validar o certificado de cliente passado para o servidor de API. Se o certificado de cliente é apresentado e verificado, o common name
O nome comum é normalmente composto de Host + Nome de domínio e será semelhante a www.seusite.com ou seusite.com. Os certificados de servidor SSL são específicos para o nome comum para o qual foram emitidos no nível do host.
O nome comum deve ser igual ao endereço da Web que você acessará ao se conectar a um site seguro. Por exemplo, um certificado de servidor SSL para o domínio domínio.com receberá um aviso do navegador se o acesso a um site chamado www.domain.com ou secure.domain.com, pois www.domain.com e secure.domain.com são diferentes de dominio.com. Você precisaria criar um CSR para o nome comum correto.
do sujeito é usado como o nome de usuário para a requisição. A partir da versão 1.4, certificados de cliente podem também indicar o pertencimento de um usuário a um grupo utilizando o campo de organização do certificado. Para incluir múltiplos grupos para o usuário, deve-se incluir múltiplos campos de organização no certificado.
Por exemplo, utilizando o comando de linha openssl para gerar uma requisição de assinatura de certificado:
O servidor de API lê bearer tokens de um arquivo quando recebe uma requisição contendo a opção --token-auth-file=ARQUIVO via linha de comando. Atualmente, tokens têm duração indefinida, e a lista de tokens não pode ser modificada sem reiniciar o servidor de API.
O arquivo de token é do tipo CSV contendo no mínimo 3 colunas: token, nome de usuário, identificador de usuário (uid), seguido pelos nomes de grupos (opcional).
Nota:
Se uma entrada possuir mais de um grupo, a coluna deve ser cercada por aspas duplas, por exemplo:
token,usuario,uid,"grupo1,grupo2,grupo3"
Adicionando um bearer token em uma requisição
Quando utilizando-se de bearer token para autenticação de um cliente HTTP, o servidor de API espera um cabeçalho Authorization com um valor Bearer TOKEN. O token deve ser uma sequência de caracteres que pode ser colocada como valor em um cabeçalho HTTP não utilizando-se mais do que as facilidades de codificação e citação de HTTP. Por exemplo, se o valor de um token é 31ada4fd-adec-460c-809a-9e56ceb75269 então iria aparecer dentro de um cabeçalho HTTP como:
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [stable]
Para permitir a inicialização simplificada para novos clusters, Kubernetes inclui um token dinamicamente gerenciado denominado Bootstrap Token. Estes tokens são armazenados como Secrets dentro do namespace kube-system, onde eles podem ser dinamicamente criados e gerenciados. O componente Gerenciador de Controle (Controller Manager) possui um controlador "TokenCleaner" que apaga os tokens de inicialização expirados.
Os tokens seguem o formato [a-z0-9]{6}.[a-z0-9]{16}. O primeiro componente é um identificador do token e o segundo é o segredo. Você pode especificar o token como um cabeçalho HTTP como:
Authorization: Bearer 781292.db7bc3a58fc5f07e
Deve-se habilitar os tokens de inicialização com a opção --enable-bootstrap-token-auth no servidor de API. Deve-se habilitar o controlador TokenCleaner através da opção --controllers no Gerenciador de Controle. Isso é feito, por exemplo, como: --controllers=*,tokencleaner. O kubeadm, por exemplo, irá realizar isso caso seja utilizado para a inicialização do cluster.
O autenticador o autentica como system:bootstrap:<Token ID> e é incluído no grupo system:bootstrappers. O nome e grupo são intencionalmente limitados para desencorajar usuários a usarem estes tokens após inicialização. Os nomes de usuários e grupos podem ser utilizados (e são utilizados pelo kubeadm) para elaborar as políticas de autorização para suportar a inicialização de um cluster.
Por favor veja Bootstrap Tokens para documentação detalhada sobre o autenticador e controladores de Token de inicialização, bem como gerenciar estes tokens com kubeadm.
Tokens de Contas de serviço
Uma conta de serviço é um autenticador habilitado automaticamente que usa bearer tokens para verificar as requisições. O plugin aceita dois parâmetros opcionais:
--service-account-key-file Um arquivo contendo uma chave codificada no formato PEM para assinar bearer tokens. Se não especificado, a chave privada de TLS no servidor de API será utilizada
--service-account-lookup Se habilitado, tokens deletados do servidor de API serão revogados.
Contas de serviço são normalmente criadas automaticamente pelo servidor de API e associada a pods rodando no cluster através do controlador de admissão Admission Controller de ServiceAccount. Os tokens de contas de serviços são montados nos Pods, em localizações já pré definidas e conhecidas e permitem processos dentro do cluster a se comunicarem com o servidor de API. Contas podem ser explicitamente associadas com pods utilizando o campo serviceAccountName na especificação do pod (PodSpec):
Nota:
serviceAccountName é normalmente omitida por ser feito automaticamente
Os tokens de contas de serviço são perfeitamente válidos para ser usados fora do cluster e podem ser utilizados para criar identidades para processos de longa duração que desejem comunicar-se com a API do Kubernetes. Para criar manualmente uma conta de serviço, utilize-se simplesmente o comando kubectl create serviceaccount (NOME). Isso cria uma conta de serviço e um segredo associado a ela no namespace atual.
O segredo criado irá armazenar a autoridade de certificado do servidor de API e um JSON Web Token (JWT) digitalmente assinado.
kubectl get secret jenkins-token-1yvwg -o yaml
apiVersion:v1data:ca.crt:(APISERVER'S CA BASE64 ENCODED)namespace:ZGVmYXVsdA==token:(BEARER TOKEN BASE64 ENCODED)kind:Secretmetadata:# ...type:kubernetes.io/service-account-token
Nota:
Valores são codificados em base64 porque segredos são sempre codificados neste formato.
O JWT assinado pode ser usado como um bearer token para autenticar-se como a conta de serviço. Veja acima como o token pode ser incluído em uma requisição. Normalmente esses segredos são montados no pod para um acesso interno ao cluster ao servidor de API, porém pode ser utilizado fora do cluster também.
Contas de serviço são autenticadas com o nome de usuário system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT) e são atribuídas aos grupos system:serviceaccounts e system:serviceaccounts:(NAMESPACE).
AVISO: porque os tokens das contas de serviço são armazenados em segredos, qualquer usuário com acesso de leitura a esses segredos podem autenticar-se como a conta de serviço. Tome cuidado quando conceder permissões a contas de serviços e capacidade de leitura de segredos.
Tokens OpenID Connect
OpenID Connect é uma variação do framework de autorização OAuth2 que suporta provedores como Azure Active Directory, Salesforce, e Google. A principal extensão do OAuth2 é um campo adicional de token de acesso chamado ID Token. Este token é um tipo de JSON Web Token (JWT) com campos bem definidos, como usuário, e-mail e é assinado pelo servidor de autorização.
Para identificar o usuário, o autenticador usa o id_token (e não access_token) do bearer token da resposta de autorização do OAuth2 token response. Veja acima como incluir um token em uma requisição.
Login no seu provedor de identidade.
Seu provedor de identidade ira fornecer um access_token, id_token e um refresh_token.
Quando utilizando kubectl, utilize do seu id_token com a opção --token ou adicione o token diretamente no seu arquivo de configuração kubeconfig.
kubectl envia o seu id_token em um cabeçalho HTTP chamado Authorization para o servidor de API.
O servidor de API irá garantir que a assinatura do token JWT é válida, verificando-o em relação ao certificado mencionado na configuração.
Verificação para garantir que oid_token não esteja expirado.
Garantir que o usuário é autorizado.
Uma vez autorizado o servidor de API retorna a resposta para o kubectl.
kubectl fornece retorno ao usuário.
Uma vez que todos os dados necessários para determinar sua identidade encontram-se no id_token, Kubernetes não precisa realizar outra chamada para o provedor de identidade. Em um modelo onde cada requisição não possui estado, isso fornece uma solução escalável para autenticação. Isso, porem, apresenta alguns desafios:
Kubernetes não possui uma "interface web" para disparar o processo de autenticação. Não há browser ou interface para coletar credenciais que são necessárias para autenticar-se primeiro no seu provedor de identidade.
O id_token não pode ser revogado, funcionando como um certificado, portanto deve possuir curta validade (somente alguns minutos) o que pode tornar a experiência um pouco desconfortável, fazendo com que se requisite um novo token toda vez em um curto intervalo (poucos minutos de validade do token)
Para autenticar-se ao dashboard Kubernetes, você deve executar o comando kubectl proxy ou um proxy reverso que consiga injetar o id_token.
Configurando o Servidor de API
Para habilitar o plugin de autorização, configure as seguintes opções no servidor de API:
Parâmetro
Descrição
Exemplo
Obrigatório
--oidc-issuer-url
URL do provedor que permite ao servidor de API descobrir chaves públicas de assinatura. Somente URLs que usam o esquema https:// são aceitas. Isto normalmente é o endereço de descoberta do provedor sem o caminho, por exemplo "https://accounts.google.com" ou "https://login.salesforce.com". Esta URL deve apontar para o nível abaixo do caminho .well-known/openid-configuration
Se o valor da URL de descoberta é https://accounts.google.com/.well-known/openid-configuration, entao o valor deve ser https://accounts.google.com
Sim
--oidc-client-id
Identificador do cliente para o qual todos os tokens são gerados.
kubernetes
Sim
--oidc-username-claim
Atributo do JWT a ser usado como nome de usuário. Por padrão o valor sub, o qual é esperado que seja um identificador único do usuário final. Administradores podem escolher outro atributo, como email ou name, dependendo de seu provedor de identidade. No entanto, outros atributos além de email serão prefixados com a URL do emissor issuer URL para prevenir conflitos de nome com outros plugins.
sub
Não
--oidc-username-prefix
Prefixos adicionados ao atributo de nome de usuário para prevenir conflitos de nomes existentes (como por exemplo usuários system:). Por exemplo, o valor oidc: irá criar usuários como oidc:jane.doe. Se esta opção não for fornecida --oidc-username-claim e um valor diferente de email irá conter um prefixo padrão com o valor de ( Issuer URL )# onde ( Issuer URL ) era o valor da opção --oidc-issuer-url. O valor - pode ser utilizado para desabilitar todos os prefixos.
oidc:
Não
--oidc-groups-claim
Atributo do JWT a ser utilizado para mapear os grupos dos usuários. Se o atributo está presente, ele deve ser do tipo vetor de Strings.
groups
Não
--oidc-groups-prefix
Prefixo adicionados ao atributo de grupo para prevenir conflitos de nomes existentes (como por exemplo system: grupos). Por exemplo, o valor oidc: irá criar nomes de grupos como oidc:engineering e oidc:infra.
oidc:
Não
--oidc-required-claim
Um par de chave=valor que descreve atributos obrigatórios no ID Token. Se configurado, a presença do atributo é verificado dentro do ID Token com um valor relacionado. Repita esta opção para configurar múltiplos atributos obrigatórios.
claim=value
Não
--oidc-ca-file
O caminho para o arquivo de certificado da autoridade de certificados (CA) que assinou o certificado do provedor de identidades.
/etc/kubernetes/ssl/kc-ca.pem
Não
É importante ressaltar que o servidor de API não é um cliente Oauth2, ao contrário, ele só pode ser configurado para confiar em um emissor. Isso permite o uso de emissores públicos, como Google, sem confiar em credenciais emitidas por terceiros. Administradores que desejam utilizar-se de múltiplos clientes OAuth2 devem explorar provedores os quais suportam atributos azp (parte autorizada), que é um mecanismo para permitir um cliente a emitir tokens em nome de outro.
Kubernetes não oferece um provedor de identidade OpenID Connect. Pode-se utilizar provedores públicos existentes como Google ou outros. Ou, pode-se rodar o próprio provedor de identidade no cluster, como dex,
Keycloak,
CloudFoundry UAA, ou
Tremolo Security's OpenUnison.
Para um provedor de identidades funcionar no Kubernetes, ele deve:
Executar TLS com cifras criptográficas não obsoletos.
Possuir certificados assinados por uma Autoridade certificadora (mesmo que o CA não seja comercial ou seja auto-assinado)
Uma nota sobre o requisito #3 acima. Se você instalar o seu próprio provedor de identidades (ao invés de utilizar um provedor como Google ou Microsoft) você DEVE ter o certificado web do seu provedor de identidades assinado por um certificado contendo a opção CA configurada para TRUE, mesmo que seja um certificado auto assinado. Isso deve-se a implementação do cliente TLS em Golang que é bastante restrito quanto aos padrões em torno da validação de certificados. Se você não possui um CA em fácil alcance, você pode usar este script criado pelo time Dex para criar um simples CA, um par de chaves e certificado assinados.
Ou você pode usar este script similar o qual gera certificados SHA256 com uma vida mais longa e tamanho maior de chave.
Instruções de configuração para sistemas específicos podem ser encontrados em:
A primeira opção é utilizar-se do autenticador oidc do kubectl, o qual define o valor do id_token como um bearer token para todas as requisições e irá atualizar o token quando o mesmo expirar. Após você efetuar o login no seu provedor, utilize o kubectl para adicionar os seus id_token, refresh_token, client_id, e client_secret para configurar o plugin.
Provedores os quais não retornem um id_token como parte da sua resposta de refresh token não são suportados por este plugin e devem utilizar a opção 2 abaixo.
kubectl config set-credentials USER_NAME \
--auth-provider=oidc \
--auth-provider-arg=idp-issuer-url=( issuer url )\
--auth-provider-arg=client-id=( your client id )\
--auth-provider-arg=client-secret=( your client secret )\
--auth-provider-arg=refresh-token=( your refresh token )\
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate )\
--auth-provider-arg=id-token=( your id_token )
Um exemplo, executando o comando abaixo após autenticar-se no seu provedor de identidades:
Uma vez que seu id_token expire, kubectl irá tentar atualizar o seu id_token utilizando-se do seu refresh_token e client_secret armazenando os novos valores para refresh_token e id_token no seu arquivo de configuração .kube/config.
Opção 2 - Utilize a opção --token
O comando kubectl o permite passar o valor de um token utilizando a opção --token. Copie e cole o valor do seu id_token nesta opção:
kubectl --token=eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczovL21sYi50cmVtb2xvLmxhbjo4MDQzL2F1dGgvaWRwL29pZGMiLCJhdWQiOiJrdWJlcm5ldGVzIiwiZXhwIjoxNDc0NTk2NjY5LCJqdGkiOiI2RDUzNXoxUEpFNjJOR3QxaWVyYm9RIiwiaWF0IjoxNDc0NTk2MzY5LCJuYmYiOjE0NzQ1OTYyNDksInN1YiI6Im13aW5kdSIsInVzZXJfcm9sZSI6WyJ1c2VycyIsIm5ldy1uYW1lc3BhY2Utdmlld2VyIl0sImVtYWlsIjoibXdpbmR1QG5vbW9yZWplZGkuY29tIn0.f2As579n9VNoaKzoF-dOQGmXkFKf1FMyNV0-va_B63jn-_n9LGSCca_6IVMP8pO-Zb4KvRqGyTP0r3HkHxYy5c81AnIh8ijarruczl-TK_yF5akjSTHFZD-0gRzlevBDiH8Q79NAr-ky0P4iIXS8lY9Vnjch5MF74Zx0c3alKJHJUnnpjIACByfF2SCaYzbWFMUNat-K1PaUk5-ujMBG7yYnr95xD-63n8CO8teGUAAEMx6zRjzfhnhbzX-ajwZLGwGUBT4WqjMs70-6a7_8gZmLZb2az1cZynkFRj2BaCkVT3A2RrjeEwZEtGXlMqKJ1_I2ulrOVsYx01_yD35-rw get nodes
Token de autenticação via Webhook
Webhook de autenticação é usado para verificar bearer tokens
--authentication-token-webhook-config-file arquivo de configuração descrevendo como acessar o serviço remoto de webhook.
--authentication-token-webhook-cache-ttl por quanto tempo guardar em cache decisões de autenticação. Configuração padrão definida para dois minutos.
--authentication-token-webhook-version determina quando usar o apiVersion authentication.k8s.io/v1beta1 ou authentication.k8s.io/v1 para objetos TokenReview quando enviar/receber informações do webhook. Valor padrão v1beta1.
O arquivo de configuração usa o formato de arquivo do kubeconfig. Dentro do arquivo, clusters refere-se ao serviço remoto e users refere-se ao servidor de API do webhook. Um exemplo seria:
# versão da API do KubernetesapiVersion:v1# tipo do objeto da APIkind:Config# clusters refere-se ao serviço remotoclusters:- name:name-of-remote-authn-servicecluster:certificate-authority:/path/to/ca.pem # CA para verificar o serviço remotoserver:https://authn.example.com/authenticate# URL para procurar o serviço remoto. Deve utilizar 'https'.# users refere-se a configuração do webhook do servidor de APIusers:- name:name-of-api-serveruser:client-certificate:/path/to/cert.pem# certificado para ser utilizado pelo plugin de webhookclient-key:/path/to/key.pem # chave referente ao certificado# arquivos kubeconfig requerem um contexto. Especifique um para o servidor de API.current-context:webhookcontexts:- context:cluster:name-of-remote-authn-serviceuser:name-of-api-servername:webhook
Quando um cliente tenta autenticar-se com o servidor de API utilizando um bearer token como discutido acima, o webhook de autenticação envia um objeto JSON serializado do tipo TokenReview contendo o valor do token para o serviço remoto.
Note que objetos de API do tipo webhook estão sujeitos às mesmas regras de compatibilidade de versão como outros objetos de API Kubernetes.
Implementadores devem verificar o campo de versão da API (apiVersion) da requisição para garantir a correta deserialização e devem responder com um objeto do tipo TokenReview da mesma versão da requisição.
O servidor de API Kubernetes envia por padrão revisão de tokens para a API authentication.k8s.io/v1beta1 para fins de compatibilidade com versões anteriores.
Para optar receber revisão de tokens de versão authentication.k8s.io/v1, o servidor de API deve ser inicializado com a opção --authentication-token-webhook-version=v1.
{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","spec": {# Bearer token opaco enviado para o servidor de API"token": "014fbff9a07c...",# Lista opcional de identificadores de audiência para o servidor ao qual o token foi apresentado# Autenticadores de token sensíveis a audiência (por exemplo, autenticadores de token OIDC)# deve-se verificar que o token foi direcionado a pelo menos um membro da lista de audiência# e retornar a interseção desta lista a audiência válida para o token no estado da resposta# Isto garante com que o token é válido para autenticar-se no servidor ao qual foi apresentado# Se nenhuma audiência for especificada, o token deve ser validado para autenticar-se ao servidor de API do Kubernetes"audiences": ["https://myserver.example.com","https://myserver.internal.example.com"]}}
{"apiVersion": "authentication.k8s.io/v1beta1","kind": "TokenReview","spec": {# Bearer token opaco enviado para o servidor de API"token": "014fbff9a07c...",# Lista opcional de identificadores de audiência para o servidor ao qual o token foi apresentado# Autenticadores de token sensíveis a audiência (por exemplo, autenticadores de token OIDC)# deve-se verificar que o token foi direcionado a pelo menos um membro da lista de audiência# e retornar a interseção desta lista a audiência válida para o token no estado da resposta# Isto garante com que o token é válido para autenticar-se no servidor ao qual foi apresentado# Se nenhuma audiência for especificada, o token deve ser validado para autenticar-se ao servidor de API do Kubernetes"audiences": ["https://myserver.example.com","https://myserver.internal.example.com"]}}
É esperado que o serviço remoto preencha o campo status da requisição para indicar o sucesso do login.
O campo spec do corpo de resposta é ignorado e pode ser omitido.
O serviço remoto deverá retornar uma resposta usando a mesma versão de API do objeto TokenReview que foi recebido.
Uma validação bem sucedida deveria retornar:
{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","status": {"authenticated": true,"user": {# Obrigatório"username": "janedoe@example.com",# Opcional"uid": "42",# Opcional: lista de grupos associados"groups": ["developers","qa"],# Opcional: informação adicional provida pelo autenticador.# Isto não deve conter dados confidenciais, pois pode ser registrados em logs ou em objetos de API e estarão disponíveis para webhooks de admissão"extra": {"extrafield1": ["extravalue1","extravalue2"]}},# Lista opcional de Autenticadores de token sensíveis a audiência que podem ser retornados,# contendo as audiências da lista `spec.audiences` válido para o token apresentado.# Se este campo for omitido, o token é considerado válido para autenticar-se no servidor de API Kubernetes"audiences": ["https://myserver.example.com"]}}
{"apiVersion": "authentication.k8s.io/v1beta1","kind": "TokenReview","status": {"authenticated": true,"user": {# Obrigatório"username": "janedoe@example.com",# Opcional"uid": "42",# Opcional: lista de grupos associados"groups": ["developers","qa"],# Opcional: informação adicional provida pelo autenticador.# Isto não deve conter dados confidenciais, pois pode ser registrados em logs ou em objetos de API e estarão disponíveis para webhooks de admissão"extra": {"extrafield1": ["extravalue1","extravalue2"]}},# Lista opcional de Autenticadores de token sensíveis a audiência que podem ser retornados,# contendo as audiências da lista `spec.audiences` válido para o token apresentado.# Se este campo for omitido, o token é considerado válido para autenticar-se no servidor de API Kubernetes"audiences": ["https://myserver.example.com"]}}
{"apiVersion": "authentication.k8s.io/v1","kind": "TokenReview","status": {"authenticated": false,# Opcionalmente inclui detalhes sobre o porque a autenticação falhou# Se nenhum erro é fornecido, a API irá retornar uma mensagem genérica de "Não autorizado"# O campo de erro é ignorado quando authenticated=true."error": "Credenciais expiradas"}}
{"apiVersion": "authentication.k8s.io/v1beta1","kind": "TokenReview","status": {"authenticated": false,# Opcionalmente inclui detalhes sobre o porque a autenticação falhou# Se nenhum erro é fornecido, a API irá retornar uma mensagem genérica de "Não autorizado"# O campo de erro é ignorado quando authenticated=true."error": "Credenciais expiradas"}}
Autenticando com Proxy
O servidor de API pode ser configurado para identificar usuários através de valores de cabeçalho de requisição, como por exemplo X-Remote-User.
Isto é projetado para o uso em combinação com um proxy de autenticação, o qual irá atribuir o valor do cabeçalho da requisição.
--requestheader-username-headers Obrigatório, não faz distinção entre caracteres maiúsculos/minúsculos. Nomes de cabeçalhos a serem verificados, em ordem, para a identidade do usuário. O primeiro cabeçalho contendo um valor será usado para o nome do usuário.
--requestheader-group-headers 1.6+. Opcional, não faz distinção entre caracteres maiúsculos/minúsculos. "X-Remote-Group" é recomendado. Nomes de cabeçalhos a serem verificados, em ordem, para os grupos do usuário. Todos os valores especificados em todos os cabeçalhos serão utilizados como nome dos grupos do usuário.
--requestheader-extra-headers-prefix 1.6+. Opcional, não faz distinção entre caracteres maiúsculos/minúsculos. "X-Remote-Extra-" é recomendado. Prefixos de cabeçalhos para serem utilizados para definir informações extras sobre o usuário (normalmente utilizado por um plugin de autorização). Todos os cabeçalhos que começam com qualquer um dos prefixos especificados têm o prefixo removido. O restante do nome do cabeçalho é transformado em letra minúscula, decodificado percent-decoded e torna-se uma chave extra, e o valor do cabeçalho torna-se um valor extra.
Para prevenir falsificação de cabeçalhos, o proxy de autenticação deverá apresentar um certificado de cliente válido para o servidor de API para que possa ser validado com a autoridade de certificados (CA) antes que os cabeçalhos de requisições sejam verificados. AVISO: não re-utilize uma autoridade de certificados (CA) que esteja sendo utilizado em um contexto diferente ao menos que você entenda os riscos e os mecanismos de proteção da utilização de uma autoridade de certificados.
--requestheader-client-ca-file Obrigatório. Pacote de certificados no formato PEM. Um certificado válido deve ser apresentado e validado com a autoridade de certificados no arquivo especificado antes da verificação de cabeçalhos de requisição para os nomes do usuário.
--requestheader-allowed-names Opcional. Lista de valores de nomes comuns (CNs). Se especificado, um certificado de cliente válido contendo uma lista de nomes comuns denominados deve ser apresentado na verificação de cabeçalhos de requisição para os nomes do usuário. Se vazio, qualquer valor de nomes comuns será permitido.
Requisições anônimas
Quando habilitado, requisições que não são rejeitadas por outros métodos de autenticação configurados são tratadas como requisições anônimas e são dadas o nome de usuário system:anonymous e filiação ao grupo system:unauthenticated.
Por exemplo, uma requisição especificando um bearer token invalido chega a um servidor com token de autenticação configurado e acesso anônimo habilitado e receberia um erro de acesso não autorizado 401 Unauthorized. Já uma requisição não especificando nenhum bearer token seria tratada como uma requisição anônima.
Nas versões 1.5.1-1.5.x, acesso anônimo é desabilitado por padrão e pode ser habilitado passando a opção --anonymous-auth=true durante a inicialização do servidor de API.
Na versão 1.6 e acima, acesso anônimo é habilitado por padrão se um modo de autorização diferente de AlwaysAllow é utilizado e pode ser desabilitado passando a opção --anonymous-auth=false durante a inicialização do servidor de API.
Começando na versão 1.6, os autorizadores ABAC (Controle de Acesso Baseado em Atributos) e RBAC (Controle de Acesso Baseado em Função) requerem autorização explícita do usuário system:anonymous e do grupo system:unauthenticated, portanto, regras de políticas legadas que permitam acesso a usuário * e grupo * nao incluíram usuários anônimos.
Personificação de usuário
Um usuário pode agir como outro através de cabeçalhos de personificação. Os mesmos permitem que requisições manualmente sobrescrevam as informações ao quais o usuário irá se autenticar como. Por exemplo, um administrador pode utilizar-se desta funcionalidade para investigar um problema com uma política de autorização e assim, temporariamente, personificar um outro usuário e ver se/como sua requisição está sendo negada.
Requisições de personificação primeiramente são autenticadas como o usuário requerente, então trocando para os detalhes de informação do usuário personificado.
O fluxo é:
Um usuário faz uma chamada de API com suas credenciais e cabeçalhos de personificação.
O servidor de API autentica o usuário.
O servidor de API garante que o usuário autenticado possui permissão de personificação.
Detalhes de informação do usuário da requisição tem seus valores substituídos com os detalhes de personificação.
A requisição é avaliada e a autorização é feita sobre os detalhes do usuário personificado.
Os seguintes cabeçalhos HTTP podem ser usados para realizar uma requisição de personificação:
Impersonate-User: O nome do usuário para se executar ações em seu nome.
Impersonate-Group: Um nome de grupo para se executar ações em seu nome. Pode ser especificado múltiplas vezes para fornecer múltiplos grupos. Opcional. Requer "Impersonate-User".
Impersonate-Extra-( extra name ): Um cabeçalho dinâmico usado para associar campos extras do usuário. Opcional. Requer "Impersonate-User". Para que seja preservado consistentemente, ( extra name ) deve ser somente minúsculo, e qualquer caracter que não seja legal em rótulos de cabeçalhos HTTP DEVE ser utf8 e codificado.
Quando utilizando-se o kubectl especifique a opção --as para determinar o cabeçalho Impersonate-User, especifique a opção --as-group para determinar o cabeçalho Impersonate-Group.
kubectl drain mynode
Error from server (Forbidden): User "clark" cannot get nodes at the cluster scope. (get nodes mynode)
Para personificar um usuário, grupo ou especificar campos extras, o usuário efetuando a personificação deve possuir a permissão de executar o verbo "impersonate" no tipo de atributo sendo personificado ("user", "group", etc.). Para clusters com o plugin de autorização RBAC habilitados, a seguinte ClusterRole abrange as regras necessárias para definir os cabeçalhos de personificação de usuário e grupo:
Campos extras são avaliados como sub-recursos de um recurso denominado "userextras". Para permitir ao usuário que utilize os cabeçalhos de personificação para o campo extra "scopes", o usuário deve receber a seguinte permissão:
apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:scopes-impersonatorrules:# Pode definir o cabeçalho "Impersonate-Extra-scopes".- apiGroups:["authentication.k8s.io"]resources:["userextras/scopes"]verbs:["impersonate"]
Os valores dos cabeçalhos de personificação podem também ser restringidos ao limitar o conjunto de nomes de recursos (resourceNames) que um recurso pode ter.
apiVersion:rbac.authorization.k8s.io/v1kind:ClusterRolemetadata:name:limited-impersonatorrules:# Pode personificar o usuário "jane.doe@example.com"- apiGroups:[""]resources:["users"]verbs:["impersonate"]resourceNames:["jane.doe@example.com"]# Pode assumir os grupos "developers" and "admins"- apiGroups:[""]resources:["groups"]verbs:["impersonate"]resourceNames:["developers","admins"]# Pode personificar os campos extras "scopes" com valores "view" e "development"- apiGroups:["authentication.k8s.io"]resources:["userextras/scopes"]verbs:["impersonate"]resourceNames:["view","development"]
Plugins de credenciais client-go
ESTADO DA FUNCIONALIDADE:Kubernetes v1.11 [beta]
Ferramentas como kubectl e kubelet utilizando-se do k8s.io/client-go são capazes de executar um comando externo para receber credenciais de usuário.
Esta funcionalidade é direcionada à integração do lado cliente, com protocolos de autenticação não suportados nativamente pelo k8s.io/client-go como: LDAP, Kerberos, OAuth2, SAML, etc. O plugin implementa a lógica específica do protocolo e então retorna credenciais opacas para serem utilizadas. Quase todos os casos de usos de plugins de credenciais requerem um componente de lado do servidor com suporte para um autenticador de token webhook para interpretar o formato das credenciais produzidas pelo plugin cliente.
Exemplo de caso de uso
Num caso de uso hipotético, uma organização executaria um serviço externo que efetuaria a troca de credenciais LDAP por tokens assinados para um usuário específico. Este serviço seria também capaz de responder requisições do autenticador de token webhook para validar tokens. Usuários seriam obrigados a instalar um plugin de credencial em sua estação de trabalho.
Para autenticar na API:
O usuário entra um comando kubectl.
O plugin de credencial solicita ao usuário a entrada de credenciais LDAP e efetua troca das credenciais por um token via um serviço externo.
O plugin de credenciais retorna um token para o client-go, o qual o utiliza como um bearer token no servidor de API.
apiVersion:v1kind:Configusers:- name:my-useruser:exec:# Comando a ser executado. Obrigatório.command:"example-client-go-exec-plugin"# Versão da API a ser utilizada quando decodificar o recurso ExecCredentials. Obrigatório## A versão da API retornada pelo plugin DEVE ser a mesma versão listada aqui.## Para integrar com ferramentas que suportem múltiplas versões (tal como client.authentication.k8s.io/v1alpha1),# defina uma variável de ambiente ou passe um argumento para a ferramenta que indique qual versão o plugin de execução deve esperar.apiVersion:"client.authentication.k8s.io/v1beta1"# Variáveis de ambiente a serem configuradas ao executar o plugin. Opcionalenv:- name:"FOO"value:"bar"# Argumentos a serem passados ao executar o plugin. Opcionalargs:- "arg1"- "arg2"# Texto exibido para o usuário quando o executável não parece estar presente. OpcionalinstallHint:| example-client-go-exec-plugin é necessário para autenticar no cluster atual. Pode ser instalado via:Em macOS:brew install example-client-go-exec-pluginEm Ubuntu:apt-get install example-client-go-exec-pluginEm Fedora:dnf install example-client-go-exec-plugin...# Deve-se ou não fornecer informações do cluster, que podem potencialmente conter grande quantidade de dados do CA,# para esse plugin de execução como parte da variável de ambiente KUBERNETES_EXEC_INFOprovideClusterInfo:trueclusters:- name:my-clustercluster:server:"https://172.17.4.100:6443"certificate-authority:"/etc/kubernetes/ca.pem"extensions:- name:client.authentication.k8s.io/exec# nome de extensão reservado para configuração exclusiva do clusterextension:arbitrary:configthis:pode ser fornecido através da variável de ambiente KUBERNETES_EXEC_INFO na configuracao de provideClusterInfoyou:["coloque","qualquer","coisa","aqui"]contexts:- name:my-clustercontext:cluster:my-clusteruser:my-usercurrent-context:my-cluster
Os caminhos relativos do comando são interpretados como relativo ao diretório do arquivo de configuração. Se
KUBECONFIG está configurado para o caminho /home/jane/kubeconfig e o comando executado é ./bin/example-client-go-exec-plugin,
o binario /home/jane/bin/example-client-go-exec-plugin será executado.
- name:my-useruser:exec:# Caminho relativo para o diretorio do kubeconfigcommand:"./bin/example-client-go-exec-plugin"apiVersion:"client.authentication.k8s.io/v1beta1"
Formatos de entrada e saída
O comando executado imprime um objeto ExecCredential para o stdout. k8s.io/client-go
autentica na API do Kubernetes utilizando as credenciais retornadas no status.
Quando executando uma sessão interativa, stdin é exposto diretamente para o plugin. plugins devem utilizar
um TTY check para determinar se é
apropriado solicitar um usuário interativamente.
Para usar credenciais do tipo bearer token, o plugin retorna um token no status do objeto ExecCredential.
Alternativamente, um certificado de cliente e chave codificados em PEM podem ser retornados para serem utilizados em autenticação de cliente TLS.
Se o plugin retornar um certificado e chave diferentes numa chamada subsequente, k8s.io/client-go
Irá fechar conexões existentes com o servidor para forçar uma nova troca TLS.
Se especificado, clientKeyData e clientCertificateData devem ambos estar presentes.
clientCertificateData pode conter certificados intermediários adicionais a serem enviados para o servidor.
Opcionalmente, a resposta pode incluir a validade da credencial em formato
RFC3339 de data/hora. A presença ou ausência de validade pode ter o seguinte impacto:
Se uma validade está incluída, o bearer token e as credenciais TLS são guardadas em cache até
a o tempo de expiração é atingido ou se o servidor responder com um codigo de status HTTP 401
ou se o processo terminar.
Se uma validate está ausente, o bearer token e as credenciais TLS são guardadas em cache até
o servidor responder com um código de status HTTP 401 ou até o processo terminar.
Para habilitar o plugin de execução para obter informações específicas do cluster, define provideClusterInfo no campo user.exec
dentro do arquivo de configuração kubeconfig.
O plugin irá então prover a variável de ambiente KUBERNETES_EXEC_INFO.
As informações desta variável de ambiente podem ser utilizadas para executar lógicas de aquisição
de credentiais específicas do cluster.
O manifesto ExecCredential abaixo descreve um exemplo de informação de cluster.
{
"apiVersion": "client.authentication.k8s.io/v1beta1",
"kind": "ExecCredential",
"spec": {
"cluster": {
"server": "https://172.17.4.100:6443",
"certificate-authority-data": "LS0t...",
"config": {
"arbitrary": "config",
"this": "pode ser fornecido por meio da variável de ambiente KUBERNETES_EXEC_INFO na configuração de provideClusterInfo",
"you": ["coloque", "qualquer", "coisa", "aqui"]
}
}
}
}
6.3 - Autenticando com Tokens de Inicialização
ESTADO DA FUNCIONALIDADE:Kubernetes v1.18 [stable]
Os tokens de inicialização são um bearer token simples que devem ser utilizados
ao criar novos clusters ou para quando novos nós são registrados a clusters existentes. Eles foram construídos
para suportar a ferramenta kubeadm, mas podem ser utilizados em outros contextos para usuários que desejam inicializar clusters sem utilizar o kubeadm.
Foram também construídos para funcionar, via políticas RBAC, com o sistema de Inicialização do Kubelet via TLS.
Visão geral dos tokens de inicialização
Os tokens de inicialização são definidos com um tipo especifico de secrets (bootstrap.kubernetes.io/token) que existem no namespace kube-system. Estes secrets são então lidos pelo autenticador de inicialização do servidor de API.
Tokens expirados são removidos pelo controlador TokenCleaner no gerenciador de controle - kube-controller-manager.
Os tokens também são utilizados para criar uma assinatura para um ConfigMap específico usado no processo de descoberta através de um controlador denominado BootstrapSigner.
Formato do Token
Tokens de inicialização tem o formato abcdef.0123456789abcdef. Mais formalmente, eles devem corresponder a expressão regular [a-z0-9]{6}\.[a-z0-9]{16}.
A primeira parte do token é um identificador ("Token ID") e é considerado informação pública.
Ele é utilizado para se referir a um token sem vazar a parte secreta usada para autenticação.
A segunda parte é o secret do token e somente deve ser compartilhado com partes confiáveis.
Habilitando autenticação com tokens de inicialização
O autenticador de tokens de inicialização pode ser habilitado utilizando a seguinte opção no servidor de API:
--enable-bootstrap-token-auth
Quando habilitado, tokens de inicialização podem ser utilizado como credenciais bearer token
para autenticar requisições no servidor de API.
Authorization: Bearer 07401b.f395accd246ae52d
Tokens são autenticados como o usuário system:bootstrap:<token id> e são membros
do grupo system:bootstrappers. Grupos adicionais podem ser
especificados dentro do secret do token.
Tokens expirados podem ser removidos automaticamente ao habilitar o controlador tokencleaner
do gerenciador de controle - kube-controller-manager.
--controllers=*,tokencleaner
Formato do secret dos tokens de inicialização
Cada token válido possui um secret no namespace kube-system. Você pode
encontrar a documentação completa aqui.
Um secret de token se parece com o exemplo abaixo:
apiVersion:v1kind:Secretmetadata:# Nome DEVE seguir o formato "bootstrap-token-<token id>"name:bootstrap-token-07401bnamespace:kube-system# Tipo DEVE ser 'bootstrap.kubernetes.io/token'type:bootstrap.kubernetes.io/tokenstringData:# Descrição legível. Opcional.description:"The default bootstrap token generated by 'kubeadm init'."# identificador do token e _secret_. Obrigatório.token-id:07401btoken-secret:f395accd246ae52d# Validade. Opcional.expiration:2017-03-10T03:22:11Z# Usos permitidos.usage-bootstrap-authentication:"true"usage-bootstrap-signing:"true"# Grupos adicionais para autenticar o token. Devem começar com "system:bootstrappers:"auth-extra-groups:system:bootstrappers:worker,system:bootstrappers:ingress
O tipo do secret deve ser bootstrap.kubernetes.io/token e o nome deve seguir o formato bootstrap-token-<token id>. Ele também tem que existir no namespace kube-system.
Os membros listados em usage-bootstrap-* indicam qual a intenção de uso deste secret. O valor true deve ser definido para que seja ativado.
usage-bootstrap-authentication indica que o token pode ser utilizado para autenticar no servidor de API como um bearer token.
usage-bootstrap-signing indica que o token pode ser utilizado para assinar o ConfigMap cluster-info como descrito abaixo.
O campo expiration controla a expiração do token. Tokens expirados são
rejeitados quando usados para autenticação e ignorados durante assinatura de ConfigMaps.
O valor de expiração é codificado como um tempo absoluto UTC utilizando a RFC3339. Para automaticamente
remover tokens expirados basta habilitar o controlador tokencleaner.
Gerenciamento de tokens com kubeadm
Você pode usar a ferramenta kubeadm para gerenciar tokens em um cluster. Veja documentação de tokens kubeadm para mais detalhes.
Assinatura de ConfigMap
Além de autenticação, os tokens podem ser utilizados para assinar um ConfigMap. Isto pode
ser utilizado em estágio inicial do processo de inicialização de um cluster, antes que o cliente confie
no servidor de API. O Configmap assinado pode ser autenticado por um token compartilhado.
Habilite a assinatura de ConfigMap ao habilitar o controlador bootstrapsigner no gerenciador de controle - kube-controller-manager.
--controllers=*,bootstrapsigner
O ConfigMap assinado é o cluster-info no namespace kube-public.
No fluxo típico, um cliente lê o ConfigMap enquanto ainda não autenticado
e ignora os erros da camada de transporte seguro (TLS).
Ele então valida o conteúdo do ConfigMap ao verificar a assinatura contida no ConfigMap.
O membro kubeconfig do ConfigMap é um arquivo de configuração contendo somente
as informações do cluster preenchidas. A informação chave sendo comunicada aqui
está em certificate-authority-data. Isto poderá ser expandido no futuro.
A assinatura é feita utilizando-se assinatura JWS em modo "separado". Para validar
a assinatura, o usuário deve codificar o conteúdo do kubeconfig de acordo com as regras do JWS
(codificando em base64 e descartando qualquer = ao final). O conteúdo codificado
e então usado para formar um JWS inteiro, inserindo-o entre os 2 pontos. Você pode
verificar o JWS utilizando o esquema HS256 (HMAC-SHA256) com o token completo
(por exemplo: 07401b.f395accd246ae52d) como o secret compartilhado. Usuários devem
verificar que o algoritmo HS256 (que é um método de assinatura simétrica) está sendo utilizado.
Aviso:
Qualquer parte em posse de um token de inicialização pode criar uma assinatura válida
daquele token. Não é recomendável, quando utilizando assinatura de ConfigMap, que se compartilhe
o mesmo token com muitos clientes, uma vez que um cliente comprometido pode abrir brecha para potenciais
"homem no meio" entre outro cliente que confia na assinatura para estabelecer inicialização via camada de transporte seguro (TLS).
O Kubeadm é uma ferramenta criada para fornecer o kubeadm init e o kubeadm join como "caminhos rápidos" de melhores práticas para criar clusters Kubernetes.
O kubeadm executa as ações necessárias para colocar um cluster minimamente viável em funcionamento, e foi projetado para se preocupar apenas com a inicialização e não com o provisionamento de máquinas. Da mesma forma, a instalação de vários complementos úteis, como o Kubernetes Dashboard, soluções de monitoramento e complementos específicos da nuvem, não está no escopo.
Em vez disso, esperamos que ferramentas de alto nível e mais personalizadas sejam construídas em cima do kubeadm e, idealmente, usando o kubeadm como base de todas as implantações torná mais fácil a criação de clusters em conformidade.
O arquivo kubeconfig usado na comunicação com o cluster. Se a flag não estiver definida, um conjunto de locais padrão pode ser pesquisado em busca de um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.4 -
Gerar chaves e solicitações de assinatura de certificados
Sinopse
Gera as chaves e as solicitações de assinatura de certificados (CSRs) para todos os certificados necessários para executar a camada de gerenciamento. Este comando também gera os arquivos kubeconfig parciais com dados de chave privada no campo "users > user > client-key-data" e, para cada arquivo kubeconfig, um arquivo ".csr" correspondente é criado.
Esse comando foi projetado para uso no modo de CA externo do Kubeadm. Ele gera CSRs que você pode enviar à sua autoridade de certificação externa para assinatura.
Os certificados PEM assinados e codificados devem ser salvos juntamente com os arquivos da chave, usando ".crt" como extensão de arquivo ou, no caso de arquivos kubeconfig, o certificado assinado codificado no formato PEM deve ser codificado em base64 e adicionado ao arquivo kubeconfig no campo "users > user > client-certificate-data".
kubeadm certs generate-csr [flags]
Exemplos
# O comando a seguir gera as chaves e CSRs para todos os certificados do plano de controle e arquivos kubeconfig:
kubeadm certs generate-csr --kubeconfig-dir /tmp/etc-k8s --cert-dir /tmp/etc-k8s/pki
Opções
--cert-dir string
O caminho para salvar os certificados
--config string
Caminho para um arquivo de configuração kubeadm.
-h, --help
ajuda para generate-csr
--kubeconfig-dir string Padrão: "/etc/kubernetes"
O caminho para salvar o arquivo kubeconfig.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.5 -
Renove certificados para um cluster Kubernetes
Sinopse
Este comando não deve ser executado sozinho. Veja a lista de subcomandos disponíveis.
kubeadm certs renew [flags]
Opções
-h, --help
ajuda para renew
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.6 -
Renove o certificado incorporado no arquivo kubeconfig para o administrador e o kubeadm usarem
Sinopse
Renove o certificado incorporado no arquivo kubeconfig para o administrador e o kubeadm usarem.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar a API de certificados do K8s para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
kubeadm certs renew admin.conf [flags]
Opções
--cert-dir string Padrão: "/etc/kubernetes/pki"
O caminho para salvar os certificados.
--config string
O caminho para um arquivo de configuração kubeadm.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.7 -
Renovar todos os certificados disponíveis
Sinopse
Renove todos os certificados conhecidos e necessários para executar a camada de gerenciamento. As renovações são executadas incondicionalmente, independentemente da data de expiração. As renovações também podem ser executadas individualmente para obter mais controle.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.8 -
Renove o certificado que o apiserver usa para acessar o etcd.
Sinopse
Renove o certificado que o apiserver usa para acessar o etcd.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar a API de certificado K8s para renovação do certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.9 -
Renove o certificado para o servidor API se conectar ao kubelet
Sinopse
Renove o certificado para o servidor da API se conectar ao kubelet.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar a API de certificado do K8s para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.10 -
Renove o certificado para servir a API do Kubernetes
Sinopse
Renove o certificado para servir a API do Kubernetes.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.11 -
Renove o certificado incorporado no arquivo kubeconfig para o uso do gerenciador de controladores.
Sinopse
Renove o certificado incorporado no arquivo kubeconfig para o uso do gerenciador de controladores.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.12 -
Renove o certificado para liveness probes para verificar a integridade do etcd
Sinopse
Renove o certificado para liveness probes para verificar a integridade do etcd.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.13 -
Renove o certificado para nós etcd se comunicarem uns com os outros
Sinopse
Renove o certificado para nós etcd se comunicarem uns com os outros.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.14 -
Renove o certificado para servir o etcd
Sinopse
Renove o certificado para servir o etcd.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.15 -
Renove o certificado para o cliente front proxy
Sinopse
Renove o certificado para o cliente front proxy.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.16 -
Renove o certificado incorporado no arquivo kubeconfig para o gerenciador de agendamento usar
Sinopse
Renove o certificado incorporado no arquivo kubeconfig para o gerenciador de agendamento usar.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.17 -
Exibe uma lista de imagens que o kubeadm usará. O arquivo de configuração é usado caso quaisquer imagens ou repositórios de imagens sejam personalizados.
Sinopse
Exibe uma lista de imagens que o kubeadm usará. O arquivo de configuração é usado caso quaisquer imagens ou repositórios de imagens sejam personalizados.
kubeadm config images list [flags]
Opções
--allow-missing-template-keys Padrão: true
Se verdadeiro (true), ignore quaisquer erros nos modelos quando um campo ou chave de mapa estiver faltando no modelo. Aplica-se apenas aos formatos de saída golang e jsonpath.
--config string
Caminho para um arquivo de configuração kubeadm.
-o, --experimental-output string Padrão: "text"
Formato de saída. Valores válidos: text|json|yaml|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
--feature-gates string
Um conjunto de pares chave=valor que descrevem opções para vários recursos. As opções são: PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false) UnversionedKubeletConfigMap=true|false (ALPHA - padrão=false)
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.18 -
Puxe imagens usadas pelo kubeadm
Sinopse
Baixa imagens usadas pelo kubeadm
kubeadm config images pull [flags]
Opções
--config string
Caminho para um arquivo de configuração kubeadm.
--cri-socket string
Caminho para se conectar ao socket CRI. Se vazio, o kubeadm tentará detectar automaticamente esse valor; use essa opção somente se você tiver mais de um CRI instalado ou se tiver um socket CRI não padrão.
--feature-gates string
Um conjunto de pares chave=valor que descrevem feature gates para vários recursos. As opções são: PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false) UnversionedKubeletConfigMap=true|false (ALPHA - padrão=false)
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.19 -
Leia uma versão mais antiga dos tipos de API de configuração do kubeadm a partir de um arquivo e envie o objeto de configuração semelhante para a versão mais recente
Sinopse
Esse comando permite converter objetos de configuração de versões mais antigas para a versão mais recente suportada, localmente na ferramenta CLI sem nunca tocar em nada no cluster. Nesta versão do kubeadm, as seguintes versões da API são suportadas:
Kubeadm.k8s.io/v1beta3
Além disso, o kubeadm só pode escrever a configuração da versão "kubeadm.k8s.io/v1beta3", mas pode ler os dois tipos. Portanto, independentemente da versão que você passar para o parâmetro --old-config , o objeto API será lido, desserializado, padronizado, convertido, validado e serializado novamente quando escrito no stdout ou --new-config, se especificado.
Em outras palavras, a saída deste comando é o que o kubeadm realmente leria internamente se você enviasse este arquivo para "kubeadm init"
kubeadm config migrate [flags]
Opções
-h, --help
ajuda para migrate
--new-config string
Caminho para o arquivo de configuração kubeadm equivalente usando a nova versão da API. Opcional, se não for especificado, a saída será enviada para o STDOUT.
--old-config string
Caminho para o arquivo de configuração do kubeadm que está usando uma versão antiga da API e que deve ser convertido. Essa flag é obrigatória.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.21 -
Exibe a configuração de inicialização padrão, que pode ser usada para 'kubeadm init'
Sinopse
Este comando exibe objetos, como a configuração de inicialização padrão que é usada para 'kubeadm init'.
Observe que os valores confidenciais, como os campos do Token Bootstrap, são substituídos por valores de exemplo como "abcdef.0123456789abcdef", a fim de passar na validação, mas não executar o cálculo real para criar um token.
kubeadm config print init-defaults [flags]
Opções
--component-configs strings
Uma lista dos objetos da API de configuração, separados por vírgulas, exibirá os valores padrão. Valores disponíveis: [KubeProxyConfiguration KubeletConfiguration]. Se essa flag não estiver definida, nenhuma configuração de componente será impressa.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.22 -
Exibe a configuração padrão do join, que pode ser usada para 'kubeadm join'
Sinopse
Este comando exibe objetos como a configuração padrão de join que é usada para 'kubeadm join'.
Observe que valores confidenciais, como os campos do Token Bootstrap, são substituídos por valores de exemplo como "abcdef.0123456789abcdef", a fim de passar na validação, mas não executar o cálculo real para criar um token.
kubeadm config print join-defaults [flags]
Opções
--component-configs strings
Uma lista dos objetos da API de configuração, separados por vírgulas, exibirá os valores padrão. Valores disponíveis: [KubeProxyConfiguration KubeletConfiguration]. Se essa flag não estiver definida, nenhuma configuração de componente será impressa.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.23 -
Rode este comando para configurar a camada de gerenciamento do Kubernetes
Sinopse
Rode este comando para configurar a camada de gerenciamento do Kubernetes
O comando "init" executa as fases abaixo:
preflight Efetua as verificações pré-execução
certs Geração de certificados
/ca Gera a autoridade de certificação (CA) auto-assinada do Kubernetes para provisionamento de identidades para outros componentes do Kubernetes
/apiserver Gera o certificado para o servidor da API do Kubernetes
/apiserver-kubelet-client Gera o certificado para o servidor da API se conectar ao Kubelet
/front-proxy-ca Gera a autoridade de certificação (CA) auto-assinada para provisionamento de identidades para o front proxy
/front-proxy-client Gera o certificado para o cliente do front proxy
/etcd-ca Gera a autoridade de certificação (CA) auto-assinada para provisionamento de identidades para o etcd
/etcd-server Gera o certificado para servir o etcd
/etcd-peer Gera o certificado para comunicação entre nós do etcd
/etcd-healthcheck-client Gera o certificado para liveness probes fazerem a verificação de integridade do etcd
/apiserver-etcd-client Gera o certificado que o servidor da API utiliza para comunicar-se com o etcd
/sa Gera uma chave privada para assinatura de tokens de conta de serviço, juntamente com sua chave pública
kubeconfig Gera todos os arquivos kubeconfig necessários para estabelecer a camada de gerenciamento e o arquivo kubeconfig de administração
/admin Gera um arquivo kubeconfig para o administrador e o próprio kubeadm utilizarem
/kubelet Gera um arquivo kubeconfig para o kubelet utilizar *somente* para fins de inicialização do cluster
/controller-manager Gera um arquivo kubeconfig para o gerenciador de controladores utilizar
/scheduler Gera um arquivo kubeconfig para o escalonador do Kubernetes utilizar
kubelet-start Escreve as configurações do kubelet e (re)inicializa o kubelet
control-plane Gera todos os manifestos de Pods estáticos necessários para estabelecer a camada de gerenciamento
/apiserver Gera o manifesto do Pod estático do kube-apiserver
/controller-manager Gera o manifesto do Pod estático do kube-controller-manager
/scheduler Gera o manifesto do Pod estático do kube-scheduler
etcd Gera o manifesto do Pod estático para um etcd local
/local Gera o manifesto do Pod estático para uma instância local e de nó único do etcd
upload-config Sobe a configuração do kubeadm e do kubelet para um ConfigMap
/kubeadm Sobe a configuração ClusterConfiguration do kubeadm para um ConfigMap
/kubelet Sobe a configuração do kubelet para um ConfigMap
upload-certs Sobe os certificados para o kubeadm-certs
mark-control-plane Marca um nó como parte da camada de gerenciamento
bootstrap-token Gera tokens de autoinicialização utilizados para associar um nó a um cluster
kubelet-finalize Atualiza configurações relevantes ao kubelet após a inicialização TLS
/experimental-cert-rotation Habilita rotação de certificados do cliente do kubelet
addon Instala os addons requeridos para passar nos testes de conformidade
/coredns Instala o addon CoreDNS em um cluster Kubernetes
/kube-proxy Instala o addon kube-proxy em um cluster Kubernetes
kubeadm init [flags]
Opções
--apiserver-advertise-address string
O endereço IP que o servidor da API irá divulgar que está escutando. Quando não informado, a interface de rede padrão é utilizada.
--apiserver-bind-port int32 Padrão: 6443
Porta para o servidor da API conectar-se.
--apiserver-cert-extra-sans strings
Nomes alternativos (Subject Alternative Names, ou SANs) opcionais a serem adicionados ao certificado utilizado pelo servidor da API. Pode conter endereços IP ou nomes DNS.
--cert-dir string Padrão: "/etc/kubernetes/pki"
O caminho para salvar e armazenar certificados.
--certificate-key string
Chave utilizada para encriptar os certificados da camada de gerenciamento no Secret kubeadm-certs.
--config string
Caminho para um arquivo de configuração do kubeadm.
--control-plane-endpoint string
Especifica um endereço IP estável ou nome DNS para a camada de gerenciamento.
--cri-socket string
Caminho para o soquete CRI se conectar. Se vazio, o kubeadm tentará autodetectar este valor; utilize esta opção somente se você possui mais que um CRI instalado ou se você possui um soquete CRI fora do padrão.
--dry-run
Não aplica as modificações; apenas imprime as alterações que seriam efetuadas.
--feature-gates string
Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são: PublicKeysECDSA=true|false (ALFA - padrão=false) RootlessControlPlane=true|false (ALFA - padrão=false) UnversionedKubeletConfigMap=true|false (BETA - padrão=true)
-h, --help
ajuda para init
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
Seleciona um registro de contêineres de onde baixar imagens.
--kubernetes-version string Padrão: "stable-1"
Seleciona uma versão do Kubernetes específica para a camada de gerenciamento.
--node-name string
Especifica o nome do nó.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json".
"target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd".
"patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic".
"extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--pod-network-cidr string
Especifica um intervalo de endereços IP para a rede do Pod. Quando especificado, a camada de gerenciamento irá automaticamente alocar CIDRs para cada nó.
--service-cidr string Padrão: "10.96.0.0/12"
Utiliza um intervalo alternativo de endereços IP para VIPs de serviço.
Utiliza um domínio alternativo para os serviços. Por exemplo, "myorg.internal".
--skip-certificate-key-print
Não exibe a chave utilizada para encriptar os certificados da camada de gerenciamento.
--skip-phases strings
Lista de fases a serem ignoradas.
--skip-token-print
Pula a impressão do token de autoinicialização padrão gerado pelo comando 'kubeadm init'.
--token string
O token a ser utilizado para estabelecer confiança bidirecional entre nós de carga de trabalho e nós da camada de gerenciamento. O formato segue a expressão regular [a-z0-9]{6}.[a-z0-9]{16} - por exemplo, abcdef.0123456789abcdef.
--token-ttl duration Padrão: 24h0m0s
A duração de tempo de um token antes deste ser automaticamente apagado (por exemplo, 1s, 2m, 3h). Quando informado '0', o token não expira.
--upload-certs
Sobe os certificados da camada de gerenciamento para o Secret kubeadm-certs.
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
6.4.1.1.24 -
Rode este comando em qualquer máquina que você deseje adicionar a um cluster
existente
Sinopse
Ao associar um novo nó a um cluster inicializado com kubeadm, temos que
estabelecer a confiança bidirecional. Este processo é dividido entre a descoberta
(em que o nó estabelece a confiança na camada de gerenciamento do Kubernetes) e
a inicialização TLS (em que a camada de gerenciamento do Kubernetes estabelece a
confiança no nó).
Existem duas principais formas de descoberta. A primeira delas é o uso de um
token compartilhado, juntamente com o endereço IP do servidor da API. A segunda
é o fornecimento de um arquivo - um subconjunto do arquivo kubeconfig padrão. O
arquivo de descoberta/kubeconfig suporta autenticação por token, plugins de
autenticação do client-go ("exec"), "tokenFile" e "authProvider". Este arquivo
pode ser um arquivo local ou um arquivo baixado através de uma URL HTTPS. Os
formatos são kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443,
kubeadm join --discovery-file caminho/para/arquivo.conf, ou
kubeadm join --discovery-file https://endereco/arquivo.conf. Somente um formato
pode ser utilizado. Se os dados para a descoberta são carregados de uma URL,
o protocolo HTTPS deve ser utilizado. Neste caso, o conjunto de CAs instalado no
host é utilizado para verificar a conexão.
Se você utilizou um token compartilhado para descoberta, você deve também passar
a opção --discovery-token-ca-cert-hash para validar a chave pública da
autoridade de certificação raiz (CA) apresentada pela camada de gerenciamento do
Kubernetes. O valor desta opção é especificado no formato
"<tipo-de-hash>:<valor-codificado-em-hexadecimal>", onde o tipo de
hash suportado é "sha256". O hash é calculado a partir dos bytes do objeto
Subject Public Key Info (SPKI), como especificado pela RFC7469. Este valor fica
disponível na saída do comando kubeadm init ou pode ser calculado utilizando
ferramentas padronizadas. A opção --discovery-token-ca-cert-hash pode ser
especificada múltiplas vezes para permitir informar mais que uma chave pública.
Se você não puder obter o hash da chave pública da autoridade de certificação
de antemão, você pode passar a opção --discovery-token-unsafe-skip-ca-verification
para desabilitar esta verificação. Esta opção enfraquece o modelo de segurança
do kubeadm, já que outros nós podem potencialmente personificar a camada de
gerenciamento do Kubernetes.
O mecanismo de inicialização TLS também é conduzido por um token compartilhado.
Este token é utilizado para temporariamente autenticar-se com a camada de
gerenciamento do Kubernetes para enviar uma requisição de assinatura de
certificado (CSR) para um par de chaves criado localmente. Por padrão, o kubeadm
irá configurar a camada de gerenciamento do Kubernetes para automaticamente
aprovar estas requisições de assinatura. O token é enviado através da opção
--tls-bootstrap-token abcdef.1234567890abcdef.
Frequentemente, o mesmo token é utilizado para ambas as partes. Neste caso, a
opção --token pode ser utilizada ao invés de especificar cada token
individualmente.
O comando join [api-server-endpoint] executa as seguintes fases:
preflight Executa as verificações pré-execução
control-plane-prepare Prepara a máquina para servir um nó da camada de gerenciamento
/download-certs [EXPERIMENTAL] Baixa certificados compartilhados entre nós da camada de gerenciamento do Secret kubeadm-certs
/certs Gera os certificados para os novos componentes da camada de gerenciamento
/kubeconfig Gera o arquivo kubeconfig para os novos componentes da camada de gerenciamento
/control-plane Gera os manifestos para os novos componentes da camada de gerenciamento
kubelet-start Escreve as configurações do kubelet, os certificados, e (re)inicia o kubelet
control-plane-join Associa uma máquina como uma instância da camada de gerenciamento
/etcd Adiciona como um novo membro do etcd local
/update-status Registra o novo nó da camada de gerenciamento no objeto ClusterStatus mantido no ConfigMap kubeadm-config (DESCONTINUADO)
/mark-control-plane Marca um nó como nó da camada de gerenciamento
kubeadm join [api-server-endpoint] [flags]
Opções
--apiserver-advertise-address string
Se o nó hospedar uma nova instância da camada de gerenciamento, este é o endereço IP que servidor da API irá anunciar que
está aguardando conexões. Quando não especificado, a interface de rede padrão é utilizada.
--apiserver-bind-port int32 Default: 6443
Se o nó hospedar uma nova instância da camada de gerenciamento, a porta que o servidor da API deve conectar-se.
--certificate-key string
Chave utilizada para decriptar as credenciais do certificado enviadas pelo comando init.
--config string
Caminho para um arquivo de configuração do kubeadm.
--control-plane
Cria uma nova instância da camada de gerenciamento neste nó.
--cri-socket string
Caminho para o soquete CRI conectar-se. Se vazio, o kubeadm tentará autodetectar este valor; utilize esta opção somente se você possui mais que um CRI instalado ou se você possui um soquete CRI fora do padrão.
--discovery-file string
Para descoberta baseada em arquivo, um caminho de arquivo ou uma URL de onde a informação do cluster deve ser carregada.
--discovery-token string
Para descoberta baseada em token, o token utilizado para validar a informação do cluster obtida do servidor da API.
--discovery-token-ca-cert-hash strings
Para descoberta baseada em token, verifica que a chave pública do CA raiz corresponde a este hash
(formato: "<tipo>:<valor>").
--discovery-token-unsafe-skip-ca-verification
Para descoberta baseada em token, permite associar-se ao cluster sem fixação da
autoridade de certificação (opção --discovery-token-ca-cert-hash).
--dry-run
Não aplica as modificações; apenas imprime as alterações que seriam efetuadas.
-h, --help
ajuda para join
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
--node-name string
Especifica o nome do nó.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--skip-phases strings
Lista de fases a serem ignoradas.
--tls-bootstrap-token string
Especifica o token a ser utilizado para autenticar temporariamente com a camada de gerenciamento do Kubernetes durante
o processo de associação do nó ao cluster.
--token string
Utiliza este token em ambas as opções discovery-token e tls-bootstrap-token quando tais valores não são informados.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
6.4.1.1.25 -
Utilitários de arquivo Kubeconfig
Sinopse
Utilitários de arquivo Kubeconfig.
Opções
-h, --help
ajuda para kubeconfig
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.26 -
Saída do arquivo kubeconfig para um usuário adicional.
Sinopse
Exibe o arquivo kubeconfig para um usuário adicional.
kubeadm kubeconfig user [flags]
Exemplos
# Exibe um arquivo kubeconfig para um usuário adicional chamado foo usando um arquivo bar de configuração
kubeadm kubeconfig user --client-name=foo --config=bar
Opções
--client-name string
O nome do usuário. Será usado como CN se os certificados do cliente forem criados.
--config string
Caminho para um arquivo de configuração kubeadm.
-h, --help
ajuda para user
--org strings
As organizações do certificado do cliente. Será usado como O se os certificados de cliente forem criados.
--token string
O token que deve ser usado como mecanismo de autenticação para esse kubeconfig, em vez de certificados de cliente
--validity-period duração Padrão: 8760h0m0s
O período de validade do certificado do cliente. É um deslocamento da hora atual.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.27 -
Executa o melhor esforço para reverter as alterações feitas no host por 'kubeadm init' ou 'kubeadm join'
Sinopse
Executa o melhor esforço para reverter as alterações feitas no host por 'kubeadm init' ou 'kubeadm join'
O comando "reset" executa as seguintes fases:
preflight Executa as verificações pré-execução do preflight.
remove-etcd-member Remove um membro etcd local.
cleanup-node Executa a limpeza do nó.
kubeadm reset [flags]
Opções
--cert-dir string Padrão: "/etc/kubernetes/pki"
O caminho para o diretório onde os certificados estão armazenados. Se especificado, limpe este diretório.
--cri-socket string
Caminho para o socket CRI se conectar. Se vazio, o kubeadm tentará detectar automaticamente esse valor; use essa opção somente se você tiver mais de um CRI instalado ou se tiver um socket CRI não padrão.
-f, --force
Redefine o nó sem solicitar confirmação..
-h, --help
ajuda para reset
--ignore-preflight-errors strings
Uma lista de verificações cujos erros serão mostrados como avisos. Exemplo: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--skip-phases strings
Lista de fases a serem ignoradas
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.28 -
Crie tokens de inicialização no servidor
Sinopse
Este comando criará um token de inicialização. Você pode especificar os usos para este token, o "tempo de vida" e uma descrição amigável, que é opcional.
O [token] é o token real para gravar. Este deve ser um token aleatório gerado com segurança da forma "[a-z0-9]{6}.[a-z0-9]{16}". Se nenhum [token] for fornecido, o kubeadm gerará um token aleatório.
kubeadm token create [token]
Opções
--certificate-key string
Quando usado em conjunto com '--print-join-command', exibe a flag completa 'kubeadm join' necessária para se unir ao cluster como um nó de camada de gerenciamento. Para criar uma nova chave de certificado, você deve usar 'kubeadm init phase upload-certs --upload-certs'.
--config string
Caminho para o arquivo de configuração kubeadm.
--description string
Uma descrição amigável de como esse token é usado.
Grupos extras que este token autenticará quando usado para autenticação. Deve corresponder "\Asystem:bootstrappers:[a-z0-9:-]{0,255}[a-z0-9]\z"
-h, --help
ajuda para create
--print-join-command
Em vez de exibir apenas o token, exibe a flag completa 'kubeadm join' necessária para se associar ao cluster usando o token.
--ttl duração Padrão: 24h0m0s
A duração antes do token ser excluído automaticamente (por exemplo, 1s, 2m, 3h). Se definido como '0', o token nunca expirará
--usages strings Padrão: "signing,authentication"
Descreve as maneiras pelas quais esse token pode ser usado. Você pode passar --usages várias vezes ou fornecer uma lista de opções separada por vírgulas. Opções válidas: [signing,authentication]
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.29 -
Excluir tokens de inicialização no servidor
Sinopse
Este comando excluirá uma lista de tokens de inicialização para você.
O [token-value] é um Token completo na forma "[a-z0-9]{6}.[a-z0-9]{16}" ou o ID do Token na forma "[a-z0-9]{6}" a ser excluído.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.30 -
Gere e exiba um token de inicialização, mas não o crie no servidor
Sinopse
Este comando exibirá um token de inicialização gerado aleatoriamente que pode ser usado com os comandos "init" e "join".
Você não precisa usar este comando para gerar um token. Você pode fazer isso sozinho, desde que esteja no formato "[a-z0-9]{6}.[a-z0-9]{16}". Este comando é fornecido por conveniência para gerar tokens no formato fornecido.
Você também pode usar "kubeadm init" sem especificar um token e ele gerará e exibirá um para você.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.31 -
Liste tokens de inicialização no servidor
Sinopse
Este comando listará todos os tokens de inicialização para você
kubeadm token list [flags]
Opções
--allow-missing-template-keys Padrão: true
Se verdadeiro (true), ignora quaisquer erros nos modelos quando um campo ou chave de mapa estiver faltando no modelo. Aplica-se apenas aos formatos de saída golang e jsonpath.
-o, --experimental-output string Padrão: "text"
Formato de saída. Valores válidos: text|json|yaml|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
-h, --help
ajuda para list
--show-managed-fields
Se verdadeiro (true), mantém os managedFields ao exibir os objetos no formato JSON ou YAML.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.32 -
Atualiza o cluster Kubernetes para uma versão específica
Sinopse
Atualiza o cluster Kubernetes para uma versão específica
kubeadm upgrade apply [versão]
Opções
--allow-experimental-upgrades
Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/release candidate do Kubernetes.
--allow-release-candidate-upgrades
Exibe as versões candidatas a lançamento do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas a lançamento do Kubernetes.
--certificate-renewal Padrão: true
Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.
--config string
Caminho para um arquivo de configuração do kubeadm.
--dry-run
Não aplica as modificações; apenas exibe as alterações que seriam efetuadas.
--etcd-upgrade Padrão: true
Atualiza o etcd.
--feature-gates string
Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false)
-f, --force
Força a atualização, embora alguns requisitos possam não estar sendo atendidos. Isso também implica o modo não interativo.
-h, --help
ajuda para apply
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--print-config
Especifica se o arquivo de configuração que será usado na atualização deve ser exibido ou não.
-y, --yes
Executa a atualização e não solicita um prompt de confirmação (modo não interativo).
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
6.4.1.1.33 -
Mostra quais diferenças serão aplicadas aos manifestos dos Pods estáticos existentes. Veja também: kubeadm upgrade apply --dry-run
Sinopse
Mostra quais diferenças serão aplicadas aos manifestos dos Pods estáticos existentes. Veja também: kubeadm upgrade apply --dry-run
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
6.4.1.1.34 -
Comando para atualização de um nó no cluster
Sinopse
Comando para atualização de um nó no cluster
O comando "node" executa as seguintes fases:
preflight Executa as verificações de pré-atualização do nó
control-plane Atualiza a instância da camada de gerenciamento implantada neste nó, se houver
kubelet-config Atualiza a configuração do kubelet para este nó
kubeadm upgrade node [flags]
Opções
--certificate-renewal Padrão: true
Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.
--dry-run
Não aplica as modificações; apenas exibe as alterações que seriam efetuadas.
--etcd-upgrade Padrão: true
Atualiza o etcd.
-h, --help
ajuda para node
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--skip-phases strings
Lista de fases a serem ignoradas
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
6.4.1.1.35 -
Use este comando para invocar uma fase única do fluxo de trabalho do nó
Sinopse
Use este comando para invocar uma fase única do fluxo de trabalho do nó
Opções
-h, --help
ajuda para fase
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.36 -
Atualiza a instância da camada de gerenciamento instalada nesse nó, se houver
Sinopse
Atualiza a instância da camada de gerenciamento instalada nesse nó, se houver
kubeadm upgrade node phase control-plane [flags]
Opções
--certificate-renewal Padrão: true
Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.
--dry-run
Não altera nenhum estado, apenas produz as ações que seriam executadas.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, uma série de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--patches string
O caminho para um diretório que contém arquivos chamados "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou apenas "etcd.json". "target" são "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". "patchtype" pode ser um dos "strategic", "merge" or "json"e eles correspondem aos formatos de patch suportados pelo kubectl. O padrão "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional que pode ser usada para determinar a ordem de aplicação dos patches alfanumericamente.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.37 -
Atualize a configuração do kubelet para este nó
Sinopse
Baixa no cluster o ConfigMap de configuração do kubelet no formato "kubelet-config-1.X", onde X é a menor versão do kubelet. O kubeadm usa o campo KuberneteVersion no ConfigMap kubeadm-config para determinar qual é a versão desejada do kubelet.
kubeadm upgrade node phase kubelet-config [flags]
Opções
--dry-run
Não altera nenhum estado, apenas produz as ações que seriam executadas.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, uma série de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.38 -
Execute verificações antes de atualização do nó
Sinopse
Execute verificações antes de atualização do nó
kubeadm upgrade node phase preflight [flags]
Opções
-h, --help
ajuda para preflight
--ignore-preflight-errors strings
Uma lista de verificações cujos erros serão mostrados como avisos. Exemplo: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.1.39 -
Verifique quais versões estão disponíveis para atualizar e verifique se o seu cluster atual é atualizável.
Para pular a verificação da Internet, passe o parâmetro opcional [versão]
Sinopse
Verifique quais versões estão disponíveis para atualizar e verifique se o seu cluster atual é atualizável.
Para pular a verificação da Internet, passe o parâmetro opcional [versão]
kubeadm upgrade plan [versão] [flags]
Opções
--allow-experimental-upgrades
Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/release candidate do Kubernetes.
--allow-release-candidate-upgrades
Exibe as versões candidatas a lançamento do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas a lançamento do Kubernetes.
--config string
Caminho para um arquivo de configuração kubeadm.
--feature-gates string
Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false)
-h, --help
ajuda para plan
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
-o, --output string Padrão: "text"
EXPERIMENTAL: Formato de saída. Opções válidas: text|json|yaml.
--print-config
Especifica se o arquivo de configuração que será usado na atualização deve ser exibido ou não.
--show-managed-fields
Se verdadeiro, mantém os managedFields ao exibir os objetos no formato JSON ou YAML.
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
6.4.1.1.40 -
Exibe a versão do kubeadm
Sinopse
Exibe a versão do kubeadm
kubeadm version [flags]
Opções
-h, --help
ajuda para version
-o, --output string
Formato de saída; as opções disponíveis são 'yaml', 'json' e 'short'
Opção herdada do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.2 - kubeadm init
Este comando inicializa um nó da camada de gerenciamento do Kubernetes.
Rode este comando para configurar a camada de gerenciamento do Kubernetes
Sinopse
Rode este comando para configurar a camada de gerenciamento do Kubernetes
O comando "init" executa as fases abaixo:
preflight Efetua as verificações pré-execução
certs Geração de certificados
/ca Gera a autoridade de certificação (CA) auto-assinada do Kubernetes para provisionamento de identidades para outros componentes do Kubernetes
/apiserver Gera o certificado para o servidor da API do Kubernetes
/apiserver-kubelet-client Gera o certificado para o servidor da API se conectar ao Kubelet
/front-proxy-ca Gera a autoridade de certificação (CA) auto-assinada para provisionamento de identidades para o front proxy
/front-proxy-client Gera o certificado para o cliente do front proxy
/etcd-ca Gera a autoridade de certificação (CA) auto-assinada para provisionamento de identidades para o etcd
/etcd-server Gera o certificado para servir o etcd
/etcd-peer Gera o certificado para comunicação entre nós do etcd
/etcd-healthcheck-client Gera o certificado para liveness probes fazerem a verificação de integridade do etcd
/apiserver-etcd-client Gera o certificado que o servidor da API utiliza para comunicar-se com o etcd
/sa Gera uma chave privada para assinatura de tokens de conta de serviço, juntamente com sua chave pública
kubeconfig Gera todos os arquivos kubeconfig necessários para estabelecer a camada de gerenciamento e o arquivo kubeconfig de administração
/admin Gera um arquivo kubeconfig para o administrador e o próprio kubeadm utilizarem
/kubelet Gera um arquivo kubeconfig para o kubelet utilizar *somente* para fins de inicialização do cluster
/controller-manager Gera um arquivo kubeconfig para o gerenciador de controladores utilizar
/scheduler Gera um arquivo kubeconfig para o escalonador do Kubernetes utilizar
kubelet-start Escreve as configurações do kubelet e (re)inicializa o kubelet
control-plane Gera todos os manifestos de Pods estáticos necessários para estabelecer a camada de gerenciamento
/apiserver Gera o manifesto do Pod estático do kube-apiserver
/controller-manager Gera o manifesto do Pod estático do kube-controller-manager
/scheduler Gera o manifesto do Pod estático do kube-scheduler
etcd Gera o manifesto do Pod estático para um etcd local
/local Gera o manifesto do Pod estático para uma instância local e de nó único do etcd
upload-config Sobe a configuração do kubeadm e do kubelet para um ConfigMap
/kubeadm Sobe a configuração ClusterConfiguration do kubeadm para um ConfigMap
/kubelet Sobe a configuração do kubelet para um ConfigMap
upload-certs Sobe os certificados para o kubeadm-certs
mark-control-plane Marca um nó como parte da camada de gerenciamento
bootstrap-token Gera tokens de autoinicialização utilizados para associar um nó a um cluster
kubelet-finalize Atualiza configurações relevantes ao kubelet após a inicialização TLS
/experimental-cert-rotation Habilita rotação de certificados do cliente do kubelet
addon Instala os addons requeridos para passar nos testes de conformidade
/coredns Instala o addon CoreDNS em um cluster Kubernetes
/kube-proxy Instala o addon kube-proxy em um cluster Kubernetes
kubeadm init [flags]
Opções
--apiserver-advertise-address string
O endereço IP que o servidor da API irá divulgar que está escutando. Quando não informado, a interface de rede padrão é utilizada.
--apiserver-bind-port int32 Padrão: 6443
Porta para o servidor da API conectar-se.
--apiserver-cert-extra-sans strings
Nomes alternativos (Subject Alternative Names, ou SANs) opcionais a serem adicionados ao certificado utilizado pelo servidor da API. Pode conter endereços IP ou nomes DNS.
--cert-dir string Padrão: "/etc/kubernetes/pki"
O caminho para salvar e armazenar certificados.
--certificate-key string
Chave utilizada para encriptar os certificados da camada de gerenciamento no Secret kubeadm-certs.
--config string
Caminho para um arquivo de configuração do kubeadm.
--control-plane-endpoint string
Especifica um endereço IP estável ou nome DNS para a camada de gerenciamento.
--cri-socket string
Caminho para o soquete CRI se conectar. Se vazio, o kubeadm tentará autodetectar este valor; utilize esta opção somente se você possui mais que um CRI instalado ou se você possui um soquete CRI fora do padrão.
--dry-run
Não aplica as modificações; apenas imprime as alterações que seriam efetuadas.
--feature-gates string
Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são: PublicKeysECDSA=true|false (ALFA - padrão=false) RootlessControlPlane=true|false (ALFA - padrão=false) UnversionedKubeletConfigMap=true|false (BETA - padrão=true)
-h, --help
ajuda para init
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
Seleciona um registro de contêineres de onde baixar imagens.
--kubernetes-version string Padrão: "stable-1"
Seleciona uma versão do Kubernetes específica para a camada de gerenciamento.
--node-name string
Especifica o nome do nó.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json".
"target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd".
"patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic".
"extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--pod-network-cidr string
Especifica um intervalo de endereços IP para a rede do Pod. Quando especificado, a camada de gerenciamento irá automaticamente alocar CIDRs para cada nó.
--service-cidr string Padrão: "10.96.0.0/12"
Utiliza um intervalo alternativo de endereços IP para VIPs de serviço.
Utiliza um domínio alternativo para os serviços. Por exemplo, "myorg.internal".
--skip-certificate-key-print
Não exibe a chave utilizada para encriptar os certificados da camada de gerenciamento.
--skip-phases strings
Lista de fases a serem ignoradas.
--skip-token-print
Pula a impressão do token de autoinicialização padrão gerado pelo comando 'kubeadm init'.
--token string
O token a ser utilizado para estabelecer confiança bidirecional entre nós de carga de trabalho e nós da camada de gerenciamento. O formato segue a expressão regular [a-z0-9]{6}.[a-z0-9]{16} - por exemplo, abcdef.0123456789abcdef.
--token-ttl duration Padrão: 24h0m0s
A duração de tempo de um token antes deste ser automaticamente apagado (por exemplo, 1s, 2m, 3h). Quando informado '0', o token não expira.
--upload-certs
Sobe os certificados da camada de gerenciamento para o Secret kubeadm-certs.
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
Fluxo do comando Init
O comando kubeadm init inicializa um nó da camada de gerenciamento do Kubernetes
através da execução dos passos abaixo:
Roda uma série de verificações pré-execução para validar o estado do sistema
antes de efetuar mudanças. Algumas verificações emitem apenas avisos, outras
são consideradas erros e cancelam a execução do kubeadm até que o problema
seja corrigido ou que o usuário especifique a opção
--ignore-preflight-errors=<lista-de-erros-a-ignorar>.
Gera uma autoridade de certificação (CA) auto-assinada para criar identidades
para cada um dos componentes do cluster. O usuário pode informar seu próprio
certificado CA e/ou chave ao instalar estes arquivos no diretório de
certificados configurado através da opção --cert-dir (por padrão, este
diretório é /etc/kubernetes/pki).
Os certificados do servidor da API terão entradas adicionais para nomes
alternativos (subject alternative names, ou SANs) especificados através da
opção --apiserver-cert-extra-sans. Estes argumentos serão modificados para
caracteres minúsculos quando necessário.
Escreve arquivos kubeconfig adicionais no diretório /etc/kubernetes para o
kubelet, para o gerenciador de controladores e para o escalonador utilizarem
ao conectarem-se ao servidor da API, cada um com sua própria identidade, bem
como um arquivo kubeconfig adicional para administração do cluster chamado
admin.conf.
Gera manifestos de Pods estáticos para o servidor da API, para o gerenciador
de controladores e para o escalonador. No caso de uma instância externa do
etcd não ter sido providenciada, um manifesto de Pod estático adicional é
gerado para o etcd.
Manifestos de Pods estáticos são escritos no diretório /etc/kubernetes/manifests;
o kubelet lê este diretório em busca de manifestos de Pods para criar na
inicialização.
Uma vez que os Pods da camada de gerenciamento estejam criados e rodando,
a sequência de execução do comando kubeadm init pode continuar.
Aplica labels e taints ao nó da camada de gerenciamento de modo que cargas
de trabalho adicionais não sejam escalonadas para executar neste nó.
Gera o token que nós adicionais podem utilizar para associarem-se a uma
camada de gerenciamento no futuro. Opcionalmente, o usuário pode fornecer um
token através da opção --token, conforme descrito na documentação do
comando kubeadm token.
Prepara todas as configurações necessárias para permitir que nós se associem
ao cluster utilizando os mecanismos de
Tokens de Inicialização
e Inicialização TLS:
Escreve um ConfigMap para disponibilizar toda a informação necessária para
associar-se a um cluster e para configurar regras de controle de acesso
baseada em funções (RBAC).
Permite o acesso dos tokens de inicialização à API de assinaturas CSR.
Configura a auto-aprovação de novas requisições CSR.
Instala um servidor DNS (CoreDNS) e os componentes adicionais do kube-proxy
através do servidor da API. A partir da versão 1.11 do Kubernetes, CoreDNS é
o servidor DNS padrão. Mesmo que o servidor DNS seja instalado nessa etapa,
o seu Pod não será escalonado até que um CNI seja instalado.
Aviso:
O uso do kube-dns com o kubeadm foi descontinuado na versão v1.18 e removido
na versão v1.21 do Kubernetes.
Utilizando fases de inicialização com o kubeadm
O kubeadm permite que você crie um nó da camada de gerenciamento em fases
utilizando o comando kubeadm init phase.
Para visualizar a lista ordenada de fases e subfases, você pode rodar o comando
kubeadm init --help. A lista estará localizada no topo da ajuda e cada fase
tem sua descrição listada juntamente com o comando. Perceba que ao rodar o
comando kubeadm init todas as fases e subfases são executadas nesta ordem
exata.
Algumas fases possuem flags específicas. Caso você deseje ver uma lista de todas
as opções disponíveis, utilize a flag --help. Por exemplo:
Você também pode utilizar a flag --help para ver uma lista de subfases de uma
fase superior:
sudo kubeadm init phase control-plane --help
kubeadm init também expõe uma flag chamada --skip-phases que pode ser
utilizada para pular a execução de certas fases. Esta flag aceita uma lista de
nomes de fases. Os nomes de fases aceitos estão descritos na lista ordenada
acima.
Um exemplo:
sudo kubeadm init phase control-plane all --config=configfile.yaml
sudo kubeadm init phase etcd local --config=configfile.yaml
# agora você pode modificar os manifestos da camada de gerenciamento e do etcdsudo kubeadm init --skip-phases=control-plane,etcd --config=configfile.yaml
O que este exemplo faz é escrever os manifestos da camada de gerenciamento e do
etcd no diretório /etc/kubernetes/manifests, baseados na configuração descrita
no arquivo configfile.yaml. Isto permite que você modifique os arquivos e
então pule estas fases utilizando a opção --skip-phases. Ao chamar o último
comando, você cria um nó da camada de gerenciamento com os manifestos
personalizados.
ESTADO DA FUNCIONALIDADE:Kubernetes v1.22 [beta]
Como alternativa, você pode também utilizar o campo skipPhases na configuração
InitConfiguration.
Utilizando kubeadm init com um arquivo de configuração
Cuidado:
O arquivo de configuração ainda é considerado uma funcionalidade de estado beta
e pode mudar em versões futuras.
É possível configurar o comando kubeadm init com um arquivo de configuração ao
invés de argumentos de linha de comando, e algumas funcionalidades mais avançadas
podem estar disponíveis apenas como opções do arquivo de configuração. Este
arquivo é fornecido utilizando a opção --config e deve conter uma estrutura
ClusterConfiguration e, opcionalmente, mais estruturas separadas por ---\n.
Combinar a opção --config com outras opções de linha de comando pode não ser
permitido em alguns casos.
A configuração padrão pode ser emitida utilizando o comando
kubeadm config print.
Se a sua configuração não estiver utilizando a última versão, é recomendado
que você migre utilizando o comando
kubeadm config migrate.
Para mais informações sobre os campos e utilização da configuração, você pode
consultar a
página de referência da API.
Utilizando kubeadm init com feature gates
O kubeadm suporta um conjunto de feature gates que são exclusivos do kubeadm e
podem ser utilizados somente durante a criação de um cluster com kubeadm init.
Estas funcionalidades podem controlar o comportamento do cluster. Os
feature gates são removidos assim que uma funcionalidade atinge a disponibilidade
geral (general availability, ou GA).
Para informar um feature gate, você pode utilizar a opção --feature-gates
do comando kubeadm init, ou pode adicioná-las no campo featureGates quando
um arquivo de configuração
é utilizado através da opção --config.
Assim que um feature gate atinge a disponibilidade geral, ele é removido desta
lista e o seu valor fica bloqueado em true por padrão. Ou seja, a funcionalidade
estará sempre ativa.
Descrição dos feature gates:
PublicKeysECDSA
Pode ser utilizado para criar um cluster que utilize certificados ECDSA no
lugar do algoritmo RSA padrão. A renovação dos certificados ECDSA existentes
também é suportada utilizando o comando kubeadm certs renew, mas você não pode
alternar entre os algoritmos RSA e ECDSA dinamicamente ou durante atualizações.
RootlessControlPlane
Quando habilitada esta opção, os componentes da camada de gerenciamento cuja
instalação de Pods estáticos é controlada pelo kubeadm, como o kube-apiserver,
kube-controller-manager, kube-scheduler e etcd, têm seus contêineres
configurados para rodarem como usuários não-root. Se a opção não for habilitada,
estes componentes são executados como root. Você pode alterar o valor deste
feature gate antes de atualizar seu cluster para uma versão mais recente do
Kubernetes.
UnversionedKubeletConfigMap
Esta opção controla o nome do ConfigMap
onde o kubeadm armazena os dados de configuração do kubelet. Quando esta opção
não for especificada ou estiver especificada com o valor true, o ConfigMap
será nomeado kubelet-config. Caso esteja especificada com o valor false, o
nome do ConfigMap incluirá as versões maior e menor do Kubernetes instalado
(por exemplo, kubelet-config-1.30). O kubeadm garante
que as regras de RBAC para leitura e escrita deste ConfigMap serão apropriadas
para o valor escolhido. Quando o kubeadm cria este ConfigMap (durante a execução
dos comandos kubeadm init ou kubeadm upgrade apply), o kubeadm irá respeitar
o valor da opção UnversionedKubeletConfigMap. Quando tal ConfigMap for lido
(durante a execução dos comandos kubeadm join, kubeadm reset,
kubeadm upgrade...), o kubeadm tentará utilizar o nome do ConfigMap sem a
versão primeiro. Se esta operação não for bem-sucedida, então o kubeadm irá
utilizar o nome legado (versionado) para este ConfigMap.
Nota:
Informar a opção UnversionedKubeletConfigMap com o valor false é suportado,
mas está descontinuado.
Adicionando parâmetros do kube-proxy
Para informações sobre como utilizar parâmetros do kube-proxy na configuração
do kubeadm, veja:
Para executar o kubeadm sem uma conexão à internet, você precisa baixar as imagens
de contêiner requeridas pela camada de gerenciamento.
Você pode listar e baixar as imagens utilizando o subcomando
kubeadm config images:
kubeadm config images list
kubeadm config images pull
Você pode passar a opção --config para os comandos acima através de um
arquivo de configuração do kubeadm para controlar os campos
kubernetesVersion e imageRepository.
Todas as imagens padrão hospedadas em registry.k8s.io que o kubeadm requer suportam
múltiplas arquiteturas.
Utilizando imagens personalizadas
Por padrão, o kubeadm baixa imagens hospedadas no repositório de contêineres
registry.k8s.io. Se a versão requisitada do Kubernetes é um rótulo de integração
contínua (por exemplo, ci/latest), o repositório de contêineres
gcr.io/k8s-staging-ci-images é utilizado.
Fornecer um valor para o campo kubernetesVersion que afeta a versão das
imagens.
Fornecer um repositório de contêineres alternativo através do campo
imageRepository para ser utilizado no lugar de registry.k8s.io.
Fornecer um valor específico para os campos imageRepository e imageTag,
correspondendo ao repositório de contêineres e tag a ser utilizada, para as imagens
dos componentes etcd ou CoreDNS.
Caminhos de imagens do repositório de contêineres padrão registry.k8s.io podem diferir
dos utilizados em repositórios de contêineres personalizados através do campo
imageRepository devido a razões de retrocompatibilidade. Por exemplo, uma
imagem pode ter um subcaminho em registry.k8s.io/subcaminho/imagem, mas quando
utilizado um repositório de contêineres personalizado, o valor padrão será
meu.repositoriopersonalizado.io/imagem.
Para garantir que você terá as imagens no seu repositório personalizado em
caminhos que o kubeadm consiga consumir, você deve:
Baixar as imagens dos caminhos padrão registry.k8s.io utilizando o comando
kubeadm config images {list|pull}.
Subir as imagens para os caminhos listados no resultado do comando
kubeadm config images list --config=config.yaml, onde config.yaml contém
o valor customizado do campo imageRepository, e/ou imageTag para os
componentes etcd e CoreDNS.
Utilizar o mesmo arquivo config.yaml quando executar o comando kubeadm init.
Imagens personalizadas para o sandbox (imagem pause)
Para configurar uma imagem personalizada para o sandbox, você precisará
configurar o agente de execução de contêineres
para utilizar a imagem.
Verifique a documentação para o seu agente de execução de contêineres para
mais informações sobre como modificar esta configuração; para alguns agentes de
execução de contêiner você também encontrará informações no tópico
Agentes de Execução de Contêineres.
Carregando certificados da camada de gerenciamento no cluster
Ao adicionar a opção --upload-certs ao comando kubeadm init você pode
subir temporariamente certificados da camada de gerenciamento em um Secret no
cluster. Este Secret expira automaticamente após 2 horas. Os certificados são
encriptados utilizando uma chave de 32 bytes que pode ser especificada através
da opção --certificate-key. A mesma chave pode ser utilizada para baixar
certificados quando nós adicionais da camada de gerenciamento estão se associando
ao cluster, utilizando as opções --control-plane e --certificate-key ao rodar
kubeadm join.
O seguinte comando de fase pode ser usado para subir os certificados novamente
após a sua expiração:
Se a opção --certificate-key não for passada aos comandos kubeadm init
e kubeadm init phase upload-certs, uma nova chave será gerada automaticamente.
O comando abaixo pode ser utilizado para gerar uma nova chave sob demanda:
kubeadm certs certificate-key
Gerenciamento de certificados com o kubeadm
Para informações detalhadas sobre gerenciamento de certificados com o kubeadm,
consulte Gerenciamento de Certificados com o kubeadm.
O documento inclui informações sobre a utilização de autoridades de certificação
(CA) externas, certificados personalizados e renovação de certificados.
Gerenciando o arquivo drop-in do kubeadm para o kubelet
O pacote kubeadm é distribuído com um arquivo de configuração para rodar o
kubelet utilizando systemd. Note que o kubeadm nunca altera este arquivo.
Este arquivo drop-in é parte do pacote DEB/RPM do kubeadm.
Por padrão, o kubeadm tenta detectar seu agente de execução de contêineres. Para
mais detalhes sobre esta detecção, consulte o
guia de instalação CRI do kubeadm.
Configurando o nome do nó
Por padrão, o kubeadm gera um nome para o nó baseado no endereço da máquina.
Você pode sobrescrever esta configuração utilizando a opção --node-name. Esta
opção passa o valor apropriado para a opção --hostname-override
do kubelet.
Ao invés de copiar o token que você obteve do comando kubeadm init para cada nó,
como descrito no tutorial básico do kubeadm,
você pode paralelizar a distribuição do token para facilitar a automação.
Para implementar esta automação, você precisa saber o endereço IP que o nó da
camada de gerenciamento irá ter após a sua inicialização, ou utilizar um nome
DNS ou um endereço de um balanceador de carga.
Gere um token. Este token deve ter a forma <string de 6 caracteres>.<string de 16 caracteres>.
Mais especificamente, o token precisa ser compatível com a expressão regular:
[a-z0-9]{6}\.[a-z0-9]{16}.
O kubeadm pode gerar um token para você:
kubeadm token generate
Inicialize o nó da camada de gerenciamento e os nós de carga de trabalho de
forma concorrente com este token. Conforme os nós forem iniciando, eles
deverão encontrar uns aos outros e formar o cluster. O mesmo argumento
--token pode ser utilizado em ambos os comandos kubeadm init e
kubeadm join.
O mesmo procedimento pode ser feito para a opção --certificate-key quando
nós adicionais da camada de gerenciamento associarem-se ao cluster. A chave
pode ser gerada utilizando:
kubeadm certs certificate-key
Uma vez que o cluster esteja inicializado, você pode buscar as credenciais para
a camada de gerenciamento no caminho /etc/kubernetes/admin.conf e utilizá-las
para conectar-se ao cluster.
Note que este tipo de inicialização tem algumas garantias de segurança relaxadas
pois ele não permite que o hash do CA raiz seja validado com a opção
--discovery-token-ca-cert-hash (pois este hash não é gerado quando os nós são
provisionados). Para detalhes, veja a documentação do comando
kubeadm join.
Próximos passos
kubeadm init phase
para entender mais sobre as fases do comando kubeadm init
kubeadm join para
inicializar um nó de carga de trabalho do Kubernetes e associá-lo ao cluster
kubeadm upgrade
para atualizar um cluster do Kubernetes para uma versão mais recente
kubeadm reset
para reverter quaisquer mudanças feitas neste host pelos comandos
kubeadm init ou kubeadm join
6.4.1.3 - kubeadm join
Este comando inicializa um nó de processamento do Kubernetes e o associa ao
cluster.
Rode este comando em qualquer máquina que você deseje adicionar a um cluster
existente
Sinopse
Ao associar um novo nó a um cluster inicializado com kubeadm, temos que
estabelecer a confiança bidirecional. Este processo é dividido entre a descoberta
(em que o nó estabelece a confiança na camada de gerenciamento do Kubernetes) e
a inicialização TLS (em que a camada de gerenciamento do Kubernetes estabelece a
confiança no nó).
Existem duas principais formas de descoberta. A primeira delas é o uso de um
token compartilhado, juntamente com o endereço IP do servidor da API. A segunda
é o fornecimento de um arquivo - um subconjunto do arquivo kubeconfig padrão. O
arquivo de descoberta/kubeconfig suporta autenticação por token, plugins de
autenticação do client-go ("exec"), "tokenFile" e "authProvider". Este arquivo
pode ser um arquivo local ou um arquivo baixado através de uma URL HTTPS. Os
formatos são kubeadm join --discovery-token abcdef.1234567890abcdef 1.2.3.4:6443,
kubeadm join --discovery-file caminho/para/arquivo.conf, ou
kubeadm join --discovery-file https://endereco/arquivo.conf. Somente um formato
pode ser utilizado. Se os dados para a descoberta são carregados de uma URL,
o protocolo HTTPS deve ser utilizado. Neste caso, o conjunto de CAs instalado no
host é utilizado para verificar a conexão.
Se você utilizou um token compartilhado para descoberta, você deve também passar
a opção --discovery-token-ca-cert-hash para validar a chave pública da
autoridade de certificação raiz (CA) apresentada pela camada de gerenciamento do
Kubernetes. O valor desta opção é especificado no formato
"<tipo-de-hash>:<valor-codificado-em-hexadecimal>", onde o tipo de
hash suportado é "sha256". O hash é calculado a partir dos bytes do objeto
Subject Public Key Info (SPKI), como especificado pela RFC7469. Este valor fica
disponível na saída do comando kubeadm init ou pode ser calculado utilizando
ferramentas padronizadas. A opção --discovery-token-ca-cert-hash pode ser
especificada múltiplas vezes para permitir informar mais que uma chave pública.
Se você não puder obter o hash da chave pública da autoridade de certificação
de antemão, você pode passar a opção --discovery-token-unsafe-skip-ca-verification
para desabilitar esta verificação. Esta opção enfraquece o modelo de segurança
do kubeadm, já que outros nós podem potencialmente personificar a camada de
gerenciamento do Kubernetes.
O mecanismo de inicialização TLS também é conduzido por um token compartilhado.
Este token é utilizado para temporariamente autenticar-se com a camada de
gerenciamento do Kubernetes para enviar uma requisição de assinatura de
certificado (CSR) para um par de chaves criado localmente. Por padrão, o kubeadm
irá configurar a camada de gerenciamento do Kubernetes para automaticamente
aprovar estas requisições de assinatura. O token é enviado através da opção
--tls-bootstrap-token abcdef.1234567890abcdef.
Frequentemente, o mesmo token é utilizado para ambas as partes. Neste caso, a
opção --token pode ser utilizada ao invés de especificar cada token
individualmente.
O comando join [api-server-endpoint] executa as seguintes fases:
preflight Executa as verificações pré-execução
control-plane-prepare Prepara a máquina para servir um nó da camada de gerenciamento
/download-certs [EXPERIMENTAL] Baixa certificados compartilhados entre nós da camada de gerenciamento do Secret kubeadm-certs
/certs Gera os certificados para os novos componentes da camada de gerenciamento
/kubeconfig Gera o arquivo kubeconfig para os novos componentes da camada de gerenciamento
/control-plane Gera os manifestos para os novos componentes da camada de gerenciamento
kubelet-start Escreve as configurações do kubelet, os certificados, e (re)inicia o kubelet
control-plane-join Associa uma máquina como uma instância da camada de gerenciamento
/etcd Adiciona como um novo membro do etcd local
/update-status Registra o novo nó da camada de gerenciamento no objeto ClusterStatus mantido no ConfigMap kubeadm-config (DESCONTINUADO)
/mark-control-plane Marca um nó como nó da camada de gerenciamento
kubeadm join [api-server-endpoint] [flags]
Opções
--apiserver-advertise-address string
Se o nó hospedar uma nova instância da camada de gerenciamento, este é o endereço IP que servidor da API irá anunciar que
está aguardando conexões. Quando não especificado, a interface de rede padrão é utilizada.
--apiserver-bind-port int32 Default: 6443
Se o nó hospedar uma nova instância da camada de gerenciamento, a porta que o servidor da API deve conectar-se.
--certificate-key string
Chave utilizada para decriptar as credenciais do certificado enviadas pelo comando init.
--config string
Caminho para um arquivo de configuração do kubeadm.
--control-plane
Cria uma nova instância da camada de gerenciamento neste nó.
--cri-socket string
Caminho para o soquete CRI conectar-se. Se vazio, o kubeadm tentará autodetectar este valor; utilize esta opção somente se você possui mais que um CRI instalado ou se você possui um soquete CRI fora do padrão.
--discovery-file string
Para descoberta baseada em arquivo, um caminho de arquivo ou uma URL de onde a informação do cluster deve ser carregada.
--discovery-token string
Para descoberta baseada em token, o token utilizado para validar a informação do cluster obtida do servidor da API.
--discovery-token-ca-cert-hash strings
Para descoberta baseada em token, verifica que a chave pública do CA raiz corresponde a este hash
(formato: "<tipo>:<valor>").
--discovery-token-unsafe-skip-ca-verification
Para descoberta baseada em token, permite associar-se ao cluster sem fixação da
autoridade de certificação (opção --discovery-token-ca-cert-hash).
--dry-run
Não aplica as modificações; apenas imprime as alterações que seriam efetuadas.
-h, --help
ajuda para join
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
--node-name string
Especifica o nome do nó.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--skip-phases strings
Lista de fases a serem ignoradas.
--tls-bootstrap-token string
Especifica o token a ser utilizado para autenticar temporariamente com a camada de gerenciamento do Kubernetes durante
o processo de associação do nó ao cluster.
--token string
Utiliza este token em ambas as opções discovery-token e tls-bootstrap-token quando tais valores não são informados.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
Fluxo do comando join
O comando kubeadm join inicializa um nó de processamento ou um nó da camada
de gerenciamento e o adiciona ao cluster. Esta ação consiste nos seguintes passos
para nós de processamento:
O kubeadm baixa as informações necessárias do cluster através servidor da API.
Por padrão, o token de autoinicialização e o hash da chave da autoridade de
certificação (CA) são utilizados para verificar a autenticidade dos dados
baixados. O certificado raiz também pode ser descoberto diretamente através
de um arquivo ou URL.
Uma vez que as informações do cluster são conhecidas, o kubelet pode começar
o processo de inicialização TLS.
A inicialização TLS utiliza o token compartilhado para autenticar
temporariamente com o servidor da API do Kubernetes a fim de submeter uma
requisição de assinatura de certificado (certificate signing request, ou
CSR); por padrão, a camada de gerenciamento assina essa requisição CSR
automaticamente.
Por fim, o kubeadm configura o kubelet local para conectar no servidor da API
com a identidade definitiva atribuída ao nó.
Para nós da camada de gerenciamento, passos adicionais são executados:
O download de certificados compartilhados por todos os nós da camada de
gerenciamento (quando explicitamente solicitado pelo usuário).
Geração de manifestos, certificados e arquivo kubeconfig para os componentes
da camada de gerenciamento.
Adição de um novo membro local do etcd.
Utilizando fases de associação com o kubeadm
O kubeadm permite que você associe um nó a um cluster em fases utilizando
kubeadm join phase.
Para visualizar a lista ordenada de fases e subfases disponíveis, você pode
executar o comando kubeadm join --help. A lista estará localizada no topo da
tela da ajuda e cada fase terá uma descrição ao lado. Note que ao chamar
kubeadm join todas as fases e subfases serão executadas nesta ordem exata.
Algumas fases possuem opções únicas, portanto, se você desejar ver uma lista das
opções disponíveis, adicione a flag--help. Por exemplo:
kubeadm join phase kubelet-start --help
De forma semelhante ao comando
kubeadm init phase,
kubeadm join phase permite que você ignore uma lista de fases utilizando a
opção --skip-phases.
Alternativamente, você pode utilizar o campo skipPhases no manifesto
JoinConfiguration.
Descobrindo em qual autoridade de certificação (CA) do cluster confiar
A descoberta do kubeadm tem diversas opções, cada uma com suas próprias
contrapartidas de segurança. O método correto para o seu ambiente depende de
como você aprovisiona seus nós e as expectativas de segurança que você tem a
respeito da rede e ciclo de vida dos seus nós.
Descoberta baseada em token com fixação da autoridade de certificação (CA)
Este é o modo padrão do kubeadm. Neste modo, o kubeadm baixa a configuração do
cluster (incluindo a CA raiz) e a valida, utilizando o token, além de verificar
que a chave pública da CA raiz corresponda ao hash fornecido e que o
certificado do servidor da API seja válido sob a CA raiz.
O hash da chave pública da CA tem o formato sha256:<hash_codificado_em_hexa>.
Por padrão, o valor do hash é retornado no comando kubeadm join impresso ao
final da execução de kubeadm init ou na saída do comando
kubeadm token create --print-join-command. Este hash é gerado em um formato
padronizado (veja a RFC7469)
e pode também ser calculado com ferramentas de terceiros ou sistemas de
provisionamento. Por exemplo, caso deseje utilizar a ferramenta de linha de
comando do OpenSSL:
Você também pode executar o comando join para um nó da camada de gerenciamento
com a opção --certificate-key para copiar certificados para este nó, caso o
comando kubeadm init tenha sido executado com a opção --upload-certs.
Vantagens:
Permite à inicialização dos nós descobrir uma raiz de confiança para a camada
de gerenciamento mesmo que outros nós de processamento ou a rede estejam
comprometidos.
É conveniente para ser executado manualmente pois toda a informação requerida
cabe num único comando kubeadm join.
Desvantagens:
O hash da autoridade de certificação normalmente não está disponível até que
a camada de gerenciamento seja aprovisionada, o que pode tornar mais difícil
a criação de ferramentas de aprovisionamento automatizadas que utilizem o
kubeadm. Uma alternativa para evitar esta limitação é gerar sua autoridade de
certificação de antemão.
Descoberta baseada em token sem fixação da autoridade de certificação (CA)
Este modo depende apenas do token simétrico para assinar (HMAC-SHA256) a
informação de descoberta que estabelece a raiz de confiança para a camada de
gerenciamento. Para utilizar este modo, os nós que estão se associando ao cluster
devem ignorar a validação do hash da chave pública da autoridade de
certificação, utilizando a opção --discovery-token-unsafe-skip-ca-verification.
Você deve considerar o uso de um dos outros modos quando possível.
O token pode ser gerado de antemão e compartilhado com os nós da camada de
gerenciamento e de processamento, que por sua vez podem inicializar-se em
paralelo, sem coordenação. Isto permite que este modo seja utilizado em muitos
cenários de aprovisionamento.
Desvantagens:
Se um mau ator conseguir roubar um token de inicialização através de algum tipo
de vulnerabilidade, este mau ator conseguirá utilizar o token (juntamente com
accesso a nível de rede) para personificar um nó da camada de gerenciamento
perante os outros nós de processamento. Esta contrapartida pode ou não ser
aceitável no seu ambiente.
Descoberta baseada em arquivos ou HTTPS
Este modo fornece uma maneira alternativa de estabelecer uma raiz de confiança
entre os nós da camada de gerenciamento e os nós de processamento. Considere
utilizar este modo se você estiver construindo uma infraestrutura de
aprovisionamento automático utilizando o kubeadm. O formato do arquivo de
descoberta é um arquivo kubeconfig
comum do Kubernetes.
Caso o arquivo de descoberta não contenha credenciais, o token de descoberta TLS
será utilizado.
Permite à inicialização dos nós descobrir uma raiz de confiança de forma segura
para que a camada de gerenciamento utilize mesmo que a rede ou outros nós de
processamento estejam comprometidos.
Desvantagens:
Requer que você tenha uma forma de carregar a informação do nó da camada de
gerenciamento para outros nós em inicialização. Se o arquivo de descoberta
contém credenciais, você precisa mantê-lo secreto e transferi-lo através de
um canal de comunicação seguro. Isto pode ser possível através do seu provedor
de nuvem ou ferramenta de aprovisionamento.
Tornando sua instalação ainda mais segura
Os valores padrão de instalação do kubeadm podem não funcionar para todos os
casos de uso. Esta seção documenta como tornar uma instalação mais segura, ao
custo de usabilidade.
Desligando a auto-aprovação de certificados de cliente para nós
Por padrão, um auto-aprovador de requisições CSR está habilitado. Este
auto-aprovador irá aprovar quaisquer requisições de certificado de cliente para
um kubelet quando um token de autoinicialização for utilizado para autenticação.
Se você não deseja que o cluster aprove automaticamente certificados de cliente
para os kubelets, você pode desligar a auto-aprovação com o seguinte comando:
Após o desligamento da auto-aprovação, o comando kubeadm join irá aguardar até
que o administrador do cluster aprove a requisição CSR:
Utilizando o comando kubeadm get csr, você verá que o CSR original está em
estado pendente.
kubectl get csr
A saída é semelhante a:
NAME AGE REQUESTOR CONDITION
node-csr-c69HXe7aYcqkS1bKmH4faEnHAWxn6i2bHZ2mD04jZyQ 18s system:bootstrap:878f07 Pending
O comando kubectl certificate approve permite ao administrador aprovar o
CSR. Esta ação informa ao controlador de assinatura de certificados que este
deve emitir um certificado para o requerente com os atributos requeridos no
CSR.
Este comando muda o estado do objeto CSR para o estado ativo.
kubectl get csr
A saída é semelhante a:
NAME AGE REQUESTOR CONDITION
node-csr-c69HXe7aYcqkS1bKmH4faEnHAWxn6i2bHZ2mD04jZyQ 1m system:bootstrap:878f07 Approved,Issued
Esta mudança força com que o fluxo do comando kubeadm join seja bem-sucedido
somente quando o comando kubectl certificate approve for executado.
Desligando o acesso público ao ConfigMap cluster-info
Para que o fluxo de associação de um nó ao cluster seja possível utilizando
somente um token como a única informação necessária para validação, um ConfigMap
com alguns dados necessários para validação da identidade do nó da camada de
gerenciamento é exposto publicamente por padrão. Embora nenhum dado deste
ConfigMap seja privado, alguns usuários ainda podem preferir bloquear este
acesso. Mudar este acesso bloqueia a habilidade de utilizar a opção
--discovery-token do fluxo do comando kubeadm join. Para desabilitar este
acesso:
Obtenha o arquivo cluster-info do servidor da API:
kubectl -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}' | tee cluster-info.yaml
Estes comandos devem ser executados após kubeadm init, mas antes de
kubeadm join.
Utilizando kubeadm join com um arquivo de configuração
Cuidado:
O arquivo de configuração ainda é considerado beta e pode mudar em versões
futuras.
É possível configurar o comando kubeadm join apenas com um arquivo de
configuração, em vez de utilizar opções de linha de comando, e algumas
funcionalidades avançadas podem estar disponíveis somente como opções no arquivo
de configuração. Este arquivo é passado através da opção --config e deve conter
uma estrutura JoinConfiguration. A utilização da opção --config com outras
opções da linha de comando pode não ser permitida em alguns casos.
A configuração padrão pode ser emitida utilizando o comando
kubeadm config print.
Caso sua configuração não esteja utilizando a versão mais recente, é
recomendado que você migre utilizando o comando
kubeadm config migrate.
Para mais informações sobre os campos e utilização da configuração você pode
consultar a referência da API.
Próximos passos
kubeadm init para
inicializar um nó da camada de gerenciamento do Kubernetes.
kubeadm token para
gerenciar tokens utilizados no comando kubeadm join.
kubeadm reset para
reverter quaisquer mudanças feitas nesta máquina pelos comandos kubeadm init
ou kubeadm join.
6.4.1.4 - kubeadm upgrade
kubeadm upgrade é um comando amigável que envolve uma lógica de atualização complexa por trás de um comando, com suporte para planejar e executar de fato uma atualização.
Guia do kubeadm upgrade
As etapas para realizar uma atualização usando kubeadm estão descritas neste documento.
Para versões mais antigas do kubeadm, consulte os conjuntos de documentação mais antigos do site Kubernetes.
Você pode usar kubeadm upgrade diff para ver as alterações que seriam aplicadas aos manifestos de Pod estático.
No Kubernetes v1.15.0 e posteriores, o kubeadm upgrade apply e kubeadm upgrade node também renovarão automaticamente os certificados gerenciados pelo kubeadm neste nó, incluindo aqueles armazenados nos arquivos do kubeconfig.
É possível optar por não renovar usando a flag --certificate-renewal=false.
Para mais detalhes sobre a renovação dos certificados, consulte a documentação de gerenciamento de certificados.
Nota:
Os comandos kubeadm upgrade apply e kubeadm upgrade plan tem uma flag legada --config que possibilita reconfigurar o cluster enquanto realiza o planejamento ou a atualização do nó específico da camada de gerenciamento.
Esteja ciente de que o fluxo de trabalho da atualização não foi projetado para este cenário e existem relatos de resultados inesperados.
kubeadm upgrade plan
Verifique quais versões estão disponíveis para atualizar e verifique se o seu cluster atual é atualizável.
Para pular a verificação da Internet, passe o parâmetro opcional [versão]
Sinopse
Verifique quais versões estão disponíveis para atualizar e verifique se o seu cluster atual é atualizável.
Para pular a verificação da Internet, passe o parâmetro opcional [versão]
kubeadm upgrade plan [versão] [flags]
Opções
--allow-experimental-upgrades
Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/release candidate do Kubernetes.
--allow-release-candidate-upgrades
Exibe as versões candidatas a lançamento do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas a lançamento do Kubernetes.
--config string
Caminho para um arquivo de configuração kubeadm.
--feature-gates string
Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false)
-h, --help
ajuda para plan
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
-o, --output string Padrão: "text"
EXPERIMENTAL: Formato de saída. Opções válidas: text|json|yaml.
--print-config
Especifica se o arquivo de configuração que será usado na atualização deve ser exibido ou não.
--show-managed-fields
Se verdadeiro, mantém os managedFields ao exibir os objetos no formato JSON ou YAML.
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
kubeadm upgrade apply
Atualiza o cluster Kubernetes para uma versão específica
Sinopse
Atualiza o cluster Kubernetes para uma versão específica
kubeadm upgrade apply [versão]
Opções
--allow-experimental-upgrades
Exibe as versões instáveis do Kubernetes como uma alternativa de atualização e permite a atualização para versões alfa/beta/release candidate do Kubernetes.
--allow-release-candidate-upgrades
Exibe as versões candidatas a lançamento do Kubernetes como uma alternativa de atualização e permite a atualização para versões candidatas a lançamento do Kubernetes.
--certificate-renewal Padrão: true
Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.
--config string
Caminho para um arquivo de configuração do kubeadm.
--dry-run
Não aplica as modificações; apenas exibe as alterações que seriam efetuadas.
--etcd-upgrade Padrão: true
Atualiza o etcd.
--feature-gates string
Um conjunto de pares chave=valor que descreve feature gates para várias funcionalidades. As opções são:
PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false)
-f, --force
Força a atualização, embora alguns requisitos possam não estar sendo atendidos. Isso também implica o modo não interativo.
-h, --help
ajuda para apply
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--print-config
Especifica se o arquivo de configuração que será usado na atualização deve ser exibido ou não.
-y, --yes
Executa a atualização e não solicita um prompt de confirmação (modo não interativo).
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
kubeadm upgrade diff
Mostra quais diferenças serão aplicadas aos manifestos dos Pods estáticos existentes. Veja também: kubeadm upgrade apply --dry-run
Sinopse
Mostra quais diferenças serão aplicadas aos manifestos dos Pods estáticos existentes. Veja também: kubeadm upgrade apply --dry-run
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
kubeadm upgrade node
Comando para atualização de um nó no cluster
Sinopse
Comando para atualização de um nó no cluster
O comando "node" executa as seguintes fases:
preflight Executa as verificações de pré-atualização do nó
control-plane Atualiza a instância da camada de gerenciamento implantada neste nó, se houver
kubelet-config Atualiza a configuração do kubelet para este nó
kubeadm upgrade node [flags]
Opções
--certificate-renewal Padrão: true
Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.
--dry-run
Não aplica as modificações; apenas exibe as alterações que seriam efetuadas.
--etcd-upgrade Padrão: true
Atualiza o etcd.
-h, --help
ajuda para node
--ignore-preflight-errors strings
Uma lista de verificações para as quais erros serão exibidos como avisos. Exemplos: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--patches string
Caminho para um diretório contendo arquivos nomeados no padrão "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou somente "etcd.json". "target" pode ser um dos seguintes valores: "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd", "kubeletconfiguration". "patchtype" pode ser "strategic", "merge" ou "json" e corresponde aos formatos de patch suportados pelo kubectl. O valor padrão para "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional utilizada para determinar quais patches são aplicados primeiro em ordem alfanumérica.
--skip-phases strings
Lista de fases a serem ignoradas
Opções herdadas de comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o sistema de arquivos raiz 'real' do host.
Próximos passos
kubeadm config se você inicializou seu cluster usando kubeadm v1.7.x ou inferior, para configurar seu cluster para kubeadm upgrade
6.4.1.5 - kubeadm config
Durante o kubeadm init, o kubeadm carrega o objeto ClusterConfiguration para o seu cluster em um ConfigMap chamado kubeadm-config no namespace do kube-system. Essa configuração é então lida durante kubeadm join, kubeadm reset e kubeadm upgrade.
Você pode usar o kubeadm config print para exibir a configuração estática padrão que o kubeadm usa para o kubeadm init e kubeadm join.
Nota:
A saída do comando deve servir de exemplo. Você deve editar manualmente a saída deste comando para adaptar à sua configuração. Remova os campos sobre os quais você não tem certeza e o kubeadm tentará usá-los como padrão, examinando o host durante a execução.
Você pode usar o kubeadm config migrate para converter seus arquivos de configuração antigos que contêm uma versão obsoleta da API para uma versão mais recente e suportada da API.
kubeadm config images list e kubeadm config images pull podem ser usadas para listar e baixar as imagens que o kubeadm precisa.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm config print init-defaults
Exibe a configuração de inicialização padrão, que pode ser usada para 'kubeadm init'
Sinopse
Este comando exibe objetos, como a configuração de inicialização padrão que é usada para 'kubeadm init'.
Observe que os valores confidenciais, como os campos do Token Bootstrap, são substituídos por valores de exemplo como "abcdef.0123456789abcdef", a fim de passar na validação, mas não executar o cálculo real para criar um token.
kubeadm config print init-defaults [flags]
Opções
--component-configs strings
Uma lista dos objetos da API de configuração, separados por vírgulas, exibirá os valores padrão. Valores disponíveis: [KubeProxyConfiguration KubeletConfiguration]. Se essa flag não estiver definida, nenhuma configuração de componente será impressa.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm config print join-defaults
Exibe a configuração padrão do join, que pode ser usada para 'kubeadm join'
Sinopse
Este comando exibe objetos como a configuração padrão de join que é usada para 'kubeadm join'.
Observe que valores confidenciais, como os campos do Token Bootstrap, são substituídos por valores de exemplo como "abcdef.0123456789abcdef", a fim de passar na validação, mas não executar o cálculo real para criar um token.
kubeadm config print join-defaults [flags]
Opções
--component-configs strings
Uma lista dos objetos da API de configuração, separados por vírgulas, exibirá os valores padrão. Valores disponíveis: [KubeProxyConfiguration KubeletConfiguration]. Se essa flag não estiver definida, nenhuma configuração de componente será impressa.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm config migrate
Leia uma versão mais antiga dos tipos de API de configuração do kubeadm a partir de um arquivo e envie o objeto de configuração semelhante para a versão mais recente
Sinopse
Esse comando permite converter objetos de configuração de versões mais antigas para a versão mais recente suportada, localmente na ferramenta CLI sem nunca tocar em nada no cluster. Nesta versão do kubeadm, as seguintes versões da API são suportadas:
Kubeadm.k8s.io/v1beta3
Além disso, o kubeadm só pode escrever a configuração da versão "kubeadm.k8s.io/v1beta3", mas pode ler os dois tipos. Portanto, independentemente da versão que você passar para o parâmetro --old-config , o objeto API será lido, desserializado, padronizado, convertido, validado e serializado novamente quando escrito no stdout ou --new-config, se especificado.
Em outras palavras, a saída deste comando é o que o kubeadm realmente leria internamente se você enviasse este arquivo para "kubeadm init"
kubeadm config migrate [flags]
Opções
-h, --help
ajuda para migrate
--new-config string
Caminho para o arquivo de configuração kubeadm equivalente usando a nova versão da API. Opcional, se não for especificado, a saída será enviada para o STDOUT.
--old-config string
Caminho para o arquivo de configuração do kubeadm que está usando uma versão antiga da API e que deve ser convertido. Essa flag é obrigatória.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm config images list
Exibe uma lista de imagens que o kubeadm usará. O arquivo de configuração é usado caso quaisquer imagens ou repositórios de imagens sejam personalizados.
Sinopse
Exibe uma lista de imagens que o kubeadm usará. O arquivo de configuração é usado caso quaisquer imagens ou repositórios de imagens sejam personalizados.
kubeadm config images list [flags]
Opções
--allow-missing-template-keys Padrão: true
Se verdadeiro (true), ignore quaisquer erros nos modelos quando um campo ou chave de mapa estiver faltando no modelo. Aplica-se apenas aos formatos de saída golang e jsonpath.
--config string
Caminho para um arquivo de configuração kubeadm.
-o, --experimental-output string Padrão: "text"
Formato de saída. Valores válidos: text|json|yaml|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
--feature-gates string
Um conjunto de pares chave=valor que descrevem opções para vários recursos. As opções são: PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false) UnversionedKubeletConfigMap=true|false (ALPHA - padrão=false)
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm config images pull
Puxe imagens usadas pelo kubeadm
Sinopse
Baixa imagens usadas pelo kubeadm
kubeadm config images pull [flags]
Opções
--config string
Caminho para um arquivo de configuração kubeadm.
--cri-socket string
Caminho para se conectar ao socket CRI. Se vazio, o kubeadm tentará detectar automaticamente esse valor; use essa opção somente se você tiver mais de um CRI instalado ou se tiver um socket CRI não padrão.
--feature-gates string
Um conjunto de pares chave=valor que descrevem feature gates para vários recursos. As opções são: PublicKeysECDSA=true|false (ALPHA - padrão=false) RootlessControlPlane=true|false (ALPHA - padrão=false) UnversionedKubeletConfigMap=true|false (ALPHA - padrão=false)
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Próximos passos
kubeadm upgrade para atualizar um cluster Kubernetes para uma versão mais recente
6.4.1.6 - kubeadm reset
Executa o melhor esforço para reverter as alterações feitas pelo kubeadm init ou kubeadm join.
Executa o melhor esforço para reverter as alterações feitas no host por 'kubeadm init' ou 'kubeadm join'
Sinopse
Executa o melhor esforço para reverter as alterações feitas no host por 'kubeadm init' ou 'kubeadm join'
O comando "reset" executa as seguintes fases:
preflight Executa as verificações pré-execução do preflight.
remove-etcd-member Remove um membro etcd local.
cleanup-node Executa a limpeza do nó.
kubeadm reset [flags]
Opções
--cert-dir string Padrão: "/etc/kubernetes/pki"
O caminho para o diretório onde os certificados estão armazenados. Se especificado, limpe este diretório.
--cri-socket string
Caminho para o socket CRI se conectar. Se vazio, o kubeadm tentará detectar automaticamente esse valor; use essa opção somente se você tiver mais de um CRI instalado ou se tiver um socket CRI não padrão.
-f, --force
Redefine o nó sem solicitar confirmação..
-h, --help
ajuda para reset
--ignore-preflight-errors strings
Uma lista de verificações cujos erros serão mostrados como avisos. Exemplo: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--skip-phases strings
Lista de fases a serem ignoradas
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Fluxo de execução do comando reset
O kubeadm reset é o responsável por limpar o sistema de arquivos local dos nós a partir dos arquivos que foram criados usando os comandos kubeadm init ou kubeadm join. O reset dos nós da camanda de gerenciamento também remove o etcd local do nó do cluster etcd.
O kubeadm reset phase pode ser usado para executar separadamente as fases do fluxo de trabalho acima. Para pular uma lista de fases você pode usar --skip-phases, que funciona de maneira semelhante aos executores de fases dos comandos kubeadm join e kubeadm init.
Limpeza do etcd externo
O kubeadm reset não excluirá nenhum dado do etcd se o etcd externo estiver em uso. Isso significa que, se você executar o kubeadm init novamente usando os mesmos etcd endpoints, verá o estado dos clusters anteriores.
Para limpar dados etcd, é recomendável que você use um cliente como etcdctl, tal como:
kubeadm init para inicializar um nó do plano de controle do Kubernetes
kubeadm join para inicializar um nó de carga de trabalho do Kubernetes e associá-lo ao cluster
6.4.1.7 - kubeadm token
Os Bootstrap tokens são usados para estabelecer uma relação de confiança bidirecional entre um nó que se junta ao cluster e um nó do plano de controle, conforme descrito na autenticação com tokens de inicialização.
O kubeadm init cria um token inicial com um TTL de 24 horas. Os comandos a seguir permitem que você gerencie esse token e também crie e gerencie os novos.
kubeadm token create
Crie tokens de inicialização no servidor
Sinopse
Este comando criará um token de inicialização. Você pode especificar os usos para este token, o "tempo de vida" e uma descrição amigável, que é opcional.
O [token] é o token real para gravar. Este deve ser um token aleatório gerado com segurança da forma "[a-z0-9]{6}.[a-z0-9]{16}". Se nenhum [token] for fornecido, o kubeadm gerará um token aleatório.
kubeadm token create [token]
Opções
--certificate-key string
Quando usado em conjunto com '--print-join-command', exibe a flag completa 'kubeadm join' necessária para se unir ao cluster como um nó de camada de gerenciamento. Para criar uma nova chave de certificado, você deve usar 'kubeadm init phase upload-certs --upload-certs'.
--config string
Caminho para o arquivo de configuração kubeadm.
--description string
Uma descrição amigável de como esse token é usado.
Grupos extras que este token autenticará quando usado para autenticação. Deve corresponder "\Asystem:bootstrappers:[a-z0-9:-]{0,255}[a-z0-9]\z"
-h, --help
ajuda para create
--print-join-command
Em vez de exibir apenas o token, exibe a flag completa 'kubeadm join' necessária para se associar ao cluster usando o token.
--ttl duração Padrão: 24h0m0s
A duração antes do token ser excluído automaticamente (por exemplo, 1s, 2m, 3h). Se definido como '0', o token nunca expirará
--usages strings Padrão: "signing,authentication"
Descreve as maneiras pelas quais esse token pode ser usado. Você pode passar --usages várias vezes ou fornecer uma lista de opções separada por vírgulas. Opções válidas: [signing,authentication]
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm token delete
Excluir tokens de inicialização no servidor
Sinopse
Este comando excluirá uma lista de tokens de inicialização para você.
O [token-value] é um Token completo na forma "[a-z0-9]{6}.[a-z0-9]{16}" ou o ID do Token na forma "[a-z0-9]{6}" a ser excluído.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm token generate
Gere e exiba um token de inicialização, mas não o crie no servidor
Sinopse
Este comando exibirá um token de inicialização gerado aleatoriamente que pode ser usado com os comandos "init" e "join".
Você não precisa usar este comando para gerar um token. Você pode fazer isso sozinho, desde que esteja no formato "[a-z0-9]{6}.[a-z0-9]{16}". Este comando é fornecido por conveniência para gerar tokens no formato fornecido.
Você também pode usar "kubeadm init" sem especificar um token e ele gerará e exibirá um para você.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm token list
Liste tokens de inicialização no servidor
Sinopse
Este comando listará todos os tokens de inicialização para você
kubeadm token list [flags]
Opções
--allow-missing-template-keys Padrão: true
Se verdadeiro (true), ignora quaisquer erros nos modelos quando um campo ou chave de mapa estiver faltando no modelo. Aplica-se apenas aos formatos de saída golang e jsonpath.
-o, --experimental-output string Padrão: "text"
Formato de saída. Valores válidos: text|json|yaml|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
-h, --help
ajuda para list
--show-managed-fields
Se verdadeiro (true), mantém os managedFields ao exibir os objetos no formato JSON ou YAML.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Próximos passos
kubeadm join para inicializar um nó de carga de trabalho do Kubernetes e associá-lo ao cluster
6.4.1.8 - kubeadm version
Este comando exibe a versão do kubeadm.
Exibe a versão do kubeadm
Sinopse
Exibe a versão do kubeadm
kubeadm version [flags]
Opções
-h, --help
ajuda para version
-o, --output string
Formato de saída; as opções disponíveis são 'yaml', 'json' e 'short'
Opção herdada do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.9 - kubeadm alpha
Cuidado:
O kubeadm alpha fornece uma prévia de um conjunto de recursos disponibilizados para coletar feedback da comunidade. Por favor, experimente e nos dê seu feedback!
Atualmente, não há comandos experimentais sob o kubeadm alpha.
Próximos passos
kubeadm init para inicializar um nó da camada de gerenciamento do Kubernetes
kubeadm join para inicializar um nó worker do Kubernetes e associá-lo ao cluster
kubeadm reset para reverter quaisquer alterações feitas neste host pelo kubeadm init ou kubeadm join
6.4.1.10 - kubeadm certs
O kubeadm certs fornece os utilitários para gerenciar os certificados. Para obter mais detalhes sobre como esses comandos podem ser usados, consulte Gerenciamento de Certificados com o kubeadm.
kubeadm certs
Um conjunto de utilitários para usar os certificados Kubernetes
Comandos relacionados ao manuseio de certificados kubernetes
Sinopse
Comandos relacionados ao manuseio de certificados kubernetes
Opções
-h, --help
ajuda para certs
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm certs renew
Você pode renovar todos os certificados Kubernetes usando o subcomando all ou renová-los seletivamente. Para mais detalhes, consulte Manual de renovação do certificado.
Este comando não deve ser executado sozinho. Veja a lista de subcomandos disponíveis.
kubeadm certs renew [flags]
Opções
-h, --help
ajuda para renew
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renovar todos os certificados disponíveis
Sinopse
Renove todos os certificados conhecidos e necessários para executar a camada de gerenciamento. As renovações são executadas incondicionalmente, independentemente da data de expiração. As renovações também podem ser executadas individualmente para obter mais controle.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado incorporado no arquivo kubeconfig para o administrador e o kubeadm usarem
Sinopse
Renove o certificado incorporado no arquivo kubeconfig para o administrador e o kubeadm usarem.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar a API de certificados do K8s para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
kubeadm certs renew admin.conf [flags]
Opções
--cert-dir string Padrão: "/etc/kubernetes/pki"
O caminho para salvar os certificados.
--config string
O caminho para um arquivo de configuração kubeadm.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado que o apiserver usa para acessar o etcd.
Sinopse
Renove o certificado que o apiserver usa para acessar o etcd.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar a API de certificado K8s para renovação do certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado para o servidor API se conectar ao kubelet
Sinopse
Renove o certificado para o servidor da API se conectar ao kubelet.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar a API de certificado do K8s para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado para servir a API do Kubernetes
Sinopse
Renove o certificado para servir a API do Kubernetes.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado incorporado no arquivo kubeconfig para o uso do gerenciador de controladores.
Sinopse
Renove o certificado incorporado no arquivo kubeconfig para o uso do gerenciador de controladores.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado para liveness probes para verificar a integridade do etcd
Sinopse
Renove o certificado para liveness probes para verificar a integridade do etcd.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado para nós etcd se comunicarem uns com os outros
Sinopse
Renove o certificado para nós etcd se comunicarem uns com os outros.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado para servir o etcd
Sinopse
Renove o certificado para servir o etcd.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado para o cliente front proxy
Sinopse
Renove o certificado para o cliente front proxy.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Renove o certificado incorporado no arquivo kubeconfig para o gerenciador de agendamento usar
Sinopse
Renove o certificado incorporado no arquivo kubeconfig para o gerenciador de agendamento usar.
As renovações são executadas incondicionalmente, independentemente da data de expiração do certificado; atributos extras, como SANs, serão baseados no arquivo/certificados existentes, não há necessidade de informá-los novamente.
A renovação, por padrão, tenta usar a autoridade de certificação na PKI local gerenciada pelo kubeadm; como alternativa, é possível usar o certificado K8s da API para renovação de certificado, ou como última opção, para gerar uma solicitação CSR.
Após a renovação, para tornar as alterações efetivas, é necessário reiniciar os componentes da camada de gerenciamento e, eventualmente, redistribuir o certificado renovado, caso o arquivo seja usado em outro lugar.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, um conjunto de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm certs certificate-key
Este comando pode ser usado para gerar uma nova chave do certificado da camada de gerenciamento. A chave pode ser passada como --certificate-key to kubeadm init e kubeadm join para permitir uma cópia automática dos certificados ao unir nós adicionais a camada de gerenciamento.
Este comando exibirá uma chave de certificado segura gerada aleatoriamente que pode ser usada com o comando "init".
Você também pode usar "kubeadm init --upload-certs" sem especificar uma chave de certificado e ela irá gerar e exibir uma para você.
kubeadm certs certificate-key [flags]
Opções
-h, --help
ajuda para certificate-key
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm certs check-expiration
Este comando verifica a expiração dos certificados na PKI local gerenciada pelo kubeadm. Para mais detalhes, consulte Verificar a expiração do certificado.
O arquivo kubeconfig usado na comunicação com o cluster. Se a flag não estiver definida, um conjunto de locais padrão pode ser pesquisado em busca de um arquivo kubeconfig existente.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
kubeadm certs generate-csr
Este comando pode ser usado para gerar chaves e CSRs para todos os certificados da camada de gerenciamento e arquivos kubeconfig. O usuário pode então assinar os CSRs com uma autoridade de certificação de sua escolha.
Gerar chaves e solicitações de assinatura de certificados
Sinopse
Gera as chaves e as solicitações de assinatura de certificados (CSRs) para todos os certificados necessários para executar a camada de gerenciamento. Este comando também gera os arquivos kubeconfig parciais com dados de chave privada no campo "users > user > client-key-data" e, para cada arquivo kubeconfig, um arquivo ".csr" correspondente é criado.
Esse comando foi projetado para uso no modo de CA externo do Kubeadm. Ele gera CSRs que você pode enviar à sua autoridade de certificação externa para assinatura.
Os certificados PEM assinados e codificados devem ser salvos juntamente com os arquivos da chave, usando ".crt" como extensão de arquivo ou, no caso de arquivos kubeconfig, o certificado assinado codificado no formato PEM deve ser codificado em base64 e adicionado ao arquivo kubeconfig no campo "users > user > client-certificate-data".
kubeadm certs generate-csr [flags]
Exemplos
# O comando a seguir gera as chaves e CSRs para todos os certificados do plano de controle e arquivos kubeconfig:
kubeadm certs generate-csr --kubeconfig-dir /tmp/etc-k8s --cert-dir /tmp/etc-k8s/pki
Opções
--cert-dir string
O caminho para salvar os certificados
--config string
Caminho para um arquivo de configuração kubeadm.
-h, --help
ajuda para generate-csr
--kubeconfig-dir string Padrão: "/etc/kubernetes"
O caminho para salvar o arquivo kubeconfig.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Próximos passos
kubeadm init para inicializar um nó da camada de gerenciamento do Kubernetes
kubeadm join para inicializar um nó de carga de trabalho do Kubernetes e associá-lo ao cluster
kubeadm reset para reverter quaisquer alterações feitas, neste host, pelo kubeadm init ou kubeadm join
6.4.1.11 - kubeadm kubeconfig
kubeadm kubeconfig fornece utilitários para gerenciar arquivos kubeconfig.
Saída do arquivo kubeconfig para um usuário adicional.
Sinopse
Exibe o arquivo kubeconfig para um usuário adicional.
kubeadm kubeconfig user [flags]
Exemplos
# Exibe um arquivo kubeconfig para um usuário adicional chamado foo usando um arquivo bar de configuração
kubeadm kubeconfig user --client-name=foo --config=bar
Opções
--client-name string
O nome do usuário. Será usado como CN se os certificados do cliente forem criados.
--config string
Caminho para um arquivo de configuração kubeadm.
-h, --help
ajuda para user
--org strings
As organizações do certificado do cliente. Será usado como O se os certificados de cliente forem criados.
--token string
O token que deve ser usado como mecanismo de autenticação para esse kubeconfig, em vez de certificados de cliente
--validity-period duração Padrão: 8760h0m0s
O período de validade do certificado do cliente. É um deslocamento da hora atual.
Opções herdadas do comando superior
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
6.4.1.12 - kubeadm upgrade phase
Na versão v1.15.0, o kubeadm introduziu suporte preliminar para as fases kubeadm upgrade node. Fases para outros subcomandos kubeadm upgrade, tal como apply, podem ser adicionadas nas seguintes versões.
kubeadm upgrade node phase
Usando essa fase, você pode optar por executar as etapas separadas da atualização de nós, sejam eles nós secundários da camada de gerenciamento ou nós de execução de cargas de trabalho. Observe que kubeadm upgrade apply ainda precisa ser chamado em um nó principal da camada de gerenciamento.
Use este comando para invocar uma fase única do fluxo de trabalho do nó
Sinopse
Use este comando para invocar uma fase única do fluxo de trabalho do nó
Opções
-h, --help
ajuda para fase
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Execute verificações antes de atualização do nó
Sinopse
Execute verificações antes de atualização do nó
kubeadm upgrade node phase preflight [flags]
Opções
-h, --help
ajuda para preflight
--ignore-preflight-errors strings
Uma lista de verificações cujos erros serão mostrados como avisos. Exemplo: 'IsPrivilegedUser,Swap'. O valor 'all' ignora erros de todas as verificações.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Atualiza a instância da camada de gerenciamento instalada nesse nó, se houver
Sinopse
Atualiza a instância da camada de gerenciamento instalada nesse nó, se houver
kubeadm upgrade node phase control-plane [flags]
Opções
--certificate-renewal Padrão: true
Executa a renovação dos certificados usados pelo componente alterado durante as atualizações.
--dry-run
Não altera nenhum estado, apenas produz as ações que seriam executadas.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, uma série de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
--patches string
O caminho para um diretório que contém arquivos chamados "target[suffix][+patchtype].extension". Por exemplo, "kube-apiserver0+merge.yaml" ou apenas "etcd.json". "target" são "kube-apiserver", "kube-controller-manager", "kube-scheduler", "etcd". "patchtype" pode ser um dos "strategic", "merge" or "json"e eles correspondem aos formatos de patch suportados pelo kubectl. O padrão "patchtype" é "strategic". "extension" deve ser "json" ou "yaml". "suffix" é uma string opcional que pode ser usada para determinar a ordem de aplicação dos patches alfanumericamente.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Atualize a configuração do kubelet para este nó
Sinopse
Baixa no cluster o ConfigMap de configuração do kubelet no formato "kubelet-config-1.X", onde X é a menor versão do kubelet. O kubeadm usa o campo KuberneteVersion no ConfigMap kubeadm-config para determinar qual é a versão desejada do kubelet.
kubeadm upgrade node phase kubelet-config [flags]
Opções
--dry-run
Não altera nenhum estado, apenas produz as ações que seriam executadas.
O arquivo kubeconfig a ser usado para se comunicar com o cluster. Se a flag não estiver definida, uma série de locais predefinidos pode ser pesquisado por um arquivo kubeconfig existente.
Opções herdadas dos comandos superiores
--rootfs string
[EXPERIMENTAL] O caminho para o 'real' sistema de arquivos raiz do host.
Próximos passos
kubeadm init para inicializar um nó da camada de gerenciamento do Kubernetes
kubeadm join para inicializar um nó worker do Kubernetes e associá-lo ao cluster
kubeadm reset para reverter quaisquer alterações feitas, neste host, pelo kubeadm init ou kubeadm join
kubeadm upgrade para atualizar um cluster Kubernetes para uma versão mais recente
kubeadm alpha para visualizar um conjunto de recursos disponibilizados para coletar feedback da comunidade
6.5 - Portas e protocolos
Quando o Kubernetes está sendo executado em um ambiente com uma rede mais restritiva,
como por exemplo um data center on-premises com firewalls de rede físicos ou redes virtuais em nuvens públicas,
é útil saber quais portas e protocolos são utilizados pelos componentes do Kubernetes.
Camada de gerenciamento
Protocolo
Direção
Intervalo de Portas
Propósito
Utilizado por
TCP
Entrada
6443
Servidor da API do Kubernetes
Todos
TCP
Entrada
2379-2380
API servidor-cliente do etcd
kube-apiserver, etcd
TCP
Entrada
10250
API do kubelet
kubeadm, Camada de gerenciamento
TCP
Entrada
10259
kube-scheduler
kubeadm
TCP
Entrada
10257
kube-controller-manager
kubeadm
Embora as portas do etcd estejam inclusas na seção da Camada de gerenciamento, você também
pode hospedar o seu próprio cluster etcd externamente ou em portas customizadas.
Todas as portas padrão podem ser sobrescritas. Quando portas customizadas são utilizadas, essas portas
precisam estar abertas, ao invés das mencionadas aqui.
Um exemplo comum é a porta do servidor da API, que as vezes é trocado para a porta 433.
Com isso, a porta padrão é mantida e o servidor da API é colocado atrás de um balanceador de carga
que escuta na porta 433 e faz o roteamento das requisições para o servidor da API na porta padrão.
6.6 - kubectl CLI
6.6.1 - kubectl Cheat Sheet
Esta página contém uma lista de comandos kubectl e flags frequentemente usados.
Kubectl Autocomplete
BASH
source <(kubectl completion bash)# configuração de autocomplete no bash do shell atual, o pacote bash-completion precisa ter sido instalado primeiro.echo"source <(kubectl completion bash)" >> ~/.bashrc # para adicionar o autocomplete permanentemente no seu shell bash.
Você também pode usar uma abreviação para o atalho para kubectl que também funciona com o auto completar:
aliask=kubectl
complete -o default -F __start_kubectl k
ZSH
source <(kubectl completion zsh)# configuração para usar autocomplete no terminal zsh no shell atualecho'[[ $commands[kubectl] ]] && source <(kubectl completion zsh)' >> ~/.zshrc # adicionar auto completar permanentemente para o seu shell zsh
Uma nota sobre --all-namespaces
Acrescentar --all-namespaces acontece com bastante frequência, onde você deve estar ciente da abreviação de --all-namespaces:
kubectl -A
Contexto e Configuração do Kubectl
Define com qual cluster Kubernetes o kubectl se comunica e modifica os detalhes da configuração.
Veja a documentação Autenticando entre clusters com o kubeconfig para
informações detalhadas do arquivo de configuração.
kubectl config view # Mostra configurações do kubeconfig mergeadas# use vários arquivos kubeconfig ao mesmo tempo e visualize a configuração mergeadaKUBECONFIG=~/.kube/config:~/.kube/kubconfig2
kubectl config view
# obtenha a senha para o usuário e2ekubectl config view -o jsonpath='{.users[?(@.name == "e2e")].user.password}'kubectl config view -o jsonpath='{.users[].name}'# exibe o primeiro usuáriokubectl config view -o jsonpath='{.users[*].name}'# obtém uma lista de usuárioskubectl config get-contexts # exibe lista de contextoskubectl config current-context # exibe o contexto atualkubectl config use-context my-cluster-name # define o contexto padrão como my-cluster-namekubectl config set-cluster my-cluster-name # define uma entrada de cluster no kubeconfig# configura a URL para um servidor proxy a ser usado para solicitações feitas por este cliente no kubeconfigkubectl config set-cluster my-cluster-name --proxy-url=my-proxy-url
# adiciona um novo cluster ao seu kubeconfig que suporte autenticação básicakubectl config set-credentials kubeuser/foo.kubernetes.com --username=kubeuser --password=kubepassword
# salva o namespace permanentemente para todos os comandos subsequentes do kubectl nesse contextokubectl config set-context --current --namespace=ggckad-s2
# define um contexto utilizando um nome de usuário e o namespacekubectl config set-context gce --user=cluster-admin --namespace=foo \
&& kubectl config use-context gce
kubectl config unset users.foo # exclui usuário foo# alias curto para definir/mostrar contexto/namespace (funciona apenas para bash e shells compatíveis com bash, contexto atual a ser definido antes de usar kn para definir namespace)aliaskx='f() { [ "$1" ] && kubectl config use-context $1 || kubectl config current-context ; } ; f'aliaskn='f() { [ "$1" ] && kubectl config set-context --current --namespace $1 || kubectl config view --minify | grep namespace | cut -d" " -f6 ; } ; f'
Kubectl apply
apply gerencia aplicações através de arquivos que definem os recursos do Kubernetes. Ele cria e atualiza recursos em um cluster através da execução kubectl apply.
Esta é a maneira recomendada para gerenciar aplicações Kubernetes em ambiente de produção. Veja a documentação do Kubectl.
Criando objetos
Manifestos Kubernetes podem ser definidos em YAML ou JSON. As extensões de arquivo .yaml,
.yml, e .json podem ser usadas.
kubectl apply -f ./my-manifest.yaml # cria recurso(s)kubectl apply -f ./my1.yaml -f ./my2.yaml # cria a partir de vários arquivoskubectl apply -f ./dir # cria recurso(s) em todos os arquivos de manifesto no diretóriokubectl apply -f https://git.io/vPieo # cria recurso(s) a partir de URLkubectl create deployment nginx --image=nginx # inicia uma única instância do nginx# cria um Job que exibe "Hello World"kubectl create job hello --image=busybox:1.28 -- echo"Hello World"# cria um CronJob que exibe "Hello World" a cada minutokubectl create cronjob hello --image=busybox:1.28 --schedule="*/1 * * * *" -- echo"Hello World"kubectl explain pods # obtém a documentação de manifesto do pod# Cria vários objetos YAML a partir de stdincat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: busybox-sleep
spec:
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000000"
---
apiVersion: v1
kind: Pod
metadata:
name: busybox-sleep-less
spec:
containers:
- name: busybox
image: busybox
args:
- sleep
- "1000"
EOF# Cria um segredo com várias chavescat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: $(echo -n "s33msi4" | base64 -w0)
username: $(echo -n "jane" | base64 -w0)
EOF
Visualizando e localizando recursos
# Comandos get com saída simpleskubectl get services # Lista todos os serviços do namespacekubectl get pods --all-namespaces # Lista todos os Pods em todos namespaceskubectl get pods -o wide # Lista todos os Pods no namespace atual, com mais detalheskubectl get deployment my-dep # Lista um deployment específicokubectl get pods # Lista todos os Pods no namespacekubectl get pod my-pod -o yaml # Obtém o YAML de um pod# Comandos describe com saída detalhadakubectl describe nodes my-node
kubectl describe pods my-pod
# Lista serviços classificados por nomekubectl get services --sort-by=.metadata.name
# Lista Pods classificados por contagem de reinicializaçõeskubectl get pods --sort-by='.status.containerStatuses[0].restartCount'# Lista PersistentVolumes classificados por capacidadekubectl get pv --sort-by=.spec.capacity.storage
# Obtém a versão da label de todos os Pods com a label app=cassandrakubectl get pods --selector=app=cassandra -o \
jsonpath='{.items[*].metadata.labels.version}'# Recupera o valor de uma chave com pontos, por exemplo 'ca.crt'kubectl get configmap myconfig \
-o jsonpath='{.data.ca\.crt}'# Recupera um valor codificado em base64 com traços em vez de sublinhadoskubectl get secret my-secret --template='{{index .data "key-name-with-dashes"}}'# Obtém todos os nós workers (use um seletor para excluir resultados que possuem uma label# nomeado 'node-role.kubernetes.io/control-plane')kubectl get node --selector='!node-role.kubernetes.io/control-plane'# Obtém todos os Pods em execução no namespacekubectl get pods --field-selector=status.phase=Running
# Obtém ExternalIPs de todos os nóskubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'# Lista nomes de Pods pertencentes a um RC particular# O comando "jq" é útil para transformações que são muito complexas para jsonpath, pode ser encontrado em https://stedolan.github.io/jq/sel=${$(kubectl get rc my-rc --output=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}echo$(kubectl get pods --selector=$sel --output=jsonpath={.items..metadata.name})# Exibe marcadores para todos os Pods (ou qualquer outro objeto Kubernetes que suporte rotulagem)kubectl get pods --show-labels
# Verifica quais nós estão prontosJSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'\
&& kubectl get nodes -o jsonpath="$JSONPATH" | grep "Ready=True"# Exibe o segredo decodificado sem utilizar ferramentas externaskubectl get secret my-secret -o go-template='{{range $k,$v := .data}}{{"### "}}{{$k}}{{"\n"}}{{$v|base64decode}}{{"\n\n"}}{{end}}'# Lista todos os segredos atualmente em uso por um podkubectl get pods -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secretKeyRef.name' | grep -v null | sort | uniq
# Lista todos os containerIDs de initContainer de todos os Pods# Útil ao limpar contêineres parados, evitando a remoção de initContainers.kubectl get pods --all-namespaces -o jsonpath='{range .items[*].status.initContainerStatuses[*]}{.containerID}{"\n"}{end}' | cut -d/ -f3
# Lista eventos classificados por timestampkubectl get events --sort-by=.metadata.creationTimestamp
# Lista todos eventos do tipo Warningkubectl events --types=Warning
# Compara o estado atual do cluster com o estado em que o cluster estaria se o manifesto fosse aplicado.kubectl diff -f ./my-manifest.yaml
# Produz uma árvore delimitada por ponto de todas as chaves retornadas para nós# Útil ao localizar uma chave em uma estrutura JSON aninhada complexakubectl get nodes -o json | jq -c 'paths|join(".")'# Produz uma árvore delimitada por ponto de todas as chaves retornadas para Pods, etc.kubectl get pods -o json | jq -c 'paths|join(".")'# Produz ENV para todos os Pods, supondo que você tenha um contêiner padrão para os Pods, namespace padrão e o comando `env` é compatível.# Útil ao executar qualquer comando suportado em todos os Pods, não apenas `env`for pod in $(kubectl get po --output=jsonpath={.items..metadata.name}); doecho$pod&& kubectl exec -it $pod -- env; done# Obtém o status de um sub-recurso de uma implantaçãokubectl get deployment nginx-deployment --subresource=status
Atualizando recursos
kubectl set image deployment/frontend www=image:v2 # Aplica o rollout nos containers "www" do deployment "frontend", atualizando a imagemkubectl rollout history deployment/frontend # Verifica o histórico do deployment, incluindo a revisãokubectl rollout undo deployment/frontend # Rollback para o deployment anteriorkubectl rollout undo deployment/frontend --to-revision=2# Rollback para uma revisão específicakubectl rollout status -w deployment/frontend # Acompanha o status de atualização do "frontend" até sua conclusão sem interrupção kubectl rollout restart deployment/frontend # Reinicia contínuo do deployment "frontend"cat pod.json | kubectl replace -f - # Substitue um pod com base no JSON passado para stdin# Força a substituição, exclui e recria o recurso. Causará uma interrupção do serviço.kubectl replace --force -f ./pod.json
# Cria um serviço para um nginx replicado, que serve na porta 80 e se conecta aos contêineres na porta 8000kubectl expose rc nginx --port=80 --target-port=8000# Atualiza a versão da imagem (tag) de um pod de contêiner único para a v4kubectl get pod mypod -o yaml | sed 's/\(image: myimage\):.*$/\1:v4/' | kubectl replace -f -
kubectl label pods my-pod new-label=awesome # Adiciona uma labelkubectl label pods my-pod new-label- # Remove a label new-labelkubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq # Adiciona uma anotaçãokubectl autoscale deployment foo --min=2 --max=10# Escala automaticamente um deployment "foo"
Recursos de correção
# Atualiza parcialmente um nókubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'# Atualiza a imagem de um contêiner; spec.containers[*].name é obrigatório porque é uma chave de mesclagemkubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'# Atualiza a imagem de um contêiner usando um patch json com matrizes posicionaiskubectl patch pod valid-pod --type='json' -p='[{"op": "replace", "path": "/spec/containers/0/image", "value":"new image"}]'# Desativa um livenessProbe de deployment usando um patch json com matrizes posicionaiskubectl patch deployment valid-deployment --type json -p='[{"op": "remove", "path": "/spec/template/spec/containers/0/livenessProbe"}]'# Adiciona um novo elemento a uma matriz posicionalkubectl patch sa default --type='json' -p='[{"op": "add", "path": "/secrets/1", "value": {"name": "whatever" } }]'# Atualiza a contagem de réplicas de uma implantação corrigindo seu sub-recurso de escalakubectl patch deployment nginx-deployment --subresource='scale' --type='merge' -p '{"spec":{"replicas":2}}'
Editando recursos
Edita qualquer recurso da API no seu editor preferido.
kubectl edit svc/docker-registry # Edita o serviço chamado docker-registryKUBE_EDITOR="nano" kubectl edit svc/docker-registry # Usa um editor alternativo
Escalando recursos
kubectl scale --replicas=3 rs/foo # Escala um replicaset chamado 'foo' para 3kubectl scale --replicas=3 -f foo.yaml # Escala um recurso especificado em "foo.yaml" para 3kubectl scale --current-replicas=2 --replicas=3 deployment/mysql # Se o tamanho atual do deployment chamado mysql for 2, escala para 3kubectl scale --replicas=5 rc/foo rc/bar rc/baz # Escala vários controladores de replicaset
Deletando resources
kubectl delete -f ./pod.json # Exclui um Pod usando o tipo e o nome especificados em pod.jsonkubectl delete pod unwanted --now ........ # Exclui um Pod imediatamente sem esperar pelo tempo configuradokubectl delete pod,service baz foo # Exclui Pods e serviços com os mesmos nomes "baz" e "foo"kubectl delete pods,services -l name=myLabel # Exclui Pods e serviços com o nome da label = myLabelkubectl -n my-ns delete pod,svc --all # Exclui todos os Pods e serviços no namespace my-ns,# Exclui todos os Pods que correspondem ao awk pattern1 ou pattern2kubectl get pods -n mynamespace --no-headers=true | awk '/pattern1|pattern2/{print $1}' | xargs kubectl delete -n mynamespace pod
Interagindo com Pods em execução
kubectl logs my-pod # despeja logs de pod (stdout)kubectl logs -l name=myLabel # despeja logs de pod, com a label de name=myLabel (stdout)kubectl logs my-pod --previous # despeja logs de pod (stdout) para a instância anterior de um contêinerkubectl logs my-pod -c my-container # despeja logs de um específico contêiner em um pod (stdout, no caso de vários contêineres)kubectl logs -l name=myLabel -c my-container # despeja logs de pod, com nome da label = myLabel (stdout)kubectl logs my-pod -c my-container --previous # despeja logs de um contêiner específico em um pod (stdout, no caso de vários contêineres) para uma instanciação anterior de um contêinerkubectl logs -f my-pod # Fluxo de logs de pod (stdout)kubectl logs -f my-pod -c my-container # Fluxo de logs para um específico contêiner em um pod (stdout, caixa com vários contêineres)kubectl logs -f -l name=myLabel --all-containers # transmite todos os logs de Pods com a label name=myLabel (stdout)kubectl run -i --tty busybox --image=busybox:1.28 -- sh # Executa pod como shell interativokubectl run nginx --image=nginx -n mynamespace # Inicia uma única instância do pod nginx no namespace de mynamespacekubectl run nginx --image=nginx --dry-run=client -o yaml > pod.yaml
# Gera a especificação para executar o pod nginx e grave-a em um arquivo chamado pod.yaml kubectl attach my-pod -i # Anexa ao contêiner em execuçãokubectl port-forward my-pod 5000:6000 # Ouça na porta 5000 na máquina local e encaminhe para a porta 6000 no my-podkubectl exec my-pod -- ls / # Executa comando no pod existente (1 contêiner)kubectl exec --stdin --tty my-pod -- /bin/sh # Acesso de shell interativo a um pod em execução (apenas 1 contêiner)kubectl exec my-pod -c my-container -- ls / # Executa comando no pod existente (pod com vários contêineres)kubectl top pod POD_NAME --containers # Mostra métricas para um determinado pod e seus contêinereskubectl top pod POD_NAME --sort-by=cpu # Mostra métricas para um determinado pod e classificá-lo por 'cpu' ou 'memória'
Copiando arquivos e diretórios de e para contêineres
kubectl cp /tmp/foo_dir my-pod:/tmp/bar_dir # Copia o diretório local /tmp/foo_dir para /tmp/bar_dir em um pod remoto no namespace atualkubectl cp /tmp/foo my-pod:/tmp/bar -c my-container # Copia o arquivo local /tmp/foo para /tmp/bar em um pod remoto em um contêiner específicokubectl cp /tmp/foo my-namespace/my-pod:/tmp/bar # Copia o arquivo local /tmp/foo para /tmp/bar em um pod remoto no namespace my-namespacekubectl cp my-namespace/my-pod:/tmp/foo /tmp/bar # Copia /tmp/foo de um pod remoto para /tmp/bar localmente
Nota:
kubectl cp requer que o binário 'tar' esteja presente em sua imagem de contêiner. Se 'tar' não estiver presente, kubectl cp falhará.
Para casos de uso avançado, como links simbólicos, expansão curinga ou preservação do modo de arquivo, considere usar kubectl exec.
tar cf - /tmp/foo | kubectl exec -i -n my-namespace my-pod -- tar xf - -C /tmp/bar # Copia o arquivo local /tmp/foo para /tmp/bar em um pod remoto no namespace my-namespacekubectl exec -n my-namespace my-pod -- tar cf - /tmp/foo | tar xf - -C /tmp/bar # Copia /tmp/foo de um pod remoto para /tmp/bar localmente
Interagindo com implantações e serviços
kubectl logs deploy/my-deployment # despeja logs de pod para uma implantação (caso de contêiner único)kubectl logs deploy/my-deployment -c my-container # despeja logs de pod para uma implantação (caso de vários contêineres)kubectl port-forward svc/my-service 5000# escuta na porta local 5000 e encaminhe para a porta 5000 no back-end do serviçokubectl port-forward svc/my-service 5000:my-service-port # escuta na porta local 5000 e encaminhe para a porta de destino do serviço com o nome <my-service-port>kubectl port-forward deploy/my-deployment 5000:6000 # escuta na porta local 5000 e encaminhe para a porta 6000 em um pod criado por <my-deployment>kubectl exec deploy/my-deployment -- ls # executa o comando no primeiro pod e primeiro contêiner na implantação (casos de um ou vários contêineres)
Interagindo com Nós e Cluster
kubectl cordon my-node # Marca o nó my-node como não agendávelkubectl drain my-node # Drena o nó my-node na preparação para manutençãokubectl uncordon my-node # Marca nó my-node como agendávelkubectl top node my-node # Mostra métricas para um determinado nókubectl cluster-info # Exibe endereços da master e serviçoskubectl cluster-info dump # Despeja o estado atual do cluster no stdoutkubectl cluster-info dump --output-directory=/path/to/cluster-state # Despeja o estado atual do cluster em /path/to/cluster-state# Veja os taints existentes nos nós atuais.kubectl get nodes -o='custom-columns=NodeName:.metadata.name,TaintKey:.spec.taints[*].key,TaintValue:.spec.taints[*].value,TaintEffect:.spec.taints[*].effect'# Se uma `taint` com essa chave e efeito já existir, seu valor será substituído conforme especificado.kubectl taint nodes foo dedicated=special-user:NoSchedule
Tipos de Recursos
Lista todos os tipos de recursos suportados junto com seus nomes abreviados, grupo de API, sejam eles namespaced e Kind:
kubectl api-resources
Outras operações para explorar os recursos da API:
kubectl api-resources --namespaced=true# Todos os recursos com namespacekubectl api-resources --namespaced=false# Todos os recursos sem namespacekubectl api-resources -o name # Todos os recursos com saída simples (apenas o nome do recurso)kubectl api-resources -o wide # Todos os recursos com saída expandida (também conhecida como "ampla")kubectl api-resources --verbs=list,get # Todos os recursos que suportam os verbos de API "list" e "get"kubectl api-resources --api-group=extensions # Todos os recursos no grupo de API "extensions"
Formatação de saída
Para enviar detalhes para a janela do terminal em um formato específico, adicione a flag -o (ou --output) para um comando kubectl suportado.
Formato de saída
Descrição
-o=custom-columns=<spec>
Exibe uma tabela usando uma lista separada por vírgula de colunas personalizadas
-o=custom-columns-file=<filename>
Exibe uma tabela usando o modelo de colunas personalizadas no arquivo <nome do arquivo>
-o=json
Saída de um objeto de API formatado em JSON
-o=jsonpath=<template>
Exibe os campos definidos em uma expressão jsonpath
-o=jsonpath-file=<filename>
Exibe os campos definidos pela expressão jsonpath no arquivo <nome do arquivo>
-o=name
Exibe apenas o nome do recurso e nada mais
-o=wide
Saída no formato de texto sem formatação com qualquer informação adicional e, para Pods, o nome do nó está incluído
-o=yaml
Saída de um objeto de API formatado em YAML
Exemplos usando -o=custom-columns:
# Todas as imagens em execução em um clusterkubectl get pods -A -o=custom-columns='DATA:spec.containers[*].image'# Todas as imagens em execução no namespace: padrão, agrupadas por podkubectl get pods --namespace default --output=custom-columns="NAME:.metadata.name,IMAGE:.spec.containers[*].image"# Todas as imagens excluindo "registry.k8s.io/coredns:1.6.2"kubectl get pods -A -o=custom-columns='DATA:spec.containers[?(@.image!="registry.k8s.io/coredns:1.6.2")].image'# Todos os campos sob metadados, independentemente do nomekubectl get pods -A -o=custom-columns='DATA:metadata.*'
A verbosidade do Kubectl é controlado com as flags -v ou --v seguidos por um número inteiro representando o nível do log. As convenções gerais de log do Kubernetes e os níveis de log associados são descritos aqui.
Verbosidade
Descrição
--v=0
Geralmente útil para sempre estar visível para um operador de cluster.
--v=1
Um nível de log padrão razoável se você não deseja verbosidade.
--v=2
Informações úteis sobre o estado estacionário sobre o serviço e mensagens importantes de log que podem se correlacionar com alterações significativas no sistema. Este é o nível de log padrão recomendado para a maioria dos sistemas.
--v=3
Informações estendidas sobre alterações.
--v=4
Detalhamento no nível de debugging.
--v=5
Verbosidade do nível de rastreamento.
--v=6
Exibe os recursos solicitados.
--v=7
Exibe cabeçalhos de solicitação HTTP.
--v=8
Exibe conteúdo da solicitação HTTP.
--v=9
Exibe o conteúdo da solicitação HTTP sem o truncamento do conteúdo.
Aprenda mais sobre autorização no Kubernetes, incluindo detalhes sobre
criação de políticas utilizando módulos de autorização suportados.
No Kubernetes, você deve estar autenticado (conectado) antes que sua requisição possa ser
autorizada (permissão concedida para acesso). Para obter informações sobre autenticação,
visite Controlando Acesso à API do Kubernetes.
O Kubernetes espera atributos que são comuns a requisições de APIs REST. Isto significa
que autorização no Kubernetes funciona com sistemas de controle de acesso a nível de organizações
ou de provedores de nuvem que possam lidar com outras APIs além das APIs do Kubernetes.
Determinar se uma requisição é permitida ou negada
O Kubernetes autoriza requisições de API utilizando o servidor de API. Ele avalia
todos os atributos de uma requisição em relação a todas as políticas disponíveis e permite ou nega a requisição.
Todas as partes de uma requisição de API deve ser permitidas por alguma política para que possa prosseguir.
Isto significa que permissões são negadas por padrão.
(Embora o Kubernetes use o servidor de API, controles de acesso e políticas que
dependem de campos específicos de tipos específicos de objetos são tratados pelos controladores de admissão.)
Quando múltiplos módulos de autorização são configurados, cada um será verificado em sequência.
Se qualquer dos autorizadores aprovarem ou negarem uma requisição, a decisão é imediatamente
retornada e nenhum outro autorizador é consultado. Se nenhum módulo de autorização tiver
nenhuma opinião sobre requisição, então a requisição é negada. Uma negação retorna um
código de status HTTP 403.
Revisão de atributos de sua requisição
O Kubernetes revisa somente os seguintes atributos de uma requisição de API:
user - O string de user fornecido durante a autenticação.
group - A lista de nomes de grupos aos quais o usuário autenticado pertence.
extra - Um mapa de chaves de string arbitrárias para valores de string, fornecido pela camada de autenticação.
API - Indica se a solicitação é para um recurso de API.
Caminho da requisição - Caminho para diversos endpoints que não manipulam recursos, como /api ou /healthz.
Verbo de requisição de API - Verbos da API como get, list, create, update, patch, watch, delete e deletecollection que são utilizados para solicitações de recursos. Para determinar o verbo de requisição para um endpoint de recurso de API , consulte Determine o verbo da requisição.
Verbo de requisição HTTP - Métodos HTTP em letras minúsculas como get, post, put e delete que são utilizados para requisições que não são de recursos.
Recurso - O identificador ou nome do recurso que está sendo acessado (somente para requisições de recursos) - para requisições de recursos usando os verbos get, update, patch e delete, deve-se fornecer o nome do recurso.
Subrecurso - O sub-recurso que está sendo acessado (somente para solicitações de recursos).
Namespace - O namespace do objeto que está sendo acessado (somente para solicitações de recursos com namespace).
Grupo de API - O API Group sendo acessado (somente para requisições de recursos). Uma string vazia designa o Grupo de APIcore.
Determine o verbo da requisição
Requisições de não-recursos
Requisições sem recursos de /api/v1/... ou /apis/<group>/<version>/...
são considerados "requisições sem recursos" e usam o método HTTP em letras minúsculas da solicitação como o verbo.
Por exemplo, uma solicitação GET para endpoints como /api ou /healthz usaria get como o verbo.
Requisições de recursos
Para determinar o verbo de requisição para um endpoint de API de recurso, revise o verbo HTTP
utilizado e se a requisição atua ou não em um recurso individual ou em uma
coleção de recursos:
Verbo HTTP
Verbo de Requisição
POST
create
GET, HEAD
get (para recursos individuais), list (para coleções, includindo o conteúdo do objeto inteiro), watch (para observar um recurso individual ou coleção de recursos)
Os verbos get, list e watch podem retornar todos os detalhes de um recurso. Eles são equivalentes em relação aos dados retornados. Por exemplo, list em secrets revelará os atributos de data de qualquer recurso retornado.
Às vezes, o Kubernetes verifica a autorização para permissões adicionais utilizando verbos especializados. Por exemplo:
Verbo impersonate em users, groups, e serviceaccounts no grupo de API core, e o userextras no grupo authentication.k8s.io de API.
Modos de Autorização
O servidor da API Kubernetes pode autorizar uma solicitação usando um dos vários modos de autorização:
Node - Um modo de autorização de finalidade especial que concede permissões a kubelets com base nos Pods que estão programados para execução. Para saber mais sobre como utilizar o modo de autorização do nó, consulte Node Authorization.
ABAC - Attribute-based access control (ABAC), ou Controle de acesso baseado em atributos, define um paradigma de controle de acesso pelo qual os direitos de acesso são concedidos aos usuários por meio do uso de políticas que combinam atributos. As políticas podem usar qualquer tipo de atributo (atributos de usuário, atributos de recurso, objeto, atributos de ambiente, etc.). Para saber mais sobre como usar o modo ABAC, consulte ABAC Mode.
RBAC - Role-based access control (RBAC), ou controle de acesso baseado em função, é um método de regular o acesso a recursos computacionais ou de rede com base nas funções de usuários individuais dentro de uma empresa. Nesse contexto, acesso é a capacidade de um usuário individual realizar uma tarefa específica, como visualizar, criar ou modificar um arquivo. Para saber mais sobre como usar o modo RBAC, consulte RBAC Mode
Quando especificado RBAC (Role-Based Access Control) usa o grupo de API rbac.authorization.k8s.io para orientar as decisões de autorização, permitindo que os administradores configurem dinamicamente as políticas de permissão por meio da API do Kubernetes.
Para habilitar o modo RBAC, inicie o servidor de API (apiserver) com a opção --authorization-mode=RBAC.
Webhook - Um WebHook é um retorno de chamada HTTP: um HTTP POST que ocorre quando algo acontece; uma simples notificação de evento via HTTP POST. Um aplicativo da Web que implementa WebHooks postará uma mensagem em um URL quando um determinado evento ocorrer. Para saber mais sobre como usar o modo Webhook, consulte Webhook Mode.
Verificando acesso a API
kubectl fornece o subcomando auth can-i para consultar rapidamente a camada de autorização da API.
O comando usa a API SelfSubjectAccessReview para determinar se o usuário atual pode executar
uma determinada ação e funciona independentemente do modo de autorização utilizado.
SelfSubjectAccessReview faz parte do grupo de API authorization.k8s.io, que
expõe a autorização do servidor de API para serviços externos. Outros recursos
neste grupo inclui:
SubjectAccessReview - Revisão de acesso para qualquer usuário, não apenas o atual. Útil para delegar decisões de autorização para o servidor de API. Por exemplo, o kubelet e extensões de servidores de API utilizam disso para determinar o acesso do usuário às suas próprias APIs.
LocalSubjectAccessReview - Similar a SubjectAccessReview, mas restrito a um namespace específico.
SelfSubjectRulesReview - Uma revisão que retorna o conjunto de ações que um usuário pode executar em um namespace. Útil para usuários resumirem rapidamente seu próprio acesso ou para interfaces de usuário mostrarem ações.
Essas APIs podem ser consultadas criando recursos normais do Kubernetes, onde a resposta no campo status
do objeto retornado é o resultado da consulta.
Você deve incluir uma flag em sua política para indicar qual módulo de autorização
suas políticas incluem:
As seguintes flags podem ser utilizadas:
--authorization-mode=ABAC O modo de controle de acesso baseado em atributos (ABAC) permite configurar políticas usando arquivos locais.
--authorization-mode=RBAC O modo de controle de acesso baseado em função (RBAC) permite que você crie e armazene políticas usando a API do Kubernetes.
--authorization-mode=Webhook WebHook é um modo de retorno de chamada HTTP que permite gerenciar a autorização usando endpoint REST.
--authorization-mode=Node A autorização de nó é um modo de autorização de propósito especial que autoriza especificamente requisições de API feitas por kubelets.
--authorization-mode=AlwaysDeny Esta flag bloqueia todas as requisições. Utilize esta flag somente para testes.
--authorization-mode=AlwaysAllow Esta flag permite todas as requisições. Utilize esta flag somente se não existam requisitos de autorização para as requisições de API.
Você pode escolher mais de um modulo de autorização. Módulos são verificados
em ordem, então, um modulo anterior tem maior prioridade para permitir ou negar uma requisição.
Escalonamento de privilégios através da criação ou edição da cargas de trabalho
Usuários que podem criar ou editar pods em um namespace diretamente ou através de um controlador
como, por exemplo, um operador, conseguiriam escalar seus próprios privilégios naquele namespace.
Cuidado:
Administradores de sistemas, tenham cuidado ao permitir acesso para criar ou editar cargas de trabalho.
Detalhes de como estas permissões podem ser usadas de forma maliciosa podem ser encontradas em caminhos para escalonamento.
Caminhos para escalonamento
Montagem de Secret arbitrários nesse namespace
Pode ser utilizado para acessar Secret destinados a outras cargas de trabalho
Pode ser utilizado para obter um token da conta de serviço com maior privilégio
Uso de contas de serviço arbitrárias nesse namespace
Pode executar ações da API do Kubernetes como outra carga de trabalho (personificação)
Pode executar quaisquer ações privilegiadas que a conta de serviço tenha acesso
Montagem de configmaps destinados a outras cargas de trabalho nesse namespace
Pode ser utilizado para obter informações destinadas a outras cargas de trabalho, como nomes de host de banco de dados.
Montagem de volumes destinados a outras cargas de trabalho nesse namespace
Pode ser utilizado para obter informações destinadas a outras cargas de trabalho e alterá-las.
Cuidado:
Administradores de sistemas devem ser cuidadosos ao instalar CRDs que
promovam mudanças nas áreas mencionadas acima. Estes podem abrir caminhos para escalonamento.
Isto deve ser considerado ao decidir os controles de acesso baseado em função (RBAC).
O projeto Kubernetes publica um Feed JSON, que pode ser programaticamente acessado, de questões de segurança publicadas. Você pode acessá-lo executando o seguinte comando:
Este feed é automaticamente atualizado, mas com um pequeno atraso perceptível (minutos a horas),
desde o momento em que um CVE é anunciado até o momento em que é acessível neste feed.
A fonte deste feed é um conjunto de issues do GitHub, filtrado pelo rótulo controlado e restrito official-cve-feed. Os dados brutos são armazenados em um Google Cloud Bucket que é somente escrito por um pequeno número de membros confiáveis da Comunidade.
6.9 - Utilizando Autorização ABAC
O controle de acesso baseado em atributos (ABAC) define um paradigma de controle de acesso onde os direitos de acesso são concedidos aos usuários por meio do uso de políticas que combinam atributos.
Formato do arquivo de política
Especifique os parametros de inicialização --authorization-policy-file=NOME_DE_ALGUM_ARQUIVO e --authorization-mode=ABAC para habilitar o modo ABAC.
O formato do arquivo é de um objeto JSON por linha. Nele não deve haver lista ou mapa envolvente, apenas um mapa por linha.
Cada linha é um "objeto de política", onde cada objeto é um mapa com as seguintes propriedades:
Propriedades de versionamento:
apiVersion, tipo string; os valores válidos são "abac.authorization.kubernetes.io/v1beta1". Permite controle de versão e conversão do formato da política.
kind, tipo string: os valores válidos são "Policy". Permite controle de versão e conversão do formato da política.
spec definida para um mapa com as seguintes propriedades:
Propriedades de correspondência de sujeito:
user, tipo string; a string de usuário de --token-auth-file. Se você especificar user, ele deve corresponder ao nome do usuário autenticado.
group, tipo string; se você especificar group, ele deve corresponder a um dos grupos do usuário autenticado system:authenticated corresponde a todas as requisições autenticadas. system:unauthenticated corresponde a todas as requisições não autenticadas.
Propriedades de correspondência de recursos:
apiGroup, tipo string; um grupo de API.
Ex: apps, networking.k8s.io
Curinga: * corresponde a todos os grupos de API.
namespace, tipo string; um namespace.
Ex: kube-system
Curinga: * corresponde a todas as requisições de recursos.
resource, tipo string; um tipo de recurso
Ex: pods, deployments
Curinga: * corresponde a todas as requisições de recursos.
Propriedades sem correspondência de recursos:
nonResourcePath, tipo string; caminhos de solicitação sem recurso.
Ex: /version ou /apis
Curinga:
* corresponde a todas as requisições que não são de recursos.
/foo/* corresponde a todos os subcaminhos de /foo/.
readonly, tipo booleano. Quando verdadeiro, significa que a política de correspondência de recursos se aplica apenas às operações get, list e watch. Em caso de políticas sem correspondência de recursos se aplica apenas à operação get.
Nota:
Uma propriedade não definida é igual a uma propriedade definida com o valor zero para seu tipo
(por exemplo, string vazia, 0, falso). No entanto, indefinido deve ser preferido para legibilidade.
No futuro, as políticas poderão ser expressas no formato JSON e gerenciadas por meio de uma interface REST.
Algoritmo de Autorização
Uma requisição possui atributos que correspondem às propriedades de um objeto de política.
Quando uma requisição é recebida, os atributos são determinados. Atributos desconhecidos são definidos com o valor zero de seu tipo (por exemplo, string vazia, 0, falso).
Uma propriedade definida como "*" corresponderá a qualquer valor do atributo correspondente.
A tupla de atributos é verificada em relação a cada política do arquivo de política. Se pelo menos uma linha corresponder aos atributos da requisição, ela é então autorizada (mas pode falhar em validação posterior).
Para permitir que qualquer usuário autenticado faça algo, escreva uma política com a propriedade do grupo definida como "system:authenticated".
Para permitir que qualquer usuário não autenticado faça algo, escreva uma política com a propriedade do grupo definida como "system:unauthenticated".
Para permitir que um usuário faça qualquer coisa, escreva uma política com as propriedades apiGroup, namespace, resource e nonResourcePath definidas como "*".
Kubectl
O Kubectl usa os endpoints /api e /apis do servidor de API para descobrir os tipos de recursos servidos e valida objetos enviados para a API pelas operações criar/atualizar usando informações de esquema localizadas em /openapi/v2.
Ao utilizar a autorização ABAC, esses recursos especiais devem ser explicitamente expostos por meio da propriedade nonResourcePath em uma política (consulte exemplos abaixo):
/api, /api/*, /apis e /apis/* para negociação de versão da API.
/version para recuperar a versão do servidor via kubectl version.
/swaggerapi/* para operações de criação/atualização.
Para inspecionar as chamadas HTTP envolvidas em uma operação kubectl específica, você pode aumentar a verbosidade:
kubectl --v=8 version
Exemplos
Alice pode fazer qualquer coisa em todos os recursos:
Cada conta de serviço tem um nome de usuário ABAC correspondente, e o nome de usuário dessa conta de serviço é gerado de acordo com a convenção de nomenclatura:
A criação de um novo namespace leva à criação de uma nova conta de serviço no seguinte formato:
system:serviceaccount:<namespace>:default
Por exemplo, se você quiser conceder à conta de serviço padrão (no namespace kube-system) privilégio total à API usando ABAC, adicione esta linha ao seu arquivo de política:
O servidor de API precisará ser reiniciado para carregar as novas linhas da política.
6.10 - Ferramentas
O Kubernetes contém várias ferramentas internas para ajudá-lo a trabalhar com o sistema Kubernetes.
Kubectl
kubectl é a ferramenta de linha de comando para o Kubernetes. Ela controla o gerenciador de cluster do Kubernetes.
Kubeadm
kubeadm é a ferramenta de linha de comando para provisionar facilmente um cluster Kubernetes seguro sobre servidores físicos ou na nuvem ou em máquinas virtuais (atualmente em alfa).
Minikube
minikube é uma ferramenta que facilita a execução local de um cluster Kubernetes de nó único em sua estação de trabalho para fins de desenvolvimento e teste.
Dashboard
Dashboard, a interface Web do Kubernetes, permite implantar aplicativos em contêiner em um cluster do Kubernetes, solucionar problemas e gerenciar o cluster e seus próprios recursos.
Helm
Kubernetes Helm é uma ferramenta para gerenciar pacotes de recursos pré-configurados do Kubernetes, também conhecidos como Kubernetes charts.
Use o Helm para:
Encontrar e usar softwares populares empacotados como Kubernetes charts
Compartilhar seus próprios aplicativos como Kubernetes charts
Criar builds reproduzíveis de seus aplicativos Kubernetes
Gerenciar de forma inteligente os arquivos de manifesto do Kubernetes
Gerenciar versões dos pacotes Helm
Kompose
Kompose é uma ferramenta para ajudar os usuários do Docker Compose a migrar para o Kubernetes.
Use o Kompose para:
Converter um arquivo Docker Compose em objetos Kubernetes
Ir do desenvolvimento local do Docker ao gerenciamento de seu aplicativo via Kubernetes
Contribuidores da documentação do Kubernetes podem:
Melhorar o conteúdo existente
Criar novo conteúdo
Traduzir a documentação
Gerenciar e publicar a documentação como parte do ciclo de lançamento do Kubernetes
Começando
Qualquer pessoa pode abrir uma issue sobre a documentação, ou contribuir com uma mudança por meio de um pull request (PR) para o repositório do Github kubernetes/website.
É recomendável que você se sinta confortável com git e
Github para trabalhar efetivamente na comunidade Kubernetes.
Algumas tarefas requerem mais confiança e mais acessos na organização do Kubernetes.
Veja Participando no SIG Docs para mais detalhes
sobre funções e permissões.
O SIG Docs é um grupo de contribuidores que publica e mantém
a documentação e o site do Kubernetes. Se envolver com o SIG Docs é uma ótima forma de contribuidores Kubernetes (pessoas desenvolvedoras de features ou outros) terem um grande impacto dentro do projeto Kubernetes.
A comunicação do SIG Docs é feita de diferentes formas:
Para contribuir com a comunidade Kubernetes por meio de fóruns on-line, como Twitter ou Stack Overflow, ou aprender sobre encontros locais e eventos do Kubernetes, visite a area de comunidade Kubernetes.
Para contribuir com o desenvolvimento de novas funcionalidades, leia o cheatsheet do colaborador para começar.
Leia o cheatsheet de contribuidor para saber mais sobre as funcionalidades de desenvolvimento do Kubernetes.
Qualquer pessoa pode revisar um pull request da documentação.
Visite a seção pull requests no repositório do site Kubernetes para ver os pull requests abertos.
Revisar os pull requests da documentação é uma ótima maneira de se apresentar à comunidade Kubernetes.
Isso ajuda você a aprender a base de código e construir a confiança com outros colaboradores.
Comente os aspectos positivos dos PRs, bem como mudanças.
Seja empático e cuidadoso, observe como sua avaliação pode ser recebida.
Assuma boas intenções e faça perguntas esclarecedoras.
Colaboradores experientes, considere trabalhar em par com os novos colaboradores cujo trabalho requer grandes mudanças.
Processo de revisão
Em geral, revise os pull requests de conteúdo e estilo em inglês.
A Figura 1 descreve as etapas para o processo de revisão.
Seguem os detalhes para cada etapa.
Filtre os PRs abertos usando um ou todos os labels seguintes:
cncf-cla: yes (Recomendado): PRs enviados por colaboradores que não assinaram o CLA não podem ser feito o merge. Consulte Assinar o CLA para obter mais informações.
language/pt (Recomendado): Filtro para PRs em português.
size/<size>: Filtro para PRs com um determinado tamanho. Se você é novo, comece com PRs menores.
Além disso, certifique-se que o PR não esteja marcado como work in progress. Os PRs que usam o labelwork in progress ainda não estão prontos para revisão.
Depois de selecionar um PR para revisar, entenda a mudança:
Lendo a descrição do PR para entender as alterações feitas e ler quaisquer issues vinculadas
Lendo quaisquer comentários de outros revisores
Clicando na aba Files changed para ver os arquivos e linhas alteradas
Pré-visualizar as alterações ambiente de pré-visualização do Netlify, rolando até a seção PR's build check na parte inferior da aba Conversation.
Aqui está uma captura da tela (isso mostra a área de trabalho do site GitHub; se você estiver revisando em um tablet ou smartphone, a interface web do usuário GitHub será um pouco diferente):
Para abrir a visualização, selecione o link Details da linha deploy/netlify na lista de verificações.
Vá para a aba Files changed para iniciar sua revisão.
Clique no símbolo + ao lado da linha que você deseja comentar.
Preencha com todos os comentários que você tenha sobre a linha e clique em Add single comment (se você tiver apenas um comentário para fazer) ou Start a review (se você tiver vários comentários para fazer)
Quando terminar, clique em Review changes na parte superior da página.
Aqui, você pode adicionar um resumo da sua revisão (e deixar alguns comentários positivos para o colaborador!).
Por favor, sempre use o "Comentário"
Evite clicar no botão "Request changes" ao concluir sua revisão.
Se você quiser bloquear o merge do PR antes que outras alterações sejam realizadas, você pode deixar um comentário "/hold".
Mencione por que você está definindo o bloqueio e, opcionalmente, especifique as condições sob as quais o bloqueio pode ser removido por você ou por outros revisores.
Evite clicar no botão "Approve" ao concluir sua revisão.
Deixar um comentário "/approve" é recomendado na maioria dos casos.
Checklist para revisão
Ao revisar, use como ponto de partida o seguinte.
Linguagem e gramática
Existe algum erro óbvio na linguagem ou gramática? Existe uma maneira melhor de expressar algo?
Concentre-se na linguagem e na gramática nas partes que o autor está mudando na página.
A menos que o autor esteja claramente com o objetivo de atualizar a página inteira, ele não tem obrigação de corrigir todos os problemas na página.
Quando um PR atualiza uma página existente, você deve se concentrar em revisar as partes que estão sendo atualizadas na página.
Esse conteúdo alterado deve ser revisado quanto à correção técnica e editorial.
Se você encontrar erros na página que não se relacionam diretamente com o que o autor do PR está tentando resolver, ele deve ser tratado em uma issue separada (primeiro, verifique se não existe uma issue existente sobre isso).
Cuidado com os pull requests que movem conteúdo.
Se um autor renomear uma página ou combinar duas páginas, nós (Kubernetes SIG Docs) geralmente evitamos pedir a esse autor que corrija todas as questões gramaticais ou ortográficas que poderíamos identificar dentro desse conteúdo movido.
Existem palavras complicadas ou arcaicas que podem ser substituídas por uma palavra mais simples?
Existem palavras, termos ou frases em uso que podem ser substituídos por uma alternativa não discriminatória?
A escolha da palavra e sua capitalização seguem o guia de estilo?
Existem frases longas que podem ser mais curtas ou menos complexas?
Existem parágrafos longos que podem funcionar melhor como uma lista ou tabela?
Conteúdo
Existe conteúdo semelhante em outro lugar no site Kubernetes?
O conteúdo está excessivamente vinculado a uma documentação externa, de um fornecedor individual ou de um código não aberto?
Website
Esse PR alterou ou removeu um título da página, slug/alias ou link?
Em caso afirmativo, existem links quebrados como resultado deste PR?
Existe outra opção, como alterar o título da página sem alterar o slug?
O PR apresenta uma nova página? Caso afirmativo:
A página está usando corretamente o tipo de conteúdo e os códigos relacionados ao Hugo?
A página aparece corretamente na navegação da seção (ou em geral)?
As alterações aparecem na visualização do Netlify? Esteja particularmente atento a listas, blocos de código, tabelas, notas e imagens.
Outro
Cuidado com as edições triviais;
se você observar uma mudança que entender ser uma edição trivial, por favor, marque essa política (ainda não há problema em aceitar a alteração se for genuinamente uma melhoria).
Incentive os autores que estão fazendo correções de espaço em branco a fazê-lo no primeiro commit de seu PR e, em seguida, adicione outras alterações além disso.
Isso facilita as revisões e o merge.
Cuidado especialmente com uma mudança trivial que aconteça em um único commit, juntamente com uma grande quantidade de limpeza dos espaços em branco (e se você observar isso, incentive o autor a corrigi-lo).
Como revisor, se você identificar pequenos problemas com um PR que não são essenciais para o significado, como erros de digitação ou espaços em branco incorretos, sinalize seus comentários com nit:.
Isso permite que o autor saiba que esta parte do seu feedback não é uma crítica.
Se você estiver considerando um pull request e todo o feedback restante estiver marcado como um nit, você pode realizar o merge do PR de qualquer maneira.
Nesse caso, muitas vezes é útil abrir uma issue sobre os nits restantes.
Considere se você é capaz de atender aos requisitos para marcar esse nova issue como uma Good First Issue; se você puder, esses são uma boa fonte.
7.2 - Visão geral do estilo da documentação
Os tópicos desta seção fornecem orientações gerais para o estilo de escrita,
formatação e organização do conteúdo, e como utilizar as customizações do Hugo
específicas para a documentação do Kubernetes.
7.2.1 - Guia de Conteúdo da Documentação
Esta página contém orientações para a documentação do Kubernetes.
Se você tiver dúvidas sobre o que é permitido, junte-se ao canal #sig-docs no
Slack do Kubernetes e pergunte!
Você pode se registrar no Slack do Kubernetes através do endereço https://slack.k8s.io/.
Para informações sobre como criar novo conteúdo para a documentação do Kubernetes,
siga o guia de estilo.
Visão geral
O código-fonte para o website do Kubernetes, incluindo a documentação, é
armazenado no repositório kubernetes/website.
Localizada dentro da pasta kubernetes/website/content/<codigo-do-idioma>/docs,
a maior parte da documentação do Kubernetes é específica para o
projeto Kubernetes.
O que é permitido
A documentação do Kubernetes permite conteúdo de projetos de terceiros somente
quando:
O conteúdo documenta software que existe no projeto Kubernetes
O conteúdo documenta software que está fora do projeto, mas é necessário para
o funcionamento do Kubernetes
O conteúdo é canônico no kubernetes.io, ou está vinculado a conteúdo canônico
em outro local
Conteúdo de terceiros
A documentação do Kubernetes contém exemplos aplicados de projetos no projeto
Kubernetes — projetos que existem nas organizações
kubernetes e
kubernetes-sigs
do GitHub.
Links para conteúdo ativo no projeto Kubernetes sempre são permitidos.
O Kubernetes requer alguns conteúdos de terceiros para funcionar. Exemplos
incluem agentes de execução de contêiner (containerd, CRI-O, Docker),
políticas de rede
(plugins CNI), controladores Ingress,
e sistemas de log.
A documentação pode conter vínculos com software de código aberto de terceiros
fora do projeto Kubernetes somente quando estes projetos são necessários para
o funcionamento do Kubernetes.
Conteúdo duplicado
Sempre que possível, a documentação do Kubernetes utiliza links para fontes
canônicas de documentação ao invés de hospedar conteúdo duplicado.
Conteúdo duplicado requer o dobro de esforço (ou mais!) para manter e fica
obsoleto mais rapidamente.
Nota:
Se você é um mantenedor e precisa de auxílio para hospedar sua própria
documentação, solicite ajuda no canal
#sig-docs do Slack do Kubernetes.
Mais informações
Se você tem dúvidas sobre o conteúdo permitido, junte-se ao canal #sig-docs
do Slack do Kubernetes e faça sua pergunta!
Esta página fornece orientações de estilo para escrita da documentação do
Kubernetes. Estas são orientações, não regras. Utilize seu melhor julgamento
e sinta-se livre para propor alterações neste documento através de um pull request.
Para informações adicionais sobre como criar novo conteúdo para a documentação
do Kubernetes, leia o
Guia de Conteúdo da Documentação.
Mudanças no guia de estilo são feitas pelo SIG Docs como um grupo. Para propor
uma alteração ou adição, inclua o tópico na agenda
de uma das reuniões futuras do SIG Docs, e participe da reunião para fazer parte
da discussão.
Nota:
A documentação do Kubernetes utiliza o
processador de markdown Goldmark com alguns
ajustes, bem como alguns shortcodes do Hugo
para suportar entradas de glossário, tabulações e representação do estado das
funcionalidades.
Língua
A documentação do Kubernetes foi traduzida para diversas línguas (veja
READMEs das Localizações).
Quando você se referir especificamente a interações com um objeto da API, utilize
UpperCamelCase, também conhecido como
Pascal case. Você poderá encontrar formatação de maiúsculas e minúsculas
diferente, como por exemplo "configMap", na referência da API.
Ao escrever documentação geral, prefira a utilização de upper camel case,
chamando o objeto de "ConfigMap".
Os exemplos a seguir focam no estilo de formatação de maiúsculas e minúsculas.
Para mais informações sobre como formatar nomes de objetos da API, revise a
orientação relacionada no manual de estilo de código.
Faça e não faça - Utilizando _Pascal case_ para objetos da API
Faça
Não faça
O recurso HorizontalPodAutoscaler é responsável por ...
O Horizontal pod autoscaler é responsável por ...
Um objeto PodList é uma lista de Pods.
Um objeto Pod List é uma lista de Pods.
O objeto Volume contém um campo hostPath.
O objeto volume contém um campo hostPath.
Cada objeto ConfigMap é parte de um namespace.
Cada objeto configMap é parte de um namespace.
Para o gerenciamento de dados confidenciais, considere utilizar a API de Secrets.
Para o gerenciamento de dados confidenciais, considere utilizar a API de segredos.
Utilize chevrons para espaços reservados
Utilize chevrons (< e >) para espaços reservados. Comunique ao leitor o
que o espaço reservado significa. Por exemplo:
kubectl describe pod <nome-do-pod> -n <namespace>
Se o nome do namespace do Pod for default, você pode omitir o paramêtro '-n'.
Grife elementos de interface de usuário
Faça e não faça - grife elementos da interface do usuário
Faça
Não faça
Clique em Fork.
Clique em "Fork".
Selecione Other.
Selecione "Other".
Utilize itálico para definir ou introduzir novos termos
Faça e não faça - Utilize itálico para novos termos
Faça
Não faça
Um cluster é um conjunto de nós ...
Um "cluster" é um conjunto de nós ...
Estes componentes formam a camada de gerenciamento.
Estes componentes formam a camada de gerenciamento.
Utilize estilo de código para nomes de arquivos, diretórios e caminhos
Faça e não faça - Utilize estilo de código para nomes de arquivos, diretórios e caminhos
Faça
Não faça
Abra o arquivo envars.yaml.
Abra o arquivo envars.yaml.
Navegue até o diretório /docs/tutorials.
Navegue até o diretório /docs/tutorials.
Abra o arquivo /_data/concepts.yaml.
Abra o arquivo /_data/concepts.yaml.
Utilize o padrão internacional para pontuação dentro de aspas
Faça e não faça - Utilize o padrão internacional para pontuação dentro de aspas
Faça
Não faça
eventos são registrados com um "estágio associado".
eventos são registrados com um "estágio associado."
A cópia é chamada de "fork".
A cópia é chamada de "fork."
Formatação de código embutido
Utilize estilo de código para código embutido, comandos e objetos da API
Para código embutido em um documento HTML, utilize a tag<code>. Em um documento
Markdown, utilize os símbolos de crase (`).
Faça e não faça - Utilize estilo de código para código embutido, comandos e objetos da API
Faça
Não faça
O comando kubectl run cria um Pod.
O comando "kubectl run" cria um pod.
O kubelet em cada nó obtém um Lease ...
O kubelet em cada nó obtem um lease...
Um PersistentVolume representa armazenamento durável ...
Um PersistentVolume representa armazenamento durável ...
Para gerenciamento declarativo, utilize kubectl apply.
Para gerenciamento declarativo, utilize "kubectl apply".
Circunde exemplos de código com três símbolos de crase. (```)
Circunde exemplos de código com quaisquer outras sintaxes.
Utilize um único símbolo de crase para circundar código embutido. Por exemplo, var example = true.
Utilize dois asteriscos (**) ou um subtraço (_) para circundar código embutido. Por exemplo, var example = true.
Utilize três símbolos de crase antes e depois de um bloco de código de múltiplas linhas para blocos de código cercados.
Utilize blocos de código de múltiplas linhas para criar diagramas, fluxogramas, ou outras ilustrações.
Utilize nomes de variáveis significativos que possuem um contexto.
Utilize nomes de variáveis como 'foo', 'bar' e 'baz' que não são significativos e não possuem contexto.
Remova espaços em branco em final de linha no código.
Adicione espaços em branco no código, onde estes são importantes, pois os leitores de tela lerão os espaços em branco também.
Nota:
Este website suporta destaque de sintaxe para exemplos de código, mas a especificação
de uma linguagem é opcional. Destaque de sintaxe nos blocos de código devem estar
de acordo com as orientações de contraste.
Utilize estilo de código para nomes de campos de objetos e namespaces
Faça e não faça - Utilize estilo de código para nomes de campos de objetos
Faça
Não faça
Especifique o valor do campo replicas no arquivo de configuração.
Especifique o valor do campo "replicas" no arquivo de configuração.
O valor do campo exec é um objeto do tipo ExecAction.
O valor do campo "exec" é um objeto do tipo ExecAction.
Execute o processo como um DaemonSet no namespace kube-system.
Execute o processo como um DaemonSet no namespace kube-system.
Utilize estilo de código para ferramentas de linha de comando e nomes de componentes do Kubernetes
Faça e não faça - Utilize estilo de código para ferramentas de linha de comando e componentes do Kubernetes
Faça
Não faça
O kubelet preserva a estabilidade do nó.
O kubelet preserva a estabilidade do nó.
O kubectl gerencia a busca e a autenticação com o servidor da API.
O kubectl gerencia a busca e a autenticação com o servidor da API.
Execute o processo com o certificado, kube-apiserver --client-ca-file=FILENAME.
Execute o processo com o certificado, kube-apiserver --client-ca-file=FILENAME.
Iniciando sentenças com o nome de uma ferramenta de linha de comando ou de um componente
Faça e não faça - Iniciando sentenças com o nome de uma ferramenta de linha de comando ou de um componente
Faça
Não faça
A ferramenta kubeadm inicializa e provisiona máquinas em um cluster.
kubeadm inicializa e provisiona ferramentas em um cluster.
O kube-scheduler é o escalonador padrão para o Kubernetes.
kube-scheduler é o escalonador padrão para o Kubernetes.
Utilize uma descrição geral no lugar de um nome de componente
Faça e não faça - Utilize uma descrição geral no lugar de um nome de componente
Faça
Não faça
O servidor da API do Kubernetes oferece uma especificação OpenAPI.
O apiserver oferece uma especificação OpenAPI.
APIs agregadas são servidores de API subordinados.
APIs agregadas são APIServers subordinados.
Utilize estilo normal para valores de campos do tipo texto ou inteiro
Para valores de campos do tipo texto ou inteiro, utilize o estilo normal sem aspas.
Faça e não faça - Utilize o estilo normal para valores de campo do tipo texto ou inteiro
Faça
Não faça
Especifique o valor Always para o campo imagePullPolicy.
Especifique o valor "Always" para o campo imagePullPolicy.
Especifique o valor nginx:1.16 para o campo image.
Especifique o valor nginx:1.16 para o campo image.
Especifique o valor 2 para o campo replicas.
Especifique o valor 2 para o campo replicas.
Referindo-se a recursos da API do Kubernetes
Esta seção discorre sobre como referenciar recursos da API na documentação.
Clarificação sobre "recurso"
O Kubernetes utiliza a palavra "recurso" para se referir a recursos da API, como
pod, deployment, e demais objetos. Também utilizamos "recurso" para falar de
requisições e limites de recursos de CPU e memória. Sempre se refira a recursos
da API como "recursos da API" para evitar confusão com recursos de CPU e memória.
Quando utilizar a terminologia da API do Kubernetes
As diferentes terminologias da API do Kubernetes são:
Tipo de recurso: o nome utilizado na URL da API (como pods, namespaces)
Recurso: uma instância única de um tipo de recurso (como pod, secret)
Objeto: um recurso que serve como um "registro de intenção". Um objeto é um
estado desejado para uma parte específica do seu cluster, que a camada de
gerenciamento do Kubernetes tenta manter.
Sempre utilize "recurso" ou "objeto" ao se referir a um recurso da API em
documentação. Por exemplo, utilize "um objeto Secret" ao invés de apenas
"um Secret".
Nomes de recursos da API
Sempre formate nomes de recursos da API utilizando
UpperCamelCase, também conhecido
como PascalCase, e formatação de código.
Para código embutido em um documento HTML, utilize a tag <code>. Em um documento
Markdown, utilize o sinal de crase (`).
Não separe um nome de objeto da API em palavras individuais. Por exemplo, escreva
PodTemplateList no lugar de Pod Template List.
Para mais informações sobre as terminologias da API do Kubernetes, por favor
revise a orientação relacionada sobre terminologia da API do Kubernetes.
Formatação de fragmentos de código
Não inclua o prompt de comando
Faça e não faça - Não inclua o prompt de comando
Faça
Não faça
kubectl get pods
$ kubectl get pods
Separe os comandos de seus resultados
Verifique que o Pod está rodando no seu nó escolhido:
kubectl get pods --output=wide
A saída é semelhante a:
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 13s 10.200.0.4 worker0
Exemplos de versionamento do Kubernetes
Exemplos de código e de configuração que incluem informação da versão devem ser
consistentes com o texto que os acompanha.
Se a informação é específica para uma versão, a versão do Kubernetes deve ser
definida na seção prerequisites dos modelos de página de
tarefa ou de
tutorial.
Assim que a página for salva, a seção prerequisitos é exibida com o título
Antes de você começar.
Para especificar uma versão do Kubernetes para uma página de tarefa ou de
tutorial, inclua a chave min-kubernetes-server-version na seção de
front matter.
Se o exemplo de YAML for um arquivo avulso, procure e revise os tópicos que
o incluem como uma referência. Verifique que quaisquer tópicos que estejam
utilizando o YAML avulso têm a informação de versão apropriada definida. Se um
arquivo avulso YAML não for referenciado em nenhum tópico, considere apagá-lo
ao invés de atualizá-lo.
Por exemplo, se você estiver escrevendo um tutorial que é relevante para a
versão 1.8 do Kubernetes, o front matter do seu arquivo Markdown deve ser
semelhante ao demonstrado abaixo:
---title:<seu título de tutorial aqui>min-kubernetes-server-version:v1.8---
Nos exemplos de código e configuração, não inclua comentários sobre versões
alternativas. Tenha o cuidado de não incluir afirmações incorretas em comentários
nos seus exemplos, como por exemplo:
apiVersion:v1# versões mais antigas usam...kind:Pod...
Kubernetes.io word list
Uma lista de termos específicos do Kubernetes para serem utilizados de forma
consistente em todo o website.
Lista de palavras do Kubernetes.io
Term
Usage
Kubernetes
Kubernetes deve sempre ser escrito com K maiúsculo.
Docker
Docker deve sempre ser escrito com D maiúsculo.
SIG Docs
Escreva SIG Docs ao invés de SIG-DOCS ou outras variantes.
On-premises
Escreva On-premises ou On-prem ao invés de On-premise ou outras variantes.
Shortcodes
Os shortcodes do Hugo
auxiliam na criação de diferentes níveis de atrativos retóricos. Nossa
documentação suporta três diferentes shortcodes nessa categoria: Nota{{< note >}}, Cuidado{{< caution >}}, e Aviso{{< warning >}}.
Circunde o texto com uma abertura e um fechamento de shortcode.
Utilize a sintaxe abaixo para aplicar um estilo:
{{< note >}}
Não há necessidade de incluir um prefixo; o _shortcode_ fornece um automaticamente (Nota:, Cuidado:, etc.).
{{< /note >}}
A saída é semelhante a:
Nota:
O prefixo é gerado automaticamente com a seleção do tipo da tag.
Nota
Utilize {{< note >}} para destacar uma dica ou uma informação que pode ser
útil para o leitor.
Por exemplo:
{{< note >}}
Você _ainda_ pode utilizar Markdown dentro destas seções de destaque.
{{< /note >}}
The output is:
Nota:
Você ainda pode utilizar Markdown dentro destas seções de destaque.
Você pode utilizar o shortcode{{< note >}} em uma lista:
1. Utilize o _shortcode_ `note` em uma lista
1. Um segundo item em uma lista com um shortcode note embutido
{{< note >}}
_Shortcodes_ Aviso, Cuidado e Nota, embutidos em listas, devem ser indentados
com quatro espaços. Veja mais em [Problemas comuns com _shortcodes_](#common-shortcode-issues).
{{< /note >}}
1. Um terceiro item em uma lista
1. Um quarto item em uma lista
A saída é:
Utilize o shortcodenote em uma lista
Um segundo item em uma lista com um shortcode note embutido
Nota:
_Shortcodes_ Aviso, Cuidado e Nota, quando embutidos em listas, devem ser
indentados com quatro espaços. Veja mais em
[Problemas comuns com _shortcodes_](#common-shortcode-issues).
Um terceiro item em uma lista
Um quarto item em uma lista
Cuidado
Utilize {{< caution >}} para chamar a atenção a informações importantes
que podem evitar problemas.
Por exemplo:
{{< caution >}}
O estilo de chamada se aplica somente à linha diretamente acima da tag.
{{< /caution >}}
A saída é:
Cuidado:
O estilo de chamada se aplica somente à linha diretamente acima da tag.
Aviso
Utilize {{< warning >}} para indicar perigo ou uma orientação que é crucial
e deve ser seguida.
Por exemplo:
{{< warning >}}
Cuidado.
{{< /warning >}}
A saída é:
Aviso:
Cuidado.
Problemas comuns com shortcodes
Listas ordenadas
Shortcodes interrompem listas numeradas a não ser que estejam indentados com
quatro espaços antes da nota e da tag.
Por exemplo:
1. Preaqueça o forno a 350°F.
1. Prepare a massa e a coloque na assadeira.
`{{< note >}}Unte a assadeira para melhores resultados.{{< /note >}}`
1. Asse por 20-25 minutos, ou até que ao testar com um palito este saia limpo.
A saída é:
Preaqueça o forno a 350°F.
Prepare a massa e a coloque na assadeira.
Nota:
Unte a assadeira para melhores resultados.
Asse por 20-25 minutos, ou até que ao testar com um palito este saia limpo.
Cláusulas include
Shortcodes dentro de cláusulas include fazem com que o build falhe. Você
deve colocá-los no documento superior, antes e depois da cláusula include.
Por exemplo:
{{< note >}}
{{< include "task-tutorial-prereqs.md" >}}
{{< /note >}}
Elementos Markdown
Quebras de linha
Utilize uma única linha em branco para dividir conteúdo a nível de bloco como por
exemplo cabeçalhos, listas, imagens, blocos de código, entre outros. A exceção
são cabeçalhos de segundo nível, onde duas linhas em branco devem ser utilizadas.
Cabeçalhos de segundo nível seguem o primeiro nível (ou o título) sem nenhum
texto ou parágrafo precedente. Um espaçamento de duas linhas em branco auxilia
a melhor visualização geral da estrutura do conteúdo em um editor de texto.
Cabeçalhos e títulos
Pessoas que acessam esta documentação podem estar fazendo uso de um leitor de
tela ou outro tipo de tecnologia auxiliar.
Leitores de tela são dispositivos
de saída linear que falam de um item por vez em uma página. Se uma grande
quantidade de conteúdo existe em uma página, você pode utilizar cabeçalhos para
dar à página uma estrutura interna. Uma boa estrutura de página auxilia todos os
leitores a navegar facilmente ou filtrar tópicos de interesse.
Faça e não faça - Cabeçalhos
Faça
Não faça
Atualize o título no front matter da página ou postagem de blog.
Utilize cabeçalho de primeiro nível, pois o Hugo automaticamente converte o título do front matter para um cabeçalho de primeiro nível.
Utilize cabeçalhos ordenados para fornecer um resumo de alto nível do seu conteúdo.
Utilize cabeçalhos de nível 4 a 6, a menos que seja absolutamente necessário. Se o seu conteúdo é detalhado a este nível, pode ser que ele precise ser dividido em artigos separados.
Utilize o sinal numérico ou cerquilha (#) para conteúdo que não seja postagem de blog.
Utilize traços ou sinais de igual (--- ou ===) para designar cabeçalhos de primeiro nível.
Utilize formatação de maiúsculas e minúsculas de sentença para cabeçalhos no corpo da página. Por exemplo, Estenda o kubectl com plugins
Utilize formatação de maiúsculas e minúsculas de título para cabeçalhos no corpo da página. Por exemplo, Estenda o Kubectl com Plugins
Utilize formatação de maiúsculas e minúsculas de título para o título da página no front matter. Por exemplo, title: Riscos do Contorno do Servidor da API do Kubernetes
Utilize formatação de maiúsculas e minúsculas de sentença para títulos de página no front matter. Por exemplo, não utilize title: Riscos do contorno do servidor da API do Kubernetes
Parágrafos
Faça e não faça - Parágrafos
Faça
Não faça
Tente manter os parágrafos abaixo de 6 sentenças.
Indente o primeiro parágrafo com caracteres de espaço. Por exemplo, ⋅⋅⋅Três espaços antes de um parágrafo o indenta.
Utilize três hífens (---) para criar uma régua horizontal. Utilize réguas horizontais para quebras no conteúdo do parágrafo. Por exemplo, uma mudança de cena em uma história, ou uma mudança de tópico dentro de uma seção.
Utilize réguas horizontais para decoração.
Links
Faça e não faça - Links
Faça
Não faça
Crie hiperlinks que forneçam o contexto para o conteúdo para o qual eles apontam. Por exemplo: certas portas estão abertas em suas máquinas. Veja Verifique portas necessárias para mais detalhes.
Utilize termos ambíguos, como "clique aqui". Por exemplo: certas portas estão abertas em suas máquinas. Veja aqui para mais detalhes.
Crie hiperlinks no estilo de Markdown: [texto do link](URL). Por exemplo: [_Shortcodes_ do Hugo](/docs/contribute/style/hugo-shortcodes/#table-captions), cuja saída é Shortcodes do Hugo.
Crie links no estilo de HTML: <a href="/media/examples/link-element-example.css" target="_blank">Visite nosso tutorial!</a>, ou crie links que abrem em novas abas ou janelas. Por exemplo: [website de exemplo](https://example.com){target="_blank"}
Listas
Agrupe em listas itens relacionados que devem aparecer em uma ordem específica,
ou para indicar uma correlação entre vários itens. Quando um leitor de tela
encontra uma lista, independentemente de ser uma lista ordenada ou não-ordenada,
o leitor de tela anunciará ao usuário que há um grupo de itens em lista. O
usuário pode então utilizar as teclas de seta para navegar para cima e para baixo
entre os vários itens da lista. Links para navegação no website também podem ser
marcados como itens de lista, pois nada mais são do que um grupo de links
relacionados.
Finalize cada item em uma lista com um ponto final se um ou mais itens na lista
forem sentenças completas. Para consistência, normalmente todos os itens da
lista devem ser sentenças completas, ou nenhum dos itens deve ser.
Nota:
Listas ordenadas que são parte de uma sentença introdutória incompleta podem
ser mantidos em letras minúsculas e pontuados como se cada item fosse uma
parte da sentença introdutória.
Utilize o número um (1.) para listas ordenadas.
Utilize (+), (*) ou (-) para listas não-ordenadas.
Deixe uma linha em branco após cada lista.
Indente listas aninhadas com quatro espaços (por exemplo, ⋅⋅⋅⋅).
Itens de lista podem consistir de múltiplos parágrafos. Cada parágrafo
subsequente em uma lista deve estar indentado em quatro espaços ou um caractere
de tabulação.
Tabelas
O propósito semântico de uma tabela de dados é apresentar dados tabulados.
Usuários que não fazem uso de leitores de tela podem inspecionar a tabela de forma
visual rapidamente, mas um leitor de tela irá ler o conteúdo linha a linha.
Uma legenda de tabela é utilizada para criar um título descritivo para uma tabela
de dados. Tecnologias auxiliares utilizam o elemento HTML caption para
identificar o conteúdo da tabela para o usuário dentro da estrutura da página.
Adicione legendas às suas tabelas utilizando os shortcodes do Hugo para tabelas.
Melhores práticas de conteúdo
Esta seção contém melhores práticas sugeridas para conteúdo claro, conciso e
consistente.
Utilize o tempo presente
Faça e não faça - Utilize o tempo presente
Faça
Não faça
Este comando inicializa um proxy.
Este comando irá iniciar um proxy.
Exceção: utilize o tempo futuro ou pretérito quando necessário para comunicar o
significado correto.
Utilize voz ativa
Faça e não faça - Utilize voz ativa
Faça
Não faça
Você pode explorar a API utilizando um navegador.
A API pode ser explorada utilizando um navegador.
O arquivo YAML especifica o número de réplicas.
O número de réplicas é especificado no arquivo YAML.
Exceção: utilize a voz passiva se a voz ativa resultar em uma construção estranha.
Utilize linguagem simples e direta
Utilize linguagem simples e direta. Evite utilizar frases ou expressões
desnecessárias, como "por favor".
Faça e não faça - Utilize linguagem simples e direta
Faça
Não faça
Para criar um ReplicaSet, ...
A fim de criar um ReplicaSet, ...
Veja o arquivo de configuração.
Por favor, veja o arquivo de configuração.
Veja os Pods.
Com este próximo comando veremos os Pods.
Dirija-se ao leitor utilizando "você"
Faça e não faça - Dirigindo-se ao leitor
Faça
Não faça
Você pode criar um Deployment através ...
Criaremos um Deployment através ...
Na saída acima, você pode ver ...
Na saída acima, vimos que ...
Evite frases em Latim
Prefira termos em inglês no lugar de abreviações em Latim.
Faça e não faça - Evite frases em Latim
Faça
Não faça
For example, ...
e.g., ...
That is, ...
i.e., ...
Exceção: utilize "etc." para et cetera.
Padrões a evitar
Evite utilizar "nós"
O uso de "nós" em uma sentença pode ser confuso, pois o leitor pode não saber
se é parte do "nós" que você está descrevendo.
Faça e não faça - Padrões a evitar
Faça
Não faça
A versão 1.4 inclui ...
Na versão 1.4, adicionamos ...
O Kubernetes fornece uma nova funcionalidade para ...
Nós fornecemos uma nova funcionalidade para ...
Esta página ensina sobre como você pode utilizar Pods.
Nesta página, iremos aprender sobre Pods.
Evite jargões e expressões idiomáticas
Alguns leitores falam inglês como segunda língua. Evite jargões e expressões
idiomáticas para auxiliar na compreensão.
Faça e não faça - Evite jargões e expressões idiomáticas
Faça
Não faça
Internally, ...
Under the hood, ...
Create a new cluster.
Turn up a new cluster.
Evite afirmações sobre o futuro
Evite fazer promessas ou dar dicas sobre o futuro. Se você precisa falar sobre
uma funcionalidade em estado alfa, coloque o texto sob um cabeçalho que
classifique a informação em estado alfa.
Uma exceção a esta regra é a documentação sobre descontinuações que serão
convertidas em remoções em uma versão futura. Um exemplo deste tipo de documentação
é o Guia de migração de APIs descontinuadas.
Evite afirmações que ficarão desatualizadas em breve
Evite palavras como "atualmente" e "novo". Uma funcionalidade que é nova hoje
pode não ser mais considerada nova em alguns meses.
Faça e não faça - Evite afirmações que ficarão desatualizadas em breve
Faça
Não faça
Na versão 1.4, ...
Na versão atual, ...
A funcionalidade de Federação fornece ...
A nova funcionalidade de Federação fornece ...
Evite palavras que assumem um nível específico de conhecimento
Evite palavras como "apenas", "simplesmente", "fácil", "facilmente" ou "simples".
Estas palavras não agregam valor.
Essa página contém informações sobre a dashboard de analystics do kubernetes.io.
Essa dashboard foi feita usando
o Google Data Studio e possui informações coletadas do
kubernetes.io usando o Google Analytics.
Usando a dashboard
Por padrão, a dashboard mostra todos os analytics coletados nos últimos 30 dias. Use o seletor de data
para ver dados de outros intervalos de data. Outras
opções de filtros permitem que você veja dados baseados
em localização do usuário para acessar o site, a tradução
da documentação usada e outros.
Se você identificar um problema com essa dashboard ou quer solicitar qualquer melhoria, abra uma issue no repositório.
7.4 - Contribuir com a documentação do Kubernetes em Português Brasileiro
Olá!
Esta página contém informações sobre o processo de localização em português (Brasil), desde o processo de contribuição até um dicionário de temos com as respectivas traduções.
Passo a passo para contribuição
Escolha uma página que deseja localizar.
Verifique se já existe uma issue no repositório (kubernetes/website) aberta para a página que escolheu.
Crie uma branch no seu fork e faça a localização da página.
Execute o check de links quebrados (os detalhes de como executar estão nessa página).
Abra o Pull Request. Caso ainda não tenha assinado o CLA, haverá instruções no Pull Request.
Verifique se as checagens no Pull Requests não estão quebradas e se foi gerado um preview da sua localização.
Por fim, recomendamos que envie o pull request no canal do slack do time #kubernetes-docs-pt.
Checagem de links quebrados
Para garantir que os links referenciados na página que localizou não estão quebrados, você pode executar um script de checagem de links quebrados.
Dentro do seu fork local do repositório, executar:
content/pt-br/<caminho-da-pagina> é o caminho da página que está localizando
Dicionário de termos com tradução
Inglês
Português
Comentários
addon
complemento
API call
chamada para a API
API server
servidor de API
backward compatibility
retrocompatibilidade
builtin
embutido
container image
imagem do contêiner
dashboard
painel
data plane
camada de dados
control plane
camada de gerenciamento
workload
carga de trabalho
workflow
fluxo de execução
Dicionário de termos não traduzidos
Inglês
Comentários
addon manager
auto-scaling
bind
cloud native
controller manager
deploy
service mesh
release
proxy
endpoint
Nomes de objetos do Kubernetes permanecem no original com a primeira letra em maiúsculo, por exemplo:
Pod
Service
Deployment
entre outros.
Perguntas frequentes
Qual título devo usar quando abrir o Pull Request?
Recomendamos usar o formato [pt-br] Update/Add <caminho do arquivo>.
Posso abrir um Pull Request traduzindo mais de uma página de documentação?
Sempre dê preferência por abrir um Pull Request por página, dessa forma facilita a revisão e o acompanhamento do trabalho.
Tenho dúvidas nos termos, preciso abrir o Pull Request e esperar alguém revisar?
Não, pode mandar a dúvida no canal do slack (#kubernetes-docs-pt) que vamos ajudar com a dúvida.
Abri um Pull Request mas ainda não teve revisão, o que fazer?
É importante lembrar que as pessoas revisoras são voluntárias, então em alguns casos pode demorar um pouco. O que recomendamos nesses casos é enviar uma mensagem no canal do slack com o link do Pull Request, assim podemos verificar o que pode ter acontecido.
Ficou alguma dúvida que não foi respondida nessa página?
Fale com a gente canal no slack do Kubernetes #kubernetes-docs-pt.
8 -
Clique nas tags ou use as listas suspensas para filtrar. Clique nos cabeçalhos das tabelas para classificar ou inverter a classificação.
Filtrar por Conceito:
Filtrar por objeto:
Filtrar por Comando: