<h2>Services: A Base da Comunicação em Kubernetes</h2>
<p>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.</p>
<p>Existem quatro tipos principais de Services: <strong>ClusterIP</strong> (acesso interno apenas), <strong>NodePort</strong> (expõe em uma porta de cada node), <strong>LoadBalancer</strong> (provisiona um balanceador externo) e <strong>ExternalName</strong> (mapeia um nome DNS externo). A escolha do tipo depende de como você quer que a aplicação seja acessada.</p>
<h3>ClusterIP: Comunicação Interna</h3>
<p>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.</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: default
spec:
type: ClusterIP
selector:
app: backend
ports:
- protocol: TCP
port: 80
targetPort: 8080</code></pre>
<p>Neste exemplo, o Service <code>backend-service</code> roteia o tráfego na porta 80 para os Pods com rótulo <code>app: backend</code> na porta 8080. Outros Pods podem acessar este serviço através de <code>backend-service.default.svc.cluster.local:80</code>.</p>
<h3>NodePort: Acesso Externo Simples</h3>
<p>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.</p>
<pre><code class="language-yaml">apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: NodePort
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 3000
nodePort: 30080</code></pre>
<p>Com esta configuração, sua aplicação estará acessível em <code>http://<qualquer-ip-do-node>:30080</code>. O tráfego entra na porta 30080 do node e é roteado para a porta 3000 do Pod.</p>
<h3>LoadBalancer: Integração com Provedores Cloud</h3>
<p>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.</p>
<pre><code class="language-yaml">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</code></pre>
<p>Aqui, o Kubernetes provisiona um Load Balancer que distribui tráfego HTTPS para seus Pods. A opção <code>sessionAffinity: ClientIP</code> garante que requisições do mesmo cliente sempre cheguem no mesmo Pod, útil para aplicações que mantêm estado na sessão.</p>
<h2>Ingress: Roteamento Inteligente de Requisições HTTP/HTTPS</h2>
<p>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 <strong>Ingress Controller</strong> rodando no cluster (como NGINX, Traefik ou Istio) para que Ingress realmente funcione.</p>
<p>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.</p>
<h3>Configuração Básica de Ingress</h3>
<p>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).</p>
<pre><code class="language-yaml">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</code></pre>
<p>Este Ingress faz o seguinte: direciona <code>example.com</code> para o frontend, <code>api.example.com</code> para a API principal, e <code>api.example.com/admin</code> 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.</p>
<h3>Roteamento Avançado</h3>
<p>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.</p>
<pre><code class="language-yaml">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</code></pre>
<p>Neste exemplo, requisições para <code>/v1/users</code> são reescritas para <code>/users</code> antes de chegar no <code>api-v1-service</code>, mantendo APIs versionadas separadas. A anotação <code>rate-limit</code> protege contra abuso com limite de 100 requisições por segundo.</p>
<h3>Instalando um Ingress Controller</h3>
<p>O Ingress Controller é quem realmente faz o trabalho. Aqui está como instalar o NGINX Ingress Controller usando Helm:</p>
<pre><code class="language-bash"># 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</code></pre>
<p>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.</p>
<h2>Exposição de Aplicações: Estratégias Práticas</h2>
<p>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.</p>
<h3>Estratégia de Desenvolvimento Local</h3>
<p>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.</p>
<pre><code class="language-bash"># 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</code></pre>
<p>Após executar um desses comandos, acesse <code>localhost:8080</code> no seu navegador. É perfeito para debug, mas não use em produção — as conexões não são balanceadas ou resilientes.</p>
<h3>Estratégia de Produção com Ingress e TLS</h3>
<p>Em produção, combine Ingress com certificados TLS automáticos. Use cert-manager para provisionar certificados do Let's Encrypt sem intervenção manual.</p>
<pre><code class="language-yaml"># 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</code></pre>
<p>O <code>ClusterIssuer</code> define como obter certificados. O Ingress com a anotação <code>cert-manager.io/cluster-issuer</code> faz cert-manager provisionar um certificado automaticamente. O certificado é renovado automaticamente 30 dias antes do vencimento.</p>
<h3>Monitorar Exposição e Acesso</h3>
<p>Verifique se suas aplicações estão sendo acessadas corretamente:</p>
<pre><code class="language-bash"># 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</code></pre>
<p>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.</p>
<h2>Conclusão</h2>
<p><strong>Primeiro aprendizado:</strong> 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.</p>
<p><strong>Segundo aprendizado:</strong> 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.</p>
<p><strong>Terceiro aprendizado:</strong> 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.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://kubernetes.io/docs/concepts/services-networking/service/" target="_blank" rel="noopener noreferrer">Documentação Oficial de Services - Kubernetes</a></li>
<li><a href="https://kubernetes.io/docs/concepts/services-networking/ingress/" target="_blank" rel="noopener noreferrer">Documentação Oficial de Ingress - Kubernetes</a></li>
<li><a href="https://kubernetes.github.io/ingress-nginx/" target="_blank" rel="noopener noreferrer">NGINX Ingress Controller - Helm Chart</a></li>
<li><a href="https://cert-manager.io/docs/" target="_blank" rel="noopener noreferrer">cert-manager Documentation</a></li>
<li><a href="https://www.manning.com/books/kubernetes-in-action" target="_blank" rel="noopener noreferrer">Kubernetes in Action - Marko Lukša</a></li>
</ul>
<p><!-- FIM --></p>