Использование Ingress для доступа к RabbitMQ на кластере Microk8s
По сравнению с Nodeport, Ingress Controller создает больше сложностей, но при этом обеспечивает большую гибкость.
Некоторое время назад я сделал пост о переносе части приложения, содержащего 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
Чтобы добиться этого, нам нужно сделать следующее:
- Отредактируйте Ingress Controller daemonset
- Отредактируйте Ingress Controller TCP config map
- Создайте файл 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
Недавний
- График временного ряда с Flask, Bootstrap и Chart.js
- Использование IPv6 с Microk8s
- Использование Ingress для доступа к RabbitMQ на кластере Microk8s
- Простая видеогалерея с Flask, Jinja, Bootstrap и JQuery
- Базовое планирование заданий с помощью APScheduler
- Коммутатор базы данных с HAProxy и HAProxy Runtime API
Большинство просмотренных
- Использование PyInstaller и Cython для создания исполняемого файла Python
- Уменьшение времени отклика на запросы на странице Flask SQLAlchemy веб-сайта
- Используя Python pyOpenSSL для проверки SSL-сертификатов, загруженных с хоста
- Подключение к службе на хосте Docker из контейнера Docker
- Использование UUID вместо Integer Autoincrement Primary Keys с SQLAlchemy и MariaDb
- SQLAlchemy: Использование Cascade Deletes для удаления связанных объектов