2016-01-13 144 views
2

嗨,我想了解docker撰寫以及如何在容器之間傳遞參數,以便我可以在我的應用程序中使用它。如何使用docker-compose在多個容器之間傳遞參數

我已經建立了使用兩個微服務

第一微服務一個簡單的Hello World應用程序是用java:

//java code hello.java 
public class hello 
{ 
    public static void main(String args[]) 
    { 
     System.out.println("hello world from java"); 
    } 
} 

//Dockerfile for creating this image 
FROM java:7 
COPY hello.java . 
RUN javac hello.java 
CMD ["java","hello"] 

同樣,對於使用python圖像我有兩個文件:

hello.py

print("hello from python") 

此圖片的Dockerfile是:

FROM python:2.7 
COPY hello.py . 
CMD ["python","hello.py"] 

我的搬運工,撰寫文件:

javacl: 
    build: . 
    links: pythoncl 
pythoncl: 
    build: ./pythonfolder 

我想要做的就是傳遞參數,這也是我在Java程序的用戶可以考慮再要傳遞參數傳給python程序,然後顯示它。這只是一個示例應用程序,因爲我想了解如何在容器之間傳遞參數

我已經看到了以Python應用程序爲例的docker網站,但任何人都可以請使用java程序和python程序,然後可以簡單地顯示如何通過一個非常簡單的示例傳遞參數。

一個解決方案是通過網絡傳遞參數,因爲所有容器都有自己的網絡堆棧,但是有沒有其他方法可以傳遞參數

我是新來的碼頭工人,任何幫助都會很棒。

回答

2

處理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$ 

人們可以通過attachexec登錄到這些容器,看看會發生什麼

+0

感謝這樣一個偉大的解釋,它真的幫了我很多。所以爲了在容器之間傳遞參數,我必須使用網絡堆棧,是否有任何替代方案 – kkk

+0

你提到有很多方法做ipc,你可以請列出它們,所以我可以檢查它們之間的權衡 – kkk

+0

1. Alternatives :您是否在此設置中看到您的基礎設施存在缺陷。在這裏瞭解問題/侷限性會很好。 2.你可能知道Ipc本身可以用很多方式實現(文件,套接字,管道,信號量,消息隊列等),我選擇了套接字方式。但是,我認爲我應該真正瞭解您的設置,可伸縮性等方面的要求。如果您有一個輕量級的基於Java的UI應用程序和一個單一的Python客戶端注入數據,那麼我們甚至可以使用單個docker容器來運行這兩個進程無需在網絡級別開放端口)。 – Maniankara

0

您可以使來自不同容器的程序使用網絡進行通信。

你想要的是在你的兩個程序之間實現某種遠程過程調用。最終,這不是Docker問題。