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 :)

image.png

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

image.png

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

image.png

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

image.png