En este cuarto capítulo vamos a ver de qué forma configuraremos el cluster y las diferentes opciones que nos proporciona Kubernetes para dar acceso a los servicios alojados.
En principio el grueso de las aplicaciones que se van a desplegar en el cluster caerán en dos grupos, servicios de producción y servicios de desarrollo y pruebas.
Aunque podría ser interesante disponer un cluster únicamente para cada uno de estos dos grupos en este momento por limitaciones todo tiene que funcionar de manera conjunta.
NodePort vs LoadBalancer vs Ingress controller
A la hora de exponer servicios del cluster a redes externas tenemos fundamentalmente los siguientes componentes de Kubernetes que son NodePort, LoadBalancer y controladores Ingress.
NodePort abre un puerto directamente en un nodo para publicar un servicio. El rango de puertos está limitado a 30000-32767 así que no se pueden publicar servicios en los tradiciones 80, 443, etc. Es fácil de desplegar porque no necesita configuración adicional pero poco adecuado para servicios de producción.
LoadBalancer es un servicio que expone los servicios del cluster a través de una única IP lo que facilita mucho su consumo desde el exterior.
Habitualmente lo implementa el proveedor del cluster (AWS, GCP, etc) con un coste adicional. Es un componente que no está incluido por defecto en un cluster Kubernetes porque cada proveedor tiene libertad de implementarlo como quiera.
En el caso de un cluster bare metal como es nuestra instalación es necesario hacer uso de un componente adicional llamado MetalLB.
Ingress controller ayuda a consolidar múltiples aplicaciones en una sola entidad. Habitualmente se monta sobre un LoadBalancer y realiza funciones de rutado a las diferentes aplicaciones así como terminador TLS. Lo trataremos en el siguiente post.
MetalLB al rescate
En un cluster Kubernetes proporcionado por un tercero como AWS, GCP y similares el uso de balanceadores es completamente transparente. En nuestro manifiesto que le pasamos a la API únicamente tenemos que crear un servicio balanceadores y en unos minutos nos resolverá a un flamante IP pública que sirve nuestra aplicación.
Lamentablemente en despliegues de Kubernetes en entornos bare metal o virtualizados on-premises no tenemos esas facilidades y tenemos que trabajar un poco más para poder acceder a estos servicios.
La opción más utilizada en estos casos es MetalLB que añade la capacidad de crear LoadBalancer a nuestro cluster local.
En su configuración más sencilla que es la que utilizaremos aquí únicamente necesitaremos un conjunto de IPs libres en la subred donde esté instalado el cluster.
Instalación
Nosotros haremos la instalación a través de un manifiesto de la siguiente forma:
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
Pasados unos instantes deberíamos tener todo desplegado y funcionando:

El siguiente paso será la configuración de MetalLB.
Configuración
MetalLB admite multitud de opciones de configuración pero la que vamos a utilizar aquí es probablemente la más sencilla.
A grandes rasgos hay dos formas de configuración, utilizando BGP o usando L2. La configuración utilizada aquí será L2.
Con la lista de IPs que puede utilizar MetalLB crearemos un fichero yaml similar a este:
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool01
namespace: metallb-system
spec:
addresses:
- 10.240.217.25/32
- 10.240.217.30/32
- 10.240.217.44/32
- 10.240.217.59/32
- 10.240.217.69/32
- 10.240.217.74/32
- 10.240.217.166/32
- 10.240.217.168/32
- 10.240.217.169/32
- 10.240.217.195/32
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: pool01-l2adv
namespace: metallb-system
En este fichero se incluyen dos bloques, uno es la definición del pool de IPs a utilizar y el otro es el anuncio de las mismas.
Habitualmente utilizaremos un rango de IPs pero en este caso las que nos han asignado no son consecutivas de ahí la máscara de red /32.
Podríamos definir también un rango con el formato x.x.x.x-y.y.y.y.
Una vez aplicado en el cluster esta configuración todo debería estar listo para crear nuestros balanceadores.
Testeando que funciona
Para comprobar que podemos crear balanceadores aplicaremos la siguiente configuración el cluster.
apiVersion: v1
kind: Namespace
metadata:
name: web
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-server
namespace: web
spec:
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: httpd
image: httpd:2.4.53-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-server-service
namespace: web
spec:
selector:
app: web
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
En esta definimos un Namespace, un deployment así como un servicio de tipo LoadBalancer para el mismo.
Consultaremos el servicio con el siguiente comando para ver si se ha asignado un IP externa:

Utilizaremos la IP externa para la llamada con curl de la siguiente forma:

Y comprobamos que el servidor web está levantado y respondiendo en el puerto 80 como hemos configurado.
Búsqueda de IPs libres en una subred
Como añadido a este post voy a detallar la forma que he utilizado para ver las IPs disponibles en una subred que no gestionamos.
Habitualmente esto no es ni recomendable ni es la mejor forma, pero sí es una forma especialmente si no disponemos información de primera mano de los administradores de la red.
Aunque este sistema no es del todo científico nos puede dar una idea si podemos hacer una prueba con un IP libre en las subred en la que esté montado el cluster.
sudo nmap -v -sn -n 192.168.1.0/24 -oG - | awk '/Status: Down/{print $2}'
En nuestro caso hemos utilizado este sistema para poder hacer pruebas con IPs libres mientras nos asignaban las definitivas.
Como he dicho, no es un sistema recomendable pero si lo necesitas para una emergencia ahí está.
Comments