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

时间:2017-03-28 19:47:17

标签: 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);}  
   }  
}  

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

2 个答案:

答案 0 :(得分:1)

适用于现代泊坞广告版本(1.13 +)

要了解这种方法出错的地方,docker networking guide包含所有错综复杂的细节,但很大程度上归结为您无法在一个容器中引用localhost并且期望它路由到主机上运行的另一个容器。

默认情况下,每个容器runs on a bridge网络,并且每个容器在同一子网中有效地显示为该网桥上的单独主机。容器可以通过桥接网络上分配的IP地址引用其他容器,但localhost只是引用容器本身,而不是运行容器的底层主机。

要实现与您之后类似的可预测路由,您可以define your own bridge network并在该用户定义的网络上运行客户端和服务器容器。这确实需要在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 embedded dns docs了解更多详情。

适用于较旧的泊坞广告版本(1.12 - )

Docker提供container linking functionality,通过提供给--link的{​​{1}}选项公开。您需要一些与上述相同的更新,特别是使用docker run代替server,并使用localhost运行服务器容器。 docker run看起来像:

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

答案 1 :(得分:0)

有3个问题:

  1. 这些类应命名为服务器客户端,否则命名为Server.java&amp; Client.Java文件应命名为MyServer.java&amp; MyClient.java分别。
  2. 创建Docker容器时,会创建2个接口:localhost和另一个用于与其他容器通信的接口。您应该将“localhost”更改为服务器容器IP或主机IP。
  3. 不推荐使用 java 图片。
  4. 此外,客户端Dockerfile中不需要 EXPOSE 指令。