首页 新闻 会员 周边

容器之间如何跨主机通信

0
悬赏园豆:50 [已解决问题] 解决于 2023-05-08 11:34

场景:
目前有个Java springboot程序的镜像,这个程序包含socket的服务器端,客户端,服务端程序设置一个监听port(7005),客户端的代码中设置了服务端的IP地址(10.229.207.15)(这个IP地址是主机2的IP地址)和端口(7005)。
我在两个主机上都以host模式启动容器(两个主机上的容器是一样的),现在主机2用postman发服务端请求,主机1上的容器用postman发客户端请求。
PS:Java程序的端口设置的都是9090(postman发请求:10.229.207.15:9090//*),主机1的IP地址(10.229.207.14)。

我想问:这个方式的错误在哪儿?因为不是很懂跨主机通信,所以才来求问会的大佬!

nihaoqingtuan的主页 nihaoqingtuan | 初学一级 | 园豆:104
提问于:2023-05-05 10:46
< >
分享
最佳答案
1

如果你说的和做的都没错,理论上是可行的。但是,这并不是推荐的使用方式,host模式会使容器和主机共享端口,列如80端口只有一个,a容器使用了80,b容器就不能使用80端口。推荐的使用方式是默认的桥接方式。
在你仅有一台主机安装docker情况下:

# 在同一台host上启动2个容器
docker run -itd --name your-app-name -p host_port:container_port images_id
# 如:
docker run -itd --name nginx(容器名称-自定义):(可接版本号)v.1.0.0 -p 80:80 1ab2(镜像的前4位即可)
# 你的例子:
docker run -itd --name app1 -p 19090:9090 -p 17005:7005 app1(镜像id)
docker run -itd --name app2 -p 29090:9090 -p 27005:7005 app2

这种情况下的调用,就是该主机的ip加上映射出的端口,如ip:19090 17005 29090 27005即可提供服务,当然,转到2台主机上是一样的,只要A主机能访问B主机即可。

收获园豆:50
蜉蝣渡海 | 菜鸟二级 |园豆:466 | 2023-05-05 14:57

好的,我会试试你说的这种方式

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-05 15:07

大佬,我试了下你说的这个方式,但是两个容器内的Java程序之间的socket好像没有连起来,因为我没有看到文件有传输。这是为什么?这两个程序的监听端口的映射需要一致吗?

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-05 15:38

大佬,如果说是

你的例子:

docker run -itd --name app1 -p 19090:9090 -p 17005:7005 app1(镜像id)
docker run -itd --name app2 -p 29090:9090 -p 27005:7005 app2

这样子操作,那么容器内java程序中主机1的客户端配置的IP地址是不是就不能填主机2的IP地址?

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-06 10:21

@nihaoqingtuan: 这样不用管容器IP,因为用的是宿主机IP,就是你虚拟机的IP加host_port。比如192.168.1.1:19090,而不是容器的172.17.1.1:9090,通信是两台虚拟机通信,因为容器的端口已经映射到主机端口了

蜉蝣渡海 | 园豆:466 (菜鸟二级) | 2023-05-06 15:18

@nihaoqingtuan: 你得看下你程序的配置文件,是配置的什么地址,如果不对,是需要改的。
例如,我这里本机起了一个grafana的容器,端口是3000,容器端口也是3000,我就可以从本机访问:localhost:3000,或者127.0.0.1:3000,再或者使用我这台电脑的内网IP:172.18.5.30:3000,都可以访问这个服务。你两个应用之间的通信,应该使用你容器所在的虚拟机的IP加上虚拟机开放的端口,就是-p host_port(这个端口):container_port。你看下你的应用是不是地址和端口配置错了。
举个例子:

# 现在有2台虚拟机,都安装了docker
# 第一台虚拟机IP为192.168.0.1,第二台为192.168.0.2。
# 第一台启动nginx应用,暴露在主机端口为180
docker run -itd -name nginx -p 180:80 xxxx(nginx_image_id)
# 第二台启动后端java应用,暴露tomcat端口8080
docker run -itd --name backend -p 18080:8080 xxxx(后端应用镜像id)

要让用户访问192.168.0.1:180页面,提交或者查询后端的数据,就需要nginx做反向代理,nginx的配置文件就要配置proxy

# nginx.conf
# 略过不必要的
proxy_pass http://192.168.0.2:18080;

这样就是一套前后端分离的应用部署在容器中的关系了,使用的通信是节点通信,如果在k8s中,就是node访问。

蜉蝣渡海 | 园豆:466 (菜鸟二级) | 2023-05-06 15:36

@蜉蝣渡海:
代码写死了地址,监听端口:
IP: "10.229.207.15"
PORT: 7005

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-06 17:41

@蜉蝣渡海:
我在本地启两个容器跑的时候采用host模式,代码中IP地址写0.0.0.0,是可以传输文件的。但是去放到两个服务器上,就不行了,报socket连接异常。

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-06 17:43

@蜉蝣渡海: 我在网上搜容器跨主机通信,给的方案都是用macvlan,我是不是应该使用这个方案?

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-08 10:57

@蜉蝣渡海: 我将端口重新映射成9090:9090 7005:7005 后成功了。感谢

nihaoqingtuan | 园豆:104 (初学一级) | 2023-05-08 11:33

@nihaoqingtuan: 我看了你回复的,根据你的描述,问题出在你在host映射的端口实际并没有在代码中做配置,比如你两个服务之间还是用的默认端口,所以两台之间的通信会不通。这也是为什么你换成默认端口就可以通的原因。理论你现在应该大致了解了,以后可以按照这种方式去做,避免使用host模式,因为不是推荐的方式。

蜉蝣渡海 | 园豆:466 (菜鸟二级) | 2023-05-09 08:55
其他回答(1)
0

你好,如为解决问题,可以私聊我解决您的问题。

Biuget-Golang | 园豆:783 (小虾三级) | 2023-05-06 10:22
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册