【发布时间】:2019-09-16 21:49:33
【问题描述】:
如何配置 Vagrant 以使用 Docker 作为其提供者并使用 Fabric 连接到它?我正在尝试运行一些单元测试,以针对 Ubuntu 18.04 的原始未修改映像验证服务器配置工具。我没有构建自定义图像。
我的 Vagrantfile 是:
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.image = "ubuntu:18.04"
d.remains_running = true
end
end
我的 Python unittest tests.py 文件看起来像:
import unittest
import vagrant
from fabric.api import settings, run
class Tests(unittest.TestCase):
def test_connect_to_server(self):
v = vagrant.Vagrant('.', quiet_stdout=False, quiet_stderr=False)
v.up(provider='docker')
with settings(host_string=v.user_hostname_port(), key_filename=v.keyfile(), disable_known_hosts=True):
run('echo "hello"')
Vagrant 似乎能够创建 Docker 实例,但在 Fabric 连接之前它很快就失败了,并出现错误:
Bringing up machine with provider docker...
Bringing machine 'default' up with 'docker' provider...
==> default: Creating the container...
default: Name: ubuntu18_docker_default_1568669393
default: Image: ubuntu:18.04
default: Volume: /path/to/my/project:/vagrant
default:
default: Container created: c5fb82fa523f0774
==> default: Starting container...
==> default: Waiting for container to enter "running" state...
The container started either never left the "stopped" state or
very quickly reverted to the "stopped" state. This is usually
because the container didn't execute a command that kept it running,
and usually indicates a misconfiguration.
If you meant for this container to not remain running, please
set the Docker provider configuration "remains_running" to "false":
config.vm.provider "docker" do |d|
d.remains_running = false
end
所以看起来默认图像正在运行,但它并没有继续运行。如何配置 Docker 以保持映像运行而不是立即退出,以便我可以使用 Fabric 测试 SSH 命令?
编辑:按照 LinPy 的建议,将我的 Vagrantfile 修改为:
我的 Vagrantfile 是:
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.image = "ubuntu:18.04"
d.remains_running = true
d.cmd = ["tail", "-f", "/dev/null"]
end
end
修复了最初的错误,但仍然导致测试失败并出现新错误:
Bringing up machine with provider docker...
Bringing machine 'default' up with 'docker' provider...
==> default: Creating the container...
default: Name: ubuntu18_docker_default_1568754416
default: Image: ubuntu:18.04
default: Cmd: tail -f /dev/null
default: Volume: /path/to/my/project:/vagrant
default:
default: Container created: 0e5023317321c5cf
==> default: Starting container...
==> default: Provisioners will not be run since container doesn't support SSH.
v.user_hostname_port(): vagrant@172.17.0.2:22
v.keyfile(): /home/myuser/.vagrant.d/insecure_private_key
[vagrant@172.17.0.2:22] run: echo "hello"
Keeping VM.
E
======================================================================
ERROR: test_dev_setup_ubuntu18 (__main__.Tests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/network.py", line 478, in connect
client.connect(**kwargs)
File "/path/to/my/project/.env/lib/python3.7/site-packages/paramiko/client.py", line 368, in connect
raise NoValidConnectionsError(errors)
paramiko.ssh_exception.NoValidConnectionsError: [Errno None] Unable to connect to port 22 on 172.17.0.2
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tests.py", line 167, in test_dev_setup_ubuntu18
run('echo "hello"')
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/network.py", line 692, in host_prompting_wrapper
return func(*args, **kwargs)
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/operations.py", line 1095, in run
shell_escape=shell_escape, capture_buffer_size=capture_buffer_size,
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/operations.py", line 935, in _run_command
channel=default_channel(), command=wrapped_command, pty=pty,
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/state.py", line 435, in default_channel
chan = _open_session()
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/state.py", line 416, in _open_session
transport = connections[env.host_string].get_transport()
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/network.py", line 156, in __getitem__
self.connect(key)
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/network.py", line 148, in connect
user, host, port, cache=self, seek_gateway=seek_gateway)
File "/path/to/my/project/.env/lib/python3.7/site-packages/fabric/network.py", line 610, in connect
raise NetworkError(msg, e)
fabric.exceptions.NetworkError: Low level socket error connecting to host 172.17.0.2 on port 22: Unable to connect to port 22 on 172.17.0.2 (tried 1 time)
我假设关键信息是“Provisioners will not be run because container doesn't support SSH.”,但我不明白这一点,因为 Ubuntu 18.04 应该预装了 SSHD。我尝试修改 cmd 以安装 SSH,变体如下:
d.cmd = ["apt", "-yq", "install", "openssh-server", "&&", "/etc/init.d/ssh", "start", "&&", "/bin/bash"]
但这没有任何效果,仍然返回相同的错误。为什么 Docker 报告 Ubuntu 容器不支持 SSH?
【问题讨论】:
标签: python docker vagrant fabric