Servicios en Kubernetes
Los servicios en Kubernetes son un recurso fundamental para exponer aplicaciones, agrupar pods y gestionar el acceso a los recursos dentro y fuera del clúster. Dado que los pods son efímeros y sus IPs pueden cambiar constantemente, los servicios proporcionan una IP estable (y DNS) y balancean las peticiones entre los pods asociados.
Dentro vídeo: https://youtu.be/LIramFKvf3E
Resumen: El Service actúa como una puerta de entrada estable, y los endpoints son la lista dinámica de pods a los que realmente se dirige el tráfico.
Comparativa rápida de tipos de servicios en Kubernetes
Tipo | Accesible desde | Exposición externa | Uso típico |
---|---|---|---|
ClusterIP | Dentro del clúster | No | Comunicación interna entre pods |
NodePort | Dentro y fuera (IP nodo) | Sí (puerto del nodo) | Acceso externo sencillo, pruebas |
LoadBalancer | Dentro y fuera | Sí (IP pública) | Exposición pública en cloud |
ExternalName | Dentro del clúster | No (redirige DNS) | Redirigir a servicios externos por DNS |
Diagrama visual de un servicio trabajando en conjunto con un deployment
Tipos de servicios en Kubernetes
ClusterIP (por defecto)
- Es el tipo de servicio por defecto.
- Crea una IP interna accesible solo dentro del clúster.
- Balancea el tráfico entre los pods seleccionados mediante endpoints.
- No es accesible desde fuera del clúster.
Ejemplo YAML:
apiVersion: v1
kind: Service
metadata:
name: mi-servicio-clusterip
spec:
selector:
app: mi-app
ports:
- port: 8080
targetPort: 80
type: ClusterIP
Ya hemos visto lo sencillo que es definir estos objetos y exponer nuestras aplicaciones. Pero, ¿cómo sabe el service a que pods debe redirigir el tráfico?
Esto es posible gracias a los selectores
y los endpoints
. Los selectores
simplemente definen qué pods deben ser parte del servicio, basándose en etiquetas (labels) que se asignan a los pods. Recordad el apartado de conceptos básicos y la importancia de las etiquetas en Kubernetes.
Los endpoints
por otra parte, son un objeto que mantiene una lista actualizada de las IPs de los pods que cumplen con el selector del servicio. Así, el Service puede redirigir el tráfico a los pods correctos, incluso si estos cambian de IP o se reemplazan. Recordemos que cada pods tiene una IP única asignada por el clúster, y los pods pueden ser efímeros, es decir, pueden aparecer y desaparecer con frecuencia.
Endpoints
Este objeto mantiene una lista actualizada de las IPs de los pods que cumplen con el selector del servicio. Así, el Service puede redirigir el tráfico a los pods correctos. Se crean automáticamente cuando se crea un Service y normalmente no es necesario interactuar directamente con ellos.
Aun así, por fines educativos, podemos ver cómo funcionan. Para ver los endpoints podemos utilizar los siguientes comandos:
kubectl get endpoints
kubectl get ep <nombre-servicio>
Esto nos mostrará un listado de los endpoints asociados a cada servicio, mostrando las IPs de los pods que están siendo balanceados por el servicio.
NodePort
- Expone el servicio fuera del clúster a través de un puerto del nodo (rango 30000-32767).
- Permite acceder al servicio usando la IP del nodo y el puerto asignado.
- Internamente sigue balanceando entre los endpoints de los pods.
- Útil para pruebas o acceso sencillo desde fuera del clúster.
Ejemplo YAML:
apiVersion: v1
kind: Service
metadata:
name: mi-servicio-nodeport
spec:
selector:
app: mi-app
ports:
- port: 8080
targetPort: 80
nodePort: 30080 # Opcional, si no se indica se asigna automáticamente
type: NodePort
LoadBalancer
- Crea un balanceador de carga externo (en cloud providers compatibles) y asigna una IP pública.
- El balanceador dirige el tráfico al NodePort, que a su vez lo distribuye entre los endpoints de los pods.
- Ideal para exponer servicios a Internet de forma sencilla.
Ejemplo YAML:
apiVersion: v1
kind: Service
metadata:
name: mi-servicio-loadbalancer
spec:
selector:
app: mi-app
ports:
- port: 80
targetPort: 80
type: LoadBalancer
ExternalName
- No crea un proxy ni IP propia.
- Mapea el nombre del servicio a un DNS externo.
- Útil para redirigir tráfico a servicios fuera del clúster (por ejemplo, una base de datos gestionada).
Ejemplo YAML:
apiVersion: v1
kind: Service
metadata:
name: mi-servicio-externalname
spec:
type: ExternalName
externalName: ejemplo.com
Nota: Ingress no es un tipo de Service, sino un recurso que permite gestionar el acceso externo (HTTP/HTTPS) a los servicios del clúster mediante reglas de enrutamiento. Suele trabajar junto a servicios de tipo ClusterIP o NodePort.
Casos de uso recomendados
- ClusterIP: Comunicación interna entre microservicios.
- NodePort: Pruebas locales, acceso sencillo desde fuera del clúster sin balanceador externo.
- LoadBalancer: Exposición pública de aplicaciones en cloud.
- ExternalName: Integración con servicios externos vía DNS.
Caso práctico exponiendo una aplicación web
Para concluir esta sección, vamos a exponer una aplicación web sencilla utilizando un Service de tipo NodePort.
apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # Puerto accesible desde fuera del clúster
type: NodePort
Ahora podremos acceder a la aplicación web desde cualquier nodo del clúster usando la IP del nodo y el puerto 30080. Podemos probarlo con:
curl http://<IP_DEL_NODO>:30080
Conclusiones e relación con Ingress
Los servicios son esenciales para exponer aplicaciones y repartir el tráfico entre los pods.
En un caso real, estos servicios se combinarían con un Ingress Controller para gestionar el acceso externo de forma más avanzada, permitiendo enrutar tráfico HTTP/HTTPS a diferentes servicios según dominios o rutas.
Esto lo veremos en la siguiente sección, Ingress Controller.
- Lista de vídeos en Youtube: Curso Kubernetes