Implantar serviços de nó com DaemonSets do Kubernetes

KubernetesBeginner
Pratique Agora

Introdução

Alguns softwares precisam ser executados uma vez em cada nó elegível, em vez de usar uma quantidade fixa de réplicas. Coletores de logs, agentes de monitoramento e componentes de rede costumam usar DaemonSets para esse tipo de posicionamento orientado a nós.

Você adicionará um rótulo ao nó preparado, implantará um agente de relatório do nó, rastreará sua propriedade, alterará a elegibilidade do nó e executará uma atualização contínua. O laboratório com um único nó facilita a observação da regra de posicionamento, preservando o mesmo comportamento do controlador usado em clusters maiores.

A pergunta principal ao longo deste laboratório não é “quantas réplicas devem ser executadas?”, mas sim “quais nós são elegíveis?”. Um DaemonSet responde continuamente a essa pergunta e cria um Pod em cada nó correspondente. Neste ambiente há apenas um nó, portanto cada alteração de elegibilidade produz um resultado claro: de um para zero ou de zero para um.

Marcar um nó elegível

Nesta etapa, você adicionará ao nó um rótulo específico para essa finalidade. Os rótulos descrevem atributos dos nós que os controladores podem selecionar.

Comece exibindo o nó e os rótulos existentes. A saída é extensa, portanto não tente memorizá-la; basta reconhecer que os rótulos são informações no formato chave-valor associadas ao objeto Node.

cd /home/labex/project/daemonset-workloads
kubectl get nodes --show-labels

Adicione o novo rótulo. A opção --overwrite não é necessária aqui, pois a configuração inicial removeu qualquer valor antigo, mas kubectl label informará se já existir um valor conflitante:

kubectl label node labex-v135 practice-tier=operations
kubectl get node labex-v135 -L practice-tier

-L practice-tier adiciona esse rótulo como uma coluna da tabela. Agora o nó se identifica como elegível para o agente de operações usado no exercício.

O segundo comando fornece um resultado mais direcionado, em vez da linha muito extensa exibida por --show-labels:

NAME         STATUS   ROLES           VERSION   PRACTICE-TIER
labex-v135   Ready    control-plane   v1.35.5   operations

PRACTICE-TIER=operations é a evidência necessária. O rótulo não executa nada por si só; ele ganha significado quando uma carga de trabalho o seleciona na próxima etapa.

Implantar um DaemonSet

Nesta etapa, você criará um DaemonSet que seleciona nós que possuem o novo rótulo.

Antes de digitá-lo, leia o manifesto como três decisões relacionadas. Tanto o seletor quanto o rótulo do Pod usam app: node-reporter, permitindo que o controlador reconheça seus Pods. Em seguida, nodeSelector restringe a elegibilidade aos nós rotulados com practice-tier=operations. Por fim, a API Downward copia o valor de spec.nodeName do Pod selecionado para o contêiner como NODE_NAME.

O loop mantém o agente de demonstração em execução. Um DaemonSet real poderia executar um coletor de logs ou um agente de monitoramento.

cat <<'EOF' > node-reporter.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-reporter
  namespace: practice-daemon
spec:
  selector:
    matchLabels:
      app: node-reporter
  template:
    metadata:
      labels:
        app: node-reporter
    spec:
      nodeSelector:
        practice-tier: operations
      containers:
        - name: reporter
          image: busybox:1.36
          imagePullPolicy: IfNotPresent
          command: ["sh", "-c", "while true; do echo node=${NODE_NAME} version=v1; sleep 15; done"]
          env:
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
EOF

Crie o namespace, aplique o arquivo e aguarde a conclusão da implantação do DaemonSet:

kubectl create namespace practice-daemon
kubectl apply -f node-reporter.yaml
kubectl rollout status daemonset/node-reporter -n practice-daemon --timeout=60s
kubectl get daemonset,pods -n practice-daemon -o wide

A API Downward, por meio de fieldRef, expõe o nome do nó agendado sem precisar defini-lo manualmente. Neste cluster de um único nó, as contagens desejada, atual e pronta devem ser todas iguais a um.

O nome do Pod contém um sufixo gerado, mas a coluna NODE deve mostrar labex-v135. Essa é uma evidência direta de que a regra de elegibilidade e o resultado do agendamento estão alinhados.

No cluster de teste com um único nó, as colunas importantes apareceram assim:

NAME            DESIRED   CURRENT   READY   NODE SELECTOR
node-reporter   1         1         1       practice-tier=operations

NAME                  READY   STATUS    NODE
node-reporter-...      1/1     Running   labex-v135

Leia a primeira linha da esquerda para a direita: um nó corresponde ao seletor, um Pod existe e esse Pod está pronto. Em um cluster maior, essas contagens aumentariam de acordo com o número de nós elegíveis.

Observar a elegibilidade e a propriedade

Nesta etapa, você comprovará que a elegibilidade dos nós, e não um campo de réplicas, controla a quantidade de Pods do DaemonSet.

Primeiro, registre uma linha de base saudável. As colunas personalizadas relacionam o Pod gerado ao DaemonSet, e os logs comprovam que a API Downward forneceu o nome do nó:

kubectl get pods -n practice-daemon -l app=node-reporter -o custom-columns='POD:.metadata.name,NODE:.spec.nodeName,OWNER:.metadata.ownerReferences[0].kind,READY:.status.containerStatuses[0].ready'
kubectl logs -n practice-daemon -l app=node-reporter --tail=3

A tabela de propriedade e o log devem ser semelhantes a:

POD                   NODE         OWNER       READY
node-reporter-...     labex-v135   DaemonSet   true
node=labex-v135 version=v1

O campo OWNER comprova que este é um Pod gerenciado por um controlador. O log comprova que NODE_NAME veio do spec.nodeName real do Pod, e não de um valor definido manualmente.

Remova temporariamente o rótulo e observe o Pod desaparecer:

kubectl label node labex-v135 practice-tier-
kubectl get daemonset node-reporter -n practice-daemon
kubectl wait --for=delete pod -n practice-daemon -l app=node-reporter --timeout=60s

Um - no final remove uma chave de rótulo. Restaure a elegibilidade e aguarde o controlador criar um Pod substituto:

Após a remoção, o DaemonSet exibirá brevemente a seguinte relação estável:

NAME            DESIRED   CURRENT   READY
node-reporter   0         0         0

Essa é uma resposta normal à alteração da elegibilidade, não uma falha. Como nenhum nó corresponde atualmente ao nodeSelector do DaemonSet, a quantidade desejada correta é zero.

kubectl label node labex-v135 practice-tier=operations
kubectl rollout status daemonset/node-reporter -n practice-daemon --timeout=60s

Compare o nome do Pod antes e depois da alteração do rótulo. O substituto possui uma nova identidade de Pod, enquanto o nome do DaemonSet e o comportamento desejado permanecem os mesmos. Isso é a reconciliação em ação.

Executar uma atualização do DaemonSet

Nesta etapa, você atualizará o manifesto salvo e observará o DaemonSet substituir o agente do nó. Manter o arquivo e o objeto em execução alinhados torna o estado desejado reproduzível.

Primeiro, crie uma cópia de trabalho com cp. Em seguida, use o mesmo padrão objetivo de edição de texto apresentado em Kubernetes para iniciantes: sed -i 's/old/new/' file substitui diretamente no arquivo o texto correspondente, enquanto grep -n exibe a linha correspondente com seu número para que você possa conferir o resultado antes de aplicá-lo.

cp node-reporter.yaml node-reporter-v2.yaml
sed -i 's/version=v1/version=v2/' node-reporter-v2.yaml
grep -n 'version=' node-reporter-v2.yaml
kubectl apply -f node-reporter-v2.yaml
kubectl rollout status daemonset/node-reporter -n practice-daemon --timeout=60s
kubectl rollout history daemonset/node-reporter -n practice-daemon
kubectl logs -n practice-daemon -l app=node-reporter --tail=3

O arquivo copiado preserva o exemplo original com v1 para comparação. A única substituição altera o texto da versão dentro do comando do contêiner; ao aplicar o arquivo atualizado, o template do Pod é modificado, o que cria uma nova revisão do controlador e um Pod substituto. Agora os logs devem conter version=v2.

rollout history confirma que o Kubernetes registrou uma nova revisão. Portanto, os DaemonSets oferecem suporte a atualizações controladas de templates, de modo semelhante aos Deployments, mas a substituição é organizada em torno dos nós elegíveis, e não de uma quantidade de réplicas.

A saída testada incluiu duas revisões e a nova mensagem de log:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>

node=labex-v135 version=v2

CHANGE-CAUSE=<none> significa apenas que nenhuma anotação legível por humanos foi registrada para a alteração. A revisão 2, juntamente com version=v2 no log do Pod substituto, são as evidências úteis de que a atualização ocorreu.

Resumo

Você usou rótulos de nós para controlar a elegibilidade de um DaemonSet, observou a reconciliação de um Pod por nó elegível, rastreou a propriedade do controlador e executou a atualização de um agente de nó. Agora você já pode comparar DaemonSets com Deployments orientados a réplicas e Jobs orientados à conclusão.