【发布时间】:2021-08-27 19:02:25
【问题描述】:
我有一个带有 IBM MQ(Docker 映像 ibmcom/mq/9.2.2.0-r1)的容器,暴露了两个端口(9443 - 管理员,1414 - 应用程序)。
OpenShift 中所有必需的设置都已完成(Pod、Service、Routes)。
有两条路线,每个港口一条。
相应地指向端口(外部端口默认为 http=80、https=443)。
可以通过第一条路径访问管理控制台,因此 MQ 已启动并运行。
我尝试使用标准方法作为客户端(JMS 2.0,com.ibm.mq.allclient:9.2.2.0)进行连接:
var fctFactory = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
var conFactory = fctFactory.createConnectionFactory();
// ... other props
conFactory.setObjectProperty(WMQConstants.WMQ_HOST_NAME, "route-app.my.domain");
conFactory.setObjectProperty(WMQConstants.WMQ_PORT, 443);
连接失败。还尝试将路由重新定义为 HTTP 并使用端口 80,但再次失败。
如果有帮助,我们假设我们使用最新版本的 MQ Explorer 作为客户端。
每次出现同样的连接错误:
...
Caused by: com.ibm.mq.MQException: JMSCMQ0001:
IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2009' ('MQRC_CONNECTION_BROKEN').
...
Caused by: com.ibm.mq.jmqi.JmqiException:
CC=2;RC=2009;AMQ9204: Connection to host 'route-app.my.domain(443)' rejected.
[1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2009;AMQ9208:
Error on receive from host 'route-app.my.domain/10.227.248.2:443 (route-app.my.domain)'.
[1=-1,2=ffffffff,3=route-app.my.domain/10.227.248.2:443 (route-app.my.domain),4=TCP]],
3=route-app.my.domain(443),5=RemoteConnection.receiveTSH]
...
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2009;AMQ9208:
Error on receive from host 'route-app.my.domain/10.227.248.2:443
也许,这个article 可以提供一些关于错误代码 2009 的提示,但仍然不确定究竟是什么影响了 OpenShift 端的连接错误。
以前,我总是通过显式指定端口值连接到 IBM MQ,但这里的情况有点不同。
如何通过 TCP 连接到 OpenShift 集群中的 IBM MQ?
OpenShift中的配置如下:
kind: Pod
apiVersion: v1
metadata:
name: ibm-mq
labels:
app: ibm-mq
spec:
containers:
- resources:
limits:
cpu: '1'
memory: 600Mi
requests:
cpu: '1'
memory: 600Mi
name: ibm-mq
ports:
- containerPort: 1414
protocol: TCP
- containerPort: 9443
protocol: TCP
containerStatuses:
image: 'nexus-ci/docker-lib/ibm_mq:latest'
---
kind: Service
apiVersion: v1
metadata:
name: ibm-mq
spec:
ports:
- name: admin
protocol: TCP
port: 9443
targetPort: 9443
- name: application
protocol: TCP
port: 1414
targetPort: 1414
selector:
app: ibm-mq
---
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: ibm-mq-admin
spec:
host: ibm-mq-admin.my-domain.com
to:
kind: Service
name: ibm-mq
weight: 100
port:
targetPort: admin
tls:
termination: passthrough
insecureEdgeTerminationPolicy: None
wildcardPolicy: None
---
kind: Route
apiVersion: route.openshift.io/v1
metadata:
name: ibm-mq-app
spec:
host: ibm-mq-app.my-domain.com
to:
kind: Service
name: ibm-mq
weight: 100
port:
targetPort: application
tls:
termination: passthrough
insecureEdgeTerminationPolicy: None
wildcardPolicy: None
---
更新:最终创建并部署到 OpenShift 的小型 Web 应用程序接收 HTTP 请求并通过 JMS(输入/获取文本消息)与 MQ 交互,例如:
-
POST /queue/{queueName}/send + <body>; -
GET /queue/{queueName}/receive。
它使用 TCP 与 OpenShift 集群内的 MQ 交互,并接受外部 HTTP 连接作为常规 Web 应用程序。
其他解决方案似乎需要付出太多努力,但我接受了其中一个,因为它在理论上是正确且简单的。
【问题讨论】:
-
您使用的是哪个版本的 mq 客户端 jar 文件? TLS 路由基于从客户端发送到 openshift 的 SNI。随着时间的推移,Java 中的 MQ 行为发生了变化。在 9.1 之前的 java 没有发送 SNI。在 9.2 中,它发送了一个基于频道名称的 SNI。在 9.2 中,它允许您发送要连接的主机名。
-
您在问题的第一行提到端口 1414,然后在整个问题中不再使用它。 1414 是要侦听的默认 IBM MQ 端口。您是否尝试连接到您的主机名和端口 1414?
-
这对ibm.com/docs/en/ibm-mq/…有帮助吗?
-
@MoragHughson 1414 是从容器(Pod)公开的端口,并通过 Service 传递给 Route。 Route 在内部使用它,而 1414 对外部世界不可见。 Route 的外部连接可以通过 HTTP (80) 或 HTTPS(443),然后根据配置(包括端口)Route 将流量重定向到 Service。
-
是的,QM 和客户端应用程序都必须启用 TLS。没有它,您将无法连接。这篇文章 - 我写的github.com/ibm-messaging/mft-cloud/blob/mftubi/docs/… 描述了将 MQExplorer 连接到在 OpenShift 中运行的队列管理器的步骤。我认为这给了你一个想法。 MQExplorer 是一个 Java 应用程序。
标签: kubernetes containers openshift ibm-mq