最近發現 docker container 對外連線速度很慢,比如說 build image 時跑 apt install、npm install 、或打 api,偶爾還會遇到 timeout。但同一個網段下的電腦卻正常,同時對外網路與區網連線也暢通,這到底是什麼問題呢?
再更進一步觀察,會發現只有該裝置「發出去」的 request 會異常卡頓甚至 timeout,但外部「發進來」的 request 卻是正常響應!研究懷疑可能如這篇文中所說,是 DNS resolution 出問題導致。
目錄
自訂 container 的 DNS server
為了驗證問題,嘗試在 docker compose 中給定 DNS 的位置,試試看速度是否有好轉。如下所示,在 service 下加一個 dns
欄位,並且給定 ip
version: '3.3'
services:
xxx-service:
image: ubuntu
networks:
- xx-network
dns:
- 8.8.8.8
networks:
xx-network:
driver: bridge
如果是用指令直接起,增加 dns
參數即可,如下:
docker run -it -dns=8.8.8.8 ubuntu
實測後發現恢復正常!果然是 DNS 在搞鬼!但難道每次起 container 都還要自己給定 DNS 位置嗎?
自訂 docker 預設的 DNS server
可以直接在 /etc/docker/daemon.json
寫入自訂的預設 DNS 位置,避免抓到 host 中有問題的設定
{
"dns": [
"8.8.8.8",
"8.8.4.4"
]
}
重啟 docker service
$ sudo systemctl restart docker
如何修改 host 的 DNS server
既然 docker 預設抓 host 的 DNS 設定,看來需要檢查一下問題來源,用以下指令查詢 linux 的 DNS
$ cat /etc/resolv.conf
nameserver x.x.x.x
nameserver x.x.x.x
之前預設中華電信的 DNS,可能有雷,難怪最近 host update 時也異常緩慢,立馬修改成 8.8.8.8。
修改方式很簡單,一行一個 DNS ip,前面加 nameserver
keyword 即可。
$ nano /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
Docker Container 裡的 resolv.conf
此時我好奇,如果到剛剛修改過 DNS 設定的 container 下一樣指令,會看到自訂的 DNS ip 嗎?
答案是看情況!如果有建立 network 給 container 使用,resolv.conf
會是 127.0.0.11
$ docker exec xxx cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0
但如果是透過指令起,沒有給定 network 的話,會是我們剛剛設定的 DNS ip
$ docker run --rm ubuntu:20.04 cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
從這則回應得知,127.0.0.11
是 docker 的 embedded DNS server ,container 會先透過此位置再路由到真正設定的 DNS server 完成查詢。
以上就是 docker container 網路速度慢的解決方法,希望能幫助到你!
延伸閱讀:關掉 Network Manager 自己手動設定 static ip 吧!
參考資料:
Solve the problem of slow network requests in docker containers
How to tell docker to use host dns configuration?
DNS not working within docker containers when host uses dnsmasq and Google’s DNS server are firewalled?