Escolha o Recurso de Carga de Trabalho Correto

KubernetesBeginner
Pratique Agora

Introdução

As tarefas do CKAD frequentemente exigem que você escolha o recurso de carga de trabalho (workload) correto do Kubernetes antes de escrever um manifesto. Um Pod é a menor unidade executável, um Deployment mantém réplicas de aplicações de longa duração disponíveis, um Job executa um trabalho até a conclusão e um CronJob armazena um modelo de Job agendado.

Neste laboratório, você comparará esses recursos através de comportamentos observáveis, em vez de apenas memorizar definições. Você verá que um Pod independente não retorna após a exclusão, um Deployment recria seu Pod, um Job finaliza e registra o sucesso, e um CronJob armazena informações de agendamento para trabalhos recorrentes.

Prepare um Namespace para Comparação de Cargas de Trabalho

Nesta etapa, você preparará um namespace limpo para comparar os recursos de carga de trabalho.

Comece em /home/labex/project. Você criará pequenos manifestos neste diretório à medida que compara o comportamento das cargas de trabalho.

mkdir -p /home/labex/project
cd /home/labex/project

Verifique se o servidor da API do Kubernetes está acessível. Se a VM acabou de iniciar e o nó ainda não está pronto, aguarde alguns segundos e execute o comando novamente.

kubectl get nodes --request-timeout=5s

A saída esperada inclui:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

As cargas de trabalho criam Pods, portanto, aguarde até que o Pod de rede do cluster esteja pronto (Ready).

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Saída esperada:

pod/calico-node-... condition met

Crie um namespace chamado ckad-prep-workloads:

kubectl create namespace ckad-prep-workloads

Defina este namespace como o namespace do contexto atual:

kubectl config set-context --current --namespace=ckad-prep-workloads

Confirme o namespace atual:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Saída esperada:

ckad-prep-workloads

Compare um Pod com um Deployment

Nesta etapa, você comparará um Pod independente com um Deployment, excluindo ambos os Pods e observando o que o Kubernetes faz em seguida.

Um Pod independente é útil quando você precisa de uma unidade de execução gerenciada diretamente para uma tarefa muito pequena ou inspeção. Um Deployment é melhor para uma aplicação de longa duração, pois um Deployment possui um ReplicaSet, e o ReplicaSet mantém o número solicitado de Pods em execução.

Crie um manifesto de Pod independente. O container entra em modo de espera (sleep) para que o Pod permaneça em execução tempo suficiente para observá-lo. O campo terminationGracePeriodSeconds: 0 torna este laboratório mais rápido quando você excluir o Pod posteriormente.

cat > standalone-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: standalone-task
  labels:
    app: standalone-task
    workload.labex.io/intent: direct-pod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: sleeper
    image: busybox:1.36
    command: ["/bin/sh", "-c", "sleep 3600"]
EOF

Crie um manifesto de Deployment. Este Deployment solicita ao Kubernetes que mantenha um Pod managed-worker em execução, e seu modelo de Pod usa a mesma configuração de terminação rápida.

cat > managed-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: managed-worker
  labels:
    workload.labex.io/intent: long-running
spec:
  replicas: 1
  selector:
    matchLabels:
      app: managed-worker
  template:
    metadata:
      labels:
        app: managed-worker
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: sleeper
        image: busybox:1.36
        command: ["/bin/sh", "-c", "sleep 3600"]
EOF

Aplique ambos os manifestos:

kubectl apply -f standalone-pod.yaml
kubectl apply -f managed-deployment.yaml

Saída esperada:

pod/standalone-task created
deployment.apps/managed-worker created

Aguarde até que ambas as cargas de trabalho estejam prontas:

kubectl wait --for=condition=Ready pod/standalone-task --timeout=120s
kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s

Saída esperada:

pod/standalone-task condition met
deployment.apps/managed-worker condition met

Capture o nome do Pod do Deployment atual e, em seguida, exclua o Pod independente e o Pod pertencente ao Deployment:

managed_pod="$(kubectl get pods -l app=managed-worker -o 'jsonpath={.items[0].metadata.name}')"
kubectl delete pod standalone-task "$managed_pod"

A saída esperada inclui:

pod "standalone-task" deleted
pod "managed-worker-..." deleted

Aguarde o Deployment ficar disponível novamente:

kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s

Saída esperada:

deployment.apps/managed-worker condition met

Liste os Pods. O Pod independente deve ter desaparecido, enquanto um novo Pod managed-worker deve existir.

kubectl get pods

A saída esperada inclui um Pod managed-worker, mas não o standalone-task:

NAME                              READY   STATUS    RESTARTS   AGE
managed-worker-...                1/1     Running   0          ...

Escolha um Job para Conclusão

Nesta etapa, você escolherá um Job para um trabalho que deve ser concluído com sucesso, em vez de ser executado indefinidamente.

Um Deployment é adequado quando o estado desejado é "manter esta aplicação em execução". Um Job é mais adequado quando o estado desejado é "executar esta tarefa até que ela seja concluída". É por isso que migrações, processamento em lote e comandos de manutenção pontuais geralmente são mapeados para Jobs.

Crie um Job chamado schema-migration:

kubectl create job schema-migration --image=busybox:1.36 -- /bin/sh -c 'echo migration-start; echo migration-complete'

Saída esperada:

job.batch/schema-migration created

Aguarde até que o Job atinja a condição Complete:

kubectl wait --for=condition=Complete job/schema-migration --timeout=120s

Saída esperada:

job.batch/schema-migration condition met

Inspecione o resumo do Job. COMPLETIONS deve mostrar 1/1, o que significa que a tarefa foi executada com sucesso uma vez.

kubectl get job schema-migration

A saída esperada inclui:

NAME               STATUS     COMPLETIONS   DURATION   AGE
schema-migration   Complete   1/1           ...        ...

Leia os logs do Job:

kubectl logs job/schema-migration

Saída esperada:

migration-start
migration-complete

Escolha um CronJob para Trabalho Recorrente

Nesta etapa, você escolherá um CronJob para um trabalho que deve ser executado de acordo com um agendamento.

Um CronJob é um modelo de Job agendado. É a escolha certa quando a tarefa deve se repetir posteriormente, e não apenas ser concluída uma vez. Para manter este laboratório guiado determinístico, você criará o CronJob em um estado suspenso. Isso permite que você inspecione o agendamento e o modelo sem esperar por um limite de tempo.

Crie o arquivo cleanup-cronjob.yaml:

cat > cleanup-cronjob.yaml <<'EOF'
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cleanup-schedule
  labels:
    workload.labex.io/intent: recurring-task
spec:
  schedule: "*/5 * * * *"
  suspend: true
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: cleanup
            image: busybox:1.36
            command:
            - /bin/sh
            - -c
            - 'echo cleanup-ready'
EOF

Aplique o manifesto:

kubectl apply -f cleanup-cronjob.yaml

Saída esperada:

cronjob.batch/cleanup-schedule created

Inspecione o resumo do CronJob. SUSPEND está como True porque este laboratório usa a definição do CronJob para aprender a escolha do recurso sem esperar pelos Jobs agendados.

kubectl get cronjob cleanup-schedule

A saída esperada inclui:

NAME               SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cleanup-schedule   */5 * * * *   <none>     True      0        <none>          ...

Leia o agendamento e a imagem do modelo diretamente do objeto:

kubectl get cronjob cleanup-schedule -o 'jsonpath={.spec.schedule}{" "}{.spec.suspend}{" "}{.spec.jobTemplate.spec.template.spec.containers[0].image}{"\n"}'

Saída esperada:

*/5 * * * * true busybox:1.36

Liste os recursos de carga de trabalho que você criou neste laboratório. Esta visualização conecta o tipo de recurso ao comportamento pretendido: um Deployment para uma réplica de longa duração, um Job para conclusão e um CronJob para recorrência.

kubectl get deployment,job,cronjob

A saída esperada inclui:

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/managed-worker   1/1     1            1           ...

NAME                         STATUS     COMPLETIONS   DURATION   AGE
job.batch/schema-migration   Complete   1/1           ...        ...

NAME                               SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/cleanup-schedule     */5 * * * *   <none>     True      0        <none>          ...

Resumo

Você comparou os recursos de carga de trabalho do Kubernetes pelo comportamento. Um Pod independente não retornou após a exclusão, um Deployment recriou seu Pod para manter uma réplica disponível, um Job executou uma tarefa até a conclusão bem-sucedida e um CronJob armazenou um modelo de Job recorrente. Essas observações ajudam você a escolher o recurso certo antes de escrever um manifesto no estilo CKAD.