使用 docker-py 进行交互式 Docker 执行

问题描述 投票:0回答:1

我正在尝试实现相当于:

docker exec -it <some_container> /bin/bash

即。在容器中运行命令,并将程序的

stdin
stdout
连接到命令的
stdin
stdout

我对文档的阅读似乎暗示以下内容应该可以完成这项工作:

import docker
client = docker.from_env()
container, = client.containers.list()
container.exec_run(['/usr/local/bin/bash'], stdin=True, tty=True)

(有一个容器正在运行

bash:latest

但是程序的

stdin
似乎并没有与
exec
'd 命令的连接起来。 命令行只是坐在那里,回显我的输入,但不会以任何方式对其做出反应。

我还尝试与原始套接字交互:

_, s = container.exec_run(['/usr/local/bin/bash'], stdin=True, tty=True, socket=True)
s.write('echo hello world')

但我越来越

UnsupportedOperation: File or stream is not writable.

问题:我需要做什么才能允许我的代码的用户与使用 docker-py 在容器中执行的命令的 std IO 进行交互?

python docker interactive dockerpy
1个回答
0
投票

exec_run的结果是一个socket.SocketIO对象。使用其套接字的recv()、sendall()。

例如

import docker
import threading
import queue

client = docker.from_env()
container = client.containers.get('YOUR CONTAINER NAME')
_, sock = container.exec_run(cmd='bash', stdin=True, socket=True)
ch = queue.Queue()

def read():
    while res := sock._sock.recv(4096):
        print(res[8:].decode())

def write():
    while item := ch.get():
        item = item + '\n'
        item = bytes(item, 'utf-8')
        sock._sock.sendall(item)

writer = threading.Thread(target=write)
writer.start()

reader = threading.Thread(target=read)
reader.start()

while cmd := input():
    ch.put(cmd)
    if cmd == 'exit':
        break

sock._sock.close()
ch.put(None)

writer.join()
reader.join()
© www.soinside.com 2019 - 2024. All rights reserved.