Sichuanren's Blog

November 22, 2014

来自官方映像的 6 个 Dockerfile 技巧,实战出真知!

Filed under: Docker — sichuanren @ 2:24 am

前篇文章是关于Docker官方镜像的,本文将根据我从官方镜像学到的经验,讲解编写Dockerfile的技巧。
1. 选择Debian
官方镜像的大多数Dockerfile,不管是直接还是通过其他镜像,都是基于Debian的。Dockerfile版本通常跟特定的发行版挂钩,
正常是使用稳定版(wheezy),有些是测试版(jessie),还有是不稳定版(sid)。Debian镜像的主要好处是文件小,加起来才
85.1MB,而Ubuntu要200MB。指定准确的发行版可以预防一些问题,比如,即使标上latest的发行版升级了,构建也不会崩溃。

2. 确定来源
如果要用户信赖你的镜像,你就要考虑如果验证此镜像上的所有软件的真实性。如果通过apt-get方式从Debian的仓库获取,这个验证过程已经
被解决了。如果从网上下载文件,或者从第三方仓库安装软件,你就应该通过校验和、数字签名等方式验证这些文件。比如,为了验证nginx包,nginx的
Dockerfile会做如下操作:
RUN apt-key adv –keyserver pgp.mit.edu –recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
RUN echo “deb http://nginx.org/packages/mainline/debian/ wheezy nginx” >> /etc/apt/sources.list
ENV NGINX_VERSION 1.7.7-1~wheezy
RUN apt-get update && apt-get install -y nginx=${NGINX_VERSION}

注意nginx也是跟一个特定的版本关联的。这种做法可以保证,维护者测试的镜像跟构建工具构建的是相同的。但是,这个假设也不是绝对的,因为nginx本身的依赖也会随时间变化(比如有些依赖会标明>=某个版本)。
你自己也可以对下载的文件做相似的操作,计算文件校验和,然后跟本地版本(stored version)比较。这些操作都由Redis Dockerfile做过了。另外,有些下载的文件可能包含签名文件,你可以通过gpg来验证,通常这些操作都由官方镜像做过了。
不幸的是,一些官方镜像也没能定期正确地进行这些验证操作,或者只验证了部分文件,所以查看官方Dockerfile时要注意下。

3. 移除构建依赖
如果通过源码编译构建,你的镜像通常比需要的大很多。可能的话,在同一条RUN指令中,安装构建工具、构建软件,然后移除构建工具。虽然这样做又诡异又恼
人,但是可以省下几百MB空间。在不同的指令中删除文件是没有意义的,因为这些文件已经被打包进镜像了。我们看下Redis
Dockerfile是怎么做的:
RUN buildDeps=’gcc libc6-dev make’; \
set -x \
&& apt-get update && apt-get install -y $buildDeps –no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
&& mkdir -p /usr/src/redis \
&& curl -sSL “$REDIS_DOWNLOAD_URL” -o redis.tar.gz \
&& echo “$REDIS_DOWNLOAD_SHA1 *redis.tar.gz” | sha1sum -c – \
&& tar -xzf redis.tar.gz -C /usr/src/redis –strip-components=1 \
&& rm redis.tar.gz \
&& make -C /usr/src/redis \
&& make -C /usr/src/redis install \
&& ln -s redis-server “$(dirname “$(which redis-server)”)/redis-sentinel” \
&& rm -r /usr/src/redis \
&& apt-get purge -y –auto-remove $buildDeps

gcc, libc和make在同一条指令中先被安装,使用,然后被删掉。另外注意下,作者还删除了不会被使用的tar.gz源文件夹。顺带提下,这些代码也演示了如何使用sha1sum来验证Redis下载文件的校验和。

4. 选择gosu
gosu实用工
具,通常用在ENTRYPOINT指令调用的脚本中,这些ENTRYPOINT指令位于官方镜像的Dockerfile中。它是个类sudo的简单工具,
接受并运行特定用户的特定指令。但是gosu可以避免sudo怪异恼人的TTY和信号转发(signal-forwarding)行为。
看下这篇编写入口点脚本的官方建议,大多数官方镜像都遵循该建议。

5. 选择buildpack-deps基础镜像
很多Docker的”language-stack”镜像都是基于 buildpack-deps 基
础镜像,该镜像包含了通常开发所必须的头文件和工具(比如源码管理工具)。如果你想构建一个language-stack镜像,使用这个基础镜像可以省下
不少时间。但是向镜像添加非必须的东西也遭受了很多批评,这导致了一些仓库,如Node提供了直接基于Debian的可选slim包(完整的Node镜像
有728MB,slim只有291.4MB)。但是记住用户可能需要某些开发库,同时也通过某种途径下载了基础镜像。

6. 使用描述性标签
所有的官方镜像都提供了很多标签。像latest标签一样,提供一个版本标签是种好做法,这样用户就不用担心基础镜像变更而破坏容器。官方镜像做了更多, 提供了上文提及的精简slim镜像,以及自动导入和编译的onbuild镜像。镜像打上onbuild标签,即使转移代码再编译,来新建子镜像,用户也不会太意外。

Advertisements

November 6, 2014

5个解决Docker网络问题的项目

Filed under: Docker, Virtualization — sichuanren @ 6:47 pm

Docker 是一个开源的应用容器引擎,它可以让开发者将自己的应用以及应用所依赖的内容打包到一个可移植的容器中,然后将该容器发布到任何流行的 Linux 机器上,也可以实现虚拟化。Docker 彻底释放了虚拟化的威力,它让应用的分发、部署和管理都变得前所未有的高效和轻松,凭借着自己出众的能力,Docker现在已经成为目前IT界创业者和创 新者的宠儿。那么Docker是否已经足够完美了呢?答案当然是否定的,对于管理者和开发人员来说网络依然是Docker的一个痛点,如何管理 Docker容器之间的交互和网络一直都充满了挑战。

为了解决网络的问题,有很多公司都开发了各自的产品以帮助开发者更方便地使用Docker。Serdar Yegulalp最近在InfoWorld上分享了一篇文章,介绍了这些项目中最重要的5个,包括Weave、Kubernetes、CoreOS, Flannel、Pipework以及SocketPlane,同时他认为这其中的部分项目将来可能会成为Docker的组成部分。下面就让我们来了解一下这5个项目。

Weave是由Zett.io公司开发的,它能够创建一个虚拟网络来连接部署在多台主机上的Docker容器。通过Weave所有的 容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。外部设备能够访问Weave网络上的应用程序容器所提供的服 务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上。另外,Weave的通信支持加密,所以用户可以 从一个不受信任的网络连接到主机。如果你想了解更多与Weave相关的信息,或者查看相关源码,那么可以点击这里

Kubernetes是由Google推出的针对容器管理和编排的开源项目,它让用户能够在跨容器主机集群的情况下轻松地管理、监 测、控制容器化应用部署。Kubernete有一个特殊的与SDN非常相似的网络化概念:通过一个服务代理创建一个可以分配给任意数目容器的IP地址,前 端的应用程序或使用该服务的用户仅通过这一IP地址调用服务,不需要关心其他的细节。这种代理方案有点SDN的味道,但是它并不是构建在典型的SDN的第 2-3层机制之上。如果对此感兴趣可以阅读一下Craig Matsumoto在sdncentral上发表的这篇文章,或者点此查看源码。

Flannel之前的名字是Rudder, 它是由CoreOS团队针对Kubernetes设计的一个覆盖网络工具,其目的在于帮助每一个使用 Kuberentes 的 CoreOS 主机拥有一个完整的子网。Kubernetes 会为每一个 POD 分配一个独立的 IP 地址,这样便于同一个 POD 中的Containers 彼此连接,而之前的 CoreOS 并不具备这种能力。为了解决这一问题,Flannel 通过在集群中创建一个覆盖网络为主机设定一个子网。点此查看该项目的源码。

Pipework是由Docker的一个工程师设计的解决方案,它让容器能够在“任意复杂的场景”下进行连接。PipeworkDocker的一个网络功能增强插件,它使用了cgroups和namespacpace。点此查看该项目的源码。

SocketPlane目前仅停留在将“SDN带给Docker”的口号上,基本上没有实质性的工作。该项目的想法是使用和部署 Docker一样的devops工具管理容器的虚拟化网络,同时为Docker构建一个相当于OpenDaylight/Open vSwitch的产品。听起来非常有前途,但是在2015年一季度之前我们无法看到任何产品。

对于以上项目,Serdar Yegulalp在自己的文章中也发表了针对性的观点,他认为Weave是最好的起点,因为它通过一种直截了当的方法解决了当前大部分的问题。 Kubernetes也是一个比较好的起点,但是真要用起来可能并不是那么简单。而Flannel则最好是和CoreOS一起使用,同时它依赖于 Kubernetes。对于Pipework,Serdar Yegulalp认为它是一个临时的设计方案,很有可能会被抛弃。最后的SocketPlane则基本上是看看就行了,不要期望太高。

Create a free website or blog at WordPress.com.