目录隐藏 |
宿主如果和容器系统不同的话,那不是和虚拟机一样,一层层的调用,那么 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 库支持,使得进程可以在受控环境下运行而已,它并没有虚拟出一个机器出来。 参考: https://www.docker.com/what-docker 视频笔记: Windows Server 和 Docker - John Starks |
|
怎么固定容器 IP 地址?每次重启容器都要变化 IP 地址怎么办? | |
一般情况是不需要指定容器 IP 地址的。这不是虚拟主机,而是容器。其地址是供容器间通讯的,容器间则不用 IP 直接通讯,而使用容器名、服务名、网络别名。 为了保持向后兼容,docker run 在不指定 --network 时,所在的网络是 default bridge,在这个网络下,需要使用 --link 参数才可以让两个容器找到对方。 这是有局限性的,因为这个时候使用的是 /etc/hosts 静态文件来进行的解析,比如一个主机挂了后,重新启动IP可能会改变。虽然说这种改变Docker是可能更新/etc/hosts文件,但是这有诸多问题,可能会因为竞争冒险导致 /etc/hosts 文件损毁,也可能还在运行的容器在取得 /etc/hosts 的解析结果后,不再去监视该文件是否变动。种种原因都可能会导致旧的主机无法通过容器名访问到新的主机。 参考官网文档: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/ 如果可能不要使用这种过时的方式,而是用下面说的自定义网络的方式。 而对于新的环境(Docker 1.10以上),应该给容器建立自定义网络,同一个自定义网络中,可以使用对方容器的容器名、服务名、网络别名来找到对方。这个时候帮助进行服务发现的是Docker 内置的DNS。所以,无论容器是否重启、更换IP,内置的DNS都能正确指定到对方的位置。 参考官网文档: https://docs.docker.com/engine/userguide/networking/work-with-networks/#linking-containers-in-user-defined-networks 建议参考一下我写的 LNMP 的例子: https://coding.net/u/twang2218/p/docker-lnmp/git |
|
docker pull 下来的镜像文件都在哪? | |
初学 Docker 要反复告诫自己,Docker 不是虚拟机。 Docker不是虚拟机,Docker 镜像也不是虚拟机的 ISO 文件。Docker 的镜像是分层存储,每一个镜像都是由很多层,很多个文件组成。而不同的镜像是共享相同的层的,所以这是一个树形结构,不存在具体哪个文件是 pull 下来的镜像的问题。 具体镜像保存位置取决于系统,一般Linux系统下,在 /var/lib/docker 里。对于使用 Union FS 的系统(Ubuntu),如 aufs, overlay2 等,可以直接在 /var/lib/docker/{aufs,overlay2} 下看到找到各个镜像的层、容器的层,以及其中的内容。 但是,对于CentOS这类没有Union FS的系统,会使用如devicemapper这类东西的一些特殊功能(如snapshot)模拟,镜像会存储于块设备里,因此无法看到具体每层信息以及每层里面的内容。 需要注意的是,默认情况下,CentOS/RHEL 使用 lvm-loop,也就是本地稀疏文件模拟块设备,这个文件会位于 /var/lib/docker/devicemapper/devicemapper/data 的位置。这是非常不推荐的,如果发现这个文件很大,那就说明你在用 devicemapper + loop 的方式,不要这么做,去参照官方文档,换 direct-lvm,也就是分配真正的块设备给 devicemapper 去用。 |
|
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 的发行版。那我们应该用哪个?其实不难选择,这都是平台特定的东西嘛,选择自己平台就完了: macOS 就选择 Docker for Mac; 阿里云(未及时更新): https://mirrors.aliyun.com/docker-toolbox/mac/docker-for-mac/stable/ Linux 就选择自己平台的 Docker 源: Ubuntu: https://docs.docker.com/engine/installation/linux/docker-ce/ubuntu/ Debian: https://docs.docker.com/engine/installation/linux/docker-ce/debian/ CentOS: https://docs.docker.com/engine/installation/linux/docker-ce/centos/ Fedora: https://docs.docker.com/engine/installation/linux/docker-ce/fedora/ Windows 要麻烦些: 如果是 Windows 10 专业版、企业版、教育版,并且版本在 10586 以后,并且不打算在 Docker 运行同时再运行其它虚拟机的情况下,可以装 Docker for Windows。 阿里云(未及时更新): https://mirrors.aliyun.com/docker-toolbox/windows/docker-for-windows/stable/ 其它情况都装 Docker Toolbox 阿里云: https://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/ 如果是特定云服务平台,可以考虑特定服务平台的版本(当然,这不是必须): AWS:Docker for AWS Azure:Docker for Azure 最后是发布通道,从今年初开始,也就是从 1.13 以后,Docker 使用了新的版本号规则,将采用类似 Ubuntu 那种 <年>.<月> 的形式,比如 17.03, 17.06 等。并且,将发布通道分为前沿版本(Edge)和稳定版本(Stable)。前沿通道将基本每个月发布一个版本,而稳定通道将基本每3个月发布一个版本。这样 Docker 的发布将有规律可寻。对于喜欢尝鲜的可以选择前沿版本,对于需要稳定的,可以选择稳定版本。 这里面需要注意的是,在参考 官方安装文档配置 Linux 源的时候,如果是国内服务器,要将其中的 https://download.docker.com/linux/ 替换为 https://mirrors.aliyun.com/docker-ce/linux/。 比如,文档如果要求执行下面的命令: $ sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" 那么就替换为: $ sudo add-apt-repository \ "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu \ $(lsb_release -cs) \ stable" 这样安装 Docker 就会使用阿里云的软件源,而不需要翻墙了。(注:这不是加速器,不要搞错了,加速器依旧需要配!) |
|
docker pull 好慢啊怎么办? | |
首先,要“感谢”伟大的墙及其亲属。 然后,我们可以使用 Docker 镜像加速器来解决这个问题,加速器就是镜像、代理的概念。国内有不少机构提供了免费的加速器以方便大家使用,这里列出一些常用的加速器服务:
Ubuntu 14.04 配置加速器(或其它使用 Upstart 的系统) Ubuntu 14.04 是使用 upstart 进行系统初始化的,对于这类系统,可以用通过编辑配置文件的方法来配置加速器。 如果是 Ubuntu 14.04,那么编辑 /etc/default/docker,在里面寻找 DOCKER_OPTS 环境变量设置的这一行,在其后添加 -–registry-mirror=<加速器地址>。如果发现该行已被注释,或者不存在该行,那么新添一行即可。 比如,在使用官方源安装了 docker-engine 后,会建立一个默认的 /etc/default/docker,其中相关 DOCKER_OPTS 的行是这样的: # Use DOCKER_OPTS to modify the daemon startup options. #DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" 假设我们得到的加速器地址为 http://abcd.m.daocloud.io,我们添加一行配置,将其改为: # Use DOCKER_OPTS to modify the daemon startup options. #DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4" DOCKER_OPTS="--registry-mirror=http://abcd.m.daocloud.io" 保存文件后,重启 Docker 引擎: $ sudo service docker restart docker stop/waiting docker start/running, process 3620 重启成功后,确认一下配置是否已经生效: $ sudo ps -ef | grep dockerd root 3620 1 0 04:26 ? 00:00:00 /usr/bin/dockerd --registry-mirror=http://abcd.m.daocloud.io --raw-logs 如果配置成功,生效后这里就会看到自己所配置的加速器的内容。 Ubuntu 16.04 或 CentOS 7 配置加速器(或其它使用 Systemd 的系统) Ubuntu 16.04 和 CentOS 7 这类系统都已经开始使用 systemd 进行系统初始化管理了,对于使用 systemd 的系统,应该通过编辑服务配置文件 docker.service 来进行加速器的配置。 在启用服务后 $ sudo systemctl enable docker 可以直接编辑 /etc/systemd/system/multi-user.target.wants/docker.service 文件来进行配置。 sudo vi /etc/systemd/system/multi-user.target.wants/docker.service 在文件中找到 ExecStart= 这一行,并且在其行尾添加上所需的配置。假设我们获得的加速器地址为 https://jxus37ac.mirror.aliyuncs.com,那么可以这样配置: ExecStart=/usr/bin/dockerd --registry-mirror=https://jxus37ac.mirror.aliyuncs.com 注: Docker 1.12 之前的版本,dockerd 应该换为 docker daemon,更早的版本则是 docker -d。不过还在用那些版本的童鞋,升级吧…
保存退出后,重新加载配置并启动服务: |
|
Docker 资料好少啊?网上的命令怎么不能用? | |
首先,做技术工作,请珍惜生命,远离百度; 其次,不翻墙、不用Google、不看英文资料,那请转行,没法混。 然后是回答问题,Docker的资料其实很丰富,特别是官方文档讲解非常详细。 https://docs.docker.com/ 另外,Docker有丰富的镜像库,Docker Hub,特别是官方(Official)的镜像可以直接在生产环境中使用,制作比较精良。 https://hub.docker.com/explore/ 所有的官方镜像都有 Dockerfile,以及在github上有全部生成镜像的配套文件,遵循了Dockerfile的最佳实践,这些也是很好地学习资料。 另外,在 YouTube 的 Docker 官方频道下有几百个视频讲座,从初级到高级用户都能从里面学到很多东西。 https://www.youtube.com/user/dockerrun |
|
是直接用 yum / apt-get 安装 Docker 吗? | |
很多人问到 docker, docker.io, docker-engine 甚至 lxc-docker 都有什么区别? 其中,RHEL/CentOS 软件源中的 Docker 包名为 docker;Ubuntu 软件源中的 Docker 包名为 docker.io;而很古老的 Docker 源中 Docker 也曾叫做 lxc-docker。这些都是非常老旧的 Docker 版本,并且基本不会更新到最新的版本,而对于使用 Docker 而言,使用最新版本非常重要。另外,17.04 以后,包名从 docker-engine 改为 docker-ce,因此从现在开始安装,应该都使用 docker-ce 这个包。 不要使用操作系统提供的软件源中的 Docker 包,去使用 Docker 官方源的包。 正确的安装方法有两种: 一种是参考官方安装文档去配置 apt 或者 yum 的源; 另一种则是使用官方提供的安装脚本快速安装。 官方文档对配置源的方法已经有很详细的讲解,这里就不赘述,需要的直接去看 官方文档。这里只介绍使用官方的脚本快速安装: 17.04 及以后的版本 从 17.04 以后,可以用下面的命令安装。 export CHANNEL=stable curl -fsSL https://test.docker.com/ | sh -- --mirror Aliyun 这里使用的是官方脚本安装,通过环境变量指定安装通道为 stable,(如果喜欢尝鲜可以改为 edge, test),并且指定使用阿里云的源(apt/yum)来安装 Docker CE 版本。 17.03 及以前的版本 早期的版本可以使用阿里云或者 DaoCloud 老的脚本安装: 使用阿里云的安装脚本: curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
使用DaoCloud的Docker安装脚本: curl -sSL https://get.daocloud.io/docker | sh |
|
总说看官方文档,可是 Docker 官网文档经常被墙,看不了怎么办? | |
首先感谢伟大的墙及其先祖。 然后,我们可以本地运行 Docker 官方文档的网站,以 docker 的方式: $ docker run -d -p 80:4000 docs/docker.github.io
对于那些访问不了我的问答录的童鞋,同样可以用这样的方式来本地运行: $ docker run -d -p 80:80 twang2218/blog.lab99.org
|
|
我要映射好几百个端口,难道要一个个 -p 么? | |
-p 是可以用范围的: -p 8001-8010:8001-8010 |
|
如何选择 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 学习而言,最好的书籍是官网文档,官网的文档很丰富。 新手教程: https://docs.docker.com/get-started/ 大量的例子: https://docs.docker.com/samples/ 用户文档: https://docs.docker.com/engine/userguide/ 镜像: https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/ 存储: https://docs.docker.com/engine/userguide/storagedriver/ 网络: https://docs.docker.com/engine/userguide/networking/ 管理文档: https://docs.docker.com/engine/admin/ 存储: https://docs.docker.com/engine/admin/volumes/ 安全: https://docs.docker.com/engine/security/security/ 集群: https://docs.docker.com/engine/swarm/ 对于新手而言,应该先从新手教程开始,内容还是很简单易懂的,很容易上手。然后,可以把用户文档好好看一遍,里面把很多 Docker 的基础概念讲的很清楚。概念清晰后,可以去把官网给出的例子好好的学习一下,这些例子都是具体怎么应用 Docker 的,有文字说明以及具体的考虑,很适合学习。 |