Services: A Base da Comunicação em Kubernetes
Um Service em Kubernetes é um recurso abstrato que define como acessar um conjunto de Pods. Diferentemente de Pods, que são efêmeros e podem ser recriados a qualquer momento, um Service fornece um ponto de acesso estável com um DNS duradouro e um IP de cluster consistente. Sem Services, seria impossível acessar suas aplicações de forma previsível, já que os Pods mudam constantemente.
Existem quatro tipos principais de Services: ClusterIP (acesso interno apenas), NodePort (expõe em uma porta de cada node), LoadBalancer (provisiona um balanceador externo) e ExternalName (mapeia um nome DNS externo). A escolha do tipo depende de como você quer que a aplicação seja acessada.
ClusterIP: Comunicação Interna
O ClusterIP é o tipo padrão e mais comum. Ele aloca um IP virtual do cluster que é roteável apenas dentro do cluster Kubernetes. Use-o quando seus Pods precisam se comunicar entre si ou com outras aplicações no mesmo cluster.
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: default
spec:
type: ClusterIP
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 8080
Neste exemplo, o Service backend-service roteia o tráfego na porta 80 para os Pods com rótulo app: backend na porta 8080. Outros Pods podem acessar este serviço através de backend-service.default.svc.cluster.local:80.
NodePort: Acesso Externo Simples
NodePort expõe o Service em uma porta específica em cada node do cluster. É útil para ambiente de desenvolvimento ou quando você não tem um balanceador de carga disponível. O Kubernetes aloca automaticamente uma porta entre 30000 e 32767, mas você pode especificá-la.
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: NodePort
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30080
Com esta configuração, sua aplicação estará acessível em http://<qualquer-ip-do-node>:30080. O tráfego entra na porta 30080 do node e é roteado para a porta 3000 do Pod.
LoadBalancer: Integração com Provedores Cloud
LoadBalancer provisiona um balanceador de carga externo (se você estiver em um cloud provider como AWS, GCP ou Azure). É a forma mais direta de expor sua aplicação para o mundo exterior, mas tem custo adicional e funciona apenas em clusters gerenciados.
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
type: LoadBalancer
selector:
app: api
ports:
- protocol: TCP
port: 443
targetPort: 8443
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
Aqui, o Kubernetes provisiona um Load Balancer que distribui tráfego HTTPS para seus Pods. A opção sessionAffinity: ClientIP garante que requisições do mesmo cliente sempre cheguem no mesmo Pod, útil para aplicações que mantêm estado na sessão.
Ingress: Roteamento Inteligente de Requisições HTTP/HTTPS
Ingress é um recurso que gerencia acesso HTTP/HTTPS externo a serviços dentro de um cluster. Enquanto Services trabalham em camadas mais baixas, Ingress opera na camada de aplicação (Layer 7), permitindo roteamento baseado em hostname, caminho da URL e outras regras sofisticadas. Você precisa de um Ingress Controller rodando no cluster (como NGINX, Traefik ou Istio) para que Ingress realmente funcione.
A grande vantagem do Ingress é usar um único IP público com múltiplos domínios e caminhos, ao invés de um LoadBalancer por serviço. Em um ambiente de produção, é quase sempre a escolha correta.
Configuração Básica de Ingress
O recurso Ingress define as regras de roteamento. Ele não faz nada sozinho — precisa de um controller para interpretar essas regras e configurar um proxy (geralmente NGINX).
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- example.com
- api.example.com
secretName: example-tls-cert
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /admin
pathType: Prefix
backend:
service:
name: admin-service
port:
number: 9090
Este Ingress faz o seguinte: direciona example.com para o frontend, api.example.com para a API principal, e api.example.com/admin para o serviço de administração. As anotações indicam que um certificado TLS será provisionado automaticamente via cert-manager com Let's Encrypt.
Roteamento Avançado
O Ingress pode fazer muito mais que roteamento simples. Você pode usar expressões regulares, reescrever URLs, adicionar headers customizados e até dividir tráfego entre múltiplos serviços.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: advanced-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/rate-limit: "100"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
spec:
ingressClassName: nginx
rules:
- host: api.example.com
http:
paths:
- path: /v1(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-v1-service
port:
number: 8080
- path: /v2(/|$)(.*)
pathType: ImplementationSpecific
backend:
service:
name: api-v2-service
port:
number: 8080
Neste exemplo, requisições para /v1/users são reescritas para /users antes de chegar no api-v1-service, mantendo APIs versionadas separadas. A anotação rate-limit protege contra abuso com limite de 100 requisições por segundo.
Instalando um Ingress Controller
O Ingress Controller é quem realmente faz o trabalho. Aqui está como instalar o NGINX Ingress Controller usando Helm:
# Adicionar repositório Helm
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Instalar o controller
helm install nginx-ingress ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.type=LoadBalancer
Após a instalação, o controller monitora todos os recursos Ingress no cluster e configura um proxy NGINX automaticamente. Quando você cria ou modifica um Ingress, a configuração do NGINX é atualizada em segundos.
Exposição de Aplicações: Estratégias Práticas
Expor uma aplicação Kubernetes não é apenas criar um Service ou Ingress — é entender qual estratégia faz sentido para seu caso. Em desenvolvimento, NodePort é rápido. Em produção, Ingress com certificados TLS é o padrão. Cada escolha tem implicações em segurança, custo e performance.
Estratégia de Desenvolvimento Local
Para trabalhar rapidamente em desenvolvimento, use port-forward ou NodePort. Port-forward permite acessar um Pod ou Service diretamente do seu computador sem expor globalmente.
# Acessar um serviço localmente
kubectl port-forward svc/backend-service 8080:80 -n default
# Acessar um Pod específico
kubectl port-forward pod/nginx-abc123 3000:80 -n default
Após executar um desses comandos, acesse localhost:8080 no seu navegador. É perfeito para debug, mas não use em produção — as conexões não são balanceadas ou resilientes.
Estratégia de Produção com Ingress e TLS
Em produção, combine Ingress com certificados TLS automáticos. Use cert-manager para provisionar certificados do Let's Encrypt sem intervenção manual.
# Primeiro, instale cert-manager
# helm repo add jetstack https://charts.jetstack.io
# helm install cert-manager jetstack/cert-manager \
# --namespace cert-manager \
# --create-namespace \
# --set installCRDs=true
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-prod-key
solvers:
- http01:
ingress:
class: nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: production-ingress
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- app.example.com
secretName: app-tls-secret
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app-service
port:
number: 80
O ClusterIssuer define como obter certificados. O Ingress com a anotação cert-manager.io/cluster-issuer faz cert-manager provisionar um certificado automaticamente. O certificado é renovado automaticamente 30 dias antes do vencimento.
Monitorar Exposição e Acesso
Verifique se suas aplicações estão sendo acessadas corretamente:
# Ver todos os Services
kubectl get svc -A
# Ver detalhes de um Ingress
kubectl describe ingress app-ingress
# Ver logs do Ingress Controller
kubectl logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=50
# Testar conectividade dentro do cluster
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- \
curl http://backend-service.default.svc.cluster.local:80
# Ver IP externo do LoadBalancer
kubectl get svc frontend-service -o wide
Estes comandos ajudam a diagnosticar problemas de conectividade. Se um serviço não é acessível, verifique se o Ingress Controller está rodando, se o DNS está resolvendo corretamente e se o certificado TLS é válido.
Conclusão
Primeiro aprendizado: Services são a base invisível de qualquer aplicação Kubernetes — sem eles, os Pods seriam acessíveis apenas por IP efêmero. Use ClusterIP para comunicação interna, NodePort para desenvolvimento, e LoadBalancer quando integrado com cloud providers.
Segundo aprendizado: Ingress é seu caminho para exposição em produção, especialmente quando você tem múltiplos serviços acessados pelo mesmo domínio. Combinar Ingress com cert-manager oferece HTTPS automático e roteamento inteligente sem necessidade de múltiplos load balancers caros.
Terceiro aprendizado: A escolha entre Service, NodePort e Ingress não é técnica apenas — é arquitetural. Comece com o mais simples (ClusterIP), evolua conforme suas necessidades crescem, e sempre teste conectividade com logs e comandos de diagnóstico antes de levar para produção.