java - 如何使用 docker-compose 在多个容器之间传递参数

标签 java python networking docker docker-compose

您好,我正在尝试了解 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程序,然后显示它。这只是一个示例应用程序,因为我试图了解如何在容器之间传递参数

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

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

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

最佳答案

处理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,端口: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$ 

然后在撰写文件中,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 登录这些容器,看看会发生什么

关于java - 如何使用 docker-compose 在多个容器之间传递参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34760439/

相关文章:

java - Sqlite 按距离现在最近的时间排序

Python列表的列表操作顺序

python - 写入数据库时​​,Python 3 中的 SQLite3 出现磁盘 I/O 错误

python - 严重难以捉摸的循环(绞尽脑汁!)

c# - 如何发送使用 Wireshark 捕获的 SSL 数据包?

java - Apache Thrift Python-Java 'Connection Refused'

java - 将列表对象转换为列表objectDto java的最佳实践

java - 尝试比较两个不同 ArrayList 的每个元素

android - Android如何获取HTTP请求?

java - 我可以在没有入口点的情况下强制进行 GWT 编译吗? (验证与 GWT 的兼容性)