简体   繁体   English

将Docker容器部署到Cloud Foundry时MQTT端口连接被拒绝

[英]MQTT port connection refused when deploying Docker container to Cloud Foundry

I have built a docker image contains a C++ application with MQTT & Mongodb module. 我已经构建了一个包含MQTT和Mongodb模块的C ++应用程序的docker映像。 When i tried to deploy it to my cloud using Cloud Foundry, this error showed up: 当我尝试使用Cloud Foundry将其部署到我的云时,出现此错误:

ERR Failed to make TCP connection to port 1883: connection refused ERR无法建立与端口1883的TCP连接:连接被拒绝

Given that 1883 is MQTT's listen port. 鉴于1883是MQTT的监听端口。 I've found on CloudFoundry Docker that the only thing i need to do is include EXPOSE 1883 in my Dockerfile, which i have already done. 我在CloudFoundry Docker上发现,我唯一需要做的就是在我的Dockerfile中包含EXPOSE 1883
Can anyone explain what i have not considered so far? 谁能解释我到目前为止尚未考虑的内容? thank you for reading. 感谢您的阅读。

Quoting a statement from github commit . 引用github commit的声明。

You expose ports using the EXPOSE keyword in the Dockerfile or the --expose flag to docker run . 您可以使用EXPOSE中的EXPOSE关键字或--expose标志将端口公开给EXPOSE docker run Exposing ports is a way of documenting which ports are used, but does not actually map or open any ports. 公开端口是一种记录使用哪些端口的方式,但实际上并没有映射或打开任何端口。 Exposing ports is optional. 公开端口是可选的。

IF you want to access MQTT on port 1883 use -p option in your docker run command. 如果要在端口1883上访问MQTT,请在docker run命令中使用-p选项

In your case 就你而言

docker run -itd -p 1883:1883 mqtt-image-name

Hope this helps. 希望这可以帮助。

Update: 更新:

Sorry I misunderstood, I gone through official doc. 抱歉,我误会了,我通过了官方文档。

EXPOSE should have to worked in your case. EXPOSE应该在您的情况下起作用。

The error you got ERR Failed to make TCP connection to port 1883: connection refused means something is wrong with your application or with cloud foundry. 您得到的ERR Failed to make TCP connection to port 1883: connection refused意味着您的应用程序或Cloud Foundry有问题。

The error might be because your app either does not become available on port 1883 due to a failure, or that it takes longer than the specified healthcheck timeout for it to be up and running, thus failing the healthcheck. 该错误可能是因为您的应用由于故障而无法在端口1883上变得不可用,或者它花费了比指定的运行状况检查超时更长的时间才能启动并运行,从而导致运行状况检查失败。

Please check this for more info. 请检查以获取更多信息。

Hope this helps. 希望这可以帮助。

i have figured it out! 我想通了! Cloud Foundry opens only port 8080 for container communication. Cloud Foundry仅打开端口8080进行容器通信。 In this site FoundryDocker it stated that if i wanna use other port then i have to specify it via EXPOSE [port]. 在此网站FoundryDocker中,它指出如果我想使用其他端口,则必须通过EXPOSE [端口]指定它。 First i understood it as the port i wanna publish must be pass to EXPOSE argument (in my case is 1883); 首先,我理解它是因为我要发布的端口必须传递给EXPOSE参数(在我的情况下是1883); however, it seemed that the EXPOSE port is the port that application will listen, like ... there is a NAT which redirects my hard-code port 1883 to 8080 for outside communication and vice versa. 但是,EXPOSE端口似乎是应用程序将侦听的端口,例如...有一个NAT将我的硬代码端口1883重定向到8080,以进行外部通信,反之亦然。 I hope someone can explain this more clearly, right now all i need to do is EXPOSE 8080 (instead of 1883) doesn't matter which port my application actually listens to. 我希望有人可以更清楚地解释这一点,现在我所要做的就是EXPOSE 8080(而不是1883)与我的应用程序实际监听的端口无关。

You are correct here, but that's only part of the story. 您在这里是正确的,但这只是故事的一部分。

I've found on CloudFoundry Docker that the only thing i need to do is include EXPOSE 1883 in my Dockerfile. 我在CloudFoundry Docker上发现,我唯一需要做的就是在我的Dockerfile中包含EXPOSE 1883。

When your image is run by Cloud Foundry, it expects your app to listen on a certain port. 当您的映像由Cloud Foundry运行时,它希望您的应用程序在某个端口上侦听。 Normally, CF will tell your app the port on which it should listen via the $PORT env variable. 通常,CF会通过$PORT env变量告诉您​​的应用程序应在其监听的$PORT With Docker, you can specify this port by adding EXPOSE to your docker file and indicating the port to use. 使用Docker时,您可以通过将EXPOSE添加到您的EXPOSE文件并指定要使用的端口来指定此端口。 CF will read this information and use the port you've specified instead of picking one to use. CF将读取此信息并使用您指定的端口,而不是选择要使用的端口。

That should be enough for your application to start, listen on the agreed upon port and for Cloud Foundry to validate the health check to your application. 这足以启动您的应用程序,侦听商定的端口,并让Cloud Foundry验证对应用程序的运行状况检查。 In other words, it should be enough for your application to start successfully. 换句话说,应用程序成功启动就足够了。 If your application is not passing its health check, then you need to confirm that your application is actually starting and listening on the port. 如果您的应用程序未通过其运行状况检查,则需要确认您的应用程序实际上正在启动并且正在侦听端口。 Also, as mentioned in the comments above, make sure it's not listening on localhost or 127.0.0.1 . 另外,如上面的评论中所述,请确保它不在localhost127.0.0.1上侦听。 Those are not accessible outside the app itself, not even to the health check. 无法在应用程序本身之外访问这些内容,甚至无法进行健康检查。

The other piece of the puzzle here is mapping external traffic to your application. 另一个难题是将外部流量映射到您的应用程序。 The port on which your application is listening inside the container is not exposed outside of that container. 容器内部应用程序正在侦听的端口未在该容器外部暴露。 To route traffic into your app, you need to map a route to your application. 要将流量路由到您的应用程序,您需要将路由映射到您的应用程序。 Typical routes on CF are HTTP based, so I don't believe they would work for MQTT. CF上的典型路由基于HTTP,因此我认为它们不适用于MQTT。 You would need to specifically map a TCP route to your application. 您需要专门将TCP路由映射到您的应用程序。

Ex: cf map-route my-app example.com --port 5000 例如: cf map-route my-app example.com --port 5000

This takes an public, external TCP port, which will probably not be 1883 (it depends entirely on what your provider makes available though), and routes traffic to the internal port on which your app is listening. 这需要一个公共的外部TCP端口(可能不会是1883)(它完全取决于您的提供程序提供的端口),并将流量路由到您的应用程序正在侦听的内部端口。 Your clients that wish to connect to the application on CF, need to connect to the mapped public/external port. 希望连接到CF上的应用程序的客户端需要连接到映射的公共/外部端口。 See diagram here for more details. 有关更多详细信息,请参见此处

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM