传统虚拟机 和 容器云的 真实优缺点对比:
本文基于的前提:同样是在 DevOps 自动化程度很高的情况下。很多时候有人说 容器云平台更先进,那是因为他们传统的模式做得不好,如果把传统的模式做好,不见得比容器化平台的自动化程度低。

构建和部署方面

传统的方案是

  • 使用支持虚机部署的 DevOps 平台,每个节点安装有 agent,可以执行命令、上传文件等做很多事(参见阿里的 云效、StarAgent);
  • 使用 jenkins,功能很成熟、强大,可以自定义脚本,有很多现成的插件;
  • 使用批量自动化工具,ansible,saltstack 等。

容器云方案

  • 使用容器云平台,但大多数都是商业版的,开源的选择不多,一般都用 Rancher;
  • 类似于 DevOps 平台的用法,编写 pipline 一键打包(实际上也是基于构建脚本和 Dockerfile),上传到镜像仓库,然后基于 kubernetes yaml 定制化部署。

总结

从构建和部署来说,容器云方案相比 Jenkins 等方案,优势并不明显,而且 jenkins+脚本+插件,可以全方位操控打包过程和服务器,定制化程度比容器平台还高(因为它直接深入到 OS 内部执行命令,且整个过程集中自动化管理,而容器要在 OS 内部做操作,一般是在构建镜像时写在 Dockerfile 中、每个镜像单独管理,有过大规模实施的人都知道,Dockfile 功能还是很鸡肋,而且不方便统一管理,很多构建编译过程,大家都倾向于在流水线上去实现,然而新兴容器平台的流水线,通常没有老牌的Jenkins 那么成熟,特别是使用开源容器云平台,比如 Rancher,很多时候不能满足需求,需要二次开发,相对而言,商业的容器云平台要好一点)。

自动扩容和缩容

自动扩容和缩容,通常的前提是无状态服务,且不要求固定 IP。拿一个后管项目来说,它只部署一个节点,无扩容、缩容需求。 再拿一个用户基础服务项目,当调用量大时,倒是可以扩容,传统方案是,前端挂载了负载均衡设备 Nginx,做4层或7层转发,添加节点时要修改 Nginx 配置。有这种需求时,执行一下手动扩缩容,好像也不难。但是说实话,对于一般中小公司,自动“扩缩容”的需求还是很少,最多只是少数入口流量会爆发的地方才用得着。而使用运维自动工具和平台,手动扩容也很简单。

只有一个问题,就是面对超大规模的系统,手工操作确实不合适。我认为,总体规模5000个节点以下,传统的运维自动化工具+虚拟机都很好做。真正的超大规模,可能是上万个节点,机房都有好几个那种。

支持多种发布策略

蓝绿发布、金丝雀(灰度)发布,蓝绿的话,重新部署一套,然后一键切换流量,使用传统方式也不难。金丝雀的话,先发布一小部分,关键是网络配置,重启 nginx,也不难。分析同上,关键是服务器规模有多大。

再来看看,有人总结的容器几大优点:

更小的计算开销意味着更低的总体成本

的确,比起虚机独立操作系统而言,Docker 更节省资源。但是 Docker 的资源隔离和控制,比起虚机有更高的学习成本。不可否则,虚拟机的隔离方法更成熟,更有效,就拿 VMware 厂商来说,它有很多很多的黑科技去优化资源使用,比如超额分配(后面会讲)。

低风险的快速部署、移植

没错,应用自带操作系统,在哪里都能运行。由于其高一致性,测试完了,直接推生产,不用考虑服务器环境问题,导致的和测试环境不一样。 但是,有数据持久化需求怎么办,日志怎么处理,网络问题怎么解决,还有不少问题要解决,OS 不能完全代表“可快速部署和移植”。

运行环境更容易管理

有利有弊。以前要修改服务器的东西,打补丁等,需要一个个虚拟机去操作,好处是,处理一个立即生效,应用不需要动。使用 Docker,好处是只需要更新基础镜像,缺点是要生效,必须更新应用,更新应用意味着要停机重启。

有人总结了4、5个优点,其实容器技术显著的优点只有两个:

  • 高资源利用率;
  • 标准化、可移植

侧面印证:我们公司之前做了一个很正式的容器技术评估报告,列了一堆容器的优点、很全面,但实际上,很多都是自动化相关的,那是因为我们本身的自动化程度太低,而不能说是容器技术的优点;然后容器技术剩下的优点实际上就是我上面列的那两条。当时根据现有资源估算的结果是,使用容器只需要现有资源的1/4,可以节约75%的服务器成本(那也是因为,传统的虚机 CPU 和内存的利用率实在是太低!如果能好好管理和利用,实际上节约不到这么多,下面详细说明)。

注意,资源利用率细节,相对于虚拟机,虚拟化 Hypervisor 层的开销是减少了,但整体并没有一些人说的那么夸张,比如节省75%,这要看具体情况。首先,容器通常是用的最小化操作系统,而虚拟机用的完整版系统,这样对比是不公平的,如果虚拟机也用最小化操作系统,其实也可以将系统内存控制在50MB以下,而容器如果使用完整版的系统,内存也能达到300MB以上。实际上,我们正式运行的容器,我看了一下,简单Java应用,也使用了2.2G内存,不见得比虚拟机要节省多少(虚拟机,你分配4G内存给它,实际上也不代表它一定独占4G物理内存)。

值得一提,商业化的虚拟化平台,都支持超额分配,比如vSphere5.0+,每个物理内核(cores)最多支持25个vCPU,一个普通服务器有2颗 CPU、总物理核数为2*12=24,按常规建议是1:1~1:3之间分配vCPU,可以分出 48~144个vCPU,最高可以按1:25比例超额分配,但是在此 Dell 白皮书中,vCPU:pCPU 指导原则如下:

  • 1:1至3:1没有任何问题
  • 3:1至5:1可能会引发性能下降
  • 6:1或更高通常会引发问题

无所谓,其实 CPU 通常是足够的,按照1:3分配就够了。内存才是瓶颈,内存分配有3种模式:Limit(上限),Reservation(保留,即私有)和 Shares(共享,即内存不够时,按设置的权重争抢)。很显然,内存是天然支持超额分配的,而且虚拟化平台的内存管理,有许多的优化技术(可参见 VMware 官方技术文档),应该是很成熟了。

所以,我个人觉得,在相当一个大的物理服务器下,比如256G内存来说,从 极限 资源利用率 来看,Docker占不了多少便宜:假设我部署 48个应用,每个应用真实占用 4G内存,用Docker部署,操作系统占用50MB,Docker引擎占用100M,实际占用内存约为:48*(4G+50MB)+100MB,而换成虚拟机部署,假设 Hypervisor 引擎占用500MB,则实际占用内存约为:48*(4G+50MB)+500MB。虚拟机也就多占用了400MB内存而已。有些人可能会喷,用 Docker 就是要多分配一些应用啊,一个256G的物理服务器,怎么才止48个容器,Docker 的场景是那种很微小的应用,一个占用0.5G的,可以分配512个容器!。好吧,就算这样,虚拟化平台难道不可以分配512个虚拟机?据我所知,是可以的(vCPU也就1:10),我阿里云的虚拟机就是1vCPU+1GB 内存的,最小的好像是256MB内存,256MB内存的系统,你登录进去看,也还有200多MB的剩余,说明系统本身占用内存才几十MB。这里有篇文章,计算了各种配置的物理机,能够做的最大虚拟机数量:虚拟机服务器经典应用配置方案,可以看到,48核+256G内存的服务器,就可以分配400个左右的“微型”虚拟机。所以,我觉得,从资源利用率角度来讲,Docker和虚拟机差别不大,Docker并不是传说中的那样,一个物理机可以运行1000个容器,我们生产也不会这样做,我亲身实践过,我们也会控制一个物理节点分配容器的数量。但容器有一个潜在的优势,那就是它的管理太方便了,随时启停、随时创建和销毁,所以容器的资源利用更灵活,在频繁启停、创建和销毁服务器的场景中,其资源利用率确实大大高于虚拟机(举个很生动的例子:我们有一个 Jenkins 自动打包的服务器,如果同时有20个打包任务执行,服务器只有4C+8G配置,性能不够,需要加资源,方案1:创建20个2C+4G的虚拟机来分摊执行任务,方案2:创建20个2C+4G的容器来分摊执行任务,表面上看,两个方案最大的差别不在资源利用率,但是方案2,任务执行完,20个容器的资源就自动释放了,而方案1的虚拟机还占用着资源,这个时候的资源利用率,容器完胜,所以我说容器适合那种 频繁启停、创建和销毁服务器的场景)。

容器技术的缺点:

  • 有较高的学习成本(不是针对个人,而是针对整个研发及运维团队)
  • 复杂度增加,引入了不少新东西,比如网络层面,引入 Calico、Traefik 等
  • 某些应用有一定的改造成本,且不是所有应用都适合
  • 增加基础环境的搭建和维护难度(自己维护 Kubernetes 等一系列环境组件)
  • 抛弃传统成熟稳定的东西,用一堆新的东西,有一定技术风险(有较多 bug,我遇到过最严重的一次是,K8s 引起一个 Linux 内核错误,导致物理机直接死机)

我再来总结一下,容器几大优点:
1)高资源利用率;更小的计算开销意味着更低的总体成本。
的确,比起虚机独立操作系统而言,Docker能节省一点点资源(5%~?,具体看情况)。更多的场景是,容器的灵活启停、创建和销毁,对资源的动态利用率,完胜虚拟机那种静态的方式。

2)标准化、可移植;低风险的快速部署、移植
没错,应用自带操作系统,在哪里都能运行。由于其高一致性,测试完了,直接推生产,不用考虑服务器环境问题,导致的和测试环境不一样。

3)运行环境更容易管理
自动调度,自动扩容和缩容,故障自愈,全方位监控。

4)支持多种发布策略
蓝绿发布、金丝雀(灰度)发布等非常容易。

个人建议

容器技术的高资源利用率,标准化和可移植性,是难以抗拒的优点!!以至于为了具备这种优点,而不惜增加人力物力对容器技术的投入。如果公司本身的自动化程度很完善,短期内,就按传统的来,不急着应用容器。但是从长远来看,还是得想办法将容器技术运用起来。最初的应用,可以是和传统的技术进行融合,取长补短。等到对容器技术驾轻就熟之后,且全面胜过传统技术之后,方可深入全面应用。