【问题标题】:How to pass parameters between Multiple containers using docker-compose如何使用 docker-compose 在多个容器之间传递参数
【发布时间】:2016-01-13 07:10:30
【问题描述】:

您好,我正在尝试了解 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 的图像,我有两个文件:

你好.py

print("hello from python")

这个镜像的 Dockerfile 是:

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

我的 docker-compose 文件:

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

我想要做的是传递参数,我将在 java 程序中从用户那里获取,然后想将该参数传递给 python 程序,然后显示它。这只是一个示例应用程序,因为我试图了解如何在容器之间传递参数

我已经看到有一个python应用程序作为示例的docker网站,但是任何人都可以使用java程序和python程序,然后可以通过一个非常简单的示例简单地展示如何传递参数。

一种解决方案是通过网络传递参数,因为所有容器都有自己的网络堆栈,但是有没有其他方法可以传递参数

我是 docker 新手,任何帮助都会很棒。

【问题讨论】:

    标签: java python networking docker docker-compose


    【解决方案1】:

    处理ipc的方法有很多种。这只是通过在目标容器(java 服务器)中公开端口和来自源容器(python 客户端)的链接的一种方法。 我为你创建了一个例子。在这种情况下,我是从 Python 连接到 Java。

    我的文件夹结构如下:

    anovil@ubuntu-anovil:~/tmp/docker-ipc$ tree .
    .
    ├── docker-compose.yml
    ├── javacl
    │   ├── Dockerfile
    │   ├── Main.class
    │   ├── Main.java
    │   └── OneConnection.class
    └── pythoncl
        ├── client.py
        └── Dockerfile
    
    2 directories, 7 files
    anovil@ubuntu-anovil:~/tmp/docker-ipc$
    

    我的服务器 (source) 监听并输出它在端口 10001 上获得的任何信息:

    anovil@ubuntu-anovil:~/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;
        }
    }
    
    anovil@ubuntu-anovil:~/tmp/docker-ipc$ 
    

    我的客户端连接到主机:java-server on port:10001 并发送“hello stackoverflow”:

    anovil@ubuntu-anovil:~/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
    anovil@ubuntu-anovil:~/tmp/docker-ipc$ 
    

    这些容器中的每一个只是分别调用服务器和客户端,除了服务器为其他容器公开 10001 端口并且这些 docker 文件如下所示:

    anovil@ubuntu-anovil:~/tmp/docker-ipc$ cat javacl/Dockerfile 
    FROM java:7
    
    COPY Main.class OneConnection.class /
    
    EXPOSE "10001"
    
    CMD ["java","Main"]
    anovil@ubuntu-anovil:~/tmp/docker-ipc$ cat pythoncl/Dockerfile 
    FROM python:2.7
    
    COPY client.py /client.py
    
    CMD python client.py
    anovil@ubuntu-anovil:~/tmp/docker-ipc$ 
    

    然后在 compose 文件中,javacl 容器被赋予一个主机名来标识自己,pythoncl 链接到 javacl,如下所示:

    anovil@ubuntu-anovil:~/tmp/docker-ipc$ cat docker-compose.yml 
    javacl:
      build: ./javacl
      hostname: java-server  
    pythoncl:
      build: ./pythoncl
      links: 
        - "javacl"
    anovil@ubuntu-anovil:~/tmp/docker-ipc$ 
    

    现在当你运行它时,

    anovil@ubuntu-anovil:~/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
    ...
    

    故意让服务器和客户端连续运行,以便我们可以像这样分别检查它们:

    anovil@ubuntu-anovil:~/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
    anovil@ubuntu-anovil:~/tmp/docker-ipc$ 
    

    可以通过attachexec 登录这些容器,看看会发生什么

    【讨论】:

    • 感谢这么好的解释,它真的帮了我很多。所以为了在容器之间传递参数我必须使用网络堆栈,是否有任何替代方案
    • 你提到了做ipc的方法有很多种,能不能列出来,让我看看它们之间的取舍
    • 1.替代方案:您是否发现此设置中的基础架构存在缺陷。很高兴知道这里的问题/限制。 2.你可能知道ipc本身可以有多种实现方式(文件、socket、管道、信号量、消息队列等),我选择了socket方式。但是,我认为我应该真正了解您在设置、可扩展性等方面的要求。如果您有一个基于 Java 的轻量级 UI 应用程序和一个注入数据的 Python 客户端,那么我们甚至可以使用一个运行这两个进程的 Docker 容器(无需在网络级别打开端口)。
    • 应用程序很大,我的应用程序中有很多微服务,它们可能运行在不同的主机上。是否可以使用消息和队列在 docker 容器之间进行通信,您能否分享一个链接,其中给出了这样的示例。
    • 还有一个问题,程序的输出没有打印“waiting for socket”,这行是在与java服务器建立任何socket连接之前在python程序中编写的
    【解决方案2】:

    您可以使来自不同容器的程序使用网络进行通信。

    你想要的是在你的两个程序之间实现某种远程过程调用。最后,这不是 Docker 的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多