Executamos o comando:
kubectl apply -f deployment.yaml
e, poucos segundos depois, nossos Pods aparecem em execução.
Mas o que realmente aconteceu dentro do Kubernetes entre esses dois momentos?
O kubectl não cria diretamente um container e o Deployment também não cria os Pods sozinho. Existe uma sequência de componentes trabalhando para transformar o estado declarado no YAML no estado real do cluster.
Neste artigo, vamos acompanhar esse caminho.

Tudo começa pelo estado desejado
Um manifesto Kubernetes descreve como queremos que determinado recurso exista.
Um exemplo simples:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-demo
spec:
replicas: 2
selector:
matchLabels:
app: webapp-demo
template:
metadata:
labels:
app: webapp-demo
spec:
containers:
- name: webapp
image: nginx:alpine
Nesse caso, estamos declarando, entre outras coisas, que queremos uma aplicação com duas réplicas (Pods).
Ao executar:
kubectl apply -f deployment.yaml
o kubectl lê essa definição e envia a requisição para a API do Kubernetes.
A partir desse momento, começa o processo de reconciliação.
1. kubectl envia a requisição ao API Server
O API Server é a principal interface de comunicação com o control plane.
Antes de aceitar o recurso, a requisição passa por etapas como autenticação, autorização, controle de admissão e validação.
Se a definição for aceita, o novo estado desejado passa a fazer parte do estado persistido do cluster.
De forma simplificada:
deployment.yaml
↓
kubectl
↓
API Server
2. O estado do cluster é persistido
O Kubernetes utiliza o etcd como armazenamento chave-valor do estado do cluster.
Isso inclui informações sobre objetos como:
- Deployments;
- ReplicaSets;
- Pods;
- Services;
- ConfigMaps;
- outros recursos da API.
Um detalhe importante: os componentes do Kubernetes normalmente interagem com esse estado através do API Server. O diagrama conceitual API Server → etcd não significa que cada controlador acessa o etcd diretamente.
3. O controlador percebe o novo Deployment
Depois que o objeto Deployment existe no cluster, o Deployment Controller identifica que há um novo estado desejado a ser atendido.
Se declaramos:
replicas: 2
o objetivo passa a ser manter duas réplicas da aplicação.
Mas o Deployment não cria diretamente esses Pods.
Ele cria e gerencia um ReplicaSet.
Deployment
↓
ReplicaSet

4. O ReplicaSet mantém a quantidade de Pods
O ReplicaSet recebe a responsabilidade de manter a quantidade desejada de Pods.
Com duas réplicas:
Deployment
↓
ReplicaSet
↙ ↘
Pod Pod
Se um desses Pods desaparecer, o ReplicaSet identifica que o estado real ficou diferente do desejado e cria outro.
É por isso que o modelo de controladores do Kubernetes é tão importante: eles trabalham continuamente para reduzir a diferença entre estado desejado (DESIRED) e estado atual (CURRENT).
5. Os Pods precisam de um node
Criar o objeto Pod ainda não significa que o container já está executando.
O Pod precisa ser associado a um node.
O kube-scheduler observa Pods que ainda não possuem um node definido e escolhe onde eles deverão executar considerando fatores como:
- recursos disponíveis;
- requests;
- affinity e anti-affinity;
- taints e tolerations;
- outras restrições de scheduling.
Depois dessa decisão, o Pod fica associado ao node selecionado.
6. Kubelet e runtime iniciam os containers
No node escolhido, o kubelet acompanha a especificação do Pod e trabalha com o runtime de containers para materializar aquele workload.
Nesse processo, podem ocorrer eventos como:
Scheduled
Pulling
Pulled
Created
Started
Esses eventos são facilmente observados com:
kubectl describe pod <pod> -n <namespace>

É nesse momento que a definição que começou no YAML resulta efetivamente em containers executando no node.
Como enxergar essa relação no cluster
Um comando simples permite visualizar boa parte dessa cadeia:
kubectl get deployment,rs,pods -n <namespace>
Também podemos confirmar a relação de propriedade entre os recursos.
O ReplicaSet possui uma referência ao Deployment:
kubectl get rs <replicaset> \
-n <namespace> \
-o jsonpath='{.metadata.ownerReferences[0].kind}/{.metadata.ownerReferences[0].name}{"\n"}'

E o Pod possui uma referência ao ReplicaSet:
kubectl get pod <pod> \
-n <namespace> \
-o jsonpath='{.metadata.ownerReferences[0].kind}/{.metadata.ownerReferences[0].name}{"\n"}'

Na prática:
Deployment
↓
ReplicaSet
↓
Pod
Essa é uma forma interessante de confirmar no próprio cluster a cadeia que normalmente vemos apenas em diagramas.
E o que acontece quando executamos apply novamente?
O kubectl apply não serve apenas para a criação inicial.
Imagine que nosso manifesto tenha:
replicas: 2
e alteremos para:
replicas: 3

Ao executar novamente:
kubectl apply -f deployment.yaml
podemos encontrar uma saída semelhante a:
deployment.apps/webapp-demo configured
O estado desejado agora é diferente.
O Kubernetes então trabalha para fazer o estado real convergir para ele:
Desejado: 3 Pods
Atual: 2 Pods
↓
Reconciliação
↓
Atual: 3 Pods

Depois:
kubectl get pods -n <namespace>
deverá mostrar três Pods.

Esse é um dos conceitos fundamentais do Kubernetes: declaramos o resultado esperado e os controladores trabalham continuamente para alcançá-lo e mantê-lo.
O fluxo completo
De forma simplificada:
deployment.yaml
↓
kubectl
↓
API Server
↓
estado persistido
↓
Deployment Controller
↓
ReplicaSet
↓
Pods
↓
Scheduler
↓
Node
↓
Kubelet + Runtime
↓
containers em execução
Esse fluxo é propositalmente simplificado.
Na arquitetura real, os componentes do control plane se comunicam por meio da API do Kubernetes e executam loops de controle independentes. O importante é compreender a responsabilidade de cada componente, e não interpretar o desenho como uma chamada síncrona e linear entre todos eles.

O principal aprendizado
Quando executamos:
kubectl apply -f deployment.yaml
não estamos simplesmente pedindo ao Kubernetes para “subir um container”.
Estamos declarando um estado desejado.
O API Server recebe essa intenção, os controladores observam os objetos correspondentes, o Deployment gerencia um ReplicaSet, o ReplicaSet mantém os Pods e os componentes do node transformam essas definições em containers efetivamente executando.
Em resumo:
YAML
↓
estado desejado
↓
controladores
↓
reconciliação
↓
workload em execução
Entender essa cadeia facilita não apenas o uso do Kubernetes, mas também troubleshooting, análise de rollouts e compreensão do que realmente acontece quando algo entre o YAML e o Pod não funciona como esperado.


