1. 程式人生 > >Docker for Windows安裝與Linux+PHP開發環境搭建(二)

Docker for Windows安裝與Linux+PHP開發環境搭建(二)

Docker for Windows安裝與Linux+PHP開發環境搭建(二)

上一篇講了docker安裝與環境搭建的步驟,這一次主要是介紹過程中遇到的錯誤情形及其錯誤處理方法:

1).執行docker pull local.registry.com:5000/php 或其他連線本地registry server的命令

錯誤提示:

Error response from daemon: invalid registry endpoint https://local.registry.com :5000/v0/: unable to ping registry endpoint https://local.registry.com:5000/v0/ v2 ping attempt failed with error: Get https://local.registry.com:5000/v2/: EOF v1 ping attempt failed with error: Get https://local.registry.com:5000/v1/_ping
dial tcp 184.168.221.96:5000: connection refused. If this private registry sup
ports only HTTP or HTTPS with an unknown CA certificate, please add --insecure-
registry local.registry.com:5000
to the daemon’s arguments. In the case of HTTP
S, if you have access to the registry’s CA certificate, no need for the flag; si
mply place the CA certificate at /etc/docker/certs.d/local.registry.com:5000/ca.
crt

原因:

Docker 1.3.1版本以上,預設禁止連線到不安全的registry,所以從自己本地私有registry上pull映象檔案時候,會報錯。

解決方法:

在VM中/var/lib/boot2docker/profile檔案新增一EXTRA_ARGS引數,重啟docker,命令如下:
boot2docker ssh “echo $’EXTRA_ARGS=\”–insecure-registry <你的私服地址>\”’ | sudo tee -a /var/lib/boot2docker/profile && sudo /etc/init.d/docker restart”
成功執行後,檔案中內容為:
EXTRA_ARGS=”–insecure-registry local.registry.com:5000”
然後重啟sudo /etc/init.d/docker restart

2). 執行docker pull local.registry.com:5000/php 或其他連線本地registry server的命令

錯誤提示:

~D docker pull local.registry.com:5000/php Error response from daemon: invalid registry endpoint “http://local.registry.com :5000/v0/”. HTTPS attempt: unable to ping registry endpoint https://local.regist ry.com:5000/v0/ v2 ping attempt failed with error: Get https://local.registry.com:5000/v2/: dial tcp 184.168.221.96:5000: connection refused v1 ping attempt failed with error: Get https://local.registry.com:5000/v1/_ping
dial tcp 184.168.221.96:5000: connection refused. HTTP attempt: unable to ping
registry endpoint http://local.registry.com:5000/v0/
v2 ping attempt failed with error: Get http://local.registry.com:5000/v2/: dial
tcp 184.168.221.96:5000: connection refused
v1 ping attempt failed with error: Get http://local.registry.com:5000/v1/_ping:
dial tcp 184.168.221.96:5000: connection refused

或:

~D docker pull local.registry.com:5000/php Error response from daemon: invalid registry endpoint “http://local.registry.com :5000/v0/”. HTTPS attempt: unable to ping registry endpoint https://local.regist ry.com:5000/v0/ v2 ping attempt failed with error: Get https://local.registry.com:5000/v2/: EOF v1 ping attempt failed with error: Get https://local.registry.com:5000/v1/_ping
dial tcp 184.168.221.96:5000: connection refused. HTTP attempt: unable to ping
registry endpoint http://local.registry.com:5000/v0/
v2 ping attempt failed with error: Get http://local.registry.com:5000/v2/: dial
tcp 184.168.221.96:5000: connection refused
v1 ping attempt failed with error: Get http://local.registry.com:5000/v1/_ping:
dial tcp 184.168.221.96:5000: i/o timeout

原因:

無法建立到本地映象伺服器http://local.registry.com:5000的連線。

解決方法:

檢查VM host檔案配置。
boot2docker ssh
sudo vi /etc/hosts
增加一行:
172.16.100.71 local.registry.com
退出exit

3).執行docker run -d -p 8000:80 -p 2222:22 –name php -v /f/projects/phpdev:/var/www/html local.registry.com:5000/php

錯誤提示:

invalid value “f:\projects\phpdev;D:\Program Files (x86)\Git\var\www\html
” for flag -v: \projects\phpdev;D:\Program Files (x86)\Git\var\www\html is not a
n absolute path
See ‘d:\Program Files\Boot2Docker for Windows\docker.exe run –help’.

原因:

在Git Bash下執行docker run並掛載一個數據卷時,需要使用雙斜線對宿主機目錄資料夾進行分割,否則不能正確解析到指定目錄。

解決方法:

使用雙斜線分隔
docker run -d -p 8000:80 -p 2222:22 –name php -v //f//projects//phpdev:/var/www/html local.registry.com:5000/php
不使用雙斜線分隔的話,也可以在windows自帶cmd或powershell等其他命令列終端執行。

4). 執行boot2docker start -v啟動boot2docker,或boot2docker up -v命令

錯誤提示:

.Connecting to tcp://localhost:2022 (attempt #0).Connecting to tcp://localhost:2
022 (attempt #0).Connecting to tcp://localhost:2022 (attempt #0).Connecting to t
cp://localhost:2022 (attempt #0).Connecting to tcp://localhost:2022 (attempt #0)
.Connecting to tcp://localhost:2022 (attempt #0).Connecting to tcp://localhost:2
022 (attempt #0).Connecting to tcp://localhost:2022 (attempt #0).Connecting to t
cp://localhost:2022 (attempt #0).Connecting to tcp://localhost:2022 (attempt #0)
.Connecting to tcp://localhost:2022 (attempt #0).Connecting to tcp://localhost:2
022 (attempt #0).Connecting to tcp://localhost:2022 (attempt #0).Connecting to t
cp://localhost:2022 (attempt #0).Connecting to tcp://localhost:2022 (attempt #0)
2015/07/31 10:43:32 executing: C:\Program Files (x86)\Git\bin\ssh.exe ssh -o Ide
ntitiesOnly=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o L
ogLevel=quiet -p 2022 -i C:\Users\Administrator.ssh\id_boot2docker [email protected]
host ip addr show dev eth1
SSH returned: 4: eth1:

原因:

無法通過boot2docker 從宿主機連線到虛擬機器VM
解決方法:檢查windows本地host檔案,新增以下對應關係
127.0.0.1 localhost
然後重新執行boot2docker start|up –v

說明:上面顯示VM Host-only IP address: 192.168.59.103,由此可知docker所在虛擬主機的ip地址為192.168.59.103。ip地址也可通過命令boot2docker ip檢視。除了boot2docker ssh命令,不可用時我們可以通過SSH登入命令連入虛擬機器,
ssh [email protected]
輸入預設密碼tcuser即可成功登入。

5).執行命令docker images 等

錯誤提示:

An error occurred trying to connect: Get https://192.168.59.103:2376/v1.19/image
s/json: x509: certificate is valid for 127.0.0.1, 10.0.2.15, not 192.168.59.103

An error occurred trying to connect: Get https://192.168.59.103:2376/v1.19/image
s/json: x509: certificate has expired or is not yet valid

原因:

TLS證書過期或ip配置有誤。
預設生成路徑為:C:\Users\Administrator.boot2docker\certs\boot2docker-vm\ 下

解決方法:

boot2docker ssh
sudo /etc/init.d/docker restart
exit
boot2docker shellinit

若依然不能解決,請嘗試git上提供的方法
https://gist.github.com/garthk/d5a17007c277aa5c76de
命令:
boot2docker ssh
sudo curl -o /var/lib/boot2docker/profile https://gist.githubusercontent.com/garthk/d5a17007c277aa5c76de/raw/3d09c77aae38b4f2809d504784965f5a16f2de4c/profile
sudo halt
boot2docker up -v
其中profile檔案的內容為:
wait4eth1() {
CNT=0
until ip a show eth1 | grep -q UP
do
[ $((CNT++)) -gt 60 ] && break || sleep 1
done
sleep 1
}
wait4eth1

6).執行命令boot2docker restart

錯誤提示:

error in run: Failed to restart machine “boot2docker-vm”: exit status 1
原因:操作超時,或者host檔案沒有設定localhost對應關係,無法重啟。

解決方法:

多試幾次,無效則檢查windows本地host檔案,新增以下對應關係
127.0.0.1 localhost
然後重新執行。

7). 執行docker pull local.registry.com:5000/php

錯誤提示:

$ docker pull local.registry.com:5000/php
An error occurred trying to connect: Post https://192.168.59.103:2376/v1.19/imag
es/create?fromImage=local.registry.com%3A5000%2Fphp%3Alatest: x509: certificate
is valid for 127.0.0.1, 10.0.2.15, not 192.168.59.103

原因:

Docker程序啟動後會隨機分配一個ip,而在環境變數中設定的DOCKER_HOST與此ip有可能不一致,導致報錯。

解決方法:

重啟docker檢視分配的ip,若不一致則手動設定DOCKER_HOST。
boot2docker ssh
sudo /etc/init.d/docker restart
exit

通過上述命令可以看到docker分配到的ip為192.168.59.105,所以需要修改DOCKER_HOST。
export DOCKER_HOST=”tcp://192.168.59.105:2376”
然後再pull映象,成功。

8). 執行docker pull local.registry.com:5000/php

錯誤提示:

An error occurred trying to connect: Get https://192.168.59.103:2376/v1.19/containers/json: dial tcp 192.168.59.103:2376: ConnectEx tcp: No connection could be made because the target machine actively refused it.

An error occurred trying to connect: Post https://192.168.59.103:2376/v1.19/imag
es/create?fromImage=local.registry.com%3A5000%2Fphp%3Alatest: dial tcp 192.168.5
9.103:2376: ConnectEx tcp: A connection attempt failed because the connected par
ty did not properly respond after a period of time, or established connection fa
iled because connected host has failed to respond.

原因:

連線問題修復後未重啟docker服務,或重啟失敗。
解決方法:輸入以下命令(其中pid根據程序列表查詢/usr/local/bin/docker對應的程序號),將docker程序殺死後重啟。
boot2docker ssh
ps -ef |grep docker
sudo kill -9 pid
sudo /etc/init.d/docker restart

9).執行$ docker pull local.registry.com:5000/php

錯誤提示:

Post http://127.0.0.1:2375/v1.19/images/create?fromImage=local.registry.com%3A50
00%2Fphp%3Alatest: dial tcp 127.0.0.1:2375: ConnectEx tcp: No connection could b
e made because the target machine actively refused it.. Are you trying to connec
t to a TLS-enabled daemon without TLS?

原因:

Docker 0.10.0以後遠端連線使用TLS(Transport Layer Security
)協議,所以我們需要為Docker設定證書路徑並允許TLS。通過export我們發現列出的環境變數中確實沒有DOCKER_CERT_PATH、 DOCKER_TLS_VERIFY、 DOCKER_HOST。

解決方法:

boot2docker shellinit 可以顯示Docker客戶端的環境變數,所以可使用以下命令自動設定環境變數
eval “$(boot2docker shellinit)”
然後,export檢視確認環境變數已經設定好。

10).Windos系統cmd中無法執行boot2docker ssh等命令

錯誤提示:

C:\Users\Administrator>boot2docker ssh
error in run: exec: “ssh”: executable file not found in %PATH%
原因:Git目錄未加入系統環境變數PATH,或環境變數失效。

解決方法:

set PATH=%PATH%;”D:\Program Files (x86)\Git\bin”
使用set設定僅在cmd本次開啟期間有效。
要永久有效的設定方法是:計算機-屬性-高階系統設定-高階-環境變數,
在系統變數PATH欄位追加;D:\Program Files (x86)\Git\bin;
然後重新啟動cmd,即可正常執行boot2docker ssh

11).執行docker rm命令報錯

錯誤提示:

$ docker rm 82bcb0ef14e8
Error response from daemon: Cannot destroy container 82bcb0ef14e8: Driver aufs f
ailed to remove root filesystem 82bcb0ef14e8eaa18a872d3b2e15923442cdf79381e7c5b3
46a93f07b4da4b3d: rename /mnt/sda1/var/lib/docker/aufs/mnt/82bcb0ef14e8eaa18a872
d3b2e15923442cdf79381e7c5b346a93f07b4da4b3d /mnt/sda1/var/lib/docker/aufs/mnt/82
bcb0ef14e8eaa18a872d3b2e15923442cdf79381e7c5b346a93f07b4da4b3d-removing: read-on
ly file system
Error: failed to remove containers: [82bcb0ef14e8]

原因:未知

解決方法:

嘗試重啟一下電腦。若熟悉此問題成因或有好的解決方法歡迎文後留言提供。參考https://github.com/docker/docker/issues/3968

12).執行docker run -d -p 8000:80 -p 2222:22 –name php -v /f/projects/phpdev:/var/www/html local.registry.com:5000/php

錯誤情形:

雖然這裡將宿主機本地目錄/f/projects/phpdev掛載到容器,但是在容器Linux環境操作檔案,本地/f/projects/phpdev目錄的檔案卻不同步改變。
原因:未設定本地共享資料夾,docker許可權不足使得資料目錄掛載失敗。

解決方法:

之所以將宿主機目錄對映到容器目錄,是由於這樣能確保容器環境中生成的資料直接儲存在使用者主機的磁碟,而不會由於容器損壞或未及時將容器持久化而造成資料丟失。這裡提到容器持久化,順便先說一下如何儲存映象/容器:
docker export命令用於持久化容器,如
sudo docker export > /home/export.tar
docker save命令用於持久化映象,如
sudo docker save > /home/save.tar
相反,docker import為匯入容器,docker load為匯入映象,如
匯入export.tar檔案
cat /home/export.tar | sudo docker import - php:latest
然後檢視是否有新映象,建立啟動容器來測試匯入是否可用。
匯入save.tar映象檔案
docker load < /home/save.tar
通過docker export命令匯出的檔案大小比通過docker save生成的檔案略小,原因是export匯出後,會丟失歷史和元資料。我們可以通過以下命令來檢視詳細情況:
顯示映象的所有層(layer)
sudo docker images –tree

匯出後再匯入(exported-imported)的映象會丟失所有的歷史,而儲存後再載入(saveed-loaded)的映象沒有丟失歷史和層(layer)。這意味著使用匯出後再匯入的方式,你將無法回滾到之前的層(layer),同時,使用儲存後再載入的方式持久化整個映象,就可以做到層回滾(可通過執行docker tag 來回滾之前的層)。

繼續回到正題,解決檔案同步的問題需要檢查虛擬機器“共享資料夾”配置,並新增所掛載的目錄。

13).使用命令sudo umount -f /f/projects/phpdev解除安裝共享資料夾報錯

錯誤提示:

umount: can’t forcibly umount /f/projects/phpdev: No such file or directory
umount: can’t forcibly umount /f/projects/phpdev: Invalid argument

原因:

在掛載目錄內部進行解除安裝或者解除安裝未掛載過的目錄。

解決方法:

解除安裝共享資料夾時注意需要先退出掛載目錄,再解除安裝,否則會報錯:
umount: can’t forcibly umount /f/projects/phpdev: No such file or directory
同時要注意解除安裝目錄一定要寫對,注意碟符F前的斜線/,如果要解除安裝的目錄沒有掛載過,則會報錯:
umount: can’t forcibly umount /f/projects/phpdev: Invalid argument

14).其他情況

其餘情況,可以結合以上處理方法,根據實際情況嘗試解決。比如從桌面快捷方式“Boot2Docker Start”啟動無法成功,可以嘗試以下命令:
boot2docker stop
boot2docker delete/destroy
boot2docker init –v
boot2docker start –v
boot2docker up –v
eval boot2docker shellinit

注意:由於執行了刪除命令,原有的映象和容器會全部清除,請謹慎操作!


參考文章

http://docs.docker.com/userguide/
https://github.com/boot2docker/boot2docker
http://blog.pavelsklenar.com/5-useful-docker-tip-and-tricks-on-windows/