Expor um Deployment com um Service

KubernetesBeginner
Pratique Agora

Introdução

Pods são temporários. Um Deployment pode substituir Pods durante atualizações (rollout), reinicializações ou escalonamentos, portanto, os clientes não devem se conectar diretamente aos IPs individuais dos Pods. Um Service fornece aos clientes um nome estável e um IP virtual, utilizando labels (rótulos) para rotear o tráfego para os Pods correspondentes atuais.

Neste laboratório, você criará um pequeno Deployment web, irá expô-lo com um Service do tipo ClusterIP, inspecionará como o Service seleciona os Pods de backend, testará o Service a partir de um Pod cliente e escalará o Deployment para observar a atualização dos endpoints do Service.

Criar um Deployment Web

Nesta etapa, você preparará um namespace e criará um Deployment que poderá ser exposto posteriormente com um Service.

Comece em /home/labex/project:

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...

Aguarde até que o Pod de rede do cluster esteja pronto (Ready). Este laboratório envia tráfego entre Pods através de um Service, portanto, a rede do cluster precisa estar saudável antes de testar o acesso.

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-service e defina-o como o namespace atual:

kubectl create namespace ckad-prep-service
kubectl config set-context --current --namespace=ckad-prep-service

Crie um Deployment chamado web-front com um Pod NGINX. A flag --port=80 registra a porta do container no template do Pod. Ela não cria um Service por si só.

kubectl create deployment web-front --image=nginx:1.25 --port=80

Aguarde até que o Deployment esteja disponível e, em seguida, inspecione o label do Pod. O label app=web-front é importante, pois o Service o utilizará para encontrar os Pods de backend.

kubectl rollout status deployment/web-front --timeout=120s
kubectl get pods -l app=web-front --show-labels

A saída esperada inclui:

deployment "web-front" successfully rolled out
NAME                         READY   STATUS    RESTARTS   AGE   LABELS
web-front-...                1/1     Running   0          ...   app=web-front,...

Expor o Deployment com um Service do tipo ClusterIP

Nesta etapa, você criará um Service para o Deployment e inspecionará os campos que conectam o Service aos Pods.

Use kubectl expose deployment para criar um Service do tipo ClusterIP. A porta do Service é 80, e --target-port=80 instrui o Service a encaminhar o tráfego para a porta 80 nos Pods correspondentes.

kubectl expose deployment web-front --name=web-front --port=80 --target-port=80

Saída esperada:

service/web-front exposed

Inspecione o Service:

kubectl get service web-front

A saída esperada inclui:

NAME        TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
web-front   ClusterIP   ...          <none>        80/TCP    ...

Agora, inspecione o seletor do Service e o mapeamento de portas. O seletor é como o Service encontra os Pods; o mapeamento de porta é como o tráfego do cliente chega ao container.

kubectl get service web-front -o jsonpath='{.spec.selector.app}{" "}{.spec.ports[0].port}{":"}{.spec.ports[0].targetPort}{"\n"}'

Saída esperada:

web-front 80:80

O Kubernetes armazena os endereços de backend selecionados em EndpointSlices. Liste o EndpointSlice criado para este Service:

kubectl get endpointslice -l kubernetes.io/service-name=web-front

A saída esperada inclui:

NAME              ADDRESSTYPE   PORTS   ENDPOINTS   AGE
web-front-...     IPv4          80      ...         ...

Testar o Service a partir de dentro do cluster

Nesta etapa, você criará um Pod cliente temporário e enviará uma requisição HTTP para o Service. Um Service do tipo ClusterIP destina-se ao acesso interno ao cluster, portanto, testar a partir de outro Pod é a maneira mais direta de verificá-lo.

Crie um Pod cliente que permaneça em execução:

kubectl run service-client --image=busybox:1.36 --restart=Never --command -- sleep 3600

Aguarde até que o Pod cliente esteja pronto:

kubectl wait --for=condition=Ready pod/service-client --timeout=120s

Saída esperada:

pod/service-client condition met

Use wget dentro do Pod cliente para solicitar http://web-front. O nome web-front é resolvido para o Service dentro do namespace.

kubectl exec service-client -- wget -qO- http://web-front | head -n 5

A saída esperada inclui o início da página padrão do NGINX:

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Isso prova que o cliente alcançou o nome estável do Service e que o Service encaminhou o tráfego para o Pod de backend atual.

Escalar o Backend e verificar novamente os Endpoints

Nesta etapa, você escalará o Deployment e confirmará que o Service mantém o mesmo ponto de entrada estável enquanto seus endpoints de backend mudam.

Escale o Deployment para duas réplicas:

kubectl scale deployment web-front --replicas=2
kubectl rollout status deployment/web-front --timeout=120s

A saída esperada inclui:

deployment.apps/web-front scaled
deployment "web-front" successfully rolled out

Liste os Pods. Agora deve haver dois Pods de backend em execução com o mesmo label app=web-front.

kubectl get pods -l app=web-front

A saída esperada inclui dois Pods:

NAME                         READY   STATUS    RESTARTS   AGE
web-front-...                1/1     Running   0          ...
web-front-...                1/1     Running   0          ...

Conte os endpoints por trás do Service. O comando imprime uma linha para cada endereço de endpoint e, em seguida, conta as linhas.

kubectl get endpointslice -l kubernetes.io/service-name=web-front -o jsonpath='{range .items[*].endpoints[*]}{.addresses[0]}{"\n"}{end}' | wc -l

Saída esperada:

2

Solicite o Service novamente a partir do mesmo Pod cliente:

kubectl exec service-client -- wget -qO- http://web-front | grep '<title>Welcome to nginx'

Saída esperada:

<title>Welcome to nginx!</title>

Resumo

Você expôs um Deployment com um Service do tipo ClusterIP e verificou o caminho completo de acesso dentro do cluster. Você criou um Deployment de backend, criou um Service com um seletor e mapeamento de porta, inspecionou o EndpointSlice gerado para o Service, testou o acesso a partir de um Pod cliente, escalou o Deployment e confirmou que o Service continuou roteando para o conjunto de backend atualizado.