目录

隐藏
  1. Docker 怎么这么多软件,我该装哪个?
  2. docker pull 好慢啊怎么办?
  3. 是直接用 yum / apt-get 安装 Docker 吗?
  4. 为什么执行 docker 命令会报 permission denied 没权限的错误啊?
  5. 如果 Docker 升级或者重启的话,那容器是不是都会被停掉然后重启啊?
  6. 服务器上线后,怎么发现总有个 xmrig 的容器在跑,删了还出来,这是什么鬼?
  7. 怎么修改了 docker 服务配置后不起作用?
  8. 不是都已经发布 Docker 17.07 了么?我怎么升级到最新还是 17.05 呀?
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。不过还在用那些版本的童鞋,升级吧…


保存退出后,重新加载配置并启动服务:

sudo systemctl daemon-reload
sudo systemctl restart docker
确认一下配置是否已经生效:

sudo ps -ef | grep dockerd
如果配置成功,生效后就会在这里看到自己所配置的加速器。

在 1.13 版本以后,可以直接 docker info 查看,如果配置成功,加速器 Registry Mirror 会在最下面列出来。

如果重启后发现无法启动 docker 服务,检查一下服务日志,看看是不是之前执行过那些加速器网站的脚本,如果有做过类似的事情,检查一下是不是被建立了 /etc/docker/daemon.json 以配置加速器,如果是的话,删掉这个文件,然后在重启服务。

使用配置文件是件好事,比如修改配置不必重启服务,只需发送 SIGHUP 信号即可。但需要注意,目前在 dockerd 中使用配置文件时,无法输出当前生效配置,并且当 dockerd 的参数和 daemon.json 文件中的配置有所重复时,并不是一个优先级覆盖另一个,而是会直接导致引擎启动失败。很多人发现配了加速器后 Docker 启动不起来了就是这个原因。解决办法很简单,去掉重复项。不过

因此在这些问题解决前,建议使用修改 docker.service 这类做法来实现配置,而不是使用配置文件 daemon.json。


是直接用 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 命令会报 permission denied 没权限的错误啊?
在 Linux 环境下,一些新装了 docker 的用户,特别是使用了 sudo 命令安装好了 Docker 后,发现当前用户一执行 docker 命令,就会报没权限的错误:

dial unix /var/run/docker.sock: permission denied
一些来自于 Windows 世界的人,就会蹦出来说,用 root 呀。而另一些有基本常识、知道不应该使用 root 人可能会说,那就用 sudo docker 吧。这两者都是不对的,或者说不合适的。

说使用 root 的人,应该回去好好学习一下 Linux 权限常识。一般 不应该直接使用 root 用户,直接使用 root 用户不仅仅是严重的违反了安全规范,而且也极容易造成操作事故。这不是 Windows 世界,Linux/Unix 世界是有严格的权限要求的,只应该使用最小的权限做事情。如果还不熟悉 Linux 权限机制,那就去学习一下,不要把 Windows 的坏毛病带过来。

说使用 sudo docker 的人,思路是对的,因为理解了平时操作应该使用普通用户,只有在需要的时候,才 sudo 提升权限进行操作。但是问题就在这个需要二字上,事实上,不需要 root 权限就可以执行 docker 命令。

其实如果看过 官方安装文档的话都会知道,只需要将操作 docker 的用户,加入 docker 组,那么该用户既拥有了操作 docker 的权限。

因此,只需要执行:

sudo usermod -aG docker $USER
就可以把当前用户加入 docker 组,退出、重新登录系统后,执行 docker info 看一下,就会发现可以不用 sudo 直接执行 docker 命令了。

如果需要添加别的用户,将其中的 $USER 换成对应的用户名即可。

将用户添加到 docker 组,可以避免 root 权限误操作的问题,但是由于 dockerd 引擎是运行在 root 用户下的,而 docker 组成员有权限指挥 dockerd 引擎来做很多事情,因此,该用户实际上是拥有了 root 的权限的。因此不要误解了将当前用户加入 docker 组的初衷,这和赋予用户 sudo 权力是一样的,可不是说这个用户就没有 root 权限了。这样做,只是不再需要使用 sudo 了,也降低了使用 sudo 时误操作的可能。

此外,这里说的权限问题,全是指使用 docker 命令操作本机 dockerd 引擎,也就是通过 /var/run/docker.sock 来操作 dockerd 引擎的事情,只有这种有之前说的权限类的问题。

而 docker 命令还可以操作远程 dockerd 的引擎,也就是 -H 参数,或者 DOCKER_HOST 环境变量所指定的 Docker 主机。这种情况通讯走的是网络、HTTP,不会有权限问题。所以,如果不打算操作本机的 dockerd 引擎,则不需要将用户加入 docker 组,也是可以操作远程服务器的。

如果 Docker 升级或者重启的话,那容器是不是都会被停掉然后重启啊?
在 1.12 以前的版本确实如此,但是从 1.12 开始,Docker 引擎加入了 --live-restore 参数,使用该参数可以避免引擎升级、重启导致容器停止服务的情况。

默认情况该功能不会被启动,如需启动,需要配置 docker 服务配置文件。比如 Ubuntu 16.04 这类 systemd 的系统,可以修改 /etc/systemd/system/multi-user.target.wants/docker.service 文件,在 ExecStart= 后面配置上 --live-restore:

ExecStart=/usr/bin/dockerd \
--registry-mirror=https://jxus37ac.mirror.aliyuncs.com \
--live-restore
上面的格式中使用了行尾 \ 的换行形式,这点和 bash 脚本一样,systemd 支持这种换行形式,如对此不了解可以先去学习 bash 程序设计。

需要注意的是,--live-restore 和 Swarm Mode 不兼容,所以在集群环境中不要使用。实际上集群环境也不用担心某个服务器重启的问题,因为其上的服务都会被调度到别的节点上,因此服务并不会被中断。

参考文档:
https://docs.docker.com/engine/admin/live-restore/

服务器上线后,怎么发现总有个 xmrig 的容器在跑,删了还出来,这是什么鬼?
警告!!你的服务器已经被入侵了!!

有些人服务器上线后,发现突然多了一些莫名奇妙的容器在跑。比如下面这个例子:

$ docker ps
IMAGE           COMMAND                  CREATED      STATUS                      PORTS    NAMES
linuxrun/cpu2   "./xmrig --algo=cr...."  4 hours ago  Exited (137) 7 minutes ago           linuxrun-cpu2
...
这就是有人在你的 Docker 宿主上跑了一个 xmrig 挖矿的蠕虫,因为你的系统被入侵了。

在你大叫 Docker 不安全之前,先检讨一下自己是不是做错了。检查一下 dockerd 引擎是否配置错误:ps -ef | grep docerd,如果你看到的是这样子的:

$ ps -ef | grep dockerd
123  root   12:34   /usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375
如果在其中没有 --tlsverify 类的 TLS 配置参数,那就说明你将你的系统大门彻底敞开了。这是配置上严重的安全事故。

-H tcp://0.0.0.0:2375 是说你希望通过 2375/tcp 来操控你的 Docker 引擎,但是如果你没有加 --tlsverify 类的配置,就表明你的意图是允许任何人来操控你的 Docker 引擎,而 Docker 引擎是以 root 权限允许的,因此,你等于给了地球上所有人你服务器的 root 权限,而且还没密码。

如果细心一些,去查看 dockerd 的服务日志,journalctl -u docker,日志中有明确的警告,警告你这么配置是极端危险的:

$ journalctl -u docker
...
level=warning msg="[!] DON'T BIND ON ANY IP ADDRESS WITHOUT setting --tlsverify IF YOU DON'T KNOW WHAT YOU'RE DOING [!]"
...
如果这些你都忽略了,那么被别人入侵就太正常了,是你自己邀请别人来的。所以,Docker 服务绑定端口,必须通过 TLS 保护起来,以后见到 -H tcp://.... 就要检查,是否同时配置了 --tlsverify,如果没看到,那就是严重错误了。

这也是为什么推荐使用 docker-machine 进行 Docker 宿主管理的原因,因为 docker-machine 会帮你创建证书、配置 TLS,确保服务器的安全。

进一步如何配置 TLS 的信息,可以查看官网文档: https://docs.docker.com/engine/security/https/
关于 docker-machine 的介绍,可以看官网文档: https://docs.docker.com/machine/overview/

怎么修改了 docker 服务配置后不起作用?
改动真的生效了么?在宿主上运行一下 ps -ef | grep dockerd 看看,自己做的那些配置有么?没有的话就说明没有生效,那么就要检查原因了。

首先,改完配置重启服务了么?虽然这个问题看着很小白,但是确实很多人犯了这个小白的错误。

Ubuntu 14.04: sudo service docker restart
Ubuntu 16.04, CentOS 7: sudo systemctl daemon-reload && sudo systemctl restart docker
另外,你改对了配置文件了么?

不少人懒得看英文文档,百度个文章就照着配,既不管百度得到的文章所讲的系统,也没注意版本,而且中文文章往往自身表达描述不清楚,很多想当然的东西,结果无数坑。这么百度的人,很有可能压根就改错了文件。

最近两年处于 upstart 到 systemd 的过渡期,所以配置服务的方式对于不同的系统版本是不一样的,要看看自己使用的是什么操作系统,以及什么版本。

对于 upstart 的系统(Ubuntu 14.10或以前的版本,Debian 7或以前的版本),配置文件可能在 /etc/default/docker,其配置方式基本是配置 DOCKER_* 的环境变量。

而对于 systemd 的系统(Ubuntu 15.04及以后的版本,Debian 8及以后的版本,CentOS 7/RHEL 7及以后的版本),配置文件则在 systemd 的配置目录下。

首先应该 enable 该服务:

sudo systemctl enable docker
然后修改配置文件 /etc/systemd/system/multi-user.target.wants/docker.service (只要服务 enable 了,那么不管什么系统,应该都会在这个位置看到配置文件)

要注意 upstart 的服务配置文件和 systemd 的配置文件的格式是不同的,不要拿着 upstart 的配置行直接复制粘贴到 systemd 的配置文件里,两码事儿,请先学习基础知识。

参考官网文档:
https://docs.docker.com/engine/admin/configuring/#ubuntu
https://docs.docker.com/engine/admin/systemd/

不是都已经发布 Docker 17.07 了么?我怎么升级到最新还是 17.05 呀?
从 17.04 以后,Docker 的源的结构以及包名都进行了调整,因此如果你你还使用的是旧的源,那么需要参照 官方文档,更新源的地址为新的源。前面的问答中已经给出了链接和替代用的阿里云源镜像地址,参照修改(apt/yum)源。

修改好后,卸载旧的 docker-engine,安装新的 docker-ce 即可。