当前位置: 首页 > 面试题库 >

使用Java在两个容器之间进行Docker通信

祝允晨
2023-03-14
问题内容

有两个Java文件,Server.java和Client.java。两者都放在单独的容器中。

DOCKER FILES: 我用于服务器的dockerfile(位于名为“ Server”的文件夹中)为:

FROM java:8
COPY Server.java /
RUN javac Server.java
EXPOSE 25000
ENTRYPOINT ["java"]
CMD ["Server"]

客户端的dockerfile(位于名为``Client’‘的文件夹中)为:

FROM java:8
COPY Client.java /
RUN javac Client.java
EXPOSE 25000
ENTRYPOINT ["java"]
CMD ["Client"]

构建容器: 使用以下容器构建容器sudo docker build -t serverimage .

运行容器: 我使用命令运行图像sudo docker run <IMAGE_NAME>。然后我首先运行serverimage。

我得到的错误(当我运行clientimage时)是:

java.net.ConnectException: Connection refused: connect

Server.java文件:

import java.io.*;  
import java.net.*;  
public class MyServer {  
   public static void main(String[] args){  
       try{  
           ServerSocket ss=new ServerSocket(25000);  
           Socket s=ss.accept();//establishes connection   
           DataInputStream dis=new DataInputStream(s.getInputStream());  
           String  str=(String)dis.readUTF();  
           System.out.println("message= "+str);  
           ss.close();  
       }catch(Exception e){System.out.println(e);}  
   }  
}

Client.java文件:

import java.io.*;  
import java.net.*;  
public class MyClient {  
   public static void main(String[] args) {  
      try{      
         Socket s=new Socket("localhost",25000);  
         DataOutputStream dout=new DataOutputStream(s.getOutputStream());  
         dout.writeUTF("Hello Server");  
         dout.flush();  
         dout.close();  
         s.close();  
      }catch(Exception e){System.out.println(e);}  
   }  
}

我可能做错了什么?谢谢!


问题答案:

对于现代Docker版本(1.13+)

为了了解这种方法在哪里出错,docker网络指南提供了所有复杂的细节,但是在很大程度上归结为您不能简单地localhost在一个容器中进行引用并期望它路由到主机上运行的另一个容器这一事实。

默认情况下,每个容器都在网桥网络上运行,并且每个容器实际上都显示为该网桥网络中同一子网中的单独主机。容器可以通过它们在桥接网络上分配的IP地址来引用其他容器,但localhost仅引用容器本身,而不是运行该容器的基础主机。

为了实现类似于您的后续工作的可预测路由,您可以定义自己的桥接网络,并在该用户定义的网络上运行客户端和服务器容器。这确实需要对您的代码进行一些小的更改Client.java。取而代之的是localhost,您必须使用选定的别名对服务器进行寻址,例如server。编辑客户端代码并重新构建后clientimage,请尝试以下操作:

  • 创建网络- sudo docker network create client_server_network
  • 运行服务器- sudo docker run --network-alias server --network client_server_network -it serverimage
  • 运行客户端- sudo docker run --network client_server_network -it clientimage
  • 您应该message= Hello Server在服务器终端中看到打印

请注意,我为--network-alias server服务器提供了额外的功能docker run,以添加网络别名,客户端可以在其中以可预测的方式到达服务器容器。您可以通过多种方式来实现该别名,包括使用该--name选项,但请查看Docker嵌入式dns文档以获取更多详细信息。

对于较旧的Docker版本(1.12-)

Docker提供了一个容器链接功能,该功能通过--link提供给的选项公开docker run。您将需要一些与上述相同的更新,特别是要使用server代替localhost和使用来运行服务器容器--name server。码头工人运行看起来像:

  • 运行服务器- sudo docker run --name server -it serverimage
  • 运行客户端- sudo docker run --link server -it clientimage
  • 您应该message= Hello Server在服务器终端中看到打印


 类似资料:
  • 我有2个Docker容器:App 应用程序-包含php应用程序代码的简单容器。它仅用于存储代码并将代码传递到远程Docker主机。 应用映像Dockerfile: Web服务容器,由PHP-FPM Nginx组成。 Web image Dockerfile: 我的问题:是否可以通过套接字链接Web容器和App容器? 主要原因是使用应用程序容器将更新的代码部署到远程Docker主机。使用卷/命名卷在

  • 我有三个集装箱: 前(vuejs) 服务器(nodejs) mongo(mongodb) http://server:3000/MyGetRoute 注意:此路由可以从我的浏览器通过 http://localhost:3000/mygetroute

  • 问题内容: 我正在macOS 10.12上使用Docker 1.12.5,并且正在使用我设置一个开发环境,其中包含一个 应用程序 映像和一个共享的 Redis 映像,其中包含一些预先填充的配置变量。 即使遵循了一些教程(并阅读了Mac上不可用的知识),我仍在努力连接两个容器。 我使用以下命令开始我的图像: 在我的图像中,我有: 而 从我的Mac 我可以通过连接成功命令没有问题。 但是,当我开始一个

  • 我有两个项目,一个是aspnet核心API项目,另一个是xUnit e2e项目,两者都部署在两个不同的容器中。 一旦两个容器都启动并运行,e2e容器就会尝试在url上访问Web API项目的APIhttps://web-api-container:5010/.但e2e项目无法实现API项目。似乎无法使用其主机名访问API项目(http://web-api-container:5010/). 我的c

  • 问题内容: 我试图在两个活动之间建立监听器接口。将开始。如果发生了某些事件,它将通知它。问题是我正在使用Intent开始新活动,那么Act1如何将自己分配为Act2接口的侦听器? Act1.java Act2.java 注意: 请不要建议我使用片段。我现在要使用活动。 问题答案: 您是否考虑过使用LocalBroadcastManager? 在Act1的onCreate中: 在Act1的onDes

  • 问题内容: 两个单独的Docker容器是否可以通过ZMQ IPC套接字进行通信?如果是这样,如何实现? 例如: Docker容器1 执行一个应用程序,该应用程序创建ZMQ响应套接字并绑定到“ ipc:// tmp / service_name”。 Docker Container#2 执行一个应用程序,该应用程序创建一个ZMQ Request套接字并连接到“ ipc:// tmp / servic