Docker 的几个实战经验分享

  • 郭蕾

2015 年 4 月 1 日

话题:DevOps语言 & 开发

云栈科技是一家提供容器解决方案(csphere)的创业公司,其创始人王利俊是之前新浪 SAE PaaS 平台的负责人,在 3 月 29 日的QClub Docker大会上,王利俊分享了题为《Docker 在生产环境的挑战以及应对》的演讲,本文根据其演讲内容整理而成。

未来的趋势是 PaaS 还是 CaaS

PaaS 从 2008 年万众瞩目到 2012 年遭受质疑,再到现在很多 PaaS 企业业务发展都不尽如人意(甚至有的已经关闭),留下的也是在苦苦支撑。究其本质原因,是由于 PaaS 在满足客户需求方面存在很多障碍。没有规范,不成 PaaS。PaaS 的关键是约束和规范,但是规范是一把双刃剑,它一方面使得应用开发更加整齐,应用管理和维护更加简单;但是另一方面客户的需求千变万化,我们很难用一套规范去满足所有的业务需求。因此通用的 PaaS 平台就处于两难的境地。未来 PaaS 的趋势一定是垂直化,比如面向游戏的 PaaS、面向某类智能硬件的 PaaS。

随着以 Docker 为代表的容器技术的成熟,CaaS(容器即服务)的概念也逐渐被接受。未来的趋势是 PaaS 还是 CaaS,这取决于未来市场是对 PaaS 还是对容器更加接受。现在的市场对 Linux 非常认可,使用率也很高,如果容器可以像 Linux 一样流行,那肯定是 CaaS 更有市场。反之,则是 PaaS 更加流行。

镜像管理

镜像是 Docker 管理最基础的部分,同时也是 Docker 最大的亮点。镜像管理涉及到镜像的制作、更新、存储、分发、权限等多个方面。

镜像制作方面,应该坚持三个原则,第一是坚持镜像总是从 Dockerfile 生成。这样做最大的好处是可以通过 Dockerfile“阅读”镜像,在后续的协作、升级维护等方面会带来巨大的便利。第二是镜像之间应该避免依赖过深,建议为三层,这三层分别是基础的操作系统镜像、中间件镜像和应用镜像。第三是坚持所有镜像都应该有对应的 Git 仓库,以方便后续的更新。

镜像的更新需要一个自动化的流程,这可以通过 SCM 和 CI 系统自动触发实现。具体的流程如下图所示。开发者首先将代码和 Dockerfile 提交到 Git 仓库,然后 Git 通过 webhook 方式触发 Jenkins 的主动获取代码和 Dockerfile 文件,Jenkins 再通过 Docker 相关的插件生成镜像并推送镜像到私有的 Registry。这样,在服务器上就可以通过拉取新的镜像部署容器。

关于 Registry,可能会涉及三方面的问题,一个是单点问题,对应的解决方案可以考虑 DRBD、分布式存储以及云存储。二是 Regitry 的性能问题,目前可用的解决方案是通过 HTTP 反向代理缓存来加速 Layer 的下载。三是 Registry 用户权限,Nginx LUA 可以提供一个简单快速的实现方案。

发布管理

和传统的发布流程相比,Docker 最大的好处是不需要考虑外部依赖,利用容器的自包含的特点,我们可以将发布回滚流程标准化和产品化。而传统的发布和回滚,需要 casebycase 去针对不同应用做升级回滚的方案。要做到基于 Docker 的发布,镜像的生成必须坚持自动化,否则会发现升级比传统的方法更麻烦。因此在现实中我们也发现很多企业将代码目录放到主机目录映射到容器内,这样做破坏了 Docker 的自包含特性,解决的办法是坚持应用镜像更新自动化。

日志管理

由于容器是无状态的,所以存储在容器内的日志会随着容器的销毁而消失。stdout/stderr 类型的日志,可通过 logspout 转发到 syslog 中心来收集。打印到文件的支持,比如 accesslog,需要将日志存储到外部的 Volume,并在 Docker 主机上使用 logstash 收集转发。

配置管理

容器里没有 CM agent,无法接收 CM 指令。CM 运行到 Host 上也无法管理容器中的文件,如果手工修改容器内的配置,那新创建的容器仍然是旧的。配置大体上分为两种类型,一种是服务之间的连接信息,这种配置建议考虑使用服务发现系统,也可以使用一些更加传统的方法,比如通过环境变量来协调作开发和生产环境的配置差异。一种是一般的配置文件参数,配置文件和 Dockerfile 应该一起存储到一个 Git 仓库,修改后自动 build 更新镜像。

网络管理

目前 Docker 支持的网络包括 Host 网络、NAT 网络、物理网桥和网络虚拟化。Host 网络中容器和主机共享网络命名空间,不同容器需要做好端口规划,防止端口冲突。Nat 网络是基于四层代理以及 NAT 技术,依赖 portmap,进出都需要转发,性能低,主机上需要做好端口规划,容易搞混。物理网桥方案,和传统虚拟机的网桥没有区别,适合容器数量有限且相对静止的场景。网络虚拟化是基于隧道的 overlay 网络,目前开源方案有 SocketPlane、Weave、Flannel,适合数量大,动态创建销毁容器的场景。

DevOps语言 & 开发