恢复虚拟机后无法连接到Docker

时间:2019-09-10 15:34:19

标签: docker

由于某种原因,每当我挂起虚拟机并恢复它时,我都无法再连接到该虚拟机中托管的Docker容器。通常,我将-p 3000:3000传递到docker容器,以便可以访问其中的rails实例,并且可以正常工作,但是当我挂起VM并在以后恢复它时,即使它位于在docker映像中监听。

这导致我不得不重启虚拟机,因为service docker restart并没有任何改变。

还有其他我应该考虑解决的问题吗?我一直在使用docker挂起/恢复我的VM已有相当一段时间,以前从未遇到过此问题。

编辑

要重现此问题,我只是恢复了我的VM并尝试从VM本身(不在docker映像内)连接到localhost端口3000,所以它无法连接。但是,以下显示端口3000正在侦听:

[root:kali:~/app]# curl http://localhost:3000
curl: (56) Recv failure: Connection reset by peer
[root:kali:~/app]# netstat -antp | grep -i listen
tcp        0      0 127.0.0.1:43050         0.0.0.0:*               LISTEN      84770/autossh       
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd           
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      20478/sshd          
tcp6       0      0 :::3000                 :::*                    LISTEN      32731/docker-proxy  
tcp6       0      0 :::3001                 :::*                    LISTEN      32715/docker-proxy  
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd           
tcp6       0      0 :::22                   :::*                    LISTEN      20478/sshd 

在docker内部,我可以看到Rails在工作:

[root:77f444beafff:~/app]# rails s --binding 0.0.0.0
=> Booting Puma
=> Rails 5.2.3 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.1 (ruby 2.5.1-p57), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

这是docker内部的netstat:

[root:77f444beafff:~/app]# netstat -antp | grep -i listen
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      478/redis-server *: 
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      765/puma 3.12.1 (tc 
tcp        0      0 127.0.0.1:5432          0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::6379   

如果我从docker映像中卷曲,我可以看到它很好地碰到了rails应用程序:

[root:77f444beafff:~/app]# curl http://localhost:3000/ -I
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: text/html; charset=utf-8
ETag: W/"5078d30a6c1a5f6fc5cb7f9a82cd89f5"
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: _vspm_session=Cace%2FN0zB%2F6QJOiietbuHxTHOMZUMuRmEukYqQTNaHQ91hskaN%2BPJzev0KdGUAAtYx9a35Mqdkr8eRkPdH4qOl6vOaCcPU0gy8s7IMfkb9VhRGPPbecepmI%2F9leA2dnD694P8ctXSBklOCnjhN0%3D--SglWrWvx3BFEAI3z--IkylACdXbR6eF27Hgn0Cgg%3D%3D; path=/; HttpOnly
X-Request-Id: 29aa7251-f29a-4309-adec-6af479e7bd9b
X-Runtime: 12.241723

4 个答案:

答案 0 :(得分:0)

这里的几个问题可能会帮助您解决这个问题:

  • 您的Docker容器是否仍在运行?运行docker ps并找到您的容器
  • 由于设置了-p 3000:3000选项,我想端口已经暴露了,但是您可能想检查一下这次是否确实使用此选项运行了容器
  • 您的应用真的在听吗?运行lsof -np | grep listen,发现您的应用程序在端口3000上监听
  • 使用docker exec -it <your_container> bash连接到您的容器,然后尝试运行lsof -np | grep listen来查看这是docker问题还是您的应用程序

答案 1 :(得分:0)

看来,当您在VM上运行netstat时,会得到以下行:

tcp6       0      0 :::3000                 :::*                    LISTEN      32731/docker-proxy

在Docker上,您得到:

tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      765/puma 3.12.1 (tc

这里有两个区别:

  • :::30000 0.0.0.0:3000,第一个表示它正在侦听IPv6,第二个表示它正在侦听IPv4(找到信息on this question)。
  • tcp6tcp,再一次是IPv6 vs IPv4。

根据this other question,看来您必须使用-b ::选项运行rails。

  

-b选项将Rails绑定到指定的IP,默认情况下为localhost。您可以通过传递-d选项将服务器作为守护程序运行。

答案 2 :(得分:0)

请做

sudo docker ps

如果没有容器,请

sudo docker ps -a

您的集装箱停了吗? 如果属实

sudo docker start CONTAINER_ID

答案 3 :(得分:0)

我的VMWare虚拟机(Windows上运行的VMWare)存在完全相同的问题。

对我来说唯一可行的解​​决方法是:

docker stop $(docker ps -aq) && sudo systemctl restart NetworkManager docker

如果我不得不猜测,它可能与启动时某些防火墙规则docker设置有关,也许当您恢复虚拟机时,网络配置的更改会破坏这些规则。

类似的问题:https://github.com/docker/for-mac/issues/1990(对于Mac的docker似乎并不特定)。