一尘不染

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

docker

有两个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);}  
   }  
}

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


阅读 398

收藏
2020-06-17

共1个答案

一尘不染

对于现代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在服务器终端中看到打印
2020-06-17