【问题标题】:How to debug "Vagrant cannot forward the specified ports on this VM" message如何调试“Vagrant 无法转发此 VM 上的指定端口”消息
【发布时间】:2012-06-08 17:01:56
【问题描述】:

我正在尝试启动 Vagrant 实例并收到以下消息:

Vagrant cannot forward the specified ports on this VM, since they
would collide with another VirtualBox virtual machine's forwarded
ports! The forwarded port to 4567 is already in use on the host
machine.

To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:

  config.vm.forward_port 80, 1234

我打开了 VirtualBox,但目前我没有任何运行的盒子,所以我很难过。如何确定哪个进程正在监听 4567?有没有办法列出我机器上运行的所有 Vagrant 盒子?

谢谢, 凯文

【问题讨论】:

  • 确保您的防火墙/防病毒软件没有阻止它。那是我的问题。
  • vagrant reload 是适合我的解决方案

标签: vagrant


【解决方案1】:

你可以通过运行来查看你的机器上正在运行哪些 vagrant 实例

$ vagrant global-status
id       name    provider   state   directory
----------------------------------------------------------------------
a20a0aa  default virtualbox saved   /Users/dude/Downloads/inst-MacOSX
64bc939  default virtualbox saved   /Users/dude/svn/dev-vms/ubuntu14
a94fb0a  default virtualbox running /Users/dude/svn/dev-vms/centos5

如果您没有看到任何虚拟机正在运行,那么您的冲突就不是 vagrant box(vagrant 知道的)。接下来要做的是启动 VirtualBox UI,并检查它是否有任何实例正在运行。如果您不想运行 UI,您可以:

ps -ef |grep VBox

如果您正在运行 VirtualBox 实例,它们应该包含在该输出中。您应该能够杀死输出中包含 VirtualBox 的进程。一个问题是这些过程之一似乎存在进行保活。只需杀死最高的 VirtualBox 进程。如果你有一个 VirtualBox 镜像正在运行但 vagrant 不知道它,一些 Vagrant 目录可能已被手动删除,这意味着 Vagrant 失去了对实例的跟踪。

【讨论】:

  • 错误消息是红鲱鱼的情况之一 - 谢谢
  • 如果你想用单线杀死VBox进程:ps -ef |grep VBox | awk '{print $2}' | xargs kill
  • 在 Mac 上,我必须真正打开 virutalbox 才能摆脱正在运行的实例,但再多的破坏也无济于事。
  • 在运行vagrant global-status 后运行vagrant destroy -f <id> 杀死它们
【解决方案2】:

注意,您的 Vagrantfile 不是唯一在调出 Vagrant 框/实例时使用的文件。

当你得到这个时:

~/dev/vagrant user$ vagrant reload
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 8001 is already in use
on the host machine.

To fix this, modify your current projects Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:

  config.vm.network :forwarded_port, guest: 8001, host: 1234

Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn't allow modifying port forwarding.
~/dev/vagrant user$ 

实际上,您不仅使用 ~/dev/vagrant 中的 Vagrantfile,而且还使用通常位于此处的“box”分发 .box 文件中的文件:

~/.vagrant.d/boxes/trusty/0/virtualbox/Vagrantfile

如果你看一下,你会发现它有很多默认端口映射:

$ cat ~/.vagrant.d/boxes//trusty/0/virtualbox/Vagrantfile
$script = <<SCRIPT
bzr branch lp:jujuredirector/quickstart /tmp/jujuredir
bash /tmp/jujuredir/setup-juju.sh
SCRIPT

Vagrant.configure("2") do |config|
  # This Vagrantfile is auto-generated by 'vagrant package' to contain
  # the MAC address of the box. Custom configuration should be placed in
  # the actual 'Vagrantfile' in this box.

  config.vm.base_mac = "080027DFD2C4"
  config.vm.network :forwarded_port, guest: 22, host: 2122, host_ip: "127.0.0.1"
  config.vm.network :forwarded_port, guest: 80, host: 6080, host_ip: "127.0.0.1"
  config.vm.network :forwarded_port, guest: 8001, host: 8001, host_ip: "127.0.0.1"
  config.vm.network "private_network", ip: "172.16.250.15"
  config.vm.provision "shell", inline: $script

end

# Load include vagrant file if it exists after the auto-generated
# so it can override any of the settings
include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)
load include_vagrantfile if File.exist?(include_vagrantfile)

所以,继续编辑此文件以删除有问题的冲突转发端口:

  config.vm.network :forwarded_port, guest: 22, host: 2122, host_ip: "127.0.0.1"
  config.vm.network :forwarded_port, guest: 80, host: 6080, host_ip: "127.0.0.1"
  # config.vm.network :forwarded_port, guest: 8001, host: 8001, host_ip: "127.0.0.1"

作者:

~/dev/vagrant user$ cp ~/.vagrant.d/boxes//trusty/0/virtualbox/Vagrantfile ~/.vagrant.d/boxes//trusty/0/virtualbox/Vagrantfile.old
~/dev/vagrant user$ vi ~/.vagrant.d/boxes//trusty/0/virtualbox/Vagrantfile

并注意其他 Vagrantfiles 包含,即:

include_vagrantfile = File.expand_path("../include/_Vagrantfile", __FILE__)

现在它可以工作了:

$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'trusty'...
==> default: Matching MAC address for NAT networking...
==> default: Setting the name of the VM: vagrant_default_1401234565101_12345
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 => 2122 (adapter 1)
    default: 80 => 6080 (adapter 1)
    default: 22 => 2222 (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Connection timeout. Retrying...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Mounting shared folders...
    default: /vagrant => /Home/user/dev/vagrant/vagrant-docker
==> default: Running provisioner: shell...
    default: Running: inline script
...

希望这会有所帮助。

【讨论】:

  • 哇,所以使用 Vagrant 你不能“覆盖”转发的端口?这意味着我不能多次使用同一个盒子;(
【解决方案3】:

正如消息所说,端口与主机箱发生冲突。我只需将端口更改为主机上的其他值。所以如果我收到错误

config.vm.forward_port 80, 1234

那我就改成

config.vm.forward_port 80, 5656

因为 1234 可能在我的主机上使用。

为了实际检查任何机器上的端口,我使用该操作系统的tcpview 实用程序并了解哪个端口在哪里使用。

【讨论】:

  • 如何更改端口?
  • stackoverflow.com/questions/24127852/… tl/dr:config.vm.network "forwarded_port", guest: 22, host: 2201, id: "ssh", auto_correct: true
  • Vishal 的回答适用于旧版本的 Vagrants vm: * The following settings shouldn't exist: forward_port
  • 对于 windows tcpView 将是 this
【解决方案4】:

我遇到了这个问题,结果发现 RubyMine 仍在保留一个端口。通过运行以下命令,我发现了哪个应用程序占用了端口(在我的例子中是 31337):

lsof -i | grep LISTEN 

输出

node       1396 richard.nienaber    7u  IPv4 0xffffff802808b320      0t0  TCP *:20559 (LISTEN)
Dropbox    1404 richard.nienaber   19u  IPv4 0xffffff8029736c20      0t0  TCP *:17500 (LISTEN)
Dropbox    1404 richard.nienaber   25u  IPv4 0xffffff8027870160      0t0  TCP localhost:26165 (LISTEN)
rubymine  11668 richard.nienaber   39u  IPv6 0xffffff8024d8e700      0t0  TCP *:26162 (LISTEN)
rubymine  11668 richard.nienaber   65u  IPv6 0xffffff8020c6e440      0t0  TCP *:31337 (LISTEN)
rubymine  11668 richard.nienaber  109u  IPv6 0xffffff8024d8df80      0t0  TCP localhost:6942 (LISTEN)
rubymine  11668 richard.nienaber  216u  IPv6 0xffffff8020c6ef80      0t0  TCP localhost:63342 (LISTEN)

【讨论】:

  • 当没有人在该端口上监听时该怎么办,但 vagrant 仍然抱怨该端口正在使用中?怎么可能?
【解决方案5】:

还请注意(至少在 Vagrant 1.6.4 中)有文件夹 ~/.vagrant.d/data/fp-leases,其中的文件名称为 80808081 等。刚刚删除此文件夹内容对我有帮助。

【讨论】:

  • 为了更深入地了解,这是当前用于虚拟机的端口,这可能会有所帮助的情况是,如果 vagrant 文件所在的目录在其仍在运行时被删除,vagrant 将仍然相信端口正在使用,因为它没有执行虚拟机的拆除,删除这些文件将“释放”这些端口供其他流浪机器使用。
  • 但是为什么 vagrant destroy 不清除与版本 2.2.4 上的框关联的 fp-leases ?似乎只有每秒destroy 才能清除它?
【解决方案6】:

Vagrant.configure("2") 做 |config|

config.vm.network "forwarded_port",访客:80,主机:8080,

auto_correct: true

结束

最后的 :auto_correct 参数设置为 true 告诉 Vagrant 自动更正任何碰撞。在 vagrant up 或 vagrant reload 期间,Vagrant 将输出有关任何碰撞检测和自动更正的信息,以便您注意并采取相应措施。

https://www.vagrantup.com/docs/networking/forwarded_ports.html

【讨论】:

  • 这是我实际问题的解决方案,Vagrant 似乎忽略了我在配置中的 config.vm.network "forwarded_port" 行中放入的任何内容。
【解决方案7】:

如果您使用 Proxifier(或类似应用),请先尝试关闭它。这是我在 OSX 10.9 上使用 Proxifier 时遇到的问题。

【讨论】:

  • 我联系了 Proxifier 的技术支持。他们让我把Localhost规则移到最上面,完美解决了问题。
【解决方案8】:

我是这样解决的:

  1. vagrant suspend
  2. 在 RubyMine IDE 上关闭项目
  3. vagrant resume
  4. 在 RubyMine IDE 上打开最近

【讨论】:

    【解决方案9】:

    我的观察: 我没有在端口 8000 上运行任何进程,因此端口转发基本上不起作用。 使固定: 菲尔的回答提供了一个解决方案

    ~/.vagrant.d/boxes/ 
    

    上面的路径有其他版本的 vagrant 文件,列出了端口 8000。一旦我使用下面的命令将它们全部修剪掉,我就可以成功运行 vagrant up

    vagrant box remove [name] --all
    

    【讨论】:

      【解决方案10】:

      出路:

      1. $ vagrant 暂停
      2. $ vagrant 简历

      【讨论】:

        【解决方案11】:

        我遇到了这个问题,因为我有一个尝试运行 Postgres 的 VM,而我的本地计算机上的端口 5432 上运行了 Postgres。

        vagrant resume之后,我得到了错误:

        Vagrant 无法转发此 VM 上的指定端口,因为它们 会与已经在监听的其他应用程序发生冲突 在这些端口上。转发到 5432 的端口已被使用 在主机上。

        查找端口 5432 上运行的内容:

        o-ets-webdeveloper:portal me$ lsof -i :5432
        COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
        postgres 1389     me    5u  IPv6 0x681a62dc601cf1e3      0t0  TCP localhost:postgresql (LISTEN)
        postgres 1389     me    6u  IPv4 0x681a62dc6499362b      0t0  TCP localhost:postgresql (LISTEN)
        

        原来是本地 Postgres,杀死这些进程让我可以成功运行 vagrant resume

        【讨论】:

          【解决方案12】:

          您必须在当前目录中修改您的 Vagrantfile,包括以下命令:

          config.vm.network "forwarded_port", guest: 4567, host: <a port not used by your host machine>
          

          请记住,还有一个隐藏文件夹 (.vagrant.d/),其中包含您的 vagrant 环境的设置以及您的盒子的配置文件。通常此文件夹位于您的主目录中。

          例如

          ~/.vagrant.d/boxes/<your_box_name>/0/virtualbox/Vagrantfile
          

          通常这个文件包括另一个位于~/.vagrant.d/boxes/&lt;your_box_name&gt;/0/virtualbox/include/_Vagrantfile的Vagrantfile

          您还必须使用端口转发命令修改此文件

          【讨论】:

            【解决方案13】:

            主机崩溃后

            我的主机崩溃之后,我遇到了这个问题(配置从几周前就开始工作了)。我正在使用 VMware 提供程序。

            问题

            问题显然是这样的(我还没有 100% 理解):

            • VMware 仍然有运行崩溃前的 Vagrant VM 的端口映射,即 IP 192.166.157.131
            • 当 Vagrant 启动时,它请求不同 IP 的映射。它无法获取它们,因为它们正在“使用中”。尽管 Vagrant 本身已经为同一个 Vagrant 框的先前运行进行了映射,但它报告了这些端口。
            • 无论我在 Vagrant 方面做什么,端口都不会被释放。

            问题的根源(推测)

            大概是我的问题的根源是我的网络配置:

            • 流浪者请求config.vm.network "private_network", ip: 192.169.0.3, 其中使用了 VMnet5,
            • 但端口映射使用 NAT,在我的机器上是 VMnet8。

            修复尝试 1

            我已手动停用 VMnet5 并将我的 Vagrantfile 更改为请求 config.vm.network "private_network", ip: 192.169.157.131,就是已经拥有所需端口映射的地址。 (更清洁的解决方案是通过使用动态 IP config.vm.network "private_network", type: "dhcp", 但这对我的设置很不方便。)

            它没有帮助。 Vagrant 仍然抱怨端口不可用。

            修复尝试 2

            我在 VMware Desktop 中删除了端口映射(编辑 -> 虚拟网络编辑器)。

            没有有帮助(你会相信吗?)。 Vagrant 仍然抱怨端口不可用。 netstat -ao 确实仍将端口报告为 LISTENING。

            我杀死了netstat 报告的进程:14032。
            netstat 仍然报告端口正在侦听,现在由不同的进程:
            我杀死了那个进程 13492。
            netstat 仍然报告端口正在监听,现在由不同的进程:
            我杀死了那个进程 13340.
            (注意递减进程ID。)

            netstat 不再将端口报告为正在侦听。
            Vagrant 可笑地仍然抱怨端口不可用。
            netstat 即使在收到 Vagrant 错误消息后也不再报告端口正在侦听。
            嗯?
            那些港口被占领的阴暗过去现在应该没有任何痕迹!

            修复尝试 3

            我接下来计划重新启动我的主机并希望最好。 但在我这样做之前,我关闭了 VMware Desktop GUI 并给了 Vagrant 最后一次尝试。

            然后就成功了。

            要点:显然 VMware 基础架构有时会保留配置

            • 比人们想要的更接近
            • 而且比它自己的 GUI 声称的更接近。

            【讨论】:

              【解决方案14】:

              在这里参考我的回答:https://superuser.com/a/1610804/1252585

              再次编写内容:

              列出所有 LISTENING 端口:

              $ netstat -a
              

              使用以下命令查找在所需端口上运行的进程的进程 ID:

              $ netstat -ano | findstr :8080
              

              结果会显示为:

              $ netstat -ano | findstr :5000
                TCP    0.0.0.0:5000           0.0.0.0:0              LISTENING       18024
              

              这里,18024 是 PID 或进程 ID。

              然后使用以下命令杀死8080后的进程:

              $ taskkill /PID 18024 /F
              

              $ taskkill //PID 18024 //F

              结果将显示为:

              $ taskkill //PID 18024 //F
              SUCCESS: The process with PID 18024 has been terminated.
              

              【讨论】:

                【解决方案15】:

                因为你的机器上已经有另一个 Vagrantfile,所以它们都使用相同的端口,所以你只能打开新的 Vagrantfile。

                创建一个转发端口映射,允许从主机上的端口访问机器内的特定端口。在下面的例子中:

                # accessing "localhost:8080" will access port 80 on the guest machine.
                  config.vm.network "forwarded_port", guest: 3000, host: 3000
                  config.vm.network "forwarded_port", guest: 3001, host: 3001
                  config.vm.network "forwarded_port", guest: 8080, host: 8080
                  config.vm.network "forwarded_port", guest: 5000, host: 5000
                  config.vm.network "forwarded_port", guest: 5432, host: 5432 >>> old port 
                  config.vm.network "forwarded_port", guest: 5432, host: 1234 >>> new port
                

                只需将主机从 5432 更改为 1234 之类的任何内容。

                【讨论】:

                • 请修正格式。为什么这里有大粗体?
                猜你喜欢
                • 2014-07-30
                • 2021-07-19
                • 1970-01-01
                • 2011-02-17
                • 2017-02-25
                • 1970-01-01
                • 2016-03-24
                • 2017-11-22
                • 2016-01-13
                相关资源
                最近更新 更多