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.


