Services e networking
Esta aula aborda os conceitos fundamentais de serviços e networking no Kubernetes, explicando os tipos de serviços (ClusterIP, NodePort, LoadBalancer), a descoberta de serviços, o Ingress e o DNS interno, com exemplos práticos em YAML e comandos kubectl.
Nesta aula, vamos explorar como o Kubernetes gerencia a comunicação entre pods e com o mundo externo através do conceito de Serviços. Serviços são abstrações que definem uma política de acesso a um conjunto de pods, fornecendo um endpoint estável (IP e porta) mesmo quando os pods subjacentes mudam. Compreender os diferentes tipos de serviços e como eles interagem com o DNS interno e o Ingress é essencial para projetar aplicações resilientes e escaláveis no Kubernetes.
Vamos detalhar os três principais tipos de serviços: ClusterIP, NodePort e LoadBalancer, além de abordar a descoberta de serviços, o recurso Ingress (que atua como um roteador HTTP) e o DNS interno baseado no CoreDNS. Ao final, você terá uma visão clara de como conectar seus pods entre si e expô-los de forma controlada.
ClusterIP, NodePort, LoadBalancer
O tipo de serviço define como o tráfego é roteado para os pods. O ClusterIP é o tipo padrão: ele cria um IP virtual interno ao cluster, acessível apenas de dentro do cluster. Esse IP balanceia a carga entre os pods selecionados pelo serviço. É ideal para comunicação interna entre microsserviços, como um backend conversando com um banco de dados.
O NodePort expande o ClusterIP, expondo o serviço em uma porta estática (30000-32767) em cada nó do cluster. Assim, o tráfego externo pode chegar a qualquer nó na porta especificada e ser redirecionado para o ClusterIP. É útil para testes rápidos ou ambientes de desenvolvimento, mas não é recomendado para produção devido à exposição direta de portas altas.
O LoadBalancer é o tipo mais avançado: ele provisiona um balanceador de carga externo (como um ELB na AWS ou um LB no GCP) que encaminha o tráfego para o NodePort ou diretamente para os pods. É a forma mais comum de expor serviços em nuvens públicas, pois fornece um IP público e gerencia a distribuição de tráfego.
Abaixo, um exemplo de definição de um serviço do tipo LoadBalancer:
apiVersion: v1
kind: Service
metadata:
name: meu-servico
spec:
type: LoadBalancer
selector:
app: meu-app
ports:
- port: 80
targetPort: 8080Para criar o serviço, use kubectl apply -f servico.yaml. O Kubernetes criará automaticamente um ClusterIP e um NodePort subjacentes, e o provedor de nuvem configurará o balanceador externo.
Descoberta de serviços
A descoberta de serviços é o mecanismo pelo qual os pods encontram outros serviços no cluster. No Kubernetes, isso é feito principalmente através do DNS interno e das variáveis de ambiente. Quando um serviço é criado, o Kubernetes registra um nome DNS no formato <serviço>.<namespace>.svc.cluster.local. Outros pods podem usar esse nome para acessar o serviço, independentemente de sua localização no cluster.
Além do DNS, o kubelet também injeta variáveis de ambiente nos pods, como MEU_SERVICO_SERVICE_HOST e MEU_SERVICO_SERVICE_PORT, contendo o IP e a porta do serviço. No entanto, essas variáveis são definidas na criação do pod, então não são atualizadas se o serviço for recriado. Por isso, o DNS é a abordagem recomendada.
Para testar a descoberta, você pode executar um pod temporário e usar o comando nslookup ou curl:
kubectl run teste --rm -it --image=busybox -- sh
/ # nslookup meu-servico
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: meu-servico
Address 1: 10.108.123.45 meu-servico.default.svc.cluster.localIsso mostra que o pod consegue resolver o nome do serviço para o IP ClusterIP. A descoberta funciona para serviços em qualquer namespace, desde que você use o nome completo ou o nome curto dentro do mesmo namespace.
Ingress (visão geral)
O Ingress é um recurso que gerencia o acesso externo aos serviços, geralmente HTTP/HTTPS. Ele atua como um proxy reverso, roteando requisições para diferentes serviços com base em regras de host e caminho. Por exemplo, você pode direcionar api.exemplo.com para um serviço backend e site.exemplo.com para um serviço frontend.
Para que o Ingress funcione, é necessário ter um Ingress Controller instalado no cluster, como o NGINX Ingress Controller ou o Traefik. O controller observa os recursos Ingress e configura o proxy de acordo. O Ingress oferece vantagens como TLS/SSL, balanceamento de carga e roteamento baseado em caminho, sem a necessidade de criar múltiplos LoadBalancers.
Um exemplo simples de Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: exemplo-ingress
spec:
rules:
- host: meuapp.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80Esse Ingress encaminha as requisições para meuapp.com/api ao serviço api-svc e as demais para web-svc. O Ingress Controller aplicará as regras e atualizará seu proxy.
DNS interno
O DNS interno do Kubernetes é fornecido pelo CoreDNS, que roda como um conjunto de pods no namespace kube-system. Ele é automaticamente configurado como o servidor DNS para todos os pods, resolvendo nomes de serviços, pods e registros personalizados.
O domínio base é cluster.local. Para um serviço chamado meu-servico no namespace default, o FQDN é meu-servico.default.svc.cluster.local. Dentro do mesmo namespace, você pode usar apenas meu-servico. O CoreDNS também oferece suporte a headless services (sem ClusterIP), que retornam os IPs de todos os pods selecionados, permitindo descoberta de pods individuais.
Você pode verificar a configuração do CoreDNS com:
kubectl get configmap -n kube-system coredns -o yamlO arquivo de configuração contém as zonas e os plugins. Por padrão, ele inclui o plugin kubernetes que integra o DNS com a API do Kubernetes.
Para testar a resolução de um nome de serviço, você pode usar o comando dig ou nslookup de dentro de um pod:
kubectl run dns-teste --rm -it --image=busybox -- nslookup meu-servico.default.svc.cluster.localIsso deve retornar o IP do serviço. O DNS interno é fundamental para a comunicação entre serviços e para o funcionamento de aplicações distribuídas.
Boas práticas e observações finais
Ao trabalhar com serviços e networking, algumas práticas recomendadas incluem:
- Use ClusterIP para comunicação interna entre serviços, evitando exposição desnecessária.
- Prefira LoadBalancer para exposição externa em nuvem, mas esteja ciente dos custos.
- Utilize Ingress para roteamento HTTP, centralizando a configuração de TLS e regras de caminho.
- Sempre defina
requestselimitspara os pods, pois isso afeta a alocação de recursos e o balanceamento. - Monitore o CoreDNS e o Ingress Controller para garantir alta disponibilidade.
Com esses conceitos, você está pronto para projetar a comunicação da sua aplicação no Kubernetes de forma robusta e escalável.
Referências
- Kubernetes Documentation: Service
- Kubernetes Documentation: Ingress
- Kubernetes Documentation: DNS for Services and Pods
- CoreDNS official site
- Kubernetes Documentation: Create External Load Balancer
Exercícios
Explique a diferença entre ClusterIP, NodePort e LoadBalancer e em quais cenários cada um é mais adequado.
✓ Resposta: ClusterIP é o tipo padrão, criando um IP virtual acessível apenas dentro do cluster, ideal para comunicação interna entre serviços. NodePort expõe o serviço em uma porta estática em todos os nós, permitindo acesso externo, mas é menos seguro e usado para testes. LoadBalancer provisiona um balanceador de carga externo (em nuvem), fornecendo um IP público e gerenciando o tráfego, sendo o mais adequado para produção.Como funciona a descoberta de serviços no Kubernetes? Cite duas formas e indique a mais recomendada.
✓ Resposta: A descoberta de serviços funciona através do DNS interno (CoreDNS) e de variáveis de ambiente injetadas pelo kubelet. O DNS é a forma recomendada porque é dinâmico e atualizado automaticamente, enquanto as variáveis de ambiente são definidas na criação do pod e não refletem mudanças futuras.Escreva um manifesto YAML para um serviço do tipo NodePort que seleciona pods com o label
app: webe expõe a porta 80 no pod, com porta do serviço 80 e nodePort 30080.✓ Resposta:apiVersion: v1 kind: Service metadata: name: web-service spec: type: NodePort selector: app: web ports: - port: 80 targetPort: 80 nodePort: 30080O que é um Ingress Controller e por que é necessário para usar recursos Ingress?
✓ Resposta: O Ingress Controller é um componente que implementa a lógica de roteamento definida nos recursos Ingress. Ele observa a API do Kubernetes e configura um proxy reverso (como NGINX) para encaminhar o tráfego conforme as regras. Sem um controller, o recurso Ingress não tem efeito, pois não há nada para processar as regras.Qual é o FQDN (nome totalmente qualificado) de um serviço chamado
apino namespaceprod? Como você acessaria esse serviço a partir de um pod no mesmo namespace?✓ Resposta: O FQDN éapi.prod.svc.cluster.local. Dentro do mesmo namespace, você pode usar apenasapicomo nome do host.