|
|
|
|
移动端

WOT张阜兴:知乎容器平台演进及与大数据融合实践

在“开源与容器技术”分论坛上,来自知乎计算平台负责人张阜兴发表了题为“知乎容器平台演进及与大数据融合实践”的精彩演讲。

作者:刘妮娜来源:51CTO|2018-07-03 09:57

开发者盛宴来袭!7月28日51CTO首届开发者大赛决赛带来技术创新分享

【51CTO.com原创稿件】2018年5月18-19日,由51CTO主办的全球软件与运维技术峰会在北京召开。来自全球企业的技术精英汇聚北京,畅谈软件技术前沿,共同探索运维技术的新边界。而在本次大会上,除了众星云集的主论坛环节,12场分论坛更是各具特色,在19日下午的“开源与容器技术”分论坛上,来自知乎计算平台负责人张阜兴发表了题为“知乎容器平台演进及与大数据融合实践”的精彩演讲。


知乎计算平台负责人张阜兴演讲

知乎计算平台负责人张阜兴硕士毕业于中科院计算所,在加入知乎之前,先后在搜狐研究院和雅虎北京研发中心从事分布式存储以及云平台相关的开发工作,现在在知乎计算平台主要负责容器,流量负载均衡,以及大数据基础组件相关的工作。在此次的演讲中,张阜兴主要从三个方面进行讲解,包括知乎容器平台演进、实践过程中在生产环境里踩过的坑,以及在容器技术和大数据应用所做的一些融合实践。

知乎容器平台演进的历程

在演讲的开始,张阜兴为大家介绍了知乎容器平台演进的历程。知乎容器平台的演进历程大致可以分成三个阶段,2015年9月,知乎的容器平台正式在生产环境中上线应用;2016年5月,知乎90%的业务迁移到容器平台;目前,除了业务容器外,包括像HBase、Kafka多个基础组件也采用容器部署,总的物理节点数达到了两千多,容器数达到了三万多。

演进过程中,张阜兴总结了三个要点:

第一是从Mesos到Kubernetes,这样一个技术选型的变化;

第二是从单集群到多集群混合云的架构调整;

第三是从滚动部署到部署发布分离这样的一种使用上的优化。

张阜兴首先分享了从Mesos到Kubernetes技术选型的思考,知乎是在2015年开始在生产环境中使用容器平台,那时Kubernetes刚刚发布,还不成熟。所以知乎选用了Mesos技术方案,Mesos的优势是非常稳定,并且架构设计中,Master的负载比较轻,单集群可以容纳的容器规模比较大,据官方介绍可以单集群容纳五万个节点。劣势是需要单独开发一套Framework,会带来较高的使用成本。

Kubernetes的优势是社区强大,功能完善,使用成本较低。但是由于他把所有的状态都放在etcd中存取,所以单集群的所能容纳节点规模没有Mesos那么大。官方说法是现在etcd升级到V3版本之后,现在可以到五千个节点。

第二个架构上的变化是从单集群到混合云的架构,为什么要做这个呢,在生产环境中也是实际所需。第一我们需要做灰度集群,也就是对于Mesos或者是对于Kubernetes做任何参数的变更,一定需要在灰度集群上去先做验证,然后才能在生产环境中大规模的实践。第二点是对单机群容量进行扩容,第三点是容忍单集群故障,采用混合云的架构因为公有云的集群池比较大,这样可以大大提升弹性资源池的大小,抵抗突发扩容情况。

在混合云架构的实现过程中,知乎也调研了像Kubernetes的Federation这些方案,首先是Kubernetes的Federation方案现在官方还不推荐在生产环境中运行。第二,由于在部署和管理上有很多的问题,所以我们采用的是自研的管理方案,大致的原理就是我们的每一组业务容器会同时在多个集群上去创建Deployment,这些Deployment的配置,比如说像容器版本,或者CPU内存资源的配置都是完全相同的,唯一的不同只不过是容器数量会根据不同集群的大小做出调整。

另一个变化是从滚动部署的模式切换成了部署和发布分离的模式。这里先给出我们对部署和发布的定义,我们可以看一个典型的服务上线流程,包括了内网,金丝雀,生产环境三个发布阶段,在每个阶段都需要观察验证指标是否正常以便决定是继续上线还是回滚,如果采用Deployment的滚动部署,可以实现每次升级部分容器,升级过程中服务不中断,消耗的瞬时最大资源较小,但是滚动部署不能控制进度暂停,导致不能和多个发布阶段对应。如果每个阶段采用独立的 k8s Deployment,会导致部署速度慢,而且由于滚动过程中旧容器即销毁了,如果要回滚,需要重新部署,回滚速度慢。为此,我们将部署和发布阶段进行了分离,服务上线时,就后台启动一组新版本容器实例,当实例数满足发布的条件时,就发布部分实例接收外部流量,在外部流量验证过程中,后台还可以并行的继续部署新容器实例,从而使得用户感知不到容器实例部署的时间,实现秒级部署。同时在发布过程中,旧容器实例只是不再对外可见,但实例依然保留一段时间,这样如果发布过程有问题,可以立即切换,秒级回滚。

在容器的使用模式上,知乎引入了持久化存储去对应着做一些支持。在容器是使用模式上我们从最初的无状态web应用,到在容器中使用持久化存储,来实现一些有状态服务的容器化部署,如可以基于Hostpath,用Daemonset方式在每个节点上启动consul agent,因为Deamon Set保证每个节点上只启动一个pod,不会存在 hostpath 冲突的情况。基于 local volume 可以进行本地磁盘调度管理,实现 kafka broker 的部署,这个在后面介绍 kafka 方案时再想细介绍。另外有基于 Fuse 将 分布式文件系统映射到容器中,目前主要应用于业务数据读取的场景。

另外一个使用模式是容器网络,我们在Kubernetes的方案上,选用的是Underlay IP网络,我们所采用的模式是容器的IP和物理机的IP是完全对等的。这样互联简单,由于不存在overlay的封包解包处理,性能几乎无损耗,另外 IP 模式下,可以方便的定位网络连接的来源,故障定位更容易。在具体的实践过程中,我们给每一台机器一个固定网络IP段,然后通过CNI插件IPAM去负责容器IP的分配和释放。

维护容器平台过程中所采过的那些坑

张阜兴在容器平台的生产环境和建立中有着丰富的经验,也踩过不少技术的“坑”。在此次的WOT峰会上,他把过去经历过的比较典型的技术故障、技术陷阱与大家分享,宝贵的“踩坑经”让来宾受益匪浅。

陷阱之一:K8S events

在一个月黑风高的夜半,我们的K8S etcd 突然间全部不能访问了,通过调查,原因就是K8S events 默认存储方式带来的性能问题。K8S默认会把集群发生的任何事件变化全部记录到etcd里。K8S events默认配置了一个过期策略,每过一段时间,这个events就会回收,释放etcd的存储空间,这样听起来是很合理,但是在etcd对TTL的实现里面,每次去遍历查找非常低效,随着集群规模变大,集群上面频繁的去发布部署变更,导致了events 越来越多,etcd负载越来越大,直至etcd崩掉,整个K8S集群就崩掉了。

K8S其实也意识到这个问题,所以为用户提供了一个配置,可以把events记录到一个单独的etcd集群里。此外,我们可以在晚低峰的时候,把整个event的etcd清空,相当于我们自己去实现过期清理的策略。

陷阱之二:K8S Eviction

第二个坑是K8S Eviction,这个坑是直接把所有生产环境中的Pods全部给删掉了。它的产生首先是API server要去配置高可用,但是即使配置了高可用,也会有很小的概率会挂掉。如果没有及时去处理,例如API server宕机超过五分钟,这些集群的Node都和它失联了,会触发控制节点将所有 pod 杀掉驱逐出集群。在1.5版本之后,官方已经增加了一个配置,就是-unhealthy-zone-threshold,例如当超过30%的Node处于一个失联状态的时候,这时候集群会禁止Controller Manager的驱逐策略,当遇到大规模异常时,防止对集群容器进行误驱逐。

另一个是容器端口泄露问题,在使用端口映射的模式时,经常在发现有容器启动时报port is already allocated,说这个端口已经被使用了。我们通过分析 Docker Daemon代码,在 Docker Daemon 分配端口到记录这个端口到内部的持久化存储这个过程不是原子的,在这个中间如果Docker Daemon重启了,只会根据存储的端口记录去恢复,所以它就遗忘掉了之前分配的端口。找到这个原因之后,我们向官方提出了对应的解决方案。

陷阱之三 :Docker NAT

还有一个坑是Docker NAT网络遇到的。大家如果看了我贴的系统配置,对于网络数据包的乱序的处理太过严格。如果容器中进程访问阿里云等公网的一些图片服务,在公网这种网络比较差的时候,如果乱序包超过了TCP的滑动窗口,这时候系统的这个配置会把这个网络连接给reset掉。把这个配置关掉之后就可以解决这个问题了。

在容器平台和大数据组建融合上的尝试

在大数据场景下其实主要有两条处理路径,如图,左边这一条是实时处理的,右边的是批处理的。因为出发点不一样,所以导致这些组件的设计思想有很大的不同,批处理因为主要是做这种ETL任务,所以说他主要是做那种数据仓库的构建,追求的是吞吐率,对于时延是不敏感的。

但是实时处理是对时延是比较敏感的,里面的任何节点的挂掉,都会导致数据落地的延迟,以及数据展示不可用。所以说,像实时处理,他的组件所运行的这些机器的负载就不能特别高。

我们在大数据生产环境维护过程中,经常遇到的一些问题,比如说某一个业务做了一些变更,他写入Kafka的流量突然大了很多,这时候把Kafka集训整个的负载都给打高了,如果打的太高,可能整个集群就崩掉了,会使生产环境受到影响。

怎么去做对应的治理呢?基本的思路时去按业务方给他们做集群的划分,集群的隔离。我们把集群划分开了,带来了另外一个问题,我们由原来的一套集群变成了几十套集群,这么多集群我们怎么去统一的配置管理和部署。这个成本是很高的,我们用了K8s的模板,因为他可以很方便的一键搭建出多种相同的运行环境。

另外一个引发的问题是每一个业务方使用的量是不一样的,有的业务方使用量比较大,有的业务方使用量比较小,如果使用量比较小的,比如说只有几十个kbs,也需要维护一个高可用的集群,如果配备三台机器,这样就带来了大量的资源浪费,我们的解决方案就是用容器来实现更细粒度的资源分配和配置。

大数据平台的管理方面,我们践行了Devops的思想,这意味着我们是平台方而非运维方,我们定位自己为工具的开发者,日常运维操作,包括创建集群、重启、扩容,都通过PaaS平台交由业务方自主式的去完成。这样的好处,首先是减少了沟通的成本,公司越来越大之后,这种业务方之间的沟通特别复杂。第二方便了业务方,比如说发现他需要扩容,可以直接在这个平台上自己独立的操作完成,减轻了日常工作负担,也让我们能够更加专注于技术本身,专注于更好的如何把这个平台和把底层的技术做的更好。

在大数据平台上,我们还提供了丰富的监控指标,这个也是Devops实践中我们必须理解的一环。因为业务本身对于像Kafka或者是对于HBase这种系统的理解是比较浅的,我们如何把我们积累的这些集群的理解和经验,传达给业务方,我们通过监控指标把这些指标完全暴露给业务方,希望把Kafka集群变成一个白盒,而不是一个黑盒,这样业务方在发生故障的时候,直接在指标系统上就能看到各种各样的异常,然后配合,比如说我们给他定制的一些报警阈值,他就能及时的自己去做一些处理。

总结而言,我们在容器和大数据融合上面的思路,首先我们要按业务方去做集群的隔离,第二是我们用K8S去做多集群的管理部署,然后用Docker去做资源的隔离和细粒度的分配和监控,以及在管理运维上我们践行Devops这种理念,然后让平台方更加专注于工具开发本身,而不是限于琐碎的运维操作不能自拔。

对于后续的展望,一方面是希望将更多的基础设计组件,全部挪到K8S上,另外在这些组件之上,提供PaaS平台,为业务方提供更好更方便更稳定的服务,最终的一个理想是将我们数据中心的资源统一的交给K8S去做调度管理,实现DCOS。

本次WOT峰会讲师演讲稿件由51CTO采编整理,如欲了解更多,敬请登录WWW.51CTO.COM进行查看。

【51CTO原创稿件,合作站点转载请注明原文作者和出处为51CTO.com】

【责任编辑:刘妮娜 TEL:(010)68476606】


点赞 0
分享:
大家都在看
猜你喜欢

热门职位+更多

读 书 +更多

网络管理员考试全真模拟试题与解析

本书是按照全国计算机技术与软件专业技术资格(水平)考试《网络管理员考试大纲》的要求,参照《网络管理员教程》及近年来考试试题编写的。...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊