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

Использование Ingress для доступа к RabbitMQ на кластере Microk8s

По сравнению с Nodeport, Ingress Controller создает больше сложностей, но при этом обеспечивает большую гибкость.

20 ноября 2024
post main image
https://www.pexels.com/@cup-of-couple

Некоторое время назад я сделал пост о переносе части приложения, содержащего RabbitMQ , работающего на Docker Swarm , на Microk8s. Мы использовали NodePort для доступа к кластеру Kubernetes RabbitMQ на хосте.

Недавно я пересмотрел это и решил использовать Microk8s Ingress Controller для доступа к RabbitMQ.
В этом посте мы предполагаем наличие подкластера RabbitMQ и сосредоточимся только на запуске Ingress Controller .

Ниже, 'kubectl' означает 'microk8s kubectl'.

Как обычно, я делаю это на Ubuntu 22.04.

Внимание: Конфигурация Ingress Controller по умолчанию конфликтует с приложениями, уже использующими порты 80 и 443.

Microk8s Ingress Controller основан на Nginx и по умолчанию включает порты 80 и 443. Если в вашей системе уже запущено другое приложение, использующее эти порты, например Nginx, то при включении Ingress Controller у вас возникнут проблемы.
В моем случае существующий сервер Nginx перестал работать... :-(

Чтобы избежать этого, перед включением Ingress Controller измените его порты на не очень используемые:

80  -> 9480
443 -> 9483

Мы делаем это, изменяя секцию портов в файле:

/var/snap/microk8s/common/addons/core/addons/ingress/ingress.yaml

Вот как это выглядит после редактирования:

        ports:
        - name: http
          containerPort: 80
          #hostPort: 80
          hostPort: 9480
        - name: https
          containerPort: 443
          #hostPort: 443
          hostPort: 9483
        - name: health
          containerPort: 10254
          hostPort: 10254

Включение и отключение Microk8s Ingress Controller

Теперь мы можем спокойно включить Ingress Controller:

microk8s enable ingress

Результат:

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

Чтобы отключить Ingress Controller позже, мы используем:

microk8s disable ingress

Чтобы проверить, запущен ли подкад Ingress Controller :

kubectl -n ingress get pod

Результат:

NAME                                      READY   STATUS    RESTARTS   AGE
nginx-ingress-microk8s-controller-fmqc7   1/1     Running   0          177m

Мы можем проверить журналы:

kubectl -n ingress logs nginx-ingress-microk8s-controller-74pns

Результат:

-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:       v1.8.0
  Build:         35f5082ee7f211555aaff431d7c4423c17f8ce9e
  Repository:    https://github.com/kubernetes/ingress-nginx
  nginx version: nginx/1.21.6

-------------------------------------------------------------------------------
....

Проверьте, что Ingress прослушивает указанный нами порт:

wget 127.0.0.1:9480

Результат:

--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.

Выглядит хорошо, он отвечает! Как видите, Microk8s Ingress Contreoller основан на веб-сервере Nginx .

Подключение Ingress к RabbitMQ в кластере Microk8s

Чтобы добиться этого, нам нужно сделать следующее:

  1. Отредактируйте Ingress Controller daemonset
  2. Отредактируйте Ingress Controller TCP config map
  3. Создайте файл Ingress YAML : 'rabbitmq-ingress.yaml'

Важно:

  • Имя службы RabbitMQ - 'rabbitmq-service', порт - 5672.
  • RabbitMQ находится в пространстве имен по умолчанию. Измените его, если вы используете другое пространство имен.

1. Отредактируйте Ingress Controller daemonset.

Здесь мы добавляем containerPort, 5672, и hostPort, 9493. Чтобы отредактировать daemonset нашего Ingress Controller:

kubectl -n ingress edit daemonset nginx-ingress-microk8s-controller

Раздел "Порты" перед редактированием:

        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

Отредактируйте так, чтобы это выглядело следующим образом. Остальные порты мы оставим как есть:

        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

Сохраните и выйдите.

2. Отредактируйте порт Ingress Controller TCP config map.

Здесь мы маршрутизируем внешний TCP/UDP-трафик от не-HTTP-протоколов к внутренним службам с помощью сопоставления TCP/UDP-портов.

Чтобы получить все config maps из Ingress Controller:

kubectl -n ingress get configmap

Результат:

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

Чтобы отредактировать TCP config map:

kubectl -n ingress edit configmaps nginx-ingress-tcp-microk8s-conf

Добавьте следующие строки:

data:
  5672: "default/rabbitmq-service:5672"

Проверьте, что это было сделано:

kubectl -n ingress get configmap nginx-ingress-tcp-microk8s-conf -o yaml

Результат:

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. Создание файла Ingress YAML

Наконец, мы создаем следующий файл 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

Развертывание Ingress Controller

После выполнения описанных выше шагов мы можем развернуть Ingress Controller:

kubectl apply -f rabbitmq-ingress.yaml

Результат:

ingress.networking.k8s.io/rabbitmq-ingress created

Проверьте дополнительную информацию:

kubectl describe ingress rabbitmq-ingress

Результат:

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>

Проверьте, соответствует ли служба IP address службе RabbitMQ !

Если впоследствии вы захотите удалить Ingress Controller:

kubectl delete ingress rabbitmq-ingress

Тест на хосте с Pika

Этот блог посвящен Python, поэтому здесь мы используем пакет Pika для создания простой тестовой программы.

# 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()

Множество Ingress Controllers

Вы можете захотеть добавить еще один маршрут между хостом и кластером. Также можно использовать несколько Ingress Controllers.

Резюме

У меня все работает без особых проблем. Если вы посмотрите на IP address выше, то заметите, что это IP address из подгруппы RabbitMQ . Похоже, что Ingress Controller подключается к стручку RabbitMQ , а не к службе RabbitMQ !
Похоже, что это правильно (?). Хммм... рассмотрим это позже...

Ссылки / кредиты

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

Подробнее

Kubernetes Microk8s

Оставить комментарий

Комментируйте анонимно или войдите в систему, чтобы прокомментировать.

Комментарии

Оставьте ответ

Ответьте анонимно или войдите в систему, чтобы ответить.