angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

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.

20 noviembre 2024
post main image
https://www.pexels.com/@cup-of-couple

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:

  1. Editar el Ingress Controller daemonset
  2. Editar el Ingress Controller TCP config map
  3. 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

Deje un comentario

Comente de forma anónima o inicie sesión para comentar.

Comentarios

Deje una respuesta.

Responda de forma anónima o inicie sesión para responder.