使用Java的两个容器之间的Docker通信 [英] Docker communication between two containers with Java

查看:448
本文介绍了使用Java的两个容器之间的Docker通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



DOCKER FILES:
Docker文件(名为Server的文件夹)我用于服务器的是:

  FROM java:8 
COPY Server.java /
运行javac Server.java
EXPOSE 25000
ENTRYPOINT [java]
CMD [服务器]

客户端的dockerfile(在名为Client的文件夹中)为:

  FROM java: 8 
COPY Client.java /
运行javac Client.java
EXPOSE 25000
ENTRYPOINT [java]
CMD [Client]

构建容器:
使用 sudo构建容器docker build -t serverimage。



运行容器:
我使用命令运行映像 sudo docker运行< IMAGE_NAME> 。我先运行serverimage。



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

  java.net.ConnectException:连接拒绝: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(); //建立连接
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);}
}
}

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

解决方案

对于现代码头版本(1.13 +) >

要了解此方法出错, docker网络指南具有所有复杂的细节,但这主要归结于以下事实:您不能简单地将 localhost 引用到一个容器中,并期望它路由到主机上运行的另一个容器。



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



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




  • 创建网络 - sudo docker network create client_server_network

  • 运行服务器 - sudo docker run --network -alias服务器--network client_server_network -it serverimage

  • 运行客户端 - sudo docker run --network client_server_network -it clientimage

  • 您应该在服务器终端中看到 message = Hello Server 打印



请注意,我向服务器的 docker运行提供了一个额外的 - 网络别名服务器 ,添加网络别名,客户端可以预见到达服务器容器。您有多种方法来实现该别名,包括使用 - 名称选项,但请查看 docker embedded dns docs 了解更多详情。



版本(1.12 - )



Docker提供了一个容器链接功能,通过链接选项提供给 docker run 。您将需要与上述相同的更新,特别是使用类似 server 代替 localhost ,并运行具有 - 名称服务器的服务器容器。码头运行将如下所示:




  • 运行服务器 - sudo docker run --name server -it serverimage

  • 运行客户端 - sudo docker run --link server -it clientimage

  • 您应该在服务器终端中看到 message = Hello Server 打印


There are two java files, Server.java and Client.java. Both are in separate containers.

DOCKER FILES: The dockerfile(in the folder named 'Server') that i use for server is:

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

The dockerfile(in the folder named 'Client') for client is:

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

BUILDING THE CONTAINERS: Building the containers using sudo docker build -t serverimage .

RUNNING THE CONTAINERS: I run the images using the command sudo docker run <IMAGE_NAME>.And I am running the serverimage first.

The error i am getting(When i run clientimage) is:

java.net.ConnectException: Connection refused: connect

Server.java File:

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 File:

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);}  
   }  
}  

What am I possibly doing wrong? Thank you!

解决方案

For modern docker versions (1.13+)

To understand where this approach goes wrong, the docker networking guide has all of the intricate details, but it largely boils down to the fact that you can't simply reference localhost in one container and expect it to route to another container running on your host.

By default each container runs on a bridge network, and each container effectively appears as a separate host on that bridge network, in the same subnet. The containers can reference other containers via their assigned IP address on the bridge network, but localhost simply refers to the container itself, rather than the underlying host that's running the container.

To achieve predictable routing similar to what you're after, you can define your own bridge network and run the client and server containers on that user-defined network. This does require one small code change in your Client.java. Instead of localhost, you have to address the server with a chosen alias, say server. Once you've edited the client code and rebuilt clientimage, try the following:

  • Create the network - sudo docker network create client_server_network
  • Run the server - sudo docker run --network-alias server --network client_server_network -it serverimage
  • Run the client - sudo docker run --network client_server_network -it clientimage
  • You should see message= Hello Server print in the server terminal

Note that I provided an additional --network-alias server to the server's docker run, to add a network alias where the client can predictably reach the server container. You have multiple ways of achieving that aliasing, including using the --name option, but check out the docker embedded dns docs for more details.

For older docker versions (1.12-)

Docker provides a container linking functionality, exposed via the --link option supplied to docker run. You'll need some of the same updates as above, notably using something like server in place of localhost, and running the server container with --name server. The docker run would look like:

  • Run the server - sudo docker run --name server -it serverimage
  • Run the client - sudo docker run --link server -it clientimage
  • You should see message= Hello Server print in the server terminal

这篇关于使用Java的两个容器之间的Docker通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆