處理ipc有很多種方法。這只是通過公開目的地容器中的端口(java服務器)和來自源容器(python客戶端)的鏈接的一種方法。 我爲你創造了一個例子。在這種情況下,我正在從Python連接到Java。
我的文件夾結構如下所示:
[email protected]:~/tmp/docker-ipc$ tree .
.
├── docker-compose.yml
├── javacl
│ ├── Dockerfile
│ ├── Main.class
│ ├── Main.java
│ └── OneConnection.class
└── pythoncl
├── client.py
└── Dockerfile
2 directories, 7 files
[email protected]:~/tmp/docker-ipc$
我的服務器(source)監聽輸出什麼都沾到端口10001:
[email protected]:~/tmp/docker-ipc$ cat javacl/Main.java
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class Main {
public static void main(String[] args) throws Exception {
final int myPort = 10001;
ServerSocket ssock = new ServerSocket(myPort);
System.out.println("Listening on port " + myPort);
while (true) {
Socket sock = ssock.accept();
System.out.println("Someone has made socket connection");
OneConnection client = new OneConnection(sock);
String s = client.getRequest();
}
}
}
class OneConnection {
Socket sock;
BufferedReader in = null;
DataOutputStream out = null;
OneConnection(Socket sock) throws Exception {
this.sock = sock;
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new DataOutputStream(sock.getOutputStream());
}
String getRequest() throws Exception {
String s = null;
while ((s = in.readLine()) != null) {
System.out.println("got: " + s);
}
return s;
}
}
[email protected]ubuntu-anovil:~/tmp/docker-ipc$
而我的客戶端連接到主機:JAVA服務器端口:10001併發送「hello stackoverflow」:
[email protected]:~/tmp/docker-ipc$ cat pythoncl/client.py
#!/usr/bin/python
#client example
import socket
import time
print "Waiting for socket"
time.sleep(3)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('java-server', 10001))
client_socket.send("hello")
client_socket.send(" stackoverflow")
client_socket.close()
while 1:
pass # do nothing
[email protected]:~/tmp/docker-ipc$
每這些容器的只是調用服務器端和客戶端分別,除了服務器公開10001端口,用於其他容器和那些搬運工文件看起來是這樣的:
[email protected]:~/tmp/docker-ipc$ cat javacl/Dockerfile
FROM java:7
COPY Main.class OneConnection.class/
EXPOSE "10001"
CMD ["java","Main"]
[email protected]:~/tmp/docker-ipc$ cat pythoncl/Dockerfile
FROM python:2.7
COPY client.py /client.py
CMD python client.py
[email protected]:~/tmp/docker-ipc$
然後在撰寫文件,javacl容器被賦予一個主機名識別自身和pythoncl鏈接javacl這樣的:
[email protected]:~/tmp/docker-ipc$ cat docker-compose.yml
javacl:
build: ./javacl
hostname: java-server
pythoncl:
build: ./pythoncl
links:
- "javacl"
[email protected]:~/tmp/docker-ipc$
現在,當你運行它,
[email protected]:~/tmp/docker-ipc$ docker-compose up
Starting dockeripc_javacl_1
Starting dockeripc_pythoncl_1
Attaching to dockeripc_javacl_1, dockeripc_pythoncl_1
javacl_1 | Listening on port 10001
javacl_1 | Someone has made socket connection
javacl_1 | got: hello stackoverflow
...
的服務器和客戶端intenti onally作出持續分別像這樣運行,以便我們可以檢查他們:
[email protected]:~/tmp/docker-ipc$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c96961f03d57 dockeripc_pythoncl "/bin/sh -c 'python c" 13 minutes ago Up 19 seconds dockeripc_pythoncl_1
9d0163aa34f5 dockeripc_javacl "java Main" 13 minutes ago Up 19 seconds 10001/tcp dockeripc_javacl_1
[email protected]:~/tmp/docker-ipc$
人們可以通過attach
或exec
登錄到這些容器,看看會發生什麼
感謝這樣一個偉大的解釋,它真的幫了我很多。所以爲了在容器之間傳遞參數,我必須使用網絡堆棧,是否有任何替代方案 – kkk
你提到有很多方法做ipc,你可以請列出它們,所以我可以檢查它們之間的權衡 – kkk
1. Alternatives :您是否在此設置中看到您的基礎設施存在缺陷。在這裏瞭解問題/侷限性會很好。 2.你可能知道Ipc本身可以用很多方式實現(文件,套接字,管道,信號量,消息隊列等),我選擇了套接字方式。但是,我認爲我應該真正瞭解您的設置,可伸縮性等方面的要求。如果您有一個輕量級的基於Java的UI應用程序和一個單一的Python客戶端注入數據,那麼我們甚至可以使用單個docker容器來運行這兩個進程無需在網絡級別開放端口)。 – Maniankara