【问题标题】:How to attach a pseudo-tty to a Docker container with docker-py to replicate behaviour of `docker exec -ti <container> <command>`?如何使用 docker-py 将伪 tty 附加到 Docker 容器以复制 `docker exec -ti <container> <command>` 的行为?
【发布时间】:2021-02-23 07:27:20
【问题描述】:

我正在使用最新版本的 Docker Py,但我无法将伪 tty 附加到已经运行的容器,以确保复制 docker exec -ti &lt;container&gt; &lt;command&gt; 的行为。任何帮助将不胜感激。

【问题讨论】:

    标签: python docker dockerpy


    【解决方案1】:

    尝试使用 docker-py 中的attach 方法或attach-stream

    如 docker-py attach 中所述,该方法是将 tty(s) 附加到正在运行的容器。这类似于原生 docker attach command 将标准输入、标准输出和标准错误附加到容器。

    在调用create_container 以使attach 工作时,需要使用stdin_open = Truetty = true 创建容器。

    使用attach-socket 的示例:

    拉动debian:latest 容器

    docker pull debian:latest
    

    如下创建python脚本test.py

    #! python3
    import docker
    import os
    import time
    
    # Create container and start it
    client = docker.from_env()
    container = client.create_container('debian:latest', name='test', stdin_open = True, tty = True, command = 'sh')
    client.start(container)
    
    # Create communication socket
    s = client.attach_socket(container, {'stdin': 1, 'stdout': 1, 'stream':1})
    
    # Set the socket as non-blocking
    s._sock.setblocking(False)
    
    # Start communication by sending cat
    os.write(s.fileno(),b'cat /etc/hosts\n')
    
    # Since we are non-blocking, wait for a while to get the output
    time.sleep(1)
    
    # Read up-to 10000 bytes. If there are more, we can issue another read
    print(os.read(s.fileno(),10000))
    
    client.stop(container)
    client.wait(container)
    client.remove_container(container)
    

    现在测试脚本。您将看到我们在 shell 中执行的命令的输出。

    ~# python3 test.py
    b'cat /etc/hosts\r\n127.0.0.1\tlocalhost\r\n::1\tlocalhost ip6-localhost ip6-loopback\r\nfe00::0\tip6-localnet\r\nff00::0\tip6-mcastprefix\r\nff02::1\tip6-allnodes\r\nff02::2\tip6-allrouters\r\n172.17.0.2\t48f4a5f32f48\r\n# '
    

    注意:套接字设置为非阻塞,以避免在等待容器响应时被阻塞。这种方法特定于用例。

    【讨论】:

    • 嘿@jordanvrtanoski,感谢您的回复。不幸的是,当我执行 DockerClient(base_url="unix://var/run/docker.sock").containers.list()[0].attach("sh", stdin_open=True, tty=True) 时,它不起作用,因为 attach 只接受 1 个位置参数。根据文档,stdin_opentty 似乎也不是 attach 的正确参数。
    • 很抱歉造成混淆,标志是在容器创建时传递的。如果容器不是使用此标志创建的(即-ti,您将无法附加到容器标准输入、标准输出)。
    • 了解@jordanvrtanoski。但在这种状态下,使用attach 函数和流式传输输出将导致我只读取输出,我仍然无法在那里发送输入,因为无法将stdin 合并到attach 中。这有助于被动获取日志,但对与容器的主动交互没有太大帮助 - 就像 docker exec -ti &lt;container&gt; &lt;command&gt; 允许的那样。
    • @AkashdeepDhar 我添加了一个小例子。我希望它有所帮助。
    猜你喜欢
    • 2022-09-28
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 2019-08-23
    • 2018-10-10
    • 2019-01-19
    • 1970-01-01
    • 2017-11-18
    相关资源
    最近更新 更多