如何将Kubernetes托管的RabbitMQ暴露给外部?

问题描述 投票:0回答:2

我们使用安装了 HAProxy Ingress 的 kubernetes 集群。我们希望将 RabbitMQ 暴露在 kubernetes 集群之外。这怎么可能?

需求:这是一个基于OpenShift的共享k8s集群,暴露服务的唯一方法是使用入口。

  1. 管理-UI提供基本的REST端点,不应用于大量数据
  2. STOMP-Websockets 看起来真的没有维护。不仅是协议,还有客户端库
  3. MQTT-Websockets 看起来不像 STOMP 那么糟糕,但也不太面向未来
  4. 自己的 REST 服务可能需要大量工作
  5. AMQP 无法通过 HAProxy 公开

我无法想象我们是第一个需要连接到 Kubernetes 托管的 RabbitMQ 的人?!?

客户端需要基于.net

c# .net kubernetes rabbitmq
2个回答
2
投票

只需为要在集群外部公开的每个组件定义一个

Service
类型
NodePort
即可。

默认情况下,您必须将组件的端口“映射”到 [32000-32767] 范围内的端口,并且您将能够使用这些端口访问您的组件

基本上,NodePort 服务将使集群的每个节点侦听该服务的端口,并将流量路由到正确端口上的正确 Pod。对于入口/路由没有协议限制。

k8s服务

节点端口上的 OCP 文档

[已更新]
这根本不能回答问题,因为要求“公开服务的唯一方法是使用入口。


0
投票

我研究了 Traefik 和 NGINX 的 RabbitMQ 外部访问用例。对于 RabbitMQ,NGINX Ingress 最终成为我通过 TCP 公开 AMQP 协议的更简单选择。它也是 minikube 的默认入口提供程序(如果启用它),这很有用。如果有人有类似的 Traefik 示例,我会对它感兴趣。

请注意,没有什么可以阻止您在集群上出于不同目的/用例使用多个入口控制器。

设置

启动集群(如果使用 minikube)-

minikube delete && minikube start --kubernetes-version=v1.23.0 --memory=4g --bootstrapper=kubeadm --extra-config=kubelet.authentication-token-webhook=true --extra-config=kubelet.authorization-mode=Webhook --extra-config=scheduler.bind-address=0.0.0.0 --extra-config=controller-manager.bind-address=0.0.0.0 --extra-config=etcd.listen-metrics-urls=http://0.0.0.0:2381 --driver=docker

有了kubernetes集群之后,我们还需要一个rabbitmq集群。我正在使用rabbitmq运算符来配置-

安装最新的 RabbitMQ Operator(如有必要)

kubectl apply -f "https://github.com/rabbitmq/cluster-operator/releases/latest/download/cluster-operator.yml"

等待操作员准备好

watch kubectl get pods -n rabbitmq-system

rabbitmq 测试集群的命名空间

kubectl create ns test-rabbitmq

创建集群 - 测试集群.yaml

apiVersion: rabbitmq.com/v1beta1
kind: RabbitmqCluster
metadata:
  name: test-cluster
  namespace: test-rabbitmq
spec:
  replicas: 1
kubectl apply -f test-cluster.yaml

等待集群准备就绪

watch kubectl get pods -n test-rabbitmq

接下来您需要 ClusterIP 类型的服务来通过 Ingress 公开管理门户和 AMQP,我们将公开端口 5672、15672(如果您想公开 prometheus 指标端点,则公开端口 15692)。端口 5671 将用于 AMQP TLS。

集群服务.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: rabbitmq
    app.kubernetes.io/name: cluster-service
    app.kubernetes.io/part-of: rabbitmq
  name: cluster-service
  namespace: test-rabbitmq
spec:
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    # - appProtocol: amqp
    #   name: amqp-tls
    #   port: 5671
    #   protocol: TCP
    #   targetPort: 5671
    - appProtocol: amqp
      name: amqp
      port: 5672
      protocol: TCP
      targetPort: 5672
    - appProtocol: http
      name: management
      port: 15672
      protocol: TCP
      targetPort: 15672
    - appProtocol: prometheus.io/metrics
      name: prometheus
      port: 15692
      protocol: TCP
      targetPort: 15692
  selector:
    app.kubernetes.io/name: test-cluster
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
kubectl apply -f cluster-service.yaml

设置入口(仅限 minikube!)

minikube addons enable ingress
#kubectl patch configmap tcp-services -n ingress-nginx --patch '{"data":{"5671":"test-rabbitmq/cluster-service:5671"}}'
kubectl patch configmap tcp-services -n ingress-nginx --patch '{"data":{"5672":"test-rabbitmq/cluster-service:5672"}}'
spec:
  template:
    spec:
      containers:
      - name: controller
        ports:
#         - containerPort: 5671
#           hostPort: 5671   
         - containerPort: 5672
           hostPort: 5672
kubectl patch deployment ingress-nginx-controller --patch "$(cat ingress-nginx-controller-patch.yaml)" -n ingress-nginx
# after the ingress pod is back up and running
telnet $(minikube ip) 5672
# Ctrl+] then quit

设置入口(舵)

安装 ingress-nginx 控制器(如有必要)

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

这处理公开 AMQP 的 TCP 端口,它将这些端口映射到我们之前创建的服务端口 - 值.yaml

controller:
  replicaCount: 1
  service:
    loadBalancerIP: "192.168.1.251" # IP reserved for ingress. If you omit, you'll be assigned an IP in the avaiable range. Better to specify one.
tcp:
  #5671: test-rabbitmq/cluster-service:5671
  5672: test-rabbitmq/cluster-service:5672
udp: {}

创建我们的 nginx 入口控制器

helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx -f values.yaml -n ingress-nginx --create-namespace

一旦 nginx 集群 Pod 启动 -

watch kubectl get pods -n ingress-nginx
telnet $(minikube ip) 5672
# Ctrl+] then quit

让我们公开我们的 HTTP 入口 - rabbitmq-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: rabbitmq-ingress
  namespace: test-rabbitmq
spec:
  ingressClassName: nginx
  rules:
    - host: rabbitmq.test
      http:
        paths:    
          - backend:
              service:
                name: cluster-service
                port:
                  number: 15692
            path: /metrics  # optional
            pathType: Exact  
          - backend:
              service:
                name: cluster-service
                port:
                  number: 15672
            path: /
            pathType: Prefix
  defaultBackend:
    service:
      name: cluster-service
      port:
        number: 15672
status:
  loadBalancer: {}
kubectl apply -f rabbitmq-ingress.yaml

等待外部地址分配给您的入口

watch kubectl get ingress -n test-rabbitmq

注意:您可以调整入口以支持 TLS/HTTPS,但这超出了本示例的范围。

主持人条目

添加映射到192.168.1.251的rabbitmq.test主机条目(或您分配的任何IP,或分配给NGINX Ingress)

如果使用 minikube

sudo -- sh -c "echo '$(minikube ip)  rabbitmq.test' >> /etc/hosts"

如果使用 helm 安装了入口控制器

sudo -- sh -c "echo $(kubectl get ingress -n test-rabbitmq -o=jsonpath='{.items[0].status.loadBalancer.ingress[0].ip}'  rabbitmq.test >> /etc/hosts"

示例主机条目 -

192.168.1.251  rabbitmq.test

验证我们通过 ingress 获取 HTML 和统计信息

curl rabbitmq.test
curl rabbitmq.test/metrics # bonus

获取rabbitmq管理门户用户/密码(如果创建集群时未明确指定)

kubectl get secret test-cluster-default-user -n test-rabbitmq -o jsonpath='{.data.username}' | base64 --decode
kubectl get secret test-cluster-default-user -n test-rabbitmq -o jsonpath='{.data.password}' | base64 --decode

您应该能够使用这些凭据从 Web 浏览器连接到管理门户

http://rabbitmq.test
http://rabbitmq.test/metrics

minikube 将入口暴露给主机

如果您在虚拟机中运行 minikube,要将入口暴露给主机以便您可以从 Web 浏览器访问管理门户,请执行以下操作。然后在虚拟机管理程序中将 80(主机)端口映射到 8080(虚拟机) -

# we forward to 8080 because 80 is a privileged port
kubectl port-forward --address 0.0.0.0 deployment/ingress-nginx-controller 8080:80 --namespace ingress-nginx
# following for TLS
#kubectl port-forward --address 0.0.0.0 deployment/ingress-nginx-controller 8443:443 --namespace ingress-nginx

从 .NET 客户端,您现在可以使用主机条目或入口 IP 测试与 TCP 端口 5672 的连接。如果将 .NET 客户端从主机运行到 VM (minikube),则端口转发 TCP 5672:5672

应该这样做。我已经在 minikube 中验证了这一点,并使用 helm 进行 nginx 入口在实际集群上做了同样的事情。

多集群考虑因素

注意:如果您托管多个rabbitmq集群(来自单个kubernetes集群),则必须映射到同一入口IP上的不同外部可用端口(例如5782 -> test-rabbitmq-2/cluster-service:第5672章)。

或者,您可以运行入口控制器的多个实例,但使用这种方法会产生额外的开销(和复杂性)。

© www.soinside.com 2019 - 2024. All rights reserved.