Quantcast
Channel: IT瘾博客推荐
Viewing all articles
Browse latest Browse all 532

容器平台选型的十大模式:Docker、DC/OS、K8S 谁与当先?(上)-社区博客-网易云

$
0
0

作者:刘超 网易云基础服务
无论是在社区,还是在同客户交流的过程中,总会被问到到底什么时候该用 Docker?什么时候用虚拟机?如果使用容器,应该使用哪个容器平台?
 
显而易见,我不会直接给大家一个答案,而是希望从技术角度进行分析具体的场景。例如客户是大公司还是小公司,将部署小集群还是大集群,倾向于私有云还是公有云,已经采购了 IaaS 还是没有 IaaS,IT 运维能力强还是弱,是否需要物理机、虚拟机、容器的混合部署,是一般的并发系统还是高并发,这里面所应该做的技术选型都不一样。举个例子,如果你是一个初创型的主营业务非 IT 的小公司,自然不应该花大力气在数据中心里面自己搭建一套大规模、高并发、高性能的容器平台。
 
接下来,首先,我们来谈下什么情况下应该使用 Docker 的问题。
 

 
如上图所示,左面是我们经常挂在嘴边的所谓容器的优势,但是虚拟机都能一一怼回去。
 
如果部署的是一个传统的应用,这个应用启动速度慢,进程数量少,基本不更新,那么虚拟机完全能够满足需求。
 
○ 应用启动慢:应用启动 15 分钟,容器本身秒级,虚拟机很多平台能优化到十几秒,两者几乎看不出差别;
○ 内存占用大:动不动 32G,64G 内存,一台机器跑不了几个;
○ 基本不更新:半年更新一次,虚拟机镜像照样能够升级和回滚;
○ 应用有状态:停机会丢数据,如果不知道丢了什么,就算秒级启动也没有用,照样恢复不了,而且还有可能因为丢数据,在没有修复的情况下,盲目重启带来数据混乱;
○ 进程数量少:两三个进程相互配置一下,不用服务发现,配置不麻烦
 
如果是一个传统应用,根本没有必要花费精力去容器化,因为白花了力气,享受不到好处。
 

 
那么什么情况下,才应该考虑做一些改变呢:
 
传统业务突然被互联网业务冲击了,应用老是变,三天两头要更新,而且流量增大了,原来支付系统是取钱刷卡的,现在要互联网支付了,流量扩大了 N 倍。
 
这种情况下就只能:拆。
 
拆开了,每个子模块独自变化,相互影响变少。
拆开了,原来一个进程扛流量,现在多个进程一起扛。
 
这被称为微服务。
 

 
微服务场景下,进程多,更新快,于是出现 100 个进程,每天一个镜像。
 
容器乐了,每个容器镜像小,没什么问题,虚拟机哭了,因为虚拟机每个镜像太大了。
 
所以微服务场景下,可以开始考虑用容器了。
 

 
这时虚拟机又怒了,我不用容器了,微服务拆分之后,用 Ansible 自动部署是一样的。
 
这从技术角度来讲没有任何问题,问题是从组织角度出现的。一般的公司,开发会比运维多得多,开发写完代码就不用管了,环境的部署完全是运维负责,运维为了自动化,写 Ansible 脚本来解决问题。
 
然而这么多进程,又拆又合并的,更新这么快,配置总是变,Ansible 脚本也要常改,每天都上线,不得累死运维。
 
所以在如此大的工作量情况下,运维很容易出错,哪怕通过自动化脚本。这时,容器就可以作为一个非常好的工具运用起来。
 
除了容器从技术角度,能够使得大部分的内部配置可以放在镜像里面之外,更重要的是从流程角度,将环境配置这件事情,往前推了,推到了开发这里,要求开发完毕之后,就需要考虑环境部署的问题,而不能当甩手掌柜。
 
这样做的好处就是,虽然进程多,配置变化多,更新频繁,但是对于某个模块的开发团队来讲,这个量是很小的,因为 5-10 个人专门维护这个模块的配置和更新,不容易出错。
 
如果这些工作量全交给少数的运维团队,不但信息传递会使得环境配置不一致,部署量也会大非常多。
 
容器是一个非常好的工具,就是让每个开发仅仅多做 5% 的工作,就能够节约运维 200% 的工作量,并且不容易出错。
 
然而原来运维该做的事情开发做了,开发的老大愿意么?开发的老大会投诉运维的老大么?
 
这就不是技术问题了,其实这就是 DevOps,DevOps 不是不区分开发和运维,而是公司从组织到流程能够打通,看如何合作,边界如何划分,对系统的稳定性更有好处。
 
所以微服务、DevOps、容器是相辅相成,不可分割的。不是微服务,根本不需要容器,虚拟机就能搞定,不需要 DevOps,一年部署一次,开发和运维沟通再慢都能搞定。
 
所以,容器的本质是基于镜像的跨环境迁移。
 
镜像是容器的根本性发明,是封装和运行的标准,其它什么 namespace,cgroup,早就有了,这是技术方面。
 
在流程方面,镜像是 DevOps 的良好工具。
 
容器是为了跨环境迁移的,第一种迁移的场景是开发、测试、生产环境之间的迁移。如果不需要迁移,或者迁移不频繁,虚拟机镜像也行,但总是要迁移,带着几百 G 的虚拟机镜像,太大了。
 
第二种迁移的场景是跨云迁移,跨公有云,跨 Region,跨两个 OpenStack 的虚拟机迁移都是非常麻烦,甚至不可能的,因为公有云不提供虚拟机镜像的下载和上传功能,而且虚拟机镜像太大了,一传传一天。
 
所以跨云场景下,混合云场景下,容器也是很好的使用场景。这也同时解决了仅仅私有云资源不足,扛不住流量的问题。
 
所以这是我认为的容器的本质,是最终应该使用容器的正确姿势,当然一开始你不一定完全按照这个来。
 

模式一:公有云虚拟机

 
适合场景:初创公司,无信息安全担忧
 
如果您是一家初创公司,人员少,IT 运维能力不足,要部署的系统很少,能够花在 IT 系统上的资金有限,当然应该选择公有云的虚拟机部署,它能够解决您的如下问题:
 
○ 基层 IT 资源的管理交给公有云平台,公司自身运维人员仅需要基本的 Linux 能力;
○ 少量的部署系统,例如 10 台以下的虚拟机,往往替换一个 war,重启 Tomcat 就能解决,如果稍微虚拟机多一点 10 到 20 台,Ansible 脚本可以很好地解决这个问题;
○ 公有云按量按时收费,可以在花费很少的情况下启动,并且在业务飞速扩展的时候,迅速申请大量虚拟机;
 
这里所说的信息安全担忧,真的仅仅是心理的担忧,公有云往往有大量的安全机制来保证每个租户的安全隔离,只要用好了这些机制,公有云的安全性绝对大于一般公司自己搭建的数据中心, 当客户在说要安全的时候,客户在想什么? 这篇文章讲到了绝对的端到端解决方案。
 
这里贴张图说明公有云的安全性:
 

 

公有云为支撑自身高并发业务积累了更强的安全防护能力和更多的安全防护经验:

 
○ 多线 BGP,外网线路冗余
○ 高吞吐量的 DDoS 外网防护
○ 更完善的防火墙,入侵检测,WAF
○ 更完善的流量清洗规则
 

公有云为支撑自身高并发业务推出了更安全、更高可靠、更高可用的 PaaS 服务:

 
数据库:
○ 高可用:主备切换数据零丢失
○ 高可靠:同城双活,异地备份
○ 安全性:访问控制,IP 白名单
 
对象存储:
○ 高可靠:超大容量,三份备份,异地同步
○ 安全性:访问控制,防盗链
 

公有云为支撑自身高并发业务推出更完善的监控运维的系统,流程,经验:

 
完善的监控系统,保障大促期间系统故障的快速定位和排障
保障大促能够极大的提升和训练一支有经验的运维团队
大促的业务层面的数据对运维也是机密的,需要流程保障

 

道高一尺魔高一丈,公有云为保证自身业务的安全性对云平台不断升级:

 
○ 越来越强的 DDoS 防护
○ 越来越完善的防火墙规则
○ 最新的云平台安全功能和机制
○ 不断更新的虚拟机和容器镜像建设漏洞
○ 不断更新的病毒库
 

模式二:无 IaaS,裸用容器

 
适用场景:初创公司无 IaaS,有信息安全担忧
 
但是即便如此,还是有初创公司或者初创项目,也许因为心理方面,也许因为合规方面,非常担心信息安全问题,还是希望采取部署在自己机房的方式。
 
但由于是初创公司,在机房里面一般是不能部署 IaaS,因为 IaaS 平台的运维难度,优化难度更大,没有一个 50 人的团队根本玩不起来,所以一般在使用容器之前,采用的是物理机部署的方式,当物理机数目非常小,比如部署 5 到 10 个应用的时候手动部署或者简单脚本部署就可以,但是一旦到了 20 个应用,手动部署和简单脚本就非常麻烦了:
 
○ 运维人员比例低,而应用相对较多
○ 部署在同一个物理机上的应用多,配置冲突,端口冲突,互相连接,运维需要一个 excel 去管理,还容易出错
○ 物理机容器被脚本和 Ansible 改的乱七八糟,难以保证环境一致性,重装物理机更加麻烦
○ 不同的应用依赖不同的操作系统和底层包,千差万别
 
这个时候,可以试一下裸用容器,即在原来的脚本,或者 Ansible 里面,将启动进程,改为使用 Docker run,可以有以下的作用:
 
○ 配置,端口隔离,冲突减少
○ 基于容器部署,使得环境一致性,安装和删除干干净净
○ 不同的操作系统和底层包,都可以用容器镜像搞定
 
在这个阶段,最简单的方式就是把容器当做虚拟机来使用,也即先启动容器,然后在里面下载 war 包等,当然也可以更进一步,将 war 包和配置直接打在容器镜像里面,这样需要一个持续集成的流程了,不仅仅是运维的事情,开发也要参与其中。
 
在这个阶段,网络的模式可以使用桥接打平的方式。
 

 
这种方式好处是访问 Docker 和访问物理机一样,可很方便地实现 Docker 里面和物理机里面的互通,兼容原来部署在物理机上的应用。
 
当然 Bridge 的性能一般,如果性能要求比较高,可使用 SR-IOV 网卡嵌入容器内。
 

 

模式三:有 IaaS,裸用容器

 
适用场景:创新项目,引入 DevOps 流程
 
有一些公司规模大一些,已经采购了 IaaS,只不过有一些创新的项目需要部署,这种状态下,基本虚拟机已经能够满足需求,而且由于能够运维 IaaS,IT 能力比较强,一般也采用了 Ansible 等部署工具。
 
这种情况下,使用容器的动力相对比较少,然而容器也是能够带来一定好处的,就是 DevOps。
 
创新项目迭代速度比较快,如果有比较多的创新项目,对运维的压力也是非常大的,这里的裸用容器和模式二的裸用容器不同的是,不是拿容器当做虚拟机来用,而是将容器当做交付物来用。
 
虽然容器化对于运维的整个过程来讲改进有限,但是关键就是要开发写一个 Dockerfile,这一点非常重要,意味着运行环境的配置提前到开发,而非直接交到运维,也即上面说的,开发 5% 的工作量增加减少大量运维工作,容器环境原子性升级回滚使得停服时间变短,可以保持开发、测试、运维环境的一致性。
 

 

模式四:使用 Docker Swarm Mode

 
适用场景:发展中公司,中等规模集群
 
当集群规模超过 50 台时,裸用容器已经非常难受了,因为网络、存储、编排、服务发现等全部要靠自己的脚本或 Ansible 来搞定,是时候引入容器平台了。
 
当容器平台规模不是很大时,Docker Swarm Mode 还是比较好用的:
 
○ 集群的维护不需要 Zookeeper,不需要 Etcd,自己内置
○ 命令行和 Docker 是一样的,用起来顺手
○ 服务发现和 DNS 是内置的
○ Docker Overlay 网络是内置的
 
总之 docker 帮你料理好了一切,你不用太关心细节,很容易就能够将集群运行起来。
 
而且可以通过 docker 命令,像在一台机器上使用容器一样使用集群上的容器,可以随时将容器当虚拟机来使用,这样对于中等规模集群,以及运维人员还是比较友好的。
 
当然内置的太多了也有缺点,就是不好定制化,不好 Debug,不好干预。当你发现有一部分性能不行时,你需要改整个代码,全部重新编译,当社区更新了,合并分支是很头疼的事情。当出现问题时,由于 Manager 大包大揽干了很多活,不知道哪一步出错了,反正就是没有返回,停在那里,如果重启整个 Manager,影响面又很大。
 

 

模式五:使用 Marathon 和 Mesos

 
使用场景:万节点集群,多定制
 
当集群规模大一些,几百个节点时,很多人就不愿意使用 Docker Swarm Mode 了,很多的选择是既没有用 DC/OS,也没有用 Kubernetes,而是仅仅用了 Marathon 和 Mesos。
 
因为 Mesos 是一个非常优秀的调度器,它的双层调度机制可以使得集群规模大很多。
 
Mesos 的调度过程如图所示:
 

 
Mesos 有 Framework、Master、Agent、Executor、Task 几部分组成。这里面有两层的 Scheduler,一层在 Master 里面,allocator 会将资源公平的分给每一个 Framework,二层在 Framework 里面,Framework 的 scheduler 将资源按规则分配给 Task。
 
其它框架的调度器是直接面对整个集群,Mesos 的优势在于,第一层调度先将整个 Node 分配给一个 Framework,然后 Framework 的调度器面对的集群规模小很多,然后在里面进行二次调度,而且如果有多个 Framework,例如有多个 Marathon,则可以并行调度不冲突。
 
详细的调度机制非常复杂,可以看 号称了解 mesos 双层调度的你,先来回答下面这五个问题!这篇文章。
 
而且 Mesos 的架构相对松耦合,有很多可以定制化的地方,从而运维人员可以根据自己的需要开发自己的模块。详细的定制方式看文章 定制化 Mesos 任务运行的几种方法。
 
这也是很多优秀的公司使用 Marathon 和 Mesos 的原因。
 
例如爱奇艺、去哪儿、携程、当当等都选择了使用 Mesos,需要提一下的是,大家如果参加社区,能发现裸用 Marathon 和 Mesos 的很多,但是整个 DC/OS 都用得比较少,而用 Marathon 和 Mesos 往往不能解决一些问题,因而这些 IT 能力非常强的互联网公司做了大量的自己的定制化,增加了 Marathon 和 Mesos 的外围模块。
 

模式六:使用开源 Kubernetes

 
使用场景:千节点集群,少定制
 
Kubernetes 模块划分得更细,模块比较多,比起裸 Marathon 和 Mesos 来讲功能丰富,而且模块之间完全的松耦合,可以非常方便地进行定制化。
 

 
而且 Kubernetes 的数据结构的设计层次比较细,非常符合微服务的设计思想。例如从容器->Pods->Deployment->Service,本来简单运行一个容器,被封装为这么多的层次,每个层次有自己的作用,每一层都可以拆分和组合,这样带来一个很大的缺点,就是学习门槛高,为了简单运行一个容器,需要先学习一大堆的概念和编排规则。
 
但是当需要部署的业务越来越复杂时,场景越来越多时,你会发现 Kubernetes 这种细粒度设计的优雅,使得你能够根据自己的需要灵活的组合,而不会因为某个组件被封装好了,从而导致很难定制。例如对于 Service 来讲,除了提供内部服务之间的发现和相互访问外,还灵活设计了 headless service,这使得很多游戏需要有状态的保持长连接有了很好的方式,另外访问外部服务时,例如数据库、缓存、headless service 相当于一个 DNS,使得配置外部服务简单很多。很多配置复杂的大型应用,更复杂的不在于服务之间的相互配置,可以有 Spring Cloud 或者 Dubbo 去解决,复杂的反而是外部服务的配置,不同的环境依赖不同的外部应用,External Name 这个提供了很好的机制。
 
包括统一的监控 cadvisor,统一的配置 confgMap,都是构建一个微服务所必须的。
 
然而 Kubernetes 当前也有一个瓶颈——集群规模还不是多么大,官方说法是几千个节点,所以超大规模的集群,还是需要有很强的 IT 能力进行定制化,这个在模式七中会说一下我们在网易云上做的事情。但是对于中等规模的集群也足够了。
 
而且 Kubernetes 社区的热度,可以使得使用开源 Kubernetes 的公司能够很快地找到帮助,等待到新功能的开发和 Bug 的解决。


 本文未结束,敬请期待下篇。


Viewing all articles
Browse latest Browse all 532

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>