【问题标题】:Port forwarding in docker-machine?docker-machine中的端口转发?
【发布时间】:2017-08-27 23:20:18
【问题描述】:

由于不推荐使用boot2docker,我已切换到docker-machine,但我不知道如何从docker-machine 打开端口。在boot2docker 我可以这样做:

boot2docker ssh -L 27017:localhost:27017

只要 SSH 连接打开,这会将端口 27017 从 VirtualBox 转发到 localhost 27017。请注意,我不是在寻找在 VirtualBox 中永久打开端口的方法。如何使用docker-machine 实现这一目标?

【问题讨论】:

    标签: docker boot2docker docker-machine


    【解决方案1】:

    您仍然可以从 docker 机器使用的 VirtualBox 访问 VBoxmanage.exe 命令:

    VBoxManage controlvm "boot2docker-vm" natpf1 "tcp-port27017,tcp,,27017,,27017";
    
    • 使用docker-machine info 获取您的虚拟机的名称。
    • 如果 vm 尚未启动,请使用 modifyvm

    请参阅this answer 中的实际示例。


    这是当前的解决方法,等待将参数传递给docker-machine ssh 的可能性:参见issue 691

    另一种解决方法是转发端口,直接使用虚拟机的IP:

     $(docker-machine ip default)
    

    作为commentedsdc

    您可以确认端口转发设置正确

     VBoxManage showvminfo boot2docker-vm | grep "NIC.* Rule" 
    

    【讨论】:

    • 虽然这行得通,但这并不是我真正想要实现的目标。如果设置不是永久的,我会更喜欢(我已经更新了问题以反映这一点)。如果这不起作用,我仍然感谢您的回答。
    • @Johan 我已经编辑了答案以解释为什么我建议使用 VM 端口转发,而不是 ssh。
    • 太棒了!!非常感谢。
    • 您可以使用VBoxManage showvminfo boot2docker-vm | grep "NIC.* Rule"确认端口转发设置正确
    • @sdc 谢谢。我已将您的评论包含在答案中以提高知名度。
    【解决方案2】:

    使用最新版本的机器,您可以简单地执行(其中 default 是机器的名称):

    docker-machine ssh default -L 27017:localhost:27017
    

    这是一个比 VM 配置更改更临时的解决方案。

    使用以下变体仅在后台进程中转发端口:

    docker-machine ssh default -f -N -L 27017:localhost:27017
    
    • -f 请求 ssh 在命令执行前进入后台。
    • -N 允许空命令(此处仅用于转发端口)

    【讨论】:

    • 尝试执行 docker-machine ssh default -N -L 80:localhost:80 并出现错误:Privileged ports can only be forwarded by root. exit status 255
    • 如果我尝试sudo docker-machine ssh default -N -L 80:localhost:80 我还有另一个通知machine does not exist
    • @noonehos 正如我在回答中所说,默认是机器的名称。通过输入 docker-machine ls 找到你的。
    • 使用 Boot2Docker 版本 1.11.2 和 docker-machine 版本 0.7.0, build a650a40 我得到了这个错误:sh: illegal option -L...
    • 嗨 Anthony,我遇到了同样的错误 sh: 非法选项 -L 。我可以知道解决方案吗?
    【解决方案3】:

    您可以通过 ssh 进入机器并传递常规端口转发参数:

    ssh docker@$(docker-machine ip default) -L 27017:localhost:27017
    

    docker用户的密码是tcuser。 (见https://github.com/boot2docker/boot2docker

    【讨论】:

    • 谢谢,很有帮助。顺便说一句,在大多数系统上,这只会使端口 27017 绑定到本地环回适配器,这意味着无法从主机外部访问它。使用ssh docker@$(docker-machine ip default) -L 1.2.3.4:27017:localhost:27017将其暴露给外界,其中1.2.3.4是本地IP地址。
    • 是否可以使用 docker-machine ssh 转发多个端口?例如。 -L 27017:localhost:27017 -L 3000:localhost:3000
    【解决方案4】:

    由于我很难记住如何执行此操作,我创建了一个名为 pf(代表“端口转发”)的小型 bash 脚本,它允许您执行以下操作:

    $ pf 8080
    

    这会将 docker 端口 8080 转发到后台的主机端口 8080(附加 -f 使其在前台运行)。要使用不同的主机端口,只需:

    $ pf 8090:8080
    

    将主机端口 8090 映射到 8080。

    要停止端口转发添加-s:

    $ pf 8090:8080 -s
    

    (实际上主机端口也足够了:pf 8090 -s)。还有其他可用选项,请查看github 页面。

    【讨论】:

      【解决方案5】:

      如果您不想使用密码,我想补充一点,您应该只指向私钥。

      ssh -L 8080:localhost:8080 -i ~/.docker/machine/machines/default/id_rsa docker@$(docker-machine ip default)
      

      【讨论】:

        【解决方案6】:

        只是为了在脚本中增强@VonC 的答案 - 目前如果在 MacOS X 上使用 Docker Toolbox,默认 VM 机器是“默认”。所以一个映射所有暴露的容器的脚本应该是这样的:

        for port in `docker port cassandra | cut -d'-' -f1`; 
        do 
            port_num=`echo ${port} | cut -d'/' -f1`
            port_type=`echo ${port} | cut -d'/' -f2`
            echo "Create rule natpf1 for ${port_type} port ${port_num}"
            VBoxManage controlvm "default" natpf1 "${port_type}-port${port_num},${port_type},,${port_num},,${port_num}"
        done
        

        如果尝试多次执行,则应在创建前添加一条语句以删除现有规则:

        VBoxManage controlvm "default" natpf1 delete "${port_type}-port${port_num}"
        

        在脚本中,它假定您已经将端口从容器转发到虚拟机。

        docker port cassandra
        

        给出如下输出:

        7000/tcp -> 0.0.0.0:7000
        

        【讨论】:

        • 注意:脚本假定正在运行的容器名称是“cassandra” - 在 for 循环中。 (码头港口卡桑德拉)