本文介绍业务方容器化的成本,同时谈谈如何降低这些成本,从而让容器化过程更为顺畅。业务方的接入成本主要有如下四种:

  • 业务迁移和改造的成本
  • 镜像的制作和管理成本
  • K8S 的学习使用成本
  • 容器环境下一些习惯转变成本

业务迁移和改造成本

业务的迁移成本主要体现在把业务从物理机或虚拟机迁移到容器的过程中,用户需要完成容器上线,测试业务功能,知会相关上下游,割接流量,最终下线业务并回收旧机器。鉴于迁移过程中的步骤多,流程长,同时为了避免对业务造成影响,故整个过程做到自动化是非常困难的。对此,似乎没有特别好的流程或者技术能够降低迁移成本。

此外,部分用户还需对业务进行一定的改造和解耦。这些改造主要体现在无状态化,以容器要求优化项目的组织,如配置文件,启动脚本等等,往往需要 PaaS 团队支撑用户进行改造。然后改造的人力和时间成本往往比较大,对于这类业务,可降低其容器化的优先级。

镜像的制作和管理成本

镜像制作是容器化必要步骤,Dockerfile 的编写和维护,镜像的制作又是镜像模块重要部分。客观而言,Dockerfile 学习成本比较高,制作一个优雅的镜像往往需要丰富的经验;此外,镜像制作环境的维护也是一个问题,如果每个用户均有一个制作环境,势必会造成大量资源的浪费,如果大家共享一个环境,则有可能造成环境混乱。

对于资源大户,建议由 PaaS 团队支撑和教育业务方编写 Dockerfile,并约定一定的规则。这些 Dockerfile 最好以 git 的方式维护起来,便于管理维护。

对于标准化业务,它们的目录组织比如启动方式,部署脚本,配置文件,依赖包等等都遵循某种规则,那么这类业务的镜像制作相对容易做到自动化。根据这些规则可以实现自动生成 Dockerfile 并完成镜像制作,最终让用户对镜像的制作流程无感知。

对于非标准化且资源需求小的业务,因其应用的环境和组织较为混乱,Dockfile 的编写和镜像制作的成本将非常高,大批量的接入容易会造成很多不良后果。对于这类用户,可将其容器化的优先级安排底一些,同时建议先做标准化,再做容器化。

从 PaaS 角度而言,需要维护到语言层次的基础镜像;其次做好引导措施,避免用户写出庞杂的镜像;对于标准化业务,实现自动生成 Dockerfile 的模块。

K8S 的学习使用成本

业务容器化后,用户可以通过 K8S 的 API 或者 Portal 来完成生命周期的管理。K8S 具有十几个 API,这些 API 的请求参数非常之多,用法较为复杂,用户往往需要较长的一段时间实践才能掌握这些参数的含义。

对于资源大客户,他们往往在 K8S 基础上构建自身的平台,所以通常直接使用 K8S 的 API 来实现生命周期管理。对于这类用户,建议由 PaaS 团队进行一定的介绍,让业务方掌握正确的姿势,避免潜在的风险。

对于采用发布系统进行发布的用户,可以打通发布系统和 K8S。每当用户发布时,应该先制作镜像,然后根据该镜像更新原有容器实例。如此,用户对 K8S 几乎不感知,大大的降低了学习成本。

对于其它一些机器资源比较少的用户,建议使用 Portal 完成生命周期的管理。

从 PaaS 角度而言,首先要做好 API 的认证和授权工作,避免安全隐患,同时做好限流措施。其次,采用一个完全扁平互通的网络非常有利于业务接入,完全扁平是指容器和虚拟机和物理机均可互通,如此可以避免引入 service 等模块。

容器环境下的一些习惯转变成本

很多用户反馈了一些体验上的问题,比如缺乏一些常用工具,free 看到的是宿主机内存,容器重启后文件丢失等等。这些问题可以总结为三类:

  • 富容器 vs 瘦容器
  • docker 的隔离性不彻底
  • 如何保存有状态数据或者工具

原则上来说,瘦容器更符合 K8S 和 Docker 的设计理念,也符合 Unix 的哲学:do one thing and do it well;其次,瘦容器的业务进程即容器内部的 pid 1 进程,容器的状态基本上反应了业务进程的真实状态,为 K8S 提供更为详尽的信息和故障决策依据;最后瘦容器节省存储空间。从实践角度出发,瘦容器给业务接入带来了很大的困难。首先是如何与公司现有的运维体系做好适配,如果容器没有注入运维相关的 agent,那么可能需要重新实现大量运维相关模块,开发和推广的工作量之大,可想而知;其次,如果没有 SSH 等功能,非常影响用户定位问题。所以,从落地的角度而言,采用富容器更利于业务方的接入,实时上,业内如阿里等,也采用了富容器的做法。

虽然 namespace, cgroup 等为容器奠定了隔离的基础,但是 /proc 下的某些文件,包括 sysconf 等系统调用,并没有隔离。用户使用一些如 free, df 等命令,看到的往往是宿主机的内容,非常容易造成误解。对于 java 9 以下应用,由于采用 sysconf 获取可用资源,非常容易造成 OOM。针对这些问题,要具体问题具体分析,比如改造 free, df 等命令,jvm 启动时设置 Xms, Xmx 等参数。

此外,业务方有时候在容器中存放一些配置文件,工具等等,当容器重启后,这些数据往往会丢失,容易给业务方造成困惑,关于这点,需要告知业务方数据需要存入持久化存储中,对于常用工具,可以写在镜像的 Dockerfile 或者业务初始化脚本中。

小结

总而言之,除了迁移和改造成本没有特别好的办法外,其它成本都可以通过技术或者流程使业务的成本降到最低。从另外一个角度来说,这些成本并不能给容器化带来质的阻碍。

此外,对于非标准化且占用资源少的业务,建议其先做标准化,再做容器化。