Diagnosticar Acesso DNS a Serviços

KubernetesBeginner
Pratique Agora

Introdução

O laboratório anterior demonstrou como um Service fornece aos Pods um ponto de entrada estável dentro do cluster. O Kubernetes também atribui a cada Service um nome DNS. Um Pod no mesmo namespace geralmente pode usar o nome curto do Service, mas um Pod em um namespace diferente frequentemente precisa de um nome mais longo que inclua o namespace do Service.

Neste laboratório, você criará um Service web, testará o acesso DNS no mesmo namespace, reproduzirá uma falha de nome curto entre namespaces, corrigirá a requisição usando o FQDN do Service e inspecionará os objetos que ajudam a diagnosticar se um problema de DNS é realmente um problema de Service, de endpoint ou do CoreDNS.

Preparar um Service Web

Nesta etapa, você criará o Service de destino que os testes de DNS posteriores irão resolver. A carga de trabalho é intencionalmente simples, pois o foco principal é a nomenclatura DNS, não a implantação da aplicação.

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 a rede do cluster esteja pronta (Ready). Este laboratório envia tráfego entre Pods, portanto, a rede de Pods deve estar saudável antes que os testes de acesso DNS sejam significativos.

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

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

Crie um Deployment e exponha-o com um Service chamado dns-web:

kubectl create deployment dns-web --image=nginx:1.25 --port=80
kubectl expose deployment dns-web --port=80 --target-port=80

Aguarde até que o Pod web esteja disponível:

kubectl rollout status deployment/dns-web --timeout=120s

Inspecione o Service e seu EndpointSlice. O Service é o destino DNS estável; o EndpointSlice mostra os endereços atuais dos Pods de backend selecionados pelo Service.

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

A saída esperada inclui:

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

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

Resolver o Service a partir do mesmo Namespace

Nesta etapa, você criará um Pod cliente no mesmo namespace do Service e usará o nome curto do Service. Este é o caso mais simples de DNS de Service.

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

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

Aguarde até que o Pod cliente esteja pronto:

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

Saída esperada:

pod/same-ns-client condition met

Use o nslookup dentro do Pod cliente para resolver o nome curto do Service dns-web. O nome curto funciona aqui porque o Pod cliente e o Service estão no mesmo namespace. O nslookup do BusyBox pode exibir linhas extras NXDOMAIN para outros sufixos de busca e retornar um código de saída diferente de zero após mostrar o endereço correto, por isso o comando usa || true e você deve observar as linhas Name e Address.

kubectl exec same-ns-client -- sh -c 'nslookup dns-web || true'

A saída esperada inclui:

Name:      dns-web.ckad-prep-dns.svc.cluster.local
Address: ...

Agora, envie uma requisição HTTP para o nome curto do Service:

kubectl exec same-ns-client -- wget -qO- http://dns-web | grep '<title>Welcome to nginx'

Saída esperada:

<title>Welcome to nginx!</title>

Diagnosticar uma falha de nome curto entre namespaces

Nesta etapa, você criará um Pod cliente em um namespace diferente e reproduzirá um erro comum de DNS. Um nome curto de Service é resolvido primeiro em relação ao namespace do Pod cliente, portanto, dns-web não encontrará o Service em ckad-prep-dns quando o cliente for executado em outro namespace.

Crie um segundo namespace e um Pod cliente nele:

kubectl create namespace ckad-prep-dns-client
kubectl run remote-client --namespace ckad-prep-dns-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --namespace ckad-prep-dns-client --for=condition=Ready pod/remote-client --timeout=120s

A saída esperada inclui:

namespace/ckad-prep-dns-client created
pod/remote-client created
pod/remote-client condition met

Tente resolver o nome curto a partir do namespace remoto. O || true mantém o laboratório em execução, pois essa falha é esperada.

kubectl exec --namespace ckad-prep-dns-client remote-client -- nslookup dns-web || true

A saída esperada inclui uma falha como:

** server can't find dns-web...

Agora, resolva o nome completo do Service (FQDN). O padrão completo é <service>.<namespace>.svc.cluster.local.

kubectl exec --namespace ckad-prep-dns-client remote-client -- nslookup dns-web.ckad-prep-dns.svc.cluster.local

A saída esperada inclui:

Name:      dns-web.ckad-prep-dns.svc.cluster.local
Address 1: ...

Use o mesmo nome totalmente qualificado para acesso HTTP:

kubectl exec --namespace ckad-prep-dns-client remote-client -- wget -qO- http://dns-web.ckad-prep-dns.svc.cluster.local | grep '<title>Welcome to nginx'

Saída esperada:

<title>Welcome to nginx!</title>

Verificar o caminho de resolução de problemas de DNS

Nesta etapa, você inspecionará os objetos que ajudam a separar um problema de nomenclatura DNS de um problema de Service ou de backend. Uma ordem prática de resolução de problemas é: confirmar o nome e o namespace do Service, confirmar se ele possui endpoints e, em seguida, confirmar se o CoreDNS está disponível.

Primeiro, inspecione o Service em seu namespace real:

kubectl get service dns-web --namespace ckad-prep-dns

A saída esperada inclui:

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

Em seguida, inspecione o EndpointSlice. Se o DNS resolve, mas o tráfego HTTP falha, a falta de endpoints é uma causa comum.

kubectl get endpointslice --namespace ckad-prep-dns -l kubernetes.io/service-name=dns-web

A saída esperada inclui pelo menos um endpoint:

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

Verifique os Pods do CoreDNS. O CoreDNS é o serviço DNS do cluster que responde às consultas DNS dos Pods.

kubectl get pods --namespace kube-system -l k8s-app=kube-dns

A saída esperada inclui Pods do CoreDNS em execução:

NAME                       READY   STATUS    RESTARTS   AGE
coredns-...                1/1     Running   ...        ...

Por fim, inspecione a configuração de busca DNS do cliente remoto. A linha search explica por que o nome curto dns-web foi pesquisado no namespace do cliente antes de você usar o nome completo.

kubectl exec --namespace ckad-prep-dns-client remote-client -- cat /etc/resolv.conf

A saída esperada inclui um caminho de busca semelhante a:

search ckad-prep-dns-client.svc.cluster.local svc.cluster.local cluster.local
nameserver ...

Resumo

Você praticou o diagnóstico de acesso DNS a Serviços no Kubernetes em uma sequência amigável para iniciantes. Você criou um Service, confirmou que um cliente no mesmo namespace pode usar o nome curto do Service, reproduziu uma falha de nome curto entre namespaces, corrigiu-a com o nome DNS completo do Service e inspecionou o Service, o EndpointSlice, os Pods do CoreDNS e o caminho de busca DNS do cliente para entender a origem dos problemas de acesso DNS.