Los pods nacen y mueren con IPs diferentes. Ningún cliente serio va a seguir eso. El Service da un nombre y una IP estable; el Ingress da una puerta de entrada HTTP(S); el DNS resuelve nombres; el TLS protege el camino.
\n\n\nSello del curso: testado en Kubernetes 1.35, ingress-nginx y cert-manager.
\n
Service: el nombre estable
\nUn Service selecciona pods por label y balancea el tráfico.
\napiVersion: v1\nkind: Service\nmetadata:\n name: api\n namespace: portal\nspec:\n selector:\n app: api\n ports:\n - port: 80\n targetPort: 8080\n type: ClusterIP\n\n
Tipos:
\n| Tipo | \nAcceso | \nUso | \n
|---|---|---|
| ClusterIP | \ninterno | \npor defecto; app → app | \n
| NodePort | \npuerto en cada nodo | \nlaboratorio, acceso directo | \n
| LoadBalancer | \nIP externa | \nnube con LB | \n
| ExternalName | \nCNAME | \napuntar a servicio externo | \n
Headless (clusterIP: None) | \n
DNS por pod | \nStatefulSet | \n
Verifique si el Service encontró los pods:
\nkubectl -n portal get endpoints api\nkubectl -n portal get endpointslices\n\n
Si ENDPOINTS está vacío, el selector no coincidió con ningún pod o los pods no están Ready. Este es el error nº 1 de Service.
DNS
\nEl CoreDNS resuelve nombres dentro del clúster:
\napi.portal.svc.cluster.local\n\n
Dentro del mismo namespace, api ya resuelve. Entre namespaces, use api.portal o el FQDN completo.
kubectl -n portal run dns --image=busybox:1.36 --rm -it --restart=Never -- \\\n nslookup api.portal\n\n
Cuidado con ndots y search domains: los nombres parciales pueden intentarse en varios sufijos antes de resolver. En aplicaciones sensibles a la latencia, use el FQDN.
NodePort y LoadBalancer
\nNodePort abre un puerto (30000–32767) en todos los nodos:
\nspec:\n type: NodePort\n ports:\n - port: 80\n targetPort: 8080\n nodePort: 30080\n\n
Es útil para laboratorio, pero malo para producción: expone puertos, no hace TLS y depende de la IP del nodo. En cloud, LoadBalancer aprovisiona un LB; en bare-metal, necesita MetalLB o equivalente.
Ingress: la puerta HTTP
\nIngress es una regla L7: host + path → Service.
\napiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n name: portal\n namespace: portal\nspec:\n ingressClassName: nginx\n rules:\n - host: portal.exemplo.com\n http:\n paths:\n - path: /\n pathType: Prefix\n backend:\n service:\n name: frontend\n port:\n number: 80\n - path: /api\n pathType: Prefix\n backend:\n service:\n name: api\n port:\n number: 80\n\n
Requisitos:
\n-
\n
- Un Ingress Controller instalado (ingress-nginx, Traefik, etc.). \n
ingressClassNamecorrecto. \n
- DNS del host apuntando al controller. \n
- Service con endpoints saludables. \n
Pruebe localmente con --resolve:
curl -k --resolve portal.exemplo.com:443:127.0.0.1 https://portal.exemplo.com/\n\n
TLS con cert-manager
\nEl cert-manager emite y renueva certificados. Un ClusterIssuer para Let's Encrypt:
apiVersion: cert-manager.io/v1\nkind: ClusterIssuer\nmetadata:\n name: letsencrypt-prod\nspec:\n acme:\n server: https://acme-v02.api.letsencrypt.org/directory\n email: [email protected]\n privateKeySecretRef:\n name: letsencrypt-prod\n solvers:\n - http01:\n ingress:\n class: nginx\n\n
En el Ingress:
\nmetadata:\n annotations:\n cert-manager.io/cluster-issuer: letsencrypt-prod\nspec:\n tls:\n - hosts:\n - portal.exemplo.com\n secretName: portal-tls\n\n
Siga:
\nkubectl -n portal get certificate,order,challenge\nkubectl -n portal describe certificate portal-tls\n\n
Use el staging de Let's Encrypt en las pruebas: el de producción tiene rate limit y va a toparse con él.
\nLaboratorio
\n-
\n
- Suba un Deployment y un Service ClusterIP. \n
- Pruebe con
port-forward. \n
- Cree un Ingress con host ficticio y pruebe con
--resolve. \n
- Emita un certificado (staging) y verifique el secret TLS. \n
- Fuerce HTTP → HTTPS con una annotation del ingress-nginx. \n
Errores comunes
\n| Síntoma | \nCausa | \n
|---|---|
| Service sin endpoints | \nselector incorrecto o pods no Ready | \n
| 404 en el Ingress | \nhost/path no coinciden o class incorrecta | \n
| 502/503 | \nService sin endpoints o app fuera de servicio | \n
| Certificado no emitido | \nDNS no apunta, challenge bloqueado o rate limit | \n
default backend - 404 | \n
Ingress no encontrado en el controller | \n
| DNS no resuelve | \nCoreDNS roto o namespace incorrecto | \n
Checklist
\n-
\n
- [ ] Service con selector y endpoints correctos. \n
- [ ] Sé la diferencia entre ClusterIP, NodePort e Ingress. \n
- [ ] Ingress con
ingressClassNamey DNS apuntando. \n
- [ ] TLS emitido y renovando. \n
- [ ] Probé HTTP → HTTPS. \n
- [ ] No expuse NodePort innecesariamente. \n
Glosario
\n-
\n
- ClusterIP: IP virtual interna del Service. \n
- EndpointSlice: lista de pods listos detrás del Service. \n
- Ingress: regla L7 de entrada. \n
- Ingress Controller: implementación que aplica el Ingress. \n
- ACME: protocolo de Let's Encrypt. \n
- ClusterIssuer: emisor de certificados para todo el clúster. \n
Próximo
\nAhora que la aplicación está accesible, vamos al capítulo más útil del curso: qué hacer cuando el pod no arranca.
\nPróximo: Curso Kubernetes 10 — El primer “no arrancó”: diagnosticando pods
Seguir leyendo
Lea también
TutoriaisManual LSI / Broadcom MegaRAID — MegaCli y StorCLI
Con esta guía, su equipo gana autonomía para diagnosticar rebuilds, resolver foreign configurations, gestionar BBU y CacheCade — con escenarios reales de producción documentados.
20 min de leitura
Nginx Cheatsheet
Guía de bolsillo con ejemplos listos para configurar Nginx en producción: desde instalación y virtual hosts hasta ajuste de rendimiento y resolución de problemas.
12 min de leitura
KubernetesCurso Kubernetes 27 — SLO/SLI, on-call y postmortem sin culpa
Qué prometer, cómo medir y qué hacer cuando el error se dispara: SLI, SLO, presupuesto de error, alertas que despiertan a alguien y postmortem sin caza de brujas.
5 min de leitura
Comentarios
Aún sin comentarios
Sea el primero en compartir su opinión sobre este artículo.

Deje un comentario