Doker的開發:常見問題及解決方法

jopen 9年前發布 | 15K 次閱讀 Doker Docker


原文鏈接: Docker for Development: Common Problems and Solutions (翻譯:Bruce.Chen)

從開發環境Dev到生產環境Prod已經開始用docker了嗎? 這里有一些hacky用來解決開發中的常見問題。有些只適用于VirtualBox,其他的則沒有限制。

端口轉發到主機

端口轉發只能用在boot2docker下的VM。 如果你也想用同一端口轉發到你的主機,比如你正在測試Android應用程序的后臺或者想分享VM呢?

你有兩個選擇:

1 — 到VirtualBox的設置里去添加一個Bridged adapter。 現在當你再啟動docker-machine,你的VM就會得到一個正式的LAN地址。 這時你就可以從網絡上的其他任何設備訪問虛擬機,而且docker-compose的端口轉發也可以使用。

2 — 等到 Issue #691 (或相關)得到解決。 就可以允許你使用SSH端口轉發。唯一的問題是你必須手動的操作需要的每一個端口。

docker-machine ssh -L <host-port>:localhost:<machine-port> 

性能低

默認情況下,當你用docker-machine創建一個VM,只得到非常低的配置(1CPU,1GB RAM)。 運行“docker-machine help create”去了解相應的flags后,就可用它們來增加CPU/RAM。 例如:

docker-machine create \ --driver virtualbox \ --virtualbox-cpu-count 2 \ --virtualbox-memory 2048 \ dev

符號鏈接錯誤

有多種原因導致 這種 錯誤發生,但是最常見的一種是VirtualBox缺少 Guest Additions 。 請確定它被安裝了(VirtualBox > Preferences > Extensions)并要匹配VirtualBox的版本。 這大多發生在VirtualBox是單獨安裝的。

共享文件夾不能得到更新

在boot2docker中,這是一個 已知的bug 。因為它為了考慮提升速度而只是緩存NFS文件。所以你需要刷新文件系統緩存。

docker-machine ssh <name-of-your-machine> sudo cache-clear

(OR)

sudo su

echo 3 > /proc/sys/vm/drop_caches}}}

有些commands/languages忽略FS的緩存。 例如,當運行npm,less, vi,等等,你將不會發現這些錯誤。但其他的命令都使用緩存 —cat,python,Apache SendFile,等等。

在VirtualBox中,這個問題也涉及到[Apache SendFile bug](https://www.virtualbox.org/ticket/9069)。

網絡錯誤

有時你會看到怪異的網絡錯誤,像地址不能解析,不能ping通,等等。通常是由于主機的網絡配置被更改了(例如,你切換到了WiFi網絡等),這時可以重啟VM獲得更新過的網絡配置。

構建和相關性

你的Dockerfile通常被用來編譯和構建應用,并準備啟動。 當以volume去掛載你的文件夾(如通常在開發的情況下),這會導致各種問題。

1—有些語言(Ruby, Python, 等等)的安裝依賴于用戶目錄的共享文件夾。 其他的(Node/NPM)直接在當前的應用程序文件夾 中安裝。 因此,盡管構建容器的時候有“npm install“,但以后當你用共享的volume運行“docker- compose up”,“node_modules”文件夾消失了!

2—類似的,build文件夾也沒了。 結果,容器用來啟動應用的CMD多數情況下就不能工作。

這是棘手的,即使你在dev和prod用不同的Dockerfiles。 因為這不是一個build image時的問題,而是一個容器的運行時 的問題。 目前的解決方法依賴于你的語言(rake/grunt/gulp/fabric/etc)對應的Task runner,并在docker的 CMD中用它去開發。 不要在Dockerfile中填寫應用的“build”邏輯,相反地請使用task runner。

{{{# gulp/grunt/rake/...

# have a "build" task

Dockerfile

# used for normal production deployment

# here you use separate tasks as needed

COPY package.json /myapp/

RUN npm install

COPY . /myapp

RUN gulp build

CMD ["npm", "start"]

docker-compose

# when developing, combine all the above commands

myservice:

volumes: ".:/myapp"

command: "sh -c 'npm install && gulp build && npm start'"

.dockerignore

確定你的“.dockerignore”文件在跨平臺時能忽略常見的特殊文件。 這些不必要的文件將無效docker的構建緩存。 有了正確的”.dockerignore“的文件,build的時候你可以簡單地運行”COPY ./myapp“去復制你的整個app源代碼,而不是一個文件夾又一個文件的去復制。

# Ignore .git folder .git*

Ignore all Windows, Linux and OSX special files

https://www.gitignore.io/api/windows ,linux,osx,vim

Ignore all your language-specific build folders

build/

target/

node_modules/

.bundler/

etc

使用 gitignore.io 獲取對應語言/平臺的常見文件清單。 但請記住,”.gitignore”和”.dockerignore”甄別這些文件的方式不同。 Dockerignore要求整個文件名必須匹配。 所以在gitignore里,你可以寫”node_modules“去忽略整個文件夾,但在dockerignore你不得不 用”node_modules/*“。

清理

下面的 docker-clean命令可以刪除所有沒有tag的image和停止的容器。 可定期運行該命令去清理VM。

docker ps -aqf status=exited | xargs docker rm

docker images -qf dangling=true | xargs docker rmi

單元測試/ CI

可以用一個單獨的docker-compose.test.yml,從平常的”docker-compose.yml“去” extend “服務,但這只是直接覆蓋“command”set來運行測試。 然后在CI上,運行以下命令:

docker-compose -f docker-compose.test.yml run <service_name> 

這將直接啟動所有的鏈接服務,并運行測試,然后會用你的測試腳本的狀態碼退出。 現在,您的CI可以簡單地安裝docker-compose,并可以為每個服務運行上面的命令而不需要了解特定的服務!

鏈接

當運行測試時,docker-compose很容易把所有的微服務鏈接在一起。 對于pet項目,這通常不是問題,但對于規模較大的項目就比較頭痛。 盡早避免它, 可以像 stubby4node 那樣,用一個描述stubbed endpoints的簡單的YAML文件去使用stub servers。

時鐘同步錯誤

當docker-machine VM的時鐘與實際時間不同步,你會得到很多奇怪的錯誤,如簽名錯誤(各種AWS服務)。 在這種情況下,只要重新啟動該VM去同步時鐘。 這通常發生在暫停/恢復你的筆記本電腦或臺式機。 你的主機操作系統更新了時間,但掛起的VM卻滯后了。 同樣的情況對于Vagrant也是如此。

忘記關閉虛擬機

”無恥的plug“:當我們正在Docker上開發一個菜單欄的應用程序,我們往往在離開時讓docker-machine VM一直運行,忘記將其關閉。 看一看 — github.com/rdsubhas/docker-menu

Doker的開發:常見問題及解決方法

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!