K8S 102 - Dónde estan mis pods?
Hoy vamos a ver los servicios, que nos permiten "encontrar" un conjunto de pods mediante un único acceso!
Qué es un servicio?
Primero lo primero, vamos a citar la fuente oficial
Ahora nuestra definición simplificada, un servicio es una manera estable de acceder a un cierto conjunto de pods. No se entendió nada, no?.
Anteriormente en esta serie de artículos vimos los deployments, donde podíamos decirle la cantidad de replicas que queríamos desplegar. Supongamos que generamos 3 replicas, por lo tanto tenemos 3 pods cada uno con su IP. Como sabemos los pods pueden "morir" por cualquier inconveniente y el deployment va a generar uno nuevo, pero este nuevo pod va a tener OTRA IP!!!.
Este es el problema que viene a solucionar el servicio, se coloca adelante del pod o pods y les brinda un modo estable de acceso para quien necesite utilizar estos pods.
Por lo general para identificar los pods los servicios usan etiquetas (label)
Además de "yapa" los servicios nos dan balanceo de carga para esos pods, y nos permiten poder no solo accederlos desde dentro del cluster sino también desde el mundo exterior!
Tipos de servicios
ClusterIP
Este es el tipo por defecto, lo que hace es simplemente asignarle al servicio una IP interna del cluster. Por lo tanto es solamente utilizado cuando necesitamos un acceso interno de este servicio.
Por ejemplo podemos definirlo de este modo:
apiVersion: v1
kind: Service
metadata:
name: my-backend-service
spec:
type: ClusterIP # Opcion por defecto
selector:
app: backend
clusterIP: 10.10.0.1 # Podemos especificar la ip, o dejar que elija una automaticamente
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
Una imágen vale mas que 1000 palabras :)
NodePort
Expone el servicio en cada nodo en un puerto estático, para poder acceder desde fuera, debemos hacer un request a :. Esta configuración nos expone el puerto en todos los nodos pero para acceder debemos apuntar a uno de ellos lo que no lo hace ideal ya que el nodo podría fallar.
Un ejemplo de configuración
apiVersion: v1
kind: Service
metadata:
name: my-frontend-service
spec:
type: NodePort
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
nodePort: 30000
Dejamos una imágen para visualizar la configuración
LoadBalancer
Expone el servicio externamente usando los load balancers de los proveedores cloud. Es la opción ideal para este tipo de casos. El "inconveniente" que podemos ver es que cada servicio que deseamos exponer necesitará de un load balancer del proveedor, esto puede ser caro. Una opción puede ser el uso de ingress, se los dejo para que lo investiguen! ingress
Ejemplo de configuración de tipo load balancer.
apiVersion: v1
kind: Service
metadata:
name: my-frontend-service
spec:
type: LoadBalancer
selector:
app: web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
Dejamos una imágen para visualizar la configuración
ExternalName
No es el más utilizado pero lo que hace es mapear el servicio con el contenido del campo externalName.
Ejemplo de configuración
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: my.database.example.com
Imágen ilustrativa