2019年7月9日 星期二

「Docker pull 卡住不動」 的實驗計畫

不太確定為什麼, 偶爾會遇到 docker pull 抓映像檔抓到一半突然卡住不動。 很多人都遇過相同的問題, 而且很多年了都沒有解決, 到現在 Bounty Source 還在懸賞。 我在電腦教室特別常遇到這個問題; 可惜上課期間來不及研究。 這篇的目的是希望下次再遇到時, 可以做一些實驗, 確認一下到底是伺服器那頭的問題, 還是我們這頭的問題。 如果夠多人測試不同的排列組合, 並且到上述 issue 回報自己的排列組合, 說不定對開發者除錯會有一些幫助。

以下提到設定檔的地方, 都以 lubuntu 18.04 bionic beaver 為準。

一、 禁止平行下載

我曾經遇過: 用 ctrl-c 把自己的下載中斷掉, 學生們的下載就突然繼續動起來了。 所以跟 這個回答 有相同的猜測: 設定禁止平行下載有沒有用?

編輯 /etc/docker/daemon.json 設定檔, 在裡面加一句: "max-concurrent-downloads": 1 。 如果這個檔原本不存在, 那就直接產生: echo '{"max-concurrent-downloads": 1} > /etc/docker/daemon.json 。 然後重新啟動 docker: systemctl daemon-reload ; systemctl restart docker 再試試看 docker pull 是否成功。

二、 改從不同的伺服器 pull

提供 docker repositories 讓人下載的地方, 不只 docker hub, 還有很多其他伺服器 (其他的 registries)。 這裡就拿兩個 (不需要特別登入手續的) registries 來測試。

[quay.io] 到 quay.io 右上角的 search 隨便搜尋, 側如 "hello world" 或 "machine learning" 之類的。 (較大、 很多 layers 的映像檔比較有機會卡在一半。) 隨便挑一個專案點進去, 再點左邊 「tags」。 隨便挑一個版本, 點右邊的 「fetch tag」。 再點 Image Format 的選單, 選取 "Docker Pull (by tag)", 會出現一個 docker pull 指令。把那個指令抄過來執行。

[gcr.io] Google Container Registry 上面有哪些公開的 repo 可以下載呢? 從 這個問答 找到 這個清單。 隨便挑一個專案點進去, 再從當中隨便挑一個 tag (版本) 點進去。 點 「Show Pull Command」, 就有指令可以抄。

如果從其他的 registries 下載大的 repo 可以成功; 從 docker hub 卻不行, 那就有可能是 docker hub 的問題。

三、 設定 proxy

或者, 會不會是我們這頭, 例如學校對外網路或本地的 ISP 的某些設定所造成的呢? 為此, 我們設定從世界其他地方的 proxy 代為連線, 看看是否還有相同的問題。 這一節基本上就是照著 官方文件 這篇文章 做而已。

建立這個設定檔: /etc/systemd/system/docker.service.d/http-proxy.conf (有可能需要先手動建立目錄), 裡面長得類似這樣:

[Service]    
Environment="HTTP_PROXY=http://12.34.56.78:9012"
Environment="NO_PROXY=localhost,127.0.0"

搜尋 free proxy, 找到 這個隨時在更新的清單。 從這裡隨便挑一個, 替換掉上面的 IP 位址跟 port 號碼。

為了確認 docker daemon 真的有看到我們的設定、 在設定檔裡 先故意寫錯 IP 或 port 號。 然後 systemctl daemon-reload ; systemctl restart docker 以便重新啟動 docker daemon。 再次 docker pull 時, 應該要看到 proxyconnect tcp: dial tcp 12.34.56.78:9011: getsockopt: connection refused 之類的錯誤訊息。

然後把 IP 跟 port 號改回正確值、 再重新啟動 docker daemon 一次。 此時如果 docker pull 成功了, 那就表示可能是本地網路設定的問題。

如果還是失敗, 那就每位同學試用不同的 proxy 看看。

如果大家各自用不同的 proxy 都失敗, 那就... 暫時認輸了 orz

沒有留言:

張貼留言