Uso de Ingress para acceder a RabbitMQ en un clúster Microk8s
En comparación con un Nodeport, un Ingress Controller añade más complejidad pero también proporciona más flexibilidad.

Hace algún tiempo hice un post sobre mover parte de una aplicación que contenía RabbitMQ corriendo en Docker Swarm a Microk8s. Utilizamos NodePort para acceder al clúster Kubernetes RabbitMQ en el host.
Recientemente me he replanteado esto y he decidido utilizar el Microk8s Ingress Controller para acceder al RabbitMQ.
En este post, asumimos que el pod RabbitMQ está presente y sólo nos centraremos en poner en marcha el Ingress Controller .
A continuación, 'kubectl' representa 'microk8s kubectl'.
Como siempre, hago esto en Ubuntu 22.04.
Atención: La configuración por defecto de Ingress Controller entra en conflicto con las aplicaciones que ya utilizan los puertos 80 y 443
El Microk8s Ingress Controller está basado en Nginx y habilita los puertos 80 y 443 por defecto. Si ya tiene otra aplicación ejecutándose en su sistema que utiliza estos puertos, como Nginx, entonces tendrá un problema cuando habilite Ingress Controller.
En mi caso, mi servidor Nginx existente dejó de funcionar... :-(
Para evitar esto, cambia los puertos del Ingress Controller a puertos poco usados ANTES de habilitarlo:
80 -> 9480
443 -> 9483
Esto lo hacemos modificando la sección de puertos en el fichero:
/var/snap/microk8s/common/addons/core/addons/ingress/ingress.yaml
Esto es lo que parece después de la edición:
ports:
- name: http
containerPort: 80
#hostPort: 80
hostPort: 9480
- name: https
containerPort: 443
#hostPort: 443
hostPort: 9483
- name: health
containerPort: 10254
hostPort: 10254
Habilitando y deshabilitando el Microk8s Ingress Controller
Ahora podemos habilitar con seguridad el Ingress Controller:
microk8s enable ingress
Resultado:
Infer repository core for addon ingress
Enabling Ingress
ingressclass.networking.k8s.io/public created
ingressclass.networking.k8s.io/nginx created
namespace/ingress created
serviceaccount/nginx-ingress-microk8s-serviceaccount created
clusterrole.rbac.authorization.k8s.io/nginx-ingress-microk8s-clusterrole created
role.rbac.authorization.k8s.io/nginx-ingress-microk8s-role created
clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-microk8s created
rolebinding.rbac.authorization.k8s.io/nginx-ingress-microk8s created
configmap/nginx-load-balancer-microk8s-conf created
configmap/nginx-ingress-tcp-microk8s-conf created
configmap/nginx-ingress-udp-microk8s-conf created
daemonset.apps/nginx-ingress-microk8s-controller created
Ingress is enabled
Para desactivar el Ingress Controller más tarde, utilizamos:
microk8s disable ingress
Para comprobar si el pod Ingress Controller se está ejecutando:
kubectl -n ingress get pod
Resultado:
NAME READY STATUS RESTARTS AGE
nginx-ingress-microk8s-controller-fmqc7 1/1 Running 0 177m
Podemos comprobar los logs:
kubectl -n ingress logs nginx-ingress-microk8s-controller-74pns
Resultado:
-------------------------------------------------------------------------------
NGINX Ingress controller
Release: v1.8.0
Build: 35f5082ee7f211555aaff431d7c4423c17f8ce9e
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.21.6
-------------------------------------------------------------------------------
....
Comprobar que Ingress está escuchando en el puerto que hemos especificado:
wget 127.0.0.1:9480
Resultado:
--2024-11-17 19:41:48-- http://127.0.0.1:9480/
Connecting to 127.0.0.1:9480... connected.
HTTP request sent, awaiting response... 404 Not Found
2024-11-17 19:41:48 ERROR 404: Not Found.
Tiene buena pinta, ¡está respondiendo! Como puedes ver, el Microk8s Ingress Contreoller está basado en el servidor web Nginx .
Conexión de Ingress a RabbitMQ en el clúster Microk8s
Para ello, debemos hacer lo siguiente:
- Editar el Ingress Controller daemonset
- Editar el Ingress Controller TCP config map
- Crear un archivo Ingress YAML : 'rabbitmq-ingress.yaml'
Importante:
- El nombre del servicio RabbitMQ es 'rabbitmq-service', el puerto es 5672.
- RabbitMQ está en el espacio de nombres por defecto. Cámbielo si utiliza otro espacio de nombres.
1. Edite el Ingress Controller daemonset
Aquí añadimos un containerPort, 5672, y un hostPort, 9493. Para editar el daemonset de nuestro Ingress Controller:
kubectl -n ingress edit daemonset nginx-ingress-microk8s-controller
La sección 'puertos' antes de la edición:
ports:
- containerPort: 80
hostPort: 9480
name: http
protocol: TCP
- containerPort: 443
hostPort: 9483
name: https
protocol: TCP
- containerPort: 10254
hostPort: 10254
name: health
protocol: TCP
Editar para que se vea así. Dejaremos los otros puertos como están:
ports:
- containerPort: 80
hostPort: 9480
name: http
protocol: TCP
- containerPort: 443
hostPort: 9483
name: https
protocol: TCP
- containerPort: 5672
hostPort: 9493
name: rabbitmq5672
protocol: TCP
- containerPort: 10254
hostPort: 10254
name: health
protocol: TCP
Guardar y salir.
2. Edita el Ingress Controller TCP config map
Aquí enrutamos el tráfico externo TCP/UDP de protocolos no HTTP a servicios internos utilizando mapeos de puertos TCP/UDP.
Para obtener todos los config maps de los Ingress Controller:
kubectl -n ingress get configmap
Resultado:
NAME DATA AGE
kube-root-ca.crt 1 3h56m
nginx-ingress-tcp-microk8s-conf 0 3h56m
nginx-ingress-udp-microk8s-conf 0 3h56m
nginx-load-balancer-microk8s-conf 0 3h56m
Para editar el TCP config map:
kubectl -n ingress edit configmaps nginx-ingress-tcp-microk8s-conf
Añada las siguientes líneas:
data:
5672: "default/rabbitmq-service:5672"
Comprobar que se ha hecho:
kubectl -n ingress get configmap nginx-ingress-tcp-microk8s-conf -o yaml
Resultado:
apiVersion: v1
data:
"5672": default/rabbitmq-service:5672
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ConfigMap","metadata":{"annotations":{},"name":"nginx-ingress-tcp-microk8s-conf","namespace":"ingress"}}
creationTimestamp: "2024-11-17T18:26:14Z"
name: nginx-ingress-tcp-microk8s-conf
namespace: ingress
resourceVersion: "9071777"
uid: c8495fca-7753-4b60-9542-dcb9879ab4d0
3. Crear un archivo Ingress YAML
Por último, creamos el siguiente archivo YAML 'rabbitmq-ingress.yaml':
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rabbitmq-ingress
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rabbitmq-service
port:
number: 5672
Despliegue del Ingress Controller
Después de completar los pasos anteriores, podemos desplegar el Ingress Controller:
kubectl apply -f rabbitmq-ingress.yaml
Resultado:
ingress.networking.k8s.io/rabbitmq-ingress created
Comprobar más información:
kubectl describe ingress rabbitmq-ingress
Resultado:
Name: rabbitmq-ingress
Labels: <none>
Namespace: default
Address: 127.0.0.1
Ingress Class: public
Default backend: <default>
Rules:
Host Path Backends
---- ---- --------
*
/ rabbitmq-service:5672 (10.1.105.102:5672)
Annotations: <none>
Events: <none>
Comprueba si el IP address coincide con el servicio RabbitMQ .
Si más adelante desea eliminar el Ingress Controller:
kubectl delete ingress rabbitmq-ingress
Prueba en el host con Pika
Este blog trata sobre Python, así que aquí utilizaremos el paquete Pika para crear un sencillo programa de prueba.
# rabbitmq_test.py
import logging
import sys
import pika
logging.basicConfig(
format='%(asctime)s %(levelname)8s [%(filename)-10s%(funcName)20s():%(lineno)04s] %(message)s',
#level=logging.DEBUG,
level=logging.INFO,
)
logger = logging.getLogger(__name__)
RABBITMQ_HOST = '127.0.0.1'
RABBITMQ_PORT = 9493
RABBITMQ_USER = '<your-user>'
RABBITMQ_PASSWORD = '<your-password>'
def main():
url_items = [
'amqp://',
f'{RABBITMQ_USER}:{RABBITMQ_PASSWORD}',
'@',
f'{RABBITMQ_HOST}:{str(RABBITMQ_PORT)}',
'/%2F',
]
url = ''.join(url_items)
logger.info(f'url = {url}')
parameters = pika.URLParameters(url)
logger.info(f'url = {url}')
logger.info(f'parameters = {parameters}')
try:
connection = pika.BlockingConnection(parameters)
logger.info(f'connection = {connection}')
except Exception as e:
logger.exception(f'connection error')
raise
logger.info(f'connected')
channel = connection.channel()
queue = 'test_queue'
channel.queue_declare(queue=queue)
logger.info(f'publishing ...')
try:
channel.basic_publish(
exchange='test_exchange',
routing_key=queue,
body='test_message',
properties=pika.BasicProperties(
content_type='text/plain',
delivery_mode=pika.DeliveryMode.Transient
),
)
except Exception as e:
logger.exception(f'publish error')
raise
logger.info(f'publish ready')
if __name__ == '__main__':
main()
Múltiples Ingress Controllers
Es posible que desee añadir otra ruta entre el host y el clúster. También es posible utilizar múltiples Ingress Controllers.
Resumen
Conseguí que esto funcionara sin mucha dificultad. Si comprueba el IP address anterior, observará que se trata del IP address del pod RabbitMQ . Parece que el Ingress Controller se está conectando al pod RabbitMQ , ¡no al servicio RabbitMQ !
Parece que es correcto (?). Hmmm ... voy a mirar en esto más tarde ...
Enlaces / créditos
Does an ingress talk to pods directly or its through a service?
https://stackoverflow.com/questions/71955811/does-an-ingress-talk-to-pods-directly-or-its-through-a-service
Exposing Redis with Ingress Nginx Controller
https://stackoverflow.com/questions/62939846/exposing-redis-with-ingress-nginx-controller
How to expose Kubernetes-hosted RabbitMQ to the outside?
https://stackoverflow.com/questions/63334992/how-to-expose-kubernetes-hosted-rabbitmq-to-the-outside
How to Set up Kubernetes Ingress with MicroK8s
https://phoenixnap.com/kb/microk8s-ingress
Issue with exposing rabbitmq port 5671
https://discuss.kubernetes.io/t/issue-with-exposing-rabbitmq-port-5671/15883
Kubernetes - Ingress-Nginx Controller
https://kubernetes.github.io/ingress-nginx
Kubernetes: microk8s with multiple metalLB endpoints and nginx ingress controllers
https://fabianlee.org/2021/07/29/kubernetes-microk8s-with-multiple-metallb-endpoints-and-nginx-ingress-controllers
Microk8s - Addon: Ingress
https://microk8s.io/docs/ingress
Minikube - Ingress nginx for TCP and UDP services
https://minikube.sigs.k8s.io/docs/tutorials/nginx_tcp_udp_ingress
Leer más
Kubernetes Microk8s
Recientes
- Gráfico de series temporales con Flask, Bootstrap y Chart.js
- Utilización de IPv6 con Microk8s
- Uso de Ingress para acceder a RabbitMQ en un clúster Microk8s
- Galería de vídeo simple con Flask, Jinja, Bootstrap y JQuery
- Programación básica de trabajos con APScheduler
- Un conmutador de base de datos con HAProxy y el HAProxy Runtime API
Más vistos
- Usando PyInstaller y Cython para crear un ejecutable de Python
- Usando Python's pyOpenSSL para verificar los certificados SSL descargados de un host
- Conectarse a un servicio en un host Docker desde un contenedor Docker
- Usando UUIDs en lugar de Integer Autoincrement Primary Keys con SQLAlchemy y MariaDb
- Programación básica de trabajos con APScheduler
- SQLAlchemy: Uso de Cascade Deletes para eliminar objetos relacionados