Como visualizar os taints aplicados a um nó Kubernetes

KubernetesBeginner
Pratique Agora

Introdução

O Kubernetes, a popular plataforma de orquestração de contêineres, oferece um recurso poderoso chamado "taints" (contaminações) para controlar o agendamento de pods em nós. Neste tutorial, exploraremos como visualizar os taints aplicados aos nós do Kubernetes, uma habilidade essencial para gerenciar efetivamente seu cluster Kubernetes.

Os taints permitem que você marque nós com atributos específicos que podem repelir certos pods, garantindo que as cargas de trabalho sejam agendadas apropriadamente com base nas capacidades e recursos do nó. Compreender como visualizar e trabalhar com taints ajuda você a manter a alocação ideal de recursos em seu ambiente Kubernetes.

Configurando um Ambiente Kubernetes para Testes

Antes de podermos visualizar os taints nos nós do Kubernetes, precisamos de um ambiente Kubernetes funcional. Para este tutorial, usaremos o Minikube, que fornece um cluster Kubernetes local e leve para fins de desenvolvimento e teste.

Vamos começar instalando o Minikube:

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
rm minikube-linux-amd64

Agora que o Minikube está instalado, vamos iniciar um cluster Kubernetes:

minikube start --driver=docker

Você deve ver uma saída semelhante a esta:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Using the docker driver based on user configuration
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
🔥  Creating docker container (CPUs=2, Memory=2200MB) ...
🐳  Preparing Kubernetes v1.26.1 on Docker 23.0.1 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Vamos verificar se o cluster está em execução verificando o status do nó:

kubectl get nodes

Você deve ver uma saída semelhante a esta:

NAME       STATUS   ROLES           AGE    VERSION
minikube   Ready    control-plane   1m     v1.26.1

Ótimo! Agora temos um ambiente Kubernetes funcional para explorar os taints. O comando kubectl já está configurado para funcionar com nosso cluster Minikube.

Entendendo os Taints do Kubernetes

Antes de começarmos a visualizar os taints, vamos entender o que eles são e como funcionam no Kubernetes.

O que são Taints?

Taints são propriedades aplicadas aos nós do Kubernetes que permitem que um nó repila certos pods. Pense nos taints como rótulos que marcam os nós como inadequados para tipos específicos de cargas de trabalho.

Os taints trabalham em conjunto com um conceito chamado "tolerations" (tolerâncias). Enquanto os taints são aplicados aos nós, as tolerâncias são aplicadas aos pods. Um pod com uma tolerância correspondente ao taint de um nó pode ser agendado nesse nó contaminado.

Estrutura do Taint

Os taints consistem em três componentes:

  1. Key (Chave): Uma string que identifica o taint (por exemplo, gpu, disk, network)
  2. Value (Valor): Uma string opcional atribuída à chave (por exemplo, true, high-performance)
  3. Effect (Efeito): Define como os pods sem tolerâncias correspondentes são tratados

Os efeitos de taint mais comuns são:

  • NoSchedule: Novos pods sem tolerâncias correspondentes não serão agendados no nó
  • PreferNoSchedule: O sistema tentará evitar colocar pods sem tolerâncias correspondentes no nó, mas não é garantido
  • NoExecute: Novos pods sem tolerâncias correspondentes não serão agendados no nó, e os pods existentes sem tolerâncias correspondentes serão removidos

Aqui está a sintaxe de um taint:

  • Com um valor: key=value:effect
  • Sem um valor: key:effect

Alguns nós em um cluster Kubernetes têm taints padrão. Por exemplo, os nós do plano de controle (control plane) são frequentemente contaminados com node-role.kubernetes.io/control-plane:NoSchedule para impedir que cargas de trabalho regulares sejam agendadas neles, preservando recursos para componentes do sistema.

Vamos examinar nosso nó Minikube para ver se ele possui algum taint padrão:

kubectl describe node minikube | grep -A3 Taints

Você provavelmente verá uma saída semelhante a:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  minikube

Esta saída mostra que nosso nó Minikube tem um taint que impede que pods regulares sejam agendados nele, pois é um nó do plano de controle.

Visualizando Taints nos Nós do Kubernetes

Agora que entendemos o que são os taints, vamos explorar os diferentes métodos para visualizar os taints aplicados aos nós do Kubernetes.

Método 1: Usando kubectl describe

A maneira mais detalhada de visualizar os taints em um nó é usando o comando kubectl describe node:

kubectl describe node minikube

Este comando gera informações abrangentes sobre o nó. Para focar apenas nos taints, você pode usar grep:

kubectl describe node minikube | grep -A1 Taints

Exemplo de saída:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false

Método 2: Usando kubectl get com colunas personalizadas

Você pode usar o comando kubectl get nodes com colunas de saída personalizadas para exibir apenas os taints:

kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints

Exemplo de saída:

NAME       TAINTS
minikube   [map[effect:NoSchedule key:node-role.kubernetes.io/control-plane]]

Método 3: Usando kubectl get com JSONPath

Outra abordagem é usar JSONPath para extrair informações de taint:

kubectl get nodes minikube -o jsonpath='{.spec.taints}'

Exemplo de saída:

[{"effect":"NoSchedule","key":"node-role.kubernetes.io/control-plane"}]

Para melhor legibilidade, você pode formatar a saída como JSON:

kubectl get nodes minikube -o jsonpath='{.spec.taints}' | jq .

Se você não tiver jq instalado, pode instalá-lo com:

sudo apt-get update && sudo apt-get install -y jq

Exemplo de saída formatada:

[
  {
    "effect": "NoSchedule",
    "key": "node-role.kubernetes.io/control-plane"
  }
]

Método 4: Usando kubectl get com saída YAML

Você também pode visualizar a especificação completa do nó em formato YAML e pesquisar por taints:

kubectl get node minikube -o yaml | grep -A5 taints:

Exemplo de saída:

  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/control-plane
  unschedulable: false
status:
  addresses:

Cada um desses métodos fornece as mesmas informações em formatos diferentes. Escolha aquele que melhor se adapta às suas necessidades com base na legibilidade e em como você planeja usar as informações.

Adicionando e Removendo Taints

Agora que sabemos como visualizar os taints, vamos aprender como adicioná-los e removê-los. Esta é uma operação comum quando você precisa controlar o agendamento de pods ou preparar nós para manutenção.

Adicionando Taints aos Nós

A sintaxe para adicionar um taint a um nó é:

kubectl taint nodes <nome-do-nó> <chave>=<valor>:<efeito>

Vamos adicionar um taint ao nosso nó Minikube para marcá-lo como tendo uma GPU:

kubectl taint nodes minikube gpu=true:NoSchedule

Você deve ver uma saída como:

node/minikube tainted

Agora, vamos verificar se o taint foi adicionado:

kubectl describe node minikube | grep -A3 Taints

Exemplo de saída:

Taints:             gpu=true:NoSchedule
                    node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:

Como você pode ver, nosso nó agora tem dois taints: o taint original do plano de controle e nosso novo taint de GPU.

Removendo Taints dos Nós

Para remover um taint, você adiciona um sinal de menos (-) à mesma definição de taint:

kubectl taint nodes <nome-do-nó> <chave>=<valor>:<efeito>-

Vamos remover o taint de GPU que acabamos de adicionar:

kubectl taint nodes minikube gpu=true:NoSchedule-

Você deve ver uma saída como:

node/minikube untainted

Vamos verificar se o taint foi removido:

kubectl describe node minikube | grep -A3 Taints

Exemplo de saída:

Taints:             node-role.kubernetes.io/control-plane:NoSchedule
Unschedulable:      false
Lease:
  HolderIdentity:  minikube

Agora, nosso nó voltou a ter apenas o taint do plano de controle.

Quando Usar Taints

Os taints são particularmente úteis em vários cenários:

  1. Hardware especializado: Contaminar nós com hardware especial (como GPUs) para garantir que apenas cargas de trabalho que exigem esse hardware sejam agendadas lá
  2. Manutenção do nó: Adicionar um taint antes de realizar a manutenção para impedir que novos pods sejam agendados
  3. Isolamento de segurança: Manter certas cargas de trabalho separadas de outras por motivos de segurança
  4. Otimização de recursos: Dedicar nós a tipos específicos de carga de trabalho para utilização ideal de recursos

Ao entender como visualizar, adicionar e remover taints, você adquiriu conhecimento fundamental para gerenciar o agendamento de pods em seu cluster Kubernetes.

Trabalhando com Tolerâncias

Agora que entendemos como os taints funcionam, vamos explorar as tolerâncias - o mecanismo que permite que os pods sejam agendados em nós com taints correspondentes.

Entendendo as Tolerâncias

As tolerâncias são especificadas nas especificações do pod e permitem que os pods sejam agendados em nós com taints correspondentes. Uma tolerância consiste em:

  • key: Corresponde à chave do taint
  • operator: Equal (corresponde à chave e ao valor) ou Exists (corresponde apenas à chave)
  • value: O valor a ser correspondido (ao usar o operador Equal)
  • effect: O efeito a ser correspondido, ou vazio para corresponder a todos os efeitos
  • tolerationSeconds: Duração opcional durante a qual o pod pode permanecer em um nó com um taint NoExecute correspondente

Criando um Pod com Tolerâncias

Vamos criar um pod que tolera nosso taint do plano de controle. Primeiro, vamos criar um arquivo YAML para nosso pod:

nano ~/project/toleration-pod.yaml

Agora, adicione o seguinte conteúdo ao arquivo:

apiVersion: v1
kind: Pod
metadata:
  name: toleration-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest
  tolerations:
    - key: "node-role.kubernetes.io/control-plane"
      operator: "Exists"
      effect: "NoSchedule"

Esta especificação de pod inclui uma tolerância que corresponde ao taint do plano de controle em nosso nó. Salve e saia do arquivo (no nano, pressione Ctrl+O, Enter e depois Ctrl+X).

Agora, vamos criar o pod:

kubectl apply -f ~/project/toleration-pod.yaml

Você deve ver uma saída como:

pod/toleration-pod created

Vamos verificar se o pod foi agendado em nosso nó:

kubectl get pods -o wide

Exemplo de saída:

NAME             READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
toleration-pod   1/1     Running   0          12s   10.244.0.5   minikube   <none>           <none>

O pod está em execução em nosso nó minikube porque ele tem uma tolerância correspondente ao taint do plano de controle.

Testando com um Pod sem Tolerâncias

Para comparação, vamos criar um pod sem tolerâncias:

nano ~/project/no-toleration-pod.yaml

Adicione o seguinte conteúdo:

apiVersion: v1
kind: Pod
metadata:
  name: no-toleration-pod
spec:
  containers:
    - name: nginx
      image: nginx:latest

Salve e saia do arquivo e, em seguida, crie o pod:

kubectl apply -f ~/project/no-toleration-pod.yaml

Agora, vamos verificar o status do pod:

kubectl get pods -o wide

Você pode notar que o pod permanece em um estado Pendente:

NAME               READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
no-toleration-pod  0/1     Pending   0          12s   <none>       <none>     <none>           <none>
toleration-pod     1/1     Running   0          2m    10.244.0.5   minikube   <none>           <none>

Vamos verificar por que o pod está pendente:

kubectl describe pod no-toleration-pod

Na seção de eventos, você deve ver algo como:

Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  45s   default-scheduler  0/1 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.

Isso confirma que o pod não pôde ser agendado porque não tolera o taint do plano de controle.

Limpeza

Vamos limpar os pods que criamos:

kubectl delete pod toleration-pod no-toleration-pod

Você deve ver:

pod "toleration-pod" deleted
pod "no-toleration-pod" deleted

Parabéns! Agora você entende como os taints e as tolerâncias trabalham juntos para controlar o agendamento de pods no Kubernetes.

Resumo

Neste laboratório prático, você aprendeu a trabalhar com taints e tolerâncias do Kubernetes, recursos-chave para controlar o agendamento de pods em seu cluster. Veja o que você realizou:

  1. Configurou um ambiente Kubernetes usando o Minikube
  2. Entendeu o conceito de taints e seus efeitos no agendamento de pods
  3. Explorou diferentes métodos para visualizar taints em nós Kubernetes
  4. Adicionou e removeu taints de nós usando comandos kubectl
  5. Criou pods com e sem tolerâncias para ver como eles interagem com nós com taints

Essas habilidades são essenciais para gerenciar a alocação de carga de trabalho e a alocação de recursos em clusters Kubernetes. Ao usar corretamente taints e tolerâncias, você pode garantir que os pods sejam agendados em nós apropriados com base nos requisitos de hardware, características da carga de trabalho e restrições de recursos.

À medida que você continua sua jornada no Kubernetes, pode construir sobre esse conhecimento para implementar estratégias de agendamento mais sofisticadas, como afinidade e anti-afinidade de nós, para otimizar ainda mais os recursos do seu cluster.