在網路上查到的文章大至上得到的說明是,這是因為 windows 可能在某個版本的升級開始會把某些 port 或某個範圍的 port 給「保留」,其中就有包含 mssql 一般慣用的 1433/tcp,而 windows 的一個 HNS 的服務有把一些 port 給「保留」
但也有一說是因為 windows 本身使用了 Hyper-V 把 1433/tcp 給保留了起來
我比較認為是 hyper-v 的問的,因為我目前的 docker 並不是運行在 WSL2 的,還是在比較早期要用 hyper-v 的虛擬機上,所以我比較認為是 hyper-v 引起的
故,如果有跟我遇到一樣問是的,可以先用
netsh interface ipv4 show excludedportrange protocol=tcp
的指定來列出被「保留」下來的 tcp port (注: 上述的指令要用「管理員身份」去執行)
如果上述的指令沒有列出你用到的 port ,那你的問題就比較偏向是你要用的 port 已被你電腦中其他的程序佔用,又或者是其他的程序先加到他自己的「保留」了,那有以下方式你可以試試
- netstat -ano|findstr "port"
- 此是先找目前電腦 listen 的 port 是不是有你要用的,如果有出現,此指令也會列出用這個 port 的 process id(PID),你如果確定這個程序你沒有要用或可以改 port 那你就中止這個程序或去改 port
- 如果沒列出來,那再走以下的建議方式
- net stop winnat && net start winnat
- 把 winnat 這服務重啟,這個服務重啟後再去看上述「excludedportrange」的指令,理論上應該就會列出來的項目變少了
- 此方式理論上應該是可以直接解決問題,但只是麻煩點,有可能要你在啟動 docker 容器時發現「Ports are not available...」時就要把 winnat 服務重啟,但我覺得此方式相對保險
- 因為認為是 hyper-v 搞的,那來對 hyper-v 處理
- dism.exe /Online /Disable-Feature:Microsoft-Hyper-V
- 先把 hyper-v 這功能停用(注意: 如果你跟我一樣 docker 目前是跑在 hyper-v 上面的,這指令下去你 docker 就會異常,直到重新把 hyper-v 啟用)
- netsh interface ipv4 add excludedportrange protocol=tcp startport={port} numberofports=1
- 把你的 {port} 增加到你自己要保留的設定中,這設定會讓有其他程序要用 {port} 時反而系統會告知該程序這個 {port} 已被保留不能用
- dism.exe /Online /Enable-Feature:Microsoft-Hyper-V /ALL
- 重新啟用 Hyper-v(注意: 如果重新啟用 hyper-v 後 docker 啟動有問題,那建議把 docker 重新安裝)
- reg add HKLM\SYSTEM\CurrentControlSet\Services\hns\State /v EnableExcludedPortRange /d 0 /f
- 此項…我認為是上述的方式都不行時再用,因為畢竟要動到regedit,多少有點風險