You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Ingress Nginx中配置ActiveMQ Artemis主备路由?

实现Ingress Nginx对ActiveMQ Artemis主备节点的TCP主备路由

针对你的需求,要通过Ingress Nginx暴露单个TCP端口(9100),自动将流量转发到ActiveMQ Artemis的主节点,备节点仅在主节点故障时接管,以下是几个可行的配置方案:

方案1:基于Nginx Stream模块的原生主备配置

利用Nginx Stream模块的backup节点标记和健康检查功能,直接在Ingress Nginx中定义主备upstream,无需额外组件。

配置步骤

  1. 修改Ingress Nginx的Helm Values
    在你的Ingress Nginx values.yaml中添加自定义Stream配置和TCP端口映射:

    controller:
      # 添加自定义Stream片段,定义主备upstream
      config:
        stream-snippets: |
          upstream artemis_active {
            # 主节点:StatefulSet的第一个Pod DNS(根据实际名称调整)
            server artemis-0.artemis-service.your-namespace.svc.cluster.local:61616 max_fails=3 fail_timeout=30s;
            # 备节点:添加backup标记,仅当主节点不可用时才会被选中
            server artemis-1.artemis-service.your-namespace.svc.cluster.local:61616 backup max_fails=3 fail_timeout=30s;
            # 启用TCP健康检查,定期探测节点可用性
            health_check interval=5s passes=2 fails=2;
          }
      # 映射外部端口9100到自定义upstream
      tcp:
        9100: "your-namespace/artemis_active:0"
    

    这里的0端口是占位符,因为upstream中已经指定了目标端口61616。

  2. 关键参数说明

    • max_fails=3 fail_timeout=30s:连续3次连接失败后,标记节点不可用30秒
    • backup:标记该节点为备节点,仅在所有非backup节点不可用时接收流量
    • health_check:每隔5秒检查节点状态,连续2次失败标记不可用,连续2次成功恢复可用

注意事项

  • 确保ActiveMQ Artemis的备节点在standby状态下会拒绝TCP连接到61616(默认Artemis主备集群中,备节点的acceptor不会对外服务),这样Nginx的健康检查能正确区分主备状态。
  • StatefulSet的Pod DNS格式为{pod-name}.{service-name}.{namespace}.svc.cluster.local,请根据实际部署名称调整。

方案2:通过动态维护Service Endpoints实现主备路由

编写脚本或使用轻量控制器,监控ActiveMQ Artemis的主节点状态,动态更新Service的Endpoints,让Ingress Nginx始终只转发流量到当前主节点。

配置步骤

  1. 准备基础Service
    创建一个指向所有Artemis节点的Service(Headless或普通Service均可):

    apiVersion: v1
    kind: Service
    metadata:
      name: artemis-service
      namespace: your-namespace
    spec:
      ports:
      - port: 61616
        name: tcp
      selector:
        app: artemis
    
  2. 编写主节点监控脚本
    以下是一个简单的bash脚本,用于查询Artemis主节点并更新Service Endpoints:

    #!/bin/bash
    NAMESPACE="your-namespace"
    SERVICE_NAME="artemis-service"
    # 查询第一个节点是否为主节点(通过Artemis的HTTP健康端点或CLI命令)
    PRIMARY_STATUS=$(curl -s http://artemis-0.${SERVICE_NAME}.${NAMESPACE}.svc.cluster.local:8161/console/jolokia/read/org.apache.activemq.artemis:broker=%22broker%22/scaleDownClusterStatus | jq -r '.value')
    
    if [ "$PRIMARY_STATUS" == "ACTIVE" ]; then
      # 获取主节点Pod IP
      POD_IP=$(kubectl get pod artemis-0 -n $NAMESPACE -o jsonpath='{.status.podIP}')
    else
      # 切换到第二个节点作为主节点
      POD_IP=$(kubectl get pod artemis-1 -n $NAMESPACE -o jsonpath='{.status.podIP}')
    fi
    
    # 更新Service的Endpoints,仅保留当前主节点
    kubectl patch endpoints $SERVICE_NAME -n $NAMESPACE -p '{
      "subsets": [
        {
          "addresses": [{"ip": "'$POD_IP'"}],
          "ports": [{"port": 61616}]
        }
      ]
    }'
    
  3. 部署定时任务
    将上述脚本打包成CronJob,定期执行(比如每10秒一次),确保Endpoints始终指向主节点:

    apiVersion: batch/v1
    kind: CronJob
    metadata:
      name: artemis-primary-monitor
      namespace: your-namespace
    spec:
      schedule: "*/10 * * * * *" # 每10秒执行一次
      jobTemplate:
        spec:
          template:
            spec:
              containers:
              - name: monitor
                image: bitnami/kubectl:latest
                command: ["/bin/bash", "-c"]
                args:
                - |
                  # 这里粘贴上面的脚本内容
              restartPolicy: OnFailure
              serviceAccountName: artemis-monitor-sa # 需要赋予该SA修改Endpoints的权限
    
  4. Ingress Nginx配置
    在values.yaml中直接映射TCP端口到Service:

    controller:
      tcp:
        9100: "your-namespace/artemis-service:61616"
    

优势

  • 无需修改Ingress Nginx的核心配置,依赖Kubernetes原生资源实现主备切换
  • 对Nginx来说,相当于只转发到一个节点,避免了Nginx层面的故障判断逻辑

方案对比

方案复杂度依赖切换效率
方案1低Nginx Stream模块秒级(依赖健康检查间隔)
方案2中自定义脚本/控制器、Kubernetes SA权限亚秒级(取决于脚本执行频率)

内容的提问来源于stack exchange,提问作者Subhidh Agarwal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 23:47:39