900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Docker 1.13版本新增功能说明

Docker 1.13版本新增功能说明

时间:2019-10-25 22:29:55

相关推荐

Docker  1.13版本新增功能说明

前言

Docker 1.13在 年 1 月 18 日发布了。从 年 7 月 29 日发布1.12发布以来,已经过去 5 个多月了,对于活跃的 Docker 社区来说,已经很久了,让我们看看都1.13都新增了什么内容吧。

1.13有一千四百多个 issue/pull request,五千多个 commits,是 Docker 历史上最高的发布版本。这并不是一个简单的小版本变化,里面有大量的更新。

在发布之后,可以直接安装最新版本。在一个新的 Ubuntu / CentOS 系统中直接执行:

Top 10 新增功能

1、正式支持服务栈docker stack2、正式支持插件:docker plugin3、添加在 Swarm 集群环境下对密码、密钥管理的secret管理服务:docker secret4、增加docker system命令5、可以直接使用docker-compose.yml进行服务部署6、添加docker service滚动升级出故障后回滚的功能7、增加强制再发布选项docker service update --force8、允许docker service create映射宿主端口,而不是边界负载均衡网络端口9、允许docker run连入指定的 swarm mode 的overlay网络10、解决中国GFW墙掉docker-engineapt/yum源的问题

让我们来详细解读一下1.13.0新增功能吧。

Docker 镜像构建

从已有镜像取得缓存

/docker/docker/pull/26839

我们都知道使用Dockerfile构建镜像的时候,会充分利用分层存储的特性进行缓存,之前构建过的层,如果没有变化,那么会直接使用缓存的内容,避免没有意义的重复构建。不过使用缓存的前提条件是曾经在本地构建过这个镜像。这在 CI 进行集群构建时是一个比较麻烦的问题,因为构建任务可能会被分配到不同的机器上,而该机器没有构建过该镜像,因此缓存总是用不上,因此大量的时间浪费在了重复构建已经构建过的层上了。

1.13中,为docker build增加了一个新的参数--cache-from,利用镜像中的 History 来判断该层是否和之前的镜像一致,从而避免重复构建。

比如我们先下载获取作为缓存的镜像:

然后我们使用更新后的Dockerfile构建镜像时,如果加上--cache-from mongo:3.2后,会发现如果是已经在mongo:3.2中存在并没有修改的层,就会用mongo:3.2中的该层做缓存。

压扁(squash)镜像(实验阶段)

/docker/docker/pull/22641

对于总是把Dockerfile当做bash文件来用的人,会发现很快由于太多的RUN导致镜像有特别多的层,镜像超级臃肿,而且甚至会碰到超出最大层数限制的问题。这些人往往不从自身找问题,反而去寻找旁门左道,比如导出镜像做一些特殊处理,合并为一层,然后再导入等等,这种做法是很错误的,除了导致构建缓存失败外,还导致docker history丢失,导致镜像变为黑箱镜像。其实正确的做法是遵循Dockerfile最佳实践,应该把多个命令合并为一个RUN,每一个RUN要精心设计,确保安装构建最后进行清理。这样才可以降低镜像体积,以及最大化的利用构建缓存。

在 Docker 1.13 中,为了应对这群用户,实验性的提供了一个--squash参数给docker build,其功能就是如上所说,将Dockerfile中所有的操作,压缩为一层。不过,与旁门左道不同,它保留了docker history

比如如下的Dockerfile

如果我们正常的构建的话,比如docker build -t my-not-squash .,其history是这样子的:

而如果我们用--squash构建:

history则是这样子:

我们可以注意到,所有层的层ID都<missing>了,并且多了一层merge

要注意,这并不是解决懒惰的办法,撰写 Dockerfile 的时候,依旧需要遵循最佳实践,不要试图用这种办法去压缩镜像。

构建镜像时支持用--network指定网络

/docker/docker/pull/27702 /docker/docker/issues/10324

在一些网络环境中,我们可能需要定制/etc/hosts文件来提供特定的主机和 IP 地址映射关系,无论是应对 GFW,还是公司内部 Git 服务器,都有可能有这种需求,这个时候构建时修改/etc/hosts是一个比较麻烦的事情。使用内部 DNS 虽然是一种解决办法,但是这将是全引擎范围的,而且并非所有环境都会有内部 DNS。更好地做法是使用宿主网络进行构建。另外,有的时候,或许这个构建所需 Git 服务器位于容器内网络,我们需要指定某个overlay网络来给镜像构建所需。

1.13中,为docker build提供了--network参数,可以指定构建时的网络。

比如,我们有一个Dockerfile内容为:

内容很简单,就是看看构建时的/etc/hosts的内容是什么。假设我们宿主的/etc/hosts中包含了一条1.2.3.4的映射关系。

如果我们如同以往,使用默认网络进行构建。那么结果会是这样:

可以注意到,这次构建所看到的是容器默认网络的/etc/hosts,其内没有宿主上添加的条目1.2.3.4

然后我们使用docker build --network=host来使用宿主网络构建:

这次由于使用了--network=host参数,于是使用的是宿主的网络命名空间,因此/etc/hosts也是宿主的内容。我们可以在其中看到1.2.3.4条目。

开始允许docker build中定义Dockerfile未使用的参数(ARG)

/docker/docker/pull/27412

我们都知道镜像构建时可以用--build-arg来定义参数,这样Dockerfile就会使用这个参数的值来进行构建。这对于 CI/CD 系统很重要,我们可以使用一套Dockerfile来构建不同条件下的镜像。

但在1.13以前,这里有个问题,在 CI 系统中,我们有时希望用一套构建命令、脚本,通过给入不同的Dockerfile来构建不同的镜像,而--build-arg的目的是定义一些有可能会用到的全局变量,但是如果有的Dockerfile中没用这个变量,那么构建就会失败。#26249

其背后的思想是,如果--build-arg指定了,但是没用,那么很可能是因为拼写错误、或者忘记了应该使用这个变量而出现的问题。最初docker build对于这类情况的处理,是直接报错退出,构建失败。

但是在上面的 CI 的案例中,--build-arg只是定义一些可能用到的环境变量,并不强制使用,这种情况下,如果因为Dockerfile没有使用可能用到的变量就报错就有些过了。因此在1.13中,将其降为警告,并不终止构建,只是提醒用户有些变量未使用。

安装

解决GFW影响Docker安装问题

/docker/docker/pull/27005

官方的apt/yum源使用的是AWS的服务,并且为了确保安全使用了HTTPS,因此伟大的墙很乐于干扰大家使用。没办法的情况下,各个云服务商纷纷建立自己官方源镜像,阿里云、DaoCloud、Azura 等等,并且自己做了个修订版的的脚本来进行安装。

现在这个发生改变了,官方的将支持--mirror参数,你可以用这个参数指定国内镜像源,目前支持微软的 Azure 云,(或阿里云?(更新:由于阿里云镜像源不支持 HTTPS,所以不会支持阿里云))。使用方法如下,将原来官网安装命令:

替换为:

增加更多的系统支持

在这次发布中,增加了Ubuntu 16.10的安装包,而且对Ubuntu系统增加了PPC64LEs390x构架的安装包。此外,还正式支持了VMWare Photon OS系统的RPM安装包,以及在的支持。并且支持了Fedora 25,甚至开始支持arm64。同时也由于一些系统生命周期的结束,而被移除支持,比如Ubuntu 15.10Fedora 22都不在支持了。

网络

允许docker run连入指定的swarm mode的网络

/docker/docker/pull/25962

在 Docker 1.12 发布新的 Swarm Mode 之后,很多人都问过这样的问题,怎么才能让docker run的容器连入 Swarm Mode 服务的overlay网络中去?答案是不可以,因为swarmoverlay网络是为了swarm mode service准备的,相对更健壮,而直接使用docker run,会破坏了这里面的安全模型。

但是由于大家需求很多,于是提供了一种折衷的办法。1.13 允许建立网络的时候,设定该网络为attachable,允许之后的docker run的容器连接到该网络上。

我们创建一个默认的、不允许之后attach的网络:

然后再创建一个允许attach的网络,这里会使用 1.13 新加入的--attachable参数:

然后我们启动一个web服务,连入这两个网络:

现在我们用docker run启动一个容器连入第一个网络:

由于mynet1不允许手动attach所以这里报错了。

在 1.12 的情况下,会报告该网络无法给docker run使用:

不过,--attachable实际上是将网络的安全模型打开了一个缺口,因此这不是默认设置,而且并不推荐使用。用户在使用这个选项建立网络的时候,一定要知道自己在做什么。

允许docker service create映射宿主端口,而不是边界负载均衡网络端口

/docker/docker/pull/27917 /docker/docker/pull/28943

docker service create中的--publish格式有进一步的变化。(在 1.13 的 RC 期间,曾经去掉--publish,改为--port,经过讨论后,决定保持一致性,继续使用--publish,不使用新的--port选项。)

在 1.12 中,docker service create允许使用参数--publish 80:80这类形式映射边界(ingress)网络的端口,这样的映射会享受边界负载均衡,以及 routing mesh。

从 1.13 开始,增加另一种映射模式,被称为host模式,也就是说,用这种模式映射的端口,只会映射于容器所运行的主机上。这就和一代 Swarm 中一样了。虽然失去了边界负载均衡,但是确定了映射点,在有的时候这种情况是需要的。

现在--publish的新的参数形式和--mount差不多。参数值为,逗号分隔的键值对,键值间以=等号分隔。目前支持 4 项内容:

protocol: 支持tcp或者udpmode: 支持ingress或者hosttarget: 容器的端口号published: 映射到宿主的端口号

比如,与-p 8080:80等效的--publish新格式选项为:

当然我们可以继续使用-p 8080:80,但是新的选项格式增加了更多的可能。比如,使用 1.13 开始加入的host映射模式:

运行成功后,查看一下服务容器运行的节点:

我们可以看到,集群有3个节点,而服务就一个副本,跑到了d3上。如果这是以前的使用边界负载均衡的网络ingress的话,那么我们访问任意节点的80端口都会看到页面。

但是,host模式不同,它只映射容器所在宿主的端口。因此,如果我们curl d1的话,应该什么看不到网页,而curl d3的话就会看到页面:

iptables的转发规则将默认拒绝

/docker/docker/pull/28257

从默认FORWARD改为DROP,从而避免容器外露的安全问题。

docker network inspect里显示连入的节点

我们都是知道,在swarm mode中创建的overlay网络,并不是一下子就在集群中的每个节点上docker network ls就可以看到这个网络,这完全没有必要。只有当使用该网络的容器调度到某个节点上后,才会将该节点连入此overlay网络。在网络排障过程中,经常会有这种需求,需要得知现在连入该overlay网络中的节点到底有哪些,这在1.13之前不容易做到。

1.13开始,docker network inspect将显示连接到了这个网络的节点(宿主)有哪些。

从上面的例子可以看出,一共有两个宿主连入了这个mynetoverlay网络,分别为138.197.213.116138.197.221.47

允许serviceVIP可以被ping

/docker/docker/pull/28019

在 1.12 的二代 Swarm 排障过程中,常见的一个问题就是跨节点的服务 VIP 不可以ping,所以很多时候很多时候搞不懂是overlay网络不通呢?还是服务没起来?还是服务发现有问题?这个问题在 1.13 解决了,VIP 可以随便ping,跨宿主也没关系。

插件

插件功能正式启用

/docker/docker/pull/28226

在 1.12 引入了插件概念后,作为试验特性得到了很多关注。包括Docker Store开始准备上线,以及第三方的插件的开发。现在 1.13 插件作为正式功能提供了。

相比于 1.12 的试验版本而言,最重要的是增加了docker plugin create命令,可以指定一个包含有config.json文件和rootfs目录的目录来创建插件。

命令行

checkpoint功能(试验功能)

/docker/docker/pull/22049

checkpoint功能可以将运行中的容器状态冻结并保存为文件,并在将来可以从文件加载恢复此时的运行状态。

准备工作

目前它所依赖的是criu这个工具,因此在 Linux 上需要先安装这个工具。(目前尚无法在 Docker for Mac 中使用docker/for-mac#1059)

如果未安装criu则会出现如下报错:

对于 Ubuntu 系统,可以执行下面的命令安装criu

由于这个是试验功能,因此需要在docker.serviceExecStart=这行后面添加--experimental选项。其它试验功能也需如此配置。

然后不要忘了systemctl daemon-reloadsystemctl restart docker

创建 Checkpoint 及恢复

执行docker checkpoint create就可以为容器创建checkpoint

可以为一个容器创建多个checkpoint,每个起不同的名字就是了。

然后可以用docker checkpoint ls来列出已经创建的checkpoint

如果不加--leave-running参数的话,容器就会在创建完checkpoint就会被停止运行。

然后我们可以通过docker start --checkpoint来从某个checkpoint恢复运行:

容器就会从checkpoint1这个点恢复并继续运行。

备份时可以用--checkpoint-dir指定具体的保存checkpoint的目录:

然后我们可以在backup中看到实际保存的文件内容:

docker stats终于可以显示容器名了

/docker/docker/pull/27797 /docker/docker/pull/24987

docker stats可以显示容器的资源占用情况,用来分析不同容器的开销很有帮助。不过一直以来有个很讨厌的问题,docker stats不显示容器名:

这让人根本没办法知道到底谁是谁。于是有各种变通的办法,比如:

但是这个列表是静态的,容器增加、删除都得重新运行这个命令。

1.13开始,虽然依旧默认没有容器名,但是增加了--format参数可以自己设计输出格式:

docker ps增加is-task过滤器

/docker/docker/pull/24411

开始使用 Swarm Mode 后,经常碰到的一个问题就是,docker ps所看到的这些容器到底哪些是服务容器?哪些是docker run跑起来的单独的容器?

1.13开始,增加了is-task过滤器,以区分普通容器和 Swarm Mode 的服务容器:

再也不会出现客户端和服务端不同版本导致的错误了

/docker/docker/pull/27745

在以前,docker 客户端和服务端必须版本一致,否则就会报Client and server don't have the same version这类错误。后来增加了DOCKER_API_VERSION环境变量,在客户端高于服务端版本时,可以通过这个环境变量指定服务端 API 版本,从而避免这类错误。

1.13开始,将进行一些版本判断来进行处理,从而不会因为版本不一致而报错了。

docker inspect将可以查看任何 docker 对象

/docker/docker/pull/23614

我们应该很熟悉docker inspect,我们经常用它查看镜像、容器。从1.13开始,这将变的更高级,可以查看任何 Docker 对象。从网络、task、service、volume到之前的镜像、容器等等。

比如,我们用docker service ps列出了服务对应的task列表,得到task id后,我们可以直接docker inspect这个task id

运行时

不在分别构建试验可执行文件,直接使用--experimental参数

/docker/docker/pull/27223

以前我们如果希望测试当前试验功能,必须添加试验分支源,重装docker。这给测试试验分支带来了困难。现在变得简单了,不在分为两组可执行文件构建,合并为一个。如果需要测试试验功能,直接在dockerd后添加--experimental即可。

overlay2存储驱动使用于xfs时可以添加磁盘配额

/docker/docker/pull/24771

在 1.13 之前,只有块设备文件系统驱动(如devicemapper,xfs,zfs等)支持磁盘配额能力,而所有Union FS的驱动,都不支持配额。现在针对使用XFS为后端的overlay2驱动支持了磁盘配额,理论上同样的方式可以在将来移植到AUFS

增加docker system命令

/docker/docker/pull/26108 /docker/docker/pull/27525

很多人在以前搞不懂自己的镜像到底占了多少空间、容器占了多少空间,卷占了多少空间。怎么删除不用的东西以释放资源。从 1.13 开始,Docker 提供了一组system命令来帮助系统管理上的问题。

docker system df是显示磁盘使用情况:

显示的列表中列出了镜像、容器、本地卷所占用的磁盘空间,以及可能回收的磁盘空间。比如,我们看到镜像有 123MB 的空间可以回收,从 1.13 开始,docker提供了一组prune命令,分别是:

docker image prune:删除无用的镜像docker container prune:删除无用的容器docker volume prune:删除无用的卷docker network prune:删除无用的网络docker system prune:删除无用的镜像、容器、卷、网络

还记得之前删除这些资源所用的docker rmi $(docker images -f dangling=true -aq)这种命令么?现在可以简单地docker image prune即可删除。

此外,从上面已经可以看到,从 1.13 开始,命令都开始归类于各个子命令了。之前默认的docker infodocker psdocker rmdocker run都开始归类于对应的docker image,docker container,docker system下了。目前之前的命令依旧可以使用,会继续保持一段时间。但是从 1.13 开始,推荐使用各个子命令的版本了。

提升overlay2的优先级

/docker/docker/pull/27932

由于overlay2在 4.+ 内核的系统上趋于稳定,因此将其优先级提到devicemapper之上(优先级最高的依旧是aufs

docker exec -t自动添加 TERM 环境变量

/docker/docker/pull/26461

对于在容器中使用vihtop之类工具的人来说是比较方便的。之前由于默认没有定义TERM,这些需要终端页面布局的程序执行可能会不正常。比如:

现在直接为docker exec -t选项添加了继承自当前的TERM变量,可以让这类工具可以正常使用。

Windows 内置的运行 Windows 程序的 Docker on Windows 的改进

#28415:支持Dockerfile中的USER了; #25736:支持syslog日志系统; #28189:支持fluentd日志系统; #28182:终于支持overlay网络了; #22208:支持自定义网络指定静态IP了; #23391:支持存储层驱动的磁盘配额; #25737:终于可以用docker stats了; #25891:终于可以用docker top了; #27838:Windows 终于可以用 Swarm Mode 跑集群了;

Swarm Mode

正式支持docker stack

1.12 中引入了二代 Swarm,也就是 Swarm Mode。由于基础理念变化很大,因此先行实现比较基本的服务(service),但是针对应用/服务栈(stack)没有成熟,只是试行使用.DAB文件进行集群部署。但是DABJSON文件,而且撰写较为复杂。相对大家已经习惯的docker-compose.yml却无法在docker stack中直接使用。只可以用docker-compose bundle命令将docker-compose.yml转换为.dab文件,然后才能拿到集群部署,而且很多功能用不了。

从 1.13 开始,将允许直接使用docker-compose.yml文件来进行部署(#27998),大大方便了习惯了docker compose的用户。不过需要注意的是,由于理念的演化,原有的docker-compose.ymlv2格式无法使用,必须使用v3格式。

幸运的是v3v2格式差距不大。

将一些过时的东西去掉,如volumes_from,需要共享数据用命名卷; 去除volume_driver,这种服务全局的东西没有必要,直接针对每个卷使用volume键下的driver即可; 将cpu_shares,cpu_quota,cpuset,mem_limit,memswap_limit移到deploy下的resources下进行管控,毕竟这是部署资源控制的部分。

具体差异可以看官方文档:/docker/docker.github.io/blob/vnext-compose/compose/compose-file.md#upgrading

用我的 LNMP 的示例为例子,显然第一行的version: '2'需要换成version: '3'

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。