Docker 常见问题汇总(转)

镜像相关
1、如何批量清理临时镜像文件?

可以使用sudo docker rmi $(sudo docker images -q -f danging=true)命令

2、如何查看镜像支持的环境变量?

使用sudo docker run IMAGE env

3、本地的镜像文件都存放在哪里

于Docker相关的本地资源存放在/var/lib/docker/目录下,其中container目录存放容器信息,graph目录存放镜像信息,aufs目录下存放具体的镜像底层文件。

4、构建Docker镜像应该遵循哪些原则?

整体远侧上,尽量保持镜像功能的明确和内容的精简,要点包括:# 尽量选取满足需求但较小的基础系统镜像,建议选择debian:wheezy镜像,仅有86MB大小# 清理编译生成文件、安装包的缓存等临时文件# 安装各个软件时候要指定准确的版本号,并避免引入不需要的依赖# 从安全的角度考虑,应用尽量使用系统的库和依赖# 使用Dockerfile创建镜像时候要添加.dockerignore文件或使用干净的工作目录

容器相关
1、容器退出后,通过docker ps 命令查看不到,数据会丢失么?

容器退出后会处于终止(exited)状态,此时可以通过 docker ps -a 查看,其中数据不会丢失,还可以通过docker start 来启动,只有删除容器才会清除数据。

2、如何停止所有正在运行的容器?

使用docker kill $(sudo docker ps -q)

3、如何清理批量后台停止的容器?

使用docker rm $(sudo docker ps -a -q)

4、如何临时退出一个正在交互的容器的终端,而不终止它?

按Ctrl+p,后按Ctrl+q,如果按Ctrl+c会使容器内的应用进程终止,进而会使容器终止。

5、很多应用容器都是默认后台运行的,怎么查看它们的输出和日志信息?

使用docker logs,后面跟容器的名称或者ID信息

6、使用docker port 命令映射容器的端口时,系统报错Error: No public port ‘80’ published for …,是什么意思?

创建镜像时Dockerfile要指定正确的EXPOSE的端口,容器启动时指定PublishAllport=true

7、可以在一个容器中同时运行多个应用进程吗?

一般不推荐在同一个容器内运行多个应用进程,如果有类似需求,可以通过额外的进程管理机制,比如supervisord来管理所运行的进程

8、如何控制容器占用系统资源(CPU,内存)的份额?

在使用docker create命令创建容器或使用docker run 创建并运行容器的时候,可以使用-c|–cpu-shares[=0]参数来调整同期使用CPU的权重,使用-m|–memory参数来调整容器使用内存的大小。

仓库相关
1、仓库(Repository)、注册服务器(Registry)、注册索引(Index)有何关系?

首先,仓库是存放一组关联镜像的集合,比如同一个应用的不同版本的镜像,注册服务器是存放实际的镜像的地方,注册索引则负责维护用户的账号,权限,搜索,标签等管理。注册服务器利用注册索引来实现认证等管理。

-2 、从非官方仓库(如:dl.dockerpool.com)下载镜像的时候,有时候会提示“Error:Invaild registry endpoint [https://dl.docker.com:5000/v1/](https://dl.docker.com:5000/v1/)…”?
Docker 自1.3.0版本往后以来,加强了对镜像安全性的验证,需要手动添加对非官方仓库的信任。DOCKER_OPTS=”–insecure-registry dl.dockerpool.com:5000”重启docker服务

配置相关
1、Docker的配置文件放在那里。如何修改配置?

Ubuntu系统下Docker的配置文件是/etc/default/docker,CentOS系统配置文件存放在/etc/sysconfig/docker

-2、如何更改Docker的默认存储设置?
Docker的默认存放位置是/var/lib/docker,如果希望将Docker的本地文件存储到其他分区,可以使用Linux软连接的方式来做。

Docker与虚拟化
1、Docker与LXC(Linux Container)有何不同?

LXC利用Linux上相关技术实现容器,Docker则在如下的几个方面进行了改进:
移植性:通过抽象容器配置,容器可以实现一个平台移植到另一个平台;镜像系统:基于AUFS的镜像系统为容器的分发带来了很多的便利,同时共同的镜像层只需要存储一份,实现高效率的存储;版本管理:类似于GIT的版本管理理念,用户可以更方面的创建、管理镜像文件;仓库系统:仓库系统大大降低了镜像的分发和管理的成本;周边工具:各种现有的工具(配置管理、云平台)对Docker的支持,以及基于Docker的Pass、CI等系统,让Docker的应用更加方便和多样化。

2 、Docker与Vagrant有何不同?

两者的定位完全不同Vagrant类似于Boot2Docker(一款运行Docker的最小内核),是一套虚拟机的管理环境,Vagrant可以在多种系统上和虚拟机软件中运行,可以在Windows。Mac等非Linux平台上为Docker支持,自身具有较好的包装性和移植性。原生Docker自身只能运行在Linux平台上,但启动和运行的性能都比虚拟机要快,往往更适合快速开发和部署应用的场景。

3、开发环境中Docker与Vagrant该如何选择?

Docker不是虚拟机,而是进程隔离,对于资源的消耗很少,单一开发环境下Vagrant是虚拟机上的封装,虚拟机本身会消耗资源。

Other FAQ
1、Docker能在非Linux平台(Windows+MacOS)上运行吗?

可以

2 、如何将一台宿主机的docker环境迁移到另外一台宿主机?

停止Docker服务,将整个docker存储文件复制到另外一台宿主机上,然后调整另外一台宿主机的配置即可

3、Docker容器创建后,删除了/var/run/netns 目录下的网络名字空间文件,可以手动恢复它:

# 查看容器进程ID,比如1234
sudo docker inspect --format='{{. State.pid}}' $container_id 1234
# 到proc目录下,把对应的网络名字空间文件链接到/var/run/netns,然后通过正常的系统命令查看操作容器的名字空间。

版权声明:本文为木偶人shaon原创文章,转载请注明原文地址,非常感谢。http://blog.csdn.net/wh211212/article/details/53208960


各位有没有在开发环境或者测试环境中使用Docker?如果有,那我猜你一定碰到过很多坑,本文汇总了常见问题的解决方案,希望能帮到你。注意,部分问题只适用于VirtualBox。端口转发到主机
端口转发只能用在Boot2Docker下的VM。 如果你也想用同一端口转发到你的主机,比如你正在测试Android应用程序的后台或者想分享VM呢?你有两个选择:到VirtualBox的设置里去添加一个Bridged adapter。 现在当你再启动docker-machine,你的VM就会得到一个正式的LAN地址。 这时你就可以从网络上的其它任何设备访问虚拟机,而且docker-compose的端口转发也可以使用。
等到Issue #691(或相关)得到解决。 就可以允许你使用SSH端口转发。唯一的问题是你必须手动的操作需要的每一个端口。docker-machine ssh -L <host-port>:localhost:<machine-port>

性能低
默认情况下,当你用docker-machine创建一个VM,只得到非常低的配置(1CPU,1GB RAM)。 运行“docker-machine help create”去了解相应的flag后,就可用它们来增加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。网络错误
有时你会看到怪异的网络错误,像地址不能解析、不能ping通等等。通常是由于主机的网络配置被更改了(例如,你切换到了WiFi网络等),这时可以重启VM获得更新过的网络配置。构建和相关性
你的Dockerfile通常被用来编译和构建应用,并准备启动。 当以Volume去挂载你的文件夹(如通常在开发的情况下),这会导致各种问题。有些语言(Ruby、Python等等)的安装依赖于用户目录的共享文件夹。 其他的(Node/NPM)直接在当前的应用程序文件夹中安装。 因此,尽管构建容器的时候有“npm install“,但以后当你用共享的volume运行“docker-compose up”,“node_modules”文件夹消失了!
类似的,build文件夹也没了。 结果,容器用来启动应用的CMD多数情况下就不能工作。

这是棘手的,即使你在dev和prod用不同的Dockerfile。 因为这不是一个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 neededCOPY package.json /myapp/RUN npm installCOPY . /myappRUN gulp buildCMD ["npm", "start"]# docker-compose# when developing, combine all the above commandsmyservice: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 foldersbuild/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 rmdocker 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![![1-V4mH1M8fDqezbKsBpAWM2g.png](http://dockerone.com/uploads/article/20151105/a7324c62049ada80fdceaef3bd7e3a54.png)](http://dockerone.com/uploads/article/20151105/a7324c62049ada80fdceaef3bd7e3a54.png)
**原文链接:Docker for Development: Common Problems and Solutions(翻译:Bruce.Chen 校对:李颖杰)**


docker 的深坑

1. 镜像数据问题

    由于容器重启后数据会被清空,所以docker中的数据需要通过映射存放到本地磁盘持久化,启动docker镜像的时候加-V diskPath:dockerPath的参数。如:

    docker run -d -e MYSQL_ROOT_PASSWORD=admin --name mysql -v /opt/data/mysql:/var/lib/mysql -p 3306:3306 mysql

    

2. 容器中的时区与语言的问题

    在docker容器中默认时间是UTC时间,北京是+8时区。默认语言为POSIX,则需在编译docker image的时候需要指定语言和时区的环境变量:

    ENV LC_ALL en_US.UTF-8,ENV TZ=Asia/Shanghai

3. docker 容器中systemctl问题

    在容器中使用systemctl报Failed to get D-Bus connection: Operation not permitted的错误,则在启动的时候把sys/fs/cgroup映射到docker容器中。

    docker run --privileged --name=test --hostname=test -v /sys/fs/cgroup:/sys/fs/cgroup image /usr/sbin/init

    

4. docker容器存放问题(最坑)

    默认情况下Docker的存放位置为:/var/lib/Docker。一般根下分区我们不会给太大。镜像和容器越存越多一般我们有两种解决方法

    

    1、挂载大分区到/var/lib/docker:

    

    一般选择建立逻辑分区lvm,方便后期扩展集体。

        a.建立新分区,并格式化

            PS: 以下操作建设你已经有现成的卷组,直接可以划逻辑卷。或者你可以自己创建逻辑卷,或者不适用逻辑卷直接使用分区

            lvcreate -L 300G lv_docker vg_home  

            mkfs.ext4 /dev/vg_home/lv__docker  

        b.挂载新分区到临时挂载点

            mkdir /mnt/docker  

            mount /dev/vg_home/lv_docker /mnt/docker/  

    

        c.停掉docker后拷贝/var/lib/docker下数据到临时挂载点

            service docker stop  

            cp -r /var/lib/docker/* /mtn/docker  

    

        d.修改/var/lib/docker 为//var/lib/docker.bak,并创建/var/lib/docker

            mv /var/lib/docker{,.bak}  

            mkdir /var/lib/docker  

    

        e.挂载新分区到/var/lib/docker,并设置开机自动挂载。

            mount /dev/vg_home/lv_docker /var/lib/docker  

            vim /etc/fstab  

            ---  

            /dev/vg_home/lv_docker /docker_data   ext4    defaults 0 0  

            ----   

    

        f.检测docker是否可用,数据是否完整

            docker images  

            docker ps -a   

    

        g.确认无误后卸载临时挂载点,删除/var/lib/docker.bak

            umount /mnt/docker  

            rm -rf /var/lib/docker.bak  

    

    2、修改镜像和容器的存放路径:

    

        a.很简单,指定镜像和容器存放路径的参数是--graph=/var/lib/docker。只需要修改配置文件指定启动参数即可

            vim /etc/sysconfig/docker  

            ------------  

            other_args="--graph=/docker"  

            ------------  

    

        b.停掉docker 

            service docker stop  

        c.备份数据到新容器存放目录

            cp -r /var/lib/docker /docker/  

    

        d.修改源存放目录名称

            mv /etc/lib/docker{,.bak}  

    

        e.启动docker

            service docker start  

    

        f.测试

            docker images  

            docker ps -a 

推荐阅读更多精彩内容