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-
to the daemon’s arguments. In the case of HTTP
registry local.registry.com:5000
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 docker@local
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 docker@192.168.59.103
输入默认密码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/