👋 欢迎来到吴老二技术博客,专注运维 / 数据库 / 云原生
首页/运维服务/正文

RocketMQ 5.x 在 Kubernetes 中的集群部署与跨公网 Proxy 接入指南

吴
吴老二
2026-11-06运维服务15 次浏览0 条评论

1. 架构概述

RocketMQ 5.x 采用了存算分离的设计,引入了 Proxy 组件作为计算层,负责协议转换与客户端接入。对于跨公网访问的场景,这带来了一个关键优势:客户端只需连接 Proxy,无需直接感知 Broker 的内部地址。

部署架构建议如下:

  • NameServer:集群内部署(建议 3 节点),不对外暴露。
  • Broker + Proxy(Local 模式):同进程部署,Broker 处理存储,内嵌 Proxy 处理 gRPC 接入。
  • Proxy 暴露:通过 Kubernetes Service 将 Proxy 的 gRPC 端口(默认 8081)以 LoadBalancer 或 NodePort 方式暴露给公网。
  • Broker 网络:brokerIP1 保持为 K8s 内网 IP 或 Pod IP,无需修改为公网地址。

为什么不需要改 brokerIP1? 在 Proxy 模式下,公网客户端连接的是 Proxy 的 8081 端口。Proxy 在内网查询 NameServer 获取 Broker 路由,并在内网与 Broker 通信。客户端不参与 NameServer 查询,因此不会拿到 Broker 的内网地址。

2. 前置准备

  • 一个运行中的 Kubernetes 集群(版本不限,但需支持 Service 的 LoadBalancer 或 NodePort)。
  • 已安装 kubectl 并配置好集群访问凭证。
  • 已安装 Helm 3.7.0+(若选择 Helm 方式)。
  • 镜像:apache/rocketmq:5.5.1(或你使用的 5.x 具体版本)。

3. 部署 NameServer(内网)

NameServer 是 RocketMQ 的路由中心,集群内部组件需要访问它。建议部署 3 个副本以保证高可用。

创建一个 StatefulSet 或 Deployment,此处以简化配置为例:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rocketmq-namesrv
  namespace: rocketmq
spec:
  serviceName: rocketmq-namesrv-headless
  replicas: 3
  selector:
    matchLabels:
      app: rocketmq-namesrv
  template:
    metadata:
      labels:
        app: rocketmq-namesrv
    spec:
      containers:
        - name: namesrv
          image: apache/rocketmq:5.5.1
          command: ["sh", "mqnamesrv"]
          ports:
            - containerPort: 9876
          resources:
            requests:
              memory: "1Gi"
              cpu: "500m"

创建一个 Headless Service,供集群内部(Broker/Proxy)通过 DNS 发现 NameServer 节点:

apiVersion: v1
kind: Service
metadata:
  name: rocketmq-namesrv-headless
  namespace: rocketmq
spec:
  clusterIP: None
  selector:
    app: rocketmq-namesrv
  ports:
    - port: 9876
      name: namesrv

说明:Broker 和 Proxy 启动时,通过 NAMESRV_ADDR 环境变量指向该 Headless Service 的 DNS 名称(如 rocketmq-namesrv-headless.rocketmq.svc.cluster.local:9876)即可完成内网发现。无需对外暴露 9876 端口。

4. 部署 Broker + Proxy(Local 模式)

采用 Local 模式,Broker 与 Proxy 同进程部署,简化运维。启动命令需添加 --enable-proxy 参数。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: rocketmq-broker
  namespace: rocketmq
spec:
  serviceName: rocketmq-broker-headless
  replicas: 2  # 根据集群规模调整,例如 2 主或 2 主 2 从
  selector:
    matchLabels:
      app: rocketmq-broker
  template:
    metadata:
      labels:
        app: rocketmq-broker
    spec:
      containers:
        - name: broker
          image: apache/rocketmq:5.5.1
          command:
            - sh
            - mqbroker
            - "-n"
            - "rocketmq-namesrv-headless.rocketmq.svc.cluster.local:9876"
            - "--enable-proxy"
            - "-c"
            - "/home/rocketmq/conf/broker.conf"
          env:
            - name: NAMESRV_ADDR
              value: "rocketmq-namesrv-headless.rocketmq.svc.cluster.local:9876"
          ports:
            - containerPort: 10911  # Broker 主端口(内网)
              name: broker
            - containerPort: 8081   # Proxy gRPC 端口(需对外暴露)
              name: proxy-grpc
            - containerPort: 8080   # Proxy Remoting 端口(可选,若客户端用旧协议)
              name: proxy-remoting
          volumeMounts:
            - name: broker-config
              mountPath: /home/rocketmq/conf
      volumes:
        - name: broker-config
          configMap:
            name: rocketmq-broker-config
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: rocketmq-broker-config
  namespace: rocketmq
data:
  broker.conf: |
    brokerClusterName = DefaultCluster
    brokerName = broker-a
    brokerId = 0
    deleteWhen = 04
    fileReservedTime = 48
    brokerRole = ASYNC_MASTER
    flushDiskType = ASYNC_FLUSH
    # brokerIP1 保持默认或填入 Pod IP 所在网段的内网地址,无需改为公网 IP
    # 因为客户端不会直连 Broker,Proxy 在内网访问即可
    autoCreateTopicEnable = true

注意:在多副本场景下,每个 Broker 副本的 brokerName 和 brokerId 需要差异化配置(例如 broker-a/brokerId=0 为主,broker-a-s/brokerId=1 为从)。上述 ConfigMap 仅为单 Broker 组示例,生产集群请根据主从模式调整。

5. 暴露 Proxy 给公网客户端

这是跨公网访问的关键步骤。只暴露 Proxy 的 gRPC 端口(8081),不要暴露 Broker 的 10911 或 NameServer 的 9876。

方式一:LoadBalancer Service(推荐)

yaml

apiVersion: v1
kind: Service
metadata:
  name: rocketmq-proxy-external
  namespace: rocketmq
  annotations:
    # 若使用云厂商,可添加相应注解指定 LB 类型
spec:
  type: LoadBalancer
  selector:
    app: rocketmq-broker
  ports:
    - name: grpc
      port: 8081
      targetPort: 8081
      protocol: TCP

创建后,获取 EXTERNAL-IP:

kubectl get svc rocketmq-proxy-external -n rocketmq

公网客户端配置的接入点即为:<EXTERNAL-IP>:8081。

方式二:NodePort

若无 LoadBalancer 支持,可使用 NodePort:

yaml

spec:
  type: NodePort
  ports:
    - port: 8081
      targetPort: 8081
      nodePort: 30081  # 指定一个可用端口

公网客户端配置为:<任一公网节点IP>:30081。需确保安全组放行该 NodePort。

6. 公网客户端配置(关键变化)

你的公网客户端不应再使用传统的 NameServer 地址,而应直接连接 Proxy 的 gRPC 端点。

以 Java 5.x gRPC 客户端为例:

// 注意:这是 Proxy 的公网地址,不是 NameServer 地址
String endpoint = "你的公网IP:8081";

ClientServiceProvider provider = ClientServiceProvider.loadService();
ClientConfiguration configuration = ClientConfiguration.newBuilder()
    .setEndpoints(endpoint)
    .build();

Producer producer = provider.newProducerBuilder()
    .setClientConfiguration(configuration)
    .setTopics("YourTopic")
    .build();

官方 Helm 部署示例中同样明确:endpoint 需要设置为 Proxy 的地址和端口,而非 NameServer。

7. 安全与网络策略

跨公网暴露 Proxy 时,务必收紧访问控制:

  1. 安全组/防火墙:仅允许你的其他私有化环境的出口 IP 访问 Proxy 暴露端口(8081 或 NodePort)。
  2. K8s NetworkPolicy(可选):限制只有特定来源的流量可以到达 Proxy Pod。
  3. 启用 ACL:RocketMQ 5.x 支持 ACL,建议在 broker.conf 中配置 aclEnable=true,为公网客户端分配独立的 AccessKey/SecretKey,避免匿名访问。

8. 验证清单

部署完成后,按以下顺序验证:

| 检查项 | 预期结果 | | ------------------- | ----------------------------------------------------------- | | NameServer Pod 状态 | 3 个 Pod 均为 Running | | Broker Pod 状态 | Broker 启动日志显示boot success | | Proxy 端口监听 | Broker Pod 内 8081 端口处于监听状态 | | Service 外部地址 | kubectl get svc能获取到 EXTERNAL-IP 或 NodePort | | 公网连通性 | 从外部telnet <公网IP> 8081成功 | | 消息收发 | 使用 5.x gRPC 客户端连接公网IP:8081发送并消费一条测试消息 |


总结:RocketMQ 5.x 的 Proxy 架构天然适合跨公网接入。你只需把 Broker 和 NameServer 留在 K8s 内网,将 Proxy 的 gRPC 端口通过 Service 暴露出去,客户端配置改为 Proxy 地址即可。brokerIP1 保持内网地址不变,完全不需要改动。

评论 0

评论需 登录 后发表(注册并验证邮箱)。
还没有评论,来抢沙发~