前言
这是我在 QQ 群
325486037
里,碰到的一些问题及其解答,大多是初学 Docker 时常见的问题。其中的回答,是基于我学习和使用 Docker 过程中的一些认知,多数是遵循 Docker 官方的最佳实践的原则而进行的解答。由于个人能力所限,回答可能会片面或错误。如发现错误后,欢迎告诉我,以方便修正该文档避免误导他人,文档会不定期进行更新。
- Docker 引擎相关问题
(67)
- 概念问题
(5)
- 安装、配置问题
(8)
- 网络问题
(13)
- 怎么固定容器 IP 地址?每次重启容器都要变化 IP 地址怎么办?
- 如何修改容器的
/etc/hosts
文件? - 怎么映射宿主端口?
Dockerfile
中的EXPOSE
和docker run -p
有啥区别? - 我要映射好几百个端口,难道要一个个
-p
么? - 为什么
-p
后还是无法通过映射端口访问容器里面的服务? vethxxxx
这种虚拟网卡和容器的对应关系从哪里看?- 如何让一个容器连接两个网络?
- Docker 多宿主网络怎么配置?
- 明明
docker network ls
中看到了建立的overlay
网络,怎么docker run
还说网络不存在啊? - 使用
Swarm Mode
的时,看到有个叫ingress
的overlay
网络,它和自己创建的网络有什么区别? - 听说
--link
过时不再用了?那容器互联、服务发现怎么办? - 使用 HBase/Hadoop 的时候,反向解析总是不对,怎么办?
- 容器怎么取宿主机 IP 啊?
- 存储问题
(11)
- 镜像问题
(17)
docker pull
下来的镜像文件都在哪?docker images
命令显示的镜像占了好大的空间,怎么办?每次都是下载这么大的镜像?docker images -a
后显示了好多<none>
的镜像?都是什么呀?能删么?- 为什么 Docker Hub 的镜像尺寸和
docker images
不一致? docker commit
怎么用啊?- 为什么说不要使用
import
,export
,save
,load
,commit
来构建镜像? Dockerfile
怎么写?Dockerfile
就是shell
脚本吧?那我懂,一行行把需要装的东西都写进去不就行了。- 那我把所有命令都合并到一个
RUN
就对了吧? context
到底是一个什么概念?ENTRYPOINT
和CMD
到底有什么不同?- 拿到一个镜像,如何获得镜像的
Dockerfile
? - 在你的 LNMP 的例子中,PHP 的
Dockerfile
里面的 “构建依赖” 和 “运行依赖” 都是什么意思? - 应用代码是应该挂载宿主目录还是放入镜像内?
- 为什么在
Dockerfile
中执行(导入.sql
、service xxx start
)不管用? - 为什么基于 Alpine 的镜像那么小?我可以都换成基于 Alpine 的镜像么?
- 可以看到镜像各层的依赖关系么?
- 日志问题
(2)
- 使用问题
(11)
- 为什么容器一运行就退出啊?
- 如何在 Docker 容器内使用
docker
命令(比如在 Jenkins 容器中)? - Docker 容器如何随系统一同启动?
docker stats
显示的只有容器ID,怎么才能显示容器名字?- 我用的是阿里云
Ubuntu 14.04
主机,内核还是3.13
,怎么办? - 如何动态修改内存限制?
- 经常在各种
Docker
命令里看到--label
,label
是什么?干什么用的? - 都说不要用
root
去运行服务,但我看到的Dockerfile
都是用root
去运行,这不安全吧? - 我在容器里运行
systemctl start xxx
怎么报错啊? - 容器内的时间和宿主不一致,怎么同步啊?
- 我想让我的程序平滑退出,为什么截获
SIGTERM
信号不管用啊?
- 概念问题
- Docker Compose 相关问题
(2)
- Docker Swarm 相关问题
(8)
- 我的 Docker 版本是 1.12,请问我跑的是一代 Swarm 还是二代 Swarm 啊?
- Swarm环境中怎么指定某个容器在指定的宿主上运行呢?
- 为什么 Swarm 集群的 overlay network 跨宿主无法互访?
- Docker 二代Swarm (既 Swarm Mode),
docker service create
不可以使用-v
那怎么使用卷(Volume)? - 对于两节点集群来说,
--replicas=2
和--mode=global
是不是一个意思? - 一代 Swarm 的时候可以用
docker run
啊,二代怎么又弄个docker service create
出来?为什么要多此一举? docker service ps
里面总是有一堆失败或者shutdown的历史容器,怎么删啊?- 怎么才能让
docker service create
创建的服务正常退出时不重启啊?
- Docker Machine 相关问题
(5)
- Docker Registry 相关问题
(10)
- 我
docker push
的时候怎么报authentication required
错误? - 为什么我
docker login
失败了?我注册用户了,在网站登录也没问题呀? - 我注册用户
pinkman
了,怎么还是无法docker push mrwhite/xxx
啊? - 不管用啊,我这回
docker push pinkman/xxx
了,怎么告诉我镜像不存在啊? docker push
到私有registry
总是不成功,怎么办?- 我
docker push
了很多镜像到私有的registry
上,怎么才能查看上面都有啥?或者搜索? docker search
为什么没有办法在私有Registry
中用?- 如何删除私有
registry
中的镜像? - 使用国内镜像还是慢,公司内好多 docker 主机,都需要去重复下载镜像,咋办?
- 自己架的
registry
怎么任何用户都可以取到镜像?这不安全啊?
- 我
- 系统相关问题
(7)
- 其它问题
(1)
Docker 引擎相关问题 (67)
概念问题 (5)
宿主如果和容器系统不同的话,那不是和虚拟机一样,一层层的调用,那么 Docker 和虚拟机还有什么差别?
要把 Windows 和 Linux 分清楚,更要把内核(kernel
)和用户空间(userland
)分清楚。
容器内的进程是直接运行于宿主内核
的,这点和宿主进程一致,只是容器的 userland
不同,容器的 userland
由容器镜像提供,也就是说镜像提供了 rootfs
。
假设宿主是 Ubuntu
,容器是 CentOS
。CentOS
容器中的进程会直接向 Ubuntu
宿主内核发送 syscall
,而不会直接或间接的使用任何 Ubuntu
的 userland
的库。
这点和虚拟机有本质的不同,虚拟机是虚拟环境,在现有系统上虚拟一套物理设备,然后在虚拟环境内运行一个虚拟环境的操作系统内核,在内核之上再跑完整系统,并在里面调用进程。
还以上面的例子去考虑,虚拟机中,CentOS
的进程发送 syscall
内核调用,该请求会被虚拟机内的 CentOS
的内核接到,然后 CentOS
内核访问虚拟硬件时,由虚拟机的服务软件截获,并使用宿主系统,也就是 Ubuntu
的内核及 userland
的库去执行。
而且,Linux 和 Windows 在这点上非常不同。Linux 的进程是直接发 syscall
的,而 Windows 则把 syscall
隐藏于一层层的 DLL
服务之后,因此 Windows 的任何一个进程如果要执行,不仅仅需要 Windows 内核,还需要一群服务来支撑,所以如果 Windows 要实现类似的机制,容器内将不会像 Linux 这样轻量级,而是非常臃肿。看一下微软移植的 Docker 就非常清楚了。
所以不要把 Docker 和虚拟机弄混,Docker 容器只是一个进程而已,只不过利用镜像提供的 rootfs
提供了调用所需的 userland
库支持,使得进程可以在受控环境下运行而已,它并没有虚拟出一个机器出来。
参考:
视频笔记: Windows Server 和 Docker - John Starks
Docker 资料好少啊?网上的命令怎么不能用?
首先,做技术工作,请珍惜生命,远离百度;
其次,不翻墙、不用Google、不看英文资料,那请转行,没法混。
然后是回答问题,Docker的资料其实很丰富,特别是官方文档讲解非常详细。
- (英文): https://docs.docker.com/
- (中文): https://docs.docker-cn.com (文档有坑,不少代码格式有错)
- (老麦的翻译): https://www.gitbook.com/read/book/octowhale/docker-doc-cn
另外,Docker有丰富的镜像库,Docker Hub,特别是官方(Official)的镜像可以直接在生产环境中使用,制作比较精良。
https://hub.docker.com/explore/
所有的官方镜像都有 Dockerfile
,以及在github上有全部生成镜像的配套文件,遵循了Dockerfile
的最佳实践,这些也是很好地学习资料。
另外,在 YouTube 的 Docker 官方频道下有几百个视频讲座,从初级到高级用户都能从里面学到很多东西。
https://www.youtube.com/user/dockerrun
如何选择 Docker 书籍?
Docker 属于敏捷开发的产品,并且处于高速创新阶段,每年都会有很多版本发布。由于这种快速开发的特性,Docker 一般只保留几个版本内的向后兼容性,再之后就会废弃。因此选择图书的时候,不应该选择比当前版本低超过2-3个版本的书籍。换句话说,市面上大部分书籍,特别是中文书籍、网文,很可能都过时了。
Docker 版本号在 2017 年以前,使用 <大版本号>.<小版本号>.<补丁版本号>
的结构,那时 Docker 基本会保持 3 个小版本号 之内的兼容性(如果一个特性宣布废弃,一般会在 3 个版本后才彻底移除)。
而从 2017 年春以后,Docker 使用了新版本号结构:<年>.<月>.<补丁版本号>
,并且将每月发布一个前沿(Edge)版本,每季度发布一个稳定(Stable)版本。因此选择书籍也应该以介绍 2-3个季度以内版本 的书籍为准。那些介绍一年以前发布的 Docker 版本的书籍不应该再看了。
因此在购买 Docker 图书的时候,应该遵循这样的原则:观察一下当前的 Docker 版本号,选择不要晚于 3 个版本的 Docker 书籍。 比如写这段文字时为 17.06
,那么就不要购买介绍 Docker 1.12
及其以前版本的书籍了,否则看到的很多东西可能将会因过时而无法使用,或者已经不必如此繁琐有更简单的方式去实现了。
所以,对于 Docker 学习而言,最好的书籍是官网文档,官网的文档很丰富。
- 新手教程:
- Docker 课程:http://training.play-with-docker.com/
- 大量的例子:
- 用户文档:
- 管理文档:https://docs.docker.com/engine/admin/
- 安全:https://docs.docker.com/engine/security/security/
- 集群:https://docs.docker.com/engine/swarm/
部分文档有对应官方的中文翻译,可以从 https://docs.docker-cn.com 查看。但是一定要注意代码格式,中文文档中许多格式是错误的,应该对比英文文档中的代码来看。
对于新手而言,应该先从新手教程开始,内容还是很简单易懂的,很容易上手。然后,可以把用户文档好好看一遍,里面把很多 Docker 的基础概念讲的很清楚。概念清晰后,可以去把官网给出的例子好好的学习一下,这些例子都是具体怎么应用 Docker 的,有文字说明以及具体的考虑,很适合学习。
总说看官方文档,可是 Docker 官网文档经常被墙,看不了怎么办?
首先感谢伟大的墙及其先祖。
然后,我们可以本地运行 Docker 官方文档的网站,以 docker 的方式:
|
这样访问 Docker 宿主的 80
端口,如 http://localhost,就会看到官网文档了。
对于那些访问不了我的问答录的童鞋,同样可以用这样的方式来本地运行:
|
然后就可以访问本地 80
端口看到最新的问答录了。
Docker 1.8 以后版本都有什么改进么?
每个版本发布时,官方博客 https://blog.docker.com 都会有专门文章描述这个版本最主要的改进。
1.9
: https://blog.docker.com/2015/11/docker-1-9-production-ready-swarm-multi-host-networking/1.10
: https://blog.docker.com/2016/02/docker-1-10/1.11
: https://blog.docker.com/2016/04/docker-engine-1-11-runc/1.12
: https://blog.docker.com/2016/06/docker-1-12-built-in-orchestration/
另外,可以看一下孙宏亮维护的《Docker 中文 Changelog》:
1.10
: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.10.0-changelog.md1.11
: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.11.0-changelog.md1.11.1
: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.11.1-changelog.md1.12
: https://github.com/allencloud/docker-changelog-chinese/blob/master/docker-1.12.0-changelog.md
关于 Docker 1.13
可以看一下我写的《Docker 1.13 新增功能》。
安装、配置问题 (8)
Docker 怎么这么多软件,我该装哪个?
好吧,我决定要装 Docker 了,于是来打开 Docker 安装文档 (中文 看看怎么装吧……呃,然后就傻了,怎么这么多种选择啊?!
首先,Docker 有好几个版本,社区版(Community Edition)、企业基础版(Enterprise Edition Basic)、企业标准版(Enterprise Edition Standard)、企业高级版(Enterprise Edition Advanced)。对于我们一般学习使用而言,使用社区版就已足够,所以记住CE就可以了。
其次,我们会看到一堆平台特定的版本,Docker for Mac、Docker for Windows、Docker Toolbox、Docker for Azure、Docker for AWS 等等,还有一堆不同 Linux 的发行版。那我们应该用哪个?其实不难选择,这都是平台特定的东西嘛,选择自己平台就完了