今天在啟動本機的redis容器時報了如下錯誤:
Error invoking remote method 'docker-start-container':
Error: (HTTP code 500) server error - Ports are not available:
listen tcp 0.0.0.0:6379: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
我的環境信息
- Windows版本: Windows 11 專業版
- Docker Desktop Version: 4.3.2
- 啟用Hyper-V 和 WSL2
查找問題
首選確保本機端口是否被占用,使用如下命令:
netstat -ano | findstr 6379
結果端口沒有被占用
查資料之后發現 Hyper-V
會保留部分tcp端口,開始到結束范圍內的端口不可用, 使用如下命令查看保留的端口:
netsh interface ipv4 show excludedportrange protocol=tcp
可以得到
協議 tcp 端口排除范圍
開始端口 結束端口
---------- --------
1026 1125
1126 1225
1226 1325
1326 1425
1426 1525
1538 1637
2327 2426
2427 2526
2527 2626
2627 2726
2727 2826
2827 2926
6344 6567
50000 50059 *
50070 50070 *
* - 管理的端口排除。
可以看到6379
在排除范圍內
解決辦法
此時可以修改容器啟動命令(主要是修改端口)重新啟動容器。
這種是繞過了被保留的端口, 如果你的程序一定要使用范圍內的端口,有如下三種方式
一、臨時關閉Hyper-V
法
-
臨時關閉
Hyper-V
-
配置端口
-
恢復
Hyper-V
二、重啟電腦大法
保留的端口是隨機的,每次重啟電腦都會改變,因此可以通過重啟電腦來解決。
三、永久排除保留端口
1、在運行 Docker 之前,以管理員身份運行 powershell
2、使用以下命令永久排除6379作為保留端口(如果端口被占用需要重啟一次電腦)
netsh int ipv4 add excludedportrange protocol=tcp startport=6379 numberofports=1 store=persistent
提示:關鍵在於
store=persistent
參數表示持久化信息
上面的命令可以通過修改numberofports
參數保留startport
開始的多個端口
3、再次運行 netsh interface ipv4 show excludedportrange protocol=tcp
命令可以看到6379端口已被排除(帶有*號標記)
協議 tcp 端口排除范圍
開始端口 結束端口
---------- --------
1026 1125
1126 1225
1226 1325
1326 1425
1426 1525
1538 1637
2327 2426
2427 2526
2527 2626
2627 2726
2727 2826
2827 2926
6379 6379 *
50000 50059 *
50070 50070 *
* - 管理的端口排除。
之后再重啟電腦6379
端口就不會包含在保留端口內了。
總結
三種解決方法中,第一種臨時關閉Hyper-V
可以避免重啟電腦,可以作為緊急解決辦法。第二種重啟電腦需要靠運氣,第三種永久排除保留端口是最高效的。