【问题标题】:How to call non-interactively docker-compose run command - SSH?如何以非交互方式调用 docker-compose 运行命令 - SSH?
【发布时间】:2020-02-25 16:47:14
【问题描述】:

情况描述:我在远程计算机 B 上运行了一个 Ubuntu VM。我可以通过在我的主机(计算机 A)上执行的 SSH 访问这台计算机 B。 当我在计算机 B 上通过 SSH 进入交互式 shell 时,我可以毫无问题地执行所有 docker 命令,步骤如下:

  • ssh user@remote_IP(在远程 shell 中交互输入)
  • docker-compose run -d --name wfirst --user 1000:1000 container(编写一个 docker 容器并启动它)

这非常有效,我的容器已安装、启动并运行。 但是,如果我尝试通过在主机终端中写入以非交互方式运行该命令:

  • ssh user@remoteIP "cd /path_to_docker_file;docker-compose run -d --name wfirst --user 1000:1000 container"

命令不成功,我的容器没有挂载,没有运行。通过使用 docker-compose 命令上的"--verbose" 标志,我能够获得更多信息。

这里是成功方法输出的有趣部分:

    compose.config.config.find: Using configuration files: ./docker-compose.yml
    WARNING: compose.config.environment.__getitem__: The DISPLAY variable is not set. Defaulting to a blank string.
    WARNING: compose.config.environment.__getitem__: The NO_PROXY variable is not set. Defaulting to a blank string.
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    urllib3.connectionpool._new_conn: Starting new HTTP connection (1): localhost:2375
    urllib3.connectionpool._make_request: http://localhost:2375 "GET /v1.25/version HTTP/1.1" 200 758
    compose.cli.command.get_client: docker-compose version 1.21.0, build unknown
    docker-py version: 3.4.1
    CPython version: 3.7.5
    OpenSSL version: OpenSSL 1.1.1c  28 May 2019
    compose.cli.command.get_client: Docker base_url: http://localhost:2375
    ...

我们可以看到与 docker 的 HTTP 连接已成功建立。然后该命令继续执行并能够从 docker 映像创建容器。

这里是失败方法的输出:

    compose.config.config.find: Using configuration files: ./docker-compose.yml
    compose.config.environment.__getitem__: The DISPLAY variable is not set. Defaulting to a blank string.
    compose.config.environment.__getitem__: The NO_PROXY variable is not set. Defaulting to a blank string.
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    docker.utils.config.find_config_file: Trying paths: ['/home/user/.docker/config.json', '/home/user/.dockercfg']
    docker.utils.config.find_config_file: No config file found
    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 384, in _make_request
        six.raise_from(e, None)
      File "<string>", line 3, in raise_from
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 380, in _make_request
        httplib_response = conn.getresponse()
      File "/usr/lib/python3.7/http/client.py", line 1344, in getresponse
        response.begin()
      File "/usr/lib/python3.7/http/client.py", line 306, in begin
        version, status, reason = self._read_status()
      File "/usr/lib/python3.7/http/client.py", line 267, in _read_status
        line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
      File "/usr/lib/python3.7/socket.py", line 589, in readinto
        return self._sock.recv_into(b)
    socket.timeout: timed out

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/requests/adapters.py", line 449, in send
        timeout=timeout
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 638, in urlopen
        _stacktrace=sys.exc_info()[2])
      File "/usr/lib/python3/dist-packages/urllib3/util/retry.py", line 367, in increment
        raise six.reraise(type(error), error, _stacktrace)
      File "/usr/lib/python3/dist-packages/six.py", line 693, in reraise
        raise value
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 600, in urlopen
        chunked=chunked)
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 386, in _make_request
        self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
      File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 306, in _raise_timeout
        raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value)
    urllib3.exceptions.ReadTimeoutError: UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/bin/docker-compose", line 11, in <module>
        load_entry_point('docker-compose==1.21.0', 'console_scripts', 'docker-compose')()
      File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 71, in main
        command()
      File "/usr/lib/python3/dist-packages/compose/cli/main.py", line 124, in perform_command
        project = project_from_options('.', options)
      File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 41, in project_from_options
        compatibility=options.get('--compatibility'),
      File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 121, in get_project
        host=host, environment=environment
      File "/usr/lib/python3/dist-packages/compose/cli/command.py", line 95, in get_client
        version_info = six.iteritems(client.version())
      File "/usr/lib/python3/dist-packages/docker/api/daemon.py", line 181, in version
        return self._result(self._get(url), json=True)
      File "/usr/lib/python3/dist-packages/docker/utils/decorators.py", line 46, in inner
        return f(self, *args, **kwargs)
      File "/usr/lib/python3/dist-packages/docker/api/client.py", line 198, in _get
        return self.get(url, **self._set_request_timeout(kwargs))
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 546, in get
        return self.request('GET', url, **kwargs)
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
        resp = self.send(prep, **send_kwargs)
      File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
        r = adapter.send(request, **kwargs)
      File "/usr/lib/python3/dist-packages/requests/adapters.py", line 529, in send
        raise ReadTimeout(e, request=request)
    requests.exceptions.ReadTimeout: UnixHTTPConnectionPool(host='localhost', port=None): Read timed out. (read timeout=60)

我们可以看到HTTP连接无法建立。

为什么我需要以非交互方式发送命令?最初,我想使用 Jenkins 发送这些命令(我在 Jenkins 中添加了一个 SSH 插件),我注意到 docker 命令不起作用(与本文中显示的输出相同)。经过几次测试,我意识到当 Jenkins 使用 SSH 时,他以非交互方式发送命令: - ssh user@remote_IP "commands_to_execute"

这种非交互式方式对于简单命令来说不是问题,但对于一些需要在交互式 shell 中执行的 docker 命令来说似乎是一个问题,我猜? 是否有人找到了在非交互式 shell 中成功执行 docker 命令的解决方法?任何帮助、提示或替代解决方案都将不胜感激,因为到目前为止我尝试了很多事情但没有成功..

【问题讨论】:

    标签: docker jenkins ssh


    【解决方案1】:

    您是否检查过它是在 tcp 上运行的 docker-engine 还是通过 unix socket 运行的?

    当您通过 ssh u @ h "command" 登录时,可能没有读取正确的环境变量。

    如果它在 unix 套接字上运行(默认)尝试...

    ssh 用户@remoteIP "cd /path_to_docker_file;DOCKER_HOST=unix:///var/run/docker.sock docker-compose run -d --name wfirst --user 1000:1000 容器"

    或者如果是在 TCP 上运行,你可以试试...

    ssh 用户@remoteIP "cd /path_to_docker_file;DOCKER_HOST=tcp://127.0.0.1:2375 docker-compose run -d --name wfirst --user 1000:1000 容器"

    【讨论】:

    • 谢谢!! docker-engine 确实在 VM 中的 tcp 上运行,删除了默认的 unix 套接字。当我从主机执行命令时,我无权访问 VM 的环境变量,并试图使用未在 VM 上配置的 unix 套接字。设置 DOCKER_HOST 环境变量允许我指定使用 tcp 来执行命令。我的一位同事还找到了与您相同的替代解决方案:- ssh user@remoteIP “docker-compose -H tcp://127.0.0.1:2375 run -d --name wfirst --user 1000:1000 container”跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多