在2017年6月28日,Docker发布了17.06 CE版本。这是自Docker四月份将代码迁移到Moby项目中后,用该项目编译发布的首个版本。这个版本包含了几个新特性:

多阶段构建(Multi-stage builds)

这是这个版本最大的新特性了。该特性在之前四月份举行的DockerCon中发布,并在这个版本中首次集成。官方声称,该特性主要是为了便于用户使用单个Dockerfile构建更干净、更小巧的Docker镜像。

简单的说,就是在一个Dockerfile中,可以多次使用FROM指令,开启一个新阶段的构建。但最后一个FROM指令构建的镜像作为最终镜像。同时,每个阶段的COPY指令,都可以通过--from=阶段序号/阶段名来复制此前阶段镜像中的文件。

这一新特性,与其说是为了实现更干净更小巧的目标,更不如说是实现编译打包分离,从而实现不泄露源代码的目标。举个例子:

在Golang中的应用中,我们的Dockerfile通常是如下:

FROM golang
ADD . /go/src/app
RUN CGO_ENABLED=0 go install app
ENTRYPOINT /app

这种方式存在一个问题,就是会导致我们的golang源代码泄露到镜像中。很多Trick的方案,或者第三方的持续集成平台,则往往是把这个Dockerfile分离为两个Dockerfile。第一个用于编译生成二进制文件:

FROM golang
ADD . /go/src/app
RUN CGO_ENABLED=0 go install app

然后将这个镜像中的/go/bin/app文件提取出来,再用第二个Dockerfile打包Docker镜像:

FROM scratch
ADD app /app
ENTRYPOINT /app

通常我们会用脚本手动完成提取和再打包的工作。当然,也有一些第三方的持续集成平台,可以通过配置文件指定要提取的文件。然后自动完成。

然而,在新版的Docker中,我们可以直接用一个Dockerfile完成:

FROM golang AS build
ADD . /go/src/app
RUN CGO_ENABLED=0 go install app

FROM scratch
COPY --from=build /go/bin/app /app
ENTRYPOINT /app

其实简单的说,就是Docker抢了大家的饭碗了。

配置对象(Swam集群专用)

之前Docker针对swarm服务中,需要配置一些敏感数据(比如密码)的需求,增加了secret对象。

简单的说,就是通过docker secret命令,设置指定敏感数据的内容。然后在创建服务的时候,通过–secret=SecretName来指定要访问的敏感数据。这个时候就会在容器的/run/secret目录下,增加一个名为SecretName的文件,内容就是运维配置的内容。这种方式可以把敏感数据和代码分离开来。比如:

docker secret create my_password /path/to/password_file
docker service create --secret my_password redis:alpine
#此时在该服务的容器中/run/secret/my_password的内容就和/path/to/password_file一致了

在17.06 CE版中,Docker把这个玩法玩的更嗨。又增加了一个新的称之为configuration的对象。这个对象也可以使用相应的docker config系列指令设置。configuration对象和secret大致有下面几个区别:

  • secret是加密传输的,configuration不加密;
  • secret在容器中是通过内存盘的方式挂载的,而configuration是以普通的文件系统方式挂载的;
  • secret在创建服务时指定,后续不可增添。configuration可以动态增减。
  • secret固定在/run/secret/下,configuration可以像下面这样指定自定义的挂载路径:
docker service create --config src=nginx_config,target=/etc/nginx/nginx.conf ...

针对桌面客户段添加了用于访问其他容器的域名

这是以前很苦恼开发者的一件事情。当你用Docker启动一个容器时,如果想要访问其他容器Publish出来的服务端口,只有两种特殊情况支持:

  • 单机容器之间,直接link
  • Swarm服务之间,加入同一个network,通过服务别名访问。

其他方式都不行。

在Docker 17.06 CE版本中,增加了两个新域名

  • docker.for.mac.localhost
  • docker.for.win.localhost

分别针对Docker for mac和Docker for win。在这两个平台上的容器上,针对该域名的访问,类似于在Host上通过127.0.0.1来访问容器publish出来的服务。

Ubunt 12.04 Precise Pangolin不再受支持

这件事情其实在之前就已经发现了。只不过Docker貌似一直没有宣布,这次算是正式宣布了。虽然并没有说理由,不过也可以理解,毕竟这个版本的ubuntu已经发布五年了。以后ubuntu 12.04就不能再通过apt-get从docker的官方源获取到更新了。