如何在Ingress Nginx中配置ActiveMQ Artemis主备路由?
实现Ingress Nginx对ActiveMQ Artemis主备节点的TCP主备路由
针对你的需求,要通过Ingress Nginx暴露单个TCP端口(9100),自动将流量转发到ActiveMQ Artemis的主节点,备节点仅在主节点故障时接管,以下是几个可行的配置方案:
方案1:基于Nginx Stream模块的原生主备配置
利用Nginx Stream模块的backup节点标记和健康检查功能,直接在Ingress Nginx中定义主备upstream,无需额外组件。
配置步骤
修改Ingress Nginx的Helm Values
在你的Ingress Nginxvalues.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。关键参数说明
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始终只转发流量到当前主节点。
配置步骤
准备基础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编写主节点监控脚本
以下是一个简单的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}] } ] }'部署定时任务
将上述脚本打包成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的权限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
相关产品推荐
相关产品推荐

