[关闭]
@xishuixixia 2016-06-05T14:04:14.000000Z 字数 2551 阅读 2192

基于Docker的运维案例剖析

Docker 运维 容器


应用迁移需求

应用运维需要考虑的一个重要问题就是迁移,在不同机器、机房、环境间迁移。迁移的原因有很多,比如硬件过保(硬件故障),机房迁移,应用扩缩容等。

应用迁移的核心需求是:

许多公司还在使用古老的 RHEL 5/6 和 Linux 2.6.x 内核,难以充分发挥现代操作系统和硬件的能力,部分原因也是受制于应用迁移技术不成熟,不能保证快速无损迁移应用,不敢迁移。

具备快速迁移的能力,同样可将应用快速切换到任意版本,实现快速回滚。

Tomcat webapp 部署结构

我们看一下一个基于 Tomcat 部署的 Java webapp 应用部署结构如下:

  1. apache-tomcat-8.0.35/
  2. ├── bin/
  3. ├── conf/
  4. ├── lib/
  5. ├── logs/
  6. ├── temp/
  7. ├── webapps/
  8. ├── work/
  9. ├── LICENSE
  10. ├── NOTICE
  11. ├── RELEASE-NOTES
  12. └── RUNNING.txt

其主要分为两个部分:

  1. 静态二进制文件。包含 bin/lib/。这部分是三方软件包 Tomcat 自带的内容。对应用而言,这部分内容是只读访问的,不会修改。
  2. 外部配置和数据。包含 conf/logs/temp/webapps/work/。这里的“外部”是指从 Tomcat 软件包的角度来看,对应用来说,这部分才是真正的应用软件包。

注意:Tomcat 软件包也包含 conf/。但应用可能会对 conf/ 进行修改,所以应用使用了一个独立维护的 conf/ 副本,而不是 Tomcat 软件包自带的 conf/ 内容。

很显然,要迁移这个应用,只需要迁移第 2 部分,即外部配置和数据即可。为了简化迁移,许多应用被设计为无状态的,即 logs/temp/work/ 等外部数据目录不包含任何影响应用功能的配置或数据,这部分内容不需要迁移。只需要迁移 conf/webapps/ 目录,这部分内容可打包为应用软件包。

这样,在新环境部署应用,只需要安装 Tomcat 软件包和应用软件包即可。

新环境部署

在新环境上完成应用部署,有两种玩法:

  1. 列一个软件包清单(如上例中的 Tomcat 和应用),在新环境上按照清单完成软件包安装,这是 juju 的玩法。

  2. 将所有软件包安装好并打包成一个二进制镜像,拷贝到新环境上部署运行,这是 Docker 的玩法。Dockerfile 描述如何创建镜像,类似于软件包清单。

Docker 镜像不止是预安装软件包,还包含基础操作系统环境,统一的日志、数据路径,环境变量等标准化应用运行环境。这可难不倒 juju,juju 同样基于一个标准镜像创建 VM 或 LXC 容器,再安装软件包,同样提供标准化的运行环境。这两种方式各有优缺点,在此不作深究。但就使用成本来说,Docker 目前在国内外发展火热,技术和实践经验相对成熟,更容易使用。

单机多实例隔离部署

使用 Docker 应用容器部署应用,Docker 容器为应用提供了标准一致且相互独立的运行环境,这样应用使用相同的配置和路径,也可以在单个宿主机上实现多实例部署。与 VM 的单机单部署模式相比,应用容器要做的足够轻,消除 VM 的额外开销,并且完美支持微服务编排。

软件包与配置分层

有些软件包很好的实现了软件包默认配置与应用自定义配置的分离,如 Tomcat,只需指定 CATALINA_BASE 目录与 CATALINA_HOME 目录分开,将应用部署到 CATALINA_BASE 下,即可实现应用自定义配置和 Tomcat 软件包默认配置分离,两者独立维护,互不影响。

许多软件包没有实现这样的能力,Docker 通过分层文件系统解决这个问题,同时可以避免每个软件包都去考虑设计配置分离功能。

docker_operation_conf_layer

应用自定义配置在软件包安装层的上层,运行容器时覆盖默认配置,但在软件包安装层升级软件包时看不到应用自定义配置,不会受应用自定义配置影响。需要注意的是,软件包升级后是否兼容旧的应用自定义配置,是否需要更新自定义配置,需要应用负责人关注和测试。

按照 Docker 的分层设计思想,越基础越固定不变的东西越要放到底层,越容易变化的东西越要放到上层,因此应用依赖的软件包和基础配置要放到底层,可以独立为一个 base 镜像,应用本身和自定义配置放在上层。如果应用本身或配置更新更频繁,可将这两者再分成两层。

配置管理

假设我们要修改一个应用配置,一种方式是登陆一台机器修改,测试 ok 后将修改同步到所有其它机器。这种方式很原始并且缺乏监管,容易出错。比如新扩容了 100 台机器每台都要更新一遍,如果操作有遗漏,哪些机器配置已经更新,哪些机器还是旧的配置也缺乏监管。

按 Docker 的玩法,应该是先更新镜像,测试 ok 后分发镜像到所有机器更新容器。Docker 监管了所有容器部署的镜像版本和容器状态,从而可以很方便的检查哪些容器更新了,哪些没有更新。对于很少变化的静态配置,应该固化到镜像中。

对于一些经常变化的配置,重新打镜像和更新容器成本太高, 应该设计成预定义的开关,通过开关平台进行监控和管理。或者通过 diamond 等专门的配置管理平台来管理。

Docker 容器数据卷

Docker 容器内的文件系统伴随容器而生,销毁或更新容器时(如升级镜像或修改容器配置),原有数据将会丢失。并且受分层文件系统设计影响,其性能可能更差(与存储引擎实现有关)。

因此,需要持久化保存的配置和数据,或有高写性能要求的,如 logs/data/ 等外部数据目录,应使用 Docker 数据卷 挂载到宿主机上。

Dockerfile 中使用 VOLUME 指定容器中需要挂载为数据卷的目录列表。

Docker 化运维方案

综上所述,Docker 化运维需要将应用拆分为 3 部分:

  1. 基础环境,应用所有依赖,应用软件包和静态配置,固化到镜像。
  2. 需要动态修改的配置,通过开关平台或 diamond 等配置平台进行管理。
  3. 需要持久化保存或频繁写需求的配置或数据目录,挂载为数据卷。

部署运维时,使用 Docker 分发镜像,配置平台推送配置,即可实现应用快速部署、迁移、更新、回滚、扩缩容等运维操作。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注