英文:
Connection refused when trying to connect to ActiveMQ Artemis deployed on Openshift
问题
以下是您提供的内容的翻译部分:
我们在 Openshift 项目(project1)中设置了一个 AMQ Artemis broker,使用的镜像是:amq-amq-broker-7-tech-preview/amq-broker-71-openshif。由于这是基本镜像,我们没有进行任何 SSL 或 TLS 配置。为了进行设置,我们使用了如下示例:https://github.com/jboss-container-images/jboss-amq-7-broker-openshift-image/blob/amq71-dev/templates/amq-broker-71-basic.yaml
在 Openshift 上部署镜像后,我们有以下内容:
- broker-amq-amqp (5672/TCP 5672) 没有路由
- broker-amq-jolokia (8161/TCP 8161) https://broker-amq-jolokia-project1.192.168.99.105.nip.io
- broker-amq-mqtt (1883/TCP 1883) 没有路由
- broker-amq-stomp (61613/TCP 61613) 没有路由
- broker-amq-tcp (61616/TCP 61616) 没有路由
从另一个 Openshift 服务中的 Java 代码中,我们尝试连接到该 broker,但是我们收到以下错误:
[org.apache.activemq.transport.failover.FailoverTransport] (ActiveMQ Task-1) Failed to connect to [tcp://broker-amq-amqp-project1.192.168.99.105.nip.io:61616?keepAlive=true] after: 230 attempt(s) with Connection refused (Connection refused), continuing to retry.
Java 代码如下:
user = "example";
password = "example";
String address = "queue/example";
InitialContext context = new InitialContext();
queue = (Queue) context.lookup(address);
ConnectionFactory cf = (ConnectionFactory) context.lookup("ConnectionFactory");
try (Connection connection = cf.createConnection(user, password);) {
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
JNDI 属性文件如下:
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=failover:(tcp://broker-amq-amqp-project1.192.168.99.105.nip.io:61616?keepAlive=true)?randomize=false
queue.queue/example=example/strings
英文:
We have an Openshift project ( project1 ) in which we setup an AMQ Artemis broker using the image : amq- amq-broker-7-tech-preview/amq-broker-71-openshif . Being the basic image we don't have any configuration such as SSL or TLS. In order to do the setup we used as example : https://github.com/jboss-container-images/jboss-amq-7-broker-openshift-image/blob/amq71-dev/templates/amq-broker-71-basic.yaml
After the deployment of the image on Openshift we have the following:
- broker-amq-amqp (5672/TCP 5672) No route
- broker-amq-jolokia (8161/TCP 8161) https://broker-amq-jolokia-project1.192.168.99.105.nip.io
- broker-amq-mqtt ( 1883/TCP 1883 ) No route
- broker-amq-stomp ( 61613/TCP 61613 ) No route
- broker-amq-tcp ( 61616/TCP 61616 ) No route
From another Openshift service, in Java we try to connect to the broker but we receive the following error :
[org.apache.activemq.transport.failover.FailoverTransport] (ActiveMQ Task-1) Failed to connect to [tcp://broker-amq-amqp-project1.192.168.99.105.nip.io:61616?keepAlive=true] after: 230 attempt(s) with Connection refused (Connection refused), continuing to retry.
The Java code:
user = "example";
password = "example";
String address = "queue/example";
InitialContext context = new InitialContext();
queue = (Queue) context.lookup(address);
ConnectionFactory cf = (ConnectionFactory) context.lookup("ConnectionFactory");
try (Connection connection = cf.createConnection(user, password);) {
connection.start();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
The JNDI Properties file
java.naming.factory.initial=org.apache.activemq.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=failover:(tcp://broker-amq-amqp-project1.192.168.99.105.nip.io:61616?keepAlive=true)?randomize=false
queue.queue/example=example/strings
答案1
得分: 3
看起来你似乎正在尝试使用OpenShift路由连接代理,但相关服务没有定义路由。你(或安装程序)为Jolokia定义了一个路由,但代理没有相关的路由。
在这里,你不会得到有用的错误消息,因为任何以正确域结尾的主机名都会连接到OpenShift路由器。然而,没有有效路由,路由器无法处理连接,可能会向JMS客户端返回某种无意义的错误数据包。
如果你正试图从与代理相同的OpenShift命名空间中的另一个应用程序连接代理,你无需通过路由连接 - 只需在JMS设置中明确使用服务名称(可能是broker-amq-tcp
)和服务端口。
如果你正从同一集群中不同的OpenShift命名空间中的另一个应用程序连接代理,你可能能够配置网络子系统以允许跨命名空间直接连接到服务。不幸的是,安装OpenShift后设置这个可能会有点麻烦。
如果你正从OpenShift命名空间外部连接到代理,并且不能直接使用服务,你必须通过路由连接,并且必须使用加密连接。这不一定是为了安全性 - 路由器将从SSL头中读取SNI信息以确定如何路由请求。
因此,你需要为代理的SSL端口创建一个服务,为该服务创建一个路由,从代理导出服务器证书,将这些证书导入到客户端中,并配置客户端使用通过路由的SSL连接URI。当然,如果可以的话,直接使用服务会更容易
所有这些设置步骤在Red Hat的AMQ7-on-OpenShift文档中都有描述:
尽管我不能否认在那份文档中有大量需要阅读的信息。
英文:
It looks as if you're trying to connect to the broker using an OpenShift route, when there is no route defined for the relevant service. You (or the installer) defined a route for Jolokia, but there's no route for the broker.
You won't get a helpful error message here, because any hostname that ends with the right domain will get connected to the OpenShift router. However, the router won't know how to process the connection without a valid route, and will probably just return some sort of meaningless error packet to the JMS client.
If you're trying to connect to the broker from another application in the same OpenShift namespace as the broker, you don't need to connect via the router -- just use the service name (presumably broker-amq-tcp
) and service port explicitly in your JMS set-up.
If you're connecting to the broker from another application in a different OpenShift namespace in the same cluster, you might be able to configure the networking subsystem to allow direct connections to the service across namespaces. This is, unfortunately, a little fiddly to set up after OpenShift is installed.
If you're connecting to the broker from outside an OpenShift namespace, and you can't use services directly, you'll have to connect via a route, and you must use an encrypted connection. That's not necessarily for security -- the router will read the SNI information from the SSL header to work out how to route the request.
So you'll need to create a service for the broker's SSL port, create a route for that service, export server certificates from the broker, import those certificates into your client, and configure the client to use an SSL connection URI via the router. Clearly, using the service directly is easier, if you can
All these set-up steps are described in Red Hat's AMQ7-on-OpenShift documentation:
although I can't deny that there's an awful lot of information to wade through in that document.
答案2
得分: 0
补充和澄清凯文·布恩的回答(非常正确)。
为了使命名为“broker-amq-tcp”的 Pod 内运行的 AMQ 中间件代理可从同一集群中的其他 Pod 访问:
- 在容器内以地址 0.0.0.0 启动代理。这非常关键 - 使用 localhost(环回;127.0.0.1)将阻止来自 Pod 外部的任何连接到达代理;
- 为 broker-amq-tcp 创建服务(例如“broker-amq-tcp-service”),将 Pod 端口映射到容器的 61616 端口;例如 62626(或其他任何端口);
- 使用 tcp://broker-amq-tcp-service:62626 从其他 Pod 进行连接。
0.0.0.0 这部分让我花了几天时间进行调试
英文:
Addition and clarification to answer by Kevin Boone (which is very much correct).
In order for the AMQ broker running inside pod named "broker-amq-tcp" to be reachable from other pods in same cluster:
- start broker inside the container on address 0.0.0.0. This is critical - localhost (loopback; 127.0.0.1) will prevent any connections from outside of the pod from reaching the broker;
- create service (e.g. "broker-amq-tcp-service") for broker-amq-tcp that maps a pod port to container's 61616; e.g. 62626 (or any other);
- connect from other pods using tcp://broker-amq-tcp-service:62626.
The 0.0.0.0 part cost me few days of debugging
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论