由于某种原因,每当我暂停并恢复虚拟机时,我都无法再连接到虚拟机中托管的 docker 容器。通常,我传递-p 3000:3000
到 docker 容器,以便可以访问其中的 Rails 实例,这工作正常,但是当我暂停虚拟机并稍后恢复它时,我无法再连接到端口 3000,即使它正在 docker 映像中侦听。
这导致我必须重新启动虚拟机,因为这service docker restart
不会改变任何内容。
我还应该考虑其他事情来解决这个问题吗?我已经暂停/恢复带有 docker 的虚拟机有一段时间了,以前从未遇到过这个问题。
编辑
为了重现此问题,我只是恢复了虚拟机并尝试从虚拟机本身(不在 docker 映像内)连接到本地主机端口 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
Run Code Online (Sandbox Code Playgroud)
从 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
Run Code Online (Sandbox Code Playgroud)
这是 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
Run Code Online (Sandbox Code Playgroud)
如果我从 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
Run Code Online (Sandbox Code Playgroud)
我的 VMWare 虚拟机(在 Windows 上运行的 VMWare)遇到了完全相同的问题。
对我有用的唯一解决方法是:
docker stop $(docker ps -aq) && sudo systemctl restart NetworkManager docker
Run Code Online (Sandbox Code Playgroud)
如果我不得不猜测,我会说这可能与启动时 docker 设置的某些防火墙规则有关,也许当您恢复虚拟机时,网络配置的更改会破坏这些规则。
类似问题: https: //github.com/docker/for-mac/issues/1990(似乎不是特定于 docker for mac)。
我能够根据lannox在评论中给出的提示解决这个问题。有必要将 docker 容器的网络接口标记为不受NetworkManager 管理。
为此,请创建一个/etc/NetworkManager/conf.d/10-unmanage-docker-interfaces.conf
包含以下内容的新文件:
[keyfile]
unmanaged-devices=interface-name:docker*;interface-name:veth*;interface-name:br-*;interface-name:vmnet*;interface-name:vboxnet*
Run Code Online (Sandbox Code Playgroud)
docker*
这会将 NetworkManager 配置为忽略名称为、
veth*
、
br-*
、
vmnet*
和
接口的所有接口vboxnet*
。
然后使用 重新启动 NetworkManager sudo systemctl restart NetworkManager
。
下次主机挂起和恢复时,docker 容器将保持其网络连接。
这里有几个问题可能会帮助您解决这个问题:
docker ps
并找到您的容器-p 3000:3000
设置了该选项,我猜端口已公开,但您可能想检查这次是否确实使用此选项运行了容器lsof -np | grep listen
并找到您的应用程序正在侦听端口 3000docker exec -it <your_container> bash
尝试运行lsof -np | grep listen
以查看这是否是 docker 问题或您的应用程序问题 归档时间: |
|
查看次数: |
2365 次 |
最近记录: |