Capítulo 4: Services y Networking
¿Por qué Services?
Los Pods son efímeros: se crean y destruyen. Sus IPs cambian constantemente. Un Service da una IP estable y balancea tráfico entre los Pods.
Tipos de Service
| Tipo | Acceso | Uso |
|---|---|---|
| ClusterIP | Solo dentro del cluster | Comunicación entre servicios |
| NodePort | Puerto en cada nodo | Acceso externo en desarrollo |
| LoadBalancer | IP externa (cloud) | Producción en cloud |
Crear el Service
Crear k8s/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: fastapi-service
namespace: dev
spec:
type: ClusterIP
selector:
app: fastapi-app
ports:
- port: 80
targetPort: 8000
protocol: TCP
El selector: app: fastapi-app conecta el Service con los Pods del Deployment.
Aplicar y verificar
kubectl apply -f k8s/service.yaml
# Ver services
kubectl get services -n dev
# NAME TYPE CLUSTER-IP PORT(S) AGE
# fastapi-service ClusterIP 10.43.12.34 80/TCP 10s
# Ver endpoints (pods conectados)
kubectl get endpoints fastapi-service -n dev
Acceder con port-forward
Para desarrollo, port-forward es la forma más rápida de acceder:
# Forward del service al puerto local
kubectl port-forward service/fastapi-service 8000:80 -n dev
# Ahora accedé desde tu máquina
curl http://localhost:8000/
curl http://localhost:8000/items/42
También podés hacer forward directo a un Pod:
kubectl port-forward pod/<nombre-pod> 8000:8000 -n dev
NodePort para acceso externo
Para exponer en un puerto del nodo (útil en desarrollo):
apiVersion: v1
kind: Service
metadata:
name: fastapi-nodeport
namespace: dev
spec:
type: NodePort
selector:
app: fastapi-app
ports:
- port: 80
targetPort: 8000
nodePort: 30080
kubectl apply -f k8s/service-nodeport.yaml
# Acceder via IP del nodo
curl http://<node-ip>:30080/
# En minikube
minikube service fastapi-nodeport -n dev --url
DNS interno
Dentro del cluster, los Services se resuelven por nombre:
<service>.<namespace>.svc.cluster.local
Ejemplo: otro pod puede llamar a tu FastAPI así:
curl http://fastapi-service.dev.svc.cluster.local/health
# O simplemente (si está en el mismo namespace):
curl http://fastapi-service/health
Diagnosticar conectividad
# Ver si el service tiene endpoints
kubectl get endpoints fastapi-service -n dev
# Si ENDPOINTS está vacío, el selector no matchea ningún pod
# Probar DNS desde un pod
kubectl run debug --rm -it --image=busybox -n dev -- nslookup fastapi-service
# Probar conectividad
kubectl run debug --rm -it --image=curlimages/curl -n dev -- curl fastapi-service/health
Problemas comunes
Service sin endpoints:
- Verificar que los labels del Pod coinciden con el selector del Service
kubectl get pods --show-labels -n dev
Connection refused:
- La app no escucha en
0.0.0.0(solo en127.0.0.1) - El
targetPortno coincide con el puerto del container
Timeout:
- NetworkPolicy bloqueando tráfico
- Pod en estado no-Ready
En el siguiente capítulo, configuramos la app con ConfigMaps y Secrets.