七牛云架构师实践日第 32 期于 11 月 23 日在成都成功举办,以「容器技术的实践与分享」为主题 ,邀请了多名业内大咖,为大家带来了精彩演讲。中移动物联网有限公司基础设施研发团队负责人姜仁杰,在会上作了题为「物联网业务的 cloud native 实践与探索」的分享。
很感谢七牛云的邀请,能够在架构师实践容器技术专场上做一些自己关于容器实践相关的分享,今天我分享的主题是关于物联网行业云平台的云原生开发实践和探索。
首先我要改变一下大家的对中国移动的固有认识,很多朋友觉得中国移动作为一家传统运营商,应该不太会有技术研发团队,至少不太会往技术研发上过多入成本。但我们公司作为中国移动的全资子公司,也算是中国移动在自主研发上的探索与尝试吧。目前我们物联网云平台这块就已经有 300 多人的团队,其中研发人员占 80% 以上,可以说我们的自主研发实力至少在运营商里还是比较强的。我们的平台 100% 自主研发,没有依靠厂商。
接下来介绍一下我们的业务。我们的物联网云平台名字叫做 OneNET,可以为行业客户提供物联网 IaaS/PaaS/SaaS 行业云服务。当前我们 PaaS 平台的这块的设备连接数已经超过 7000 万了,北向 API 每天调用量差不多 1.3 亿左右,整个平台生态上差不多有 9000 企业用户,可以说平台正处于一个快速发展的阶段。
上图是 OneNET 平台的业务场景介绍。现在所有的厂家包括阿里云、华为这些公有云的厂商在物联网战略方面都在提「云、管、边、端」布局,管是什么意思呢?管就是通信管道,管道是运营商擅长做的事,我们公司就有自己的管道业务平台。管道可以理解为怎么样去管卡,资费、流量,「云」这一端就是我们通常认为的云服务,端就是指设备端,一般是芯片模组或者物联网操作系统。「边」就是我后面会讲到的边缘计算。
一个典型的云管边端协同的物联网业务场景就是:设备与边缘端建立连接,并且在边缘端做大量的数据的处理和存储,将少量的处理好的数据再和云端通过通用物联网协议来实现交互。同时客户的 SaaS 应用可以托管在我们云端的行业云上。行业云就是面向物联网行业的公有云,我们的行业云预计明年 3 月份就可以推出。
除了直接托管用户的应用,ISV 还可以把软件托管到我们的应用市场,卖给不具备研发实力的厂家或客户,为这种客户提供端到端的 Iaas/PaaS/Sass 解决方案。如果客户要求很高,我们可以提供私有化一体机的产品,可以在你自己私有云里完整部署一套物联网行业的端到端的 Iaas/PaaS/Sass 的解决方案,另外我们的一体机里面提供的私有云还可以和公有云组成缓和云,用户可以随时扩展云服务资源。以上就是我们相对比较完整的应用场景。
首先我来介绍下 OneNET 平台的应用架构发展历程吧,有了发展历程,才能讲为什么后面我们要做对云原生的一些探索。从开始到现在, OneNET 经历了差不多 4 年的时间,整个平台也不是一帆风顺发展过来的。我觉得每个企业针对自己的业务都会有一个完整的发展阶段,OneNET 也是这样,从刚开始三四个人的团队,到现在 300 多人的团队。业务架构和技术架构的决策原则都会随着关注点的不同不断调整。
在 OneNET 初期,最重要的生存,所以初期的架构决策原则就是识别出潜在客户,找到最核心的需求,要快速上线。另外物联网 PaaS 是一个很不错的切入点,所以初期我们主要做 PaaS 这一块, OneNET 初期就是一个很简单的单体架构,不过对于初期的需求,我觉得已经足够了。好了,初期阶段过了以后,业务逐渐发展,特别是在 2016 年开始,我们的设备连接数处于爆增的阶段,单体机构已经不能再满足你的的业务发展需求,这里面的需求来自于几个方面,第一个是团队大了之后,大家都在这个单体架构上进行开发,肯定是不太可能了,另外平台已经要需要保证高可用了,不能说三天两头就宕机。因为已经开始有生产业务依靠 OneNET 了。另外,产品功能还得不断地迭代,来满足市场以及未来新的需求,还有就是所有研发团队都要在统一的研发基础设施上玩,不然就会彻底乱套。初期由于研发缺乏规则和标准,没有统一的基础设施,我们在这方面吃了很多亏,走了很多弯路。需求越来越多,研发速度跟不上,运维变更越频繁,可用性越低,平台已经危机重重,上线已经变成拆弹,谁都不知道会不会爆炸(全场笑)。
所以,是时候现在我们的单体业务架构进行改造了,但是改造不是请客吃饭,要说服业务团队去配合你改造是非常难的,因为业务团队比较有话语权比较强势,同时他们从心理上还是有抵触情绪的。但是我觉得业务有抵触情绪也可以理解,首先你作为一个对他业务的稳定性有威胁的事情,肯定会有所顾虑,同时还会在初期给他们带来额外的学习成本。好在老板在这块还是比较有眼光,知道长痛不如短痛。所以自上而下,我们的压力小了很多。当然我们自身也下了很多的力气来说服这个团队,比如想办法减少各个业务研发团队学习成本,又比如用数据来说明我们的优势和稳定,所以我们目前业务改造还算顺利,大家已经开始接受这种服务化的思维。但是初期由于业务改造难度实在太大,只能化繁为简,先提供一个相对比较简单的架构,至少让大家有这个服务化的意识。
虽然做了服务化,实际上还是有很多存在的问题。比如说前端 API 网关与负载均衡框架耦合的问题,对 RPC 框架例如 gRPC 的支持不好。由于网关是用的 Nginx,服务治理需要写 LUA 进行控制,另外从 DevOps 角度来说,服务的交付到下线的全生命周期管理还有多个阶段没有进行覆盖,服务化了,但是构建和发布的频率也同样成几何倍增长。另外,代码质量这些老问题也越发突出,越来越难以管控。服务化组网趋于复杂,稳定性也无法得到保证。最后一个也是我觉得最重要的,就是老板和各个团队对你做的工作的价值没有一个很直观的感受,到底好了,好在哪里?也就是无法衡量服务化后的价值。
云原生的概念我先给大家解释一下。云原生是 2015 年由 pivotal 公司提出来的一个概念, CNCF 也就是云原生计算基金会,对云原生给出了一个相对详细的定义,中文版本是这么说的:云原生技术帮助各公司或组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和生命式 API。这些技术能够构建容错性好、易于管理、便于观察和松耦合系统。结合可靠的自动化手段,云原生技术可以使开发者轻松地对系统进行频繁并可预测的重大变更。CNCF 基金会为了达到这个目标,在旗下也在孵化很多相关的开源的软件。大家可以去看 CNCF 那张经典的 landscape 图里面包含 CNCF 正式旗下的软件。
OneNET 现在最新迭代的版本是 4.0,那么首先我们的痛点和问题上面已经说到了,云原生刚好也可以帮助我们去解决这些问题,所以我们在应用架构设计和基础设施方面参照了云原生的思路:利用微服务+容器+不可变基础设施+自动化手段去解决上面我提到的关于交付过程中自动化水平较低的问题。其实也就是 DevOps 的方法论里面所倡导的东西。当然我们的最终的目标也是和上述目标一致的:希望建容错性好、易于管理、便于观察和松耦合系统。
首先从应用架构来讲,业务架构方面我们会遵照所谓的 12 要素,12 要素是关于微服务和云原生应用架构的基本原则。是 heroku 这个商业 PaaS 服务提供商提出来的一个关于应用架构指导原则,比如基准代码,关于配置和依赖的一些建议。大家可自行 google 下细节,由于时间关系,这个我这里不做重点介绍,另外是服务通信这块主要就是结合统一 API 和 Service Mesh 实践,基础设施这一块我们主要是基于 K8S 打造自己的 PaaS 平台,这一块也是进行中,还有完善的空间。最后指导我们改造的方法论,主要就是 DevOps 了。说到 Devops 感觉现在大家都听过,但是具体什么意思比较模糊了,这里说下我对 DevOps 的理解吧,其实我觉得就是尽量缩短把一个需求变成可用的产品的时间的最佳实践,在缩短周期的同时要提升交付软件的质量。当然 Devops 是一套完整的方法论和实践的集合,我的理解可能只是一方面。
我们基于 Kubernetes 构建了内部的研发基础设施 PaaS 平台,devops 这块就不多说,都是常规技术,服务目录我们是基于 helm+operator 来做的。监控用的自己的 +prometheus,网络用的 calico。服务代理那一块实际是在混合云方面的探索, kubernetes 有项目叫做 service broker,主要就是混合云管理的,这个在边缘计算和公有云协同的场景,非常有用。另外我们在 AI 和大数据在 k8s 上也做了一些探索的实现,到目前没有批量上。整个 OneNET 的能力们以统一应用市场包括 API 市场的形式,把我们的能力对外输出,产生一些商业模式。
这是完整的 DevOps 的流水线,也是自源+开源的模式。监控方面我们投入了很多精力去做,因为我们发现可能开源的监控能满足日常关于监控场景的 95% 的覆盖,但是另外那 5% 的监控场景,可能会和 20% 以上的引起故障的场景相关,所以我们觉得这种投入是值得的。另外在研发管理这块,我们自己研发了一个项目管理工具,来进行项目管理,CI/CD 流水线是基于 jenkins 来做的上层封装,这块没什么可多说的。
在测试这一块,我们做了一些物联网场景的全链路压力测试的实践。全链路压测其实在互联网公司用的比较多,我们也是借鉴了很多互联网公司的经验。我们的痛点和互联网公司也略微不同,物联网的场景相对简单,只有南向和北向的对外提供服务,这不是我们主要的测试点,但是物联网这个行业有很大的特点就是物联网行业协议特别多,随便说出十几个协议都可以。所以在做压测的时候按照一个什么样的比例的流量来对压测环境的应用进行整体压测呢,这个不好预估,所以压力测试的时候,流量模型这块不是很好造数据。
于是我们的全链路压测的流程就是:我们将线上流量的 TCP 报文拷贝下来作为一个个文件保存到对象存储里面,然后对 TCP 报文进行脱敏,把涉及安全敏感的一些内容抹掉,同时把目的 IP 和端口这些信息修改为压测环境的,另外还可以利用程序对流量进行放大。然后再把数据通过我们的一个 worker 线程池解析出来推到压测集群去,最后利用分布式的压测集群将力量打到压测环境,这样就形成一个和真实环境一模一样的流量模型,这样就可以避免自己去造压力测试模型不准的问题。另外可以结合监控自动生产性能非常丰富的测试报告。在变更方面也可以利用线上流量进行线下的灰度发布,这样可以在上线之前,尽量在预发布环节看到风险和隐患。当然这块也是在持续优化的阶段,还有很多工作需要做。
刚才提到关于监控方面我们也投入了很多人力。监控这块我们也是站在巨人的肩膀上,我们基于小米开源的 Open-faclon 做了定制化开发,改了他很多东西。比如在 agent 增加对 gRPC 的支持,对 agent 上报数据性能提升优化、增加对自研的链路监控 SDK 的数据上报的支持,重写了整个 portal,重构了数据存储模块等等。这样我们从基础资源监控到中间件监控到业务层面监控到外围的服务质量监控我们都可以统一用一套基础设施来实现。
这是我们链路监控的截图,主要就是做一些链路性能的分析。链路监控这个互联网公司也讲得比较多,开源的也不少。只是我们支持更多的语言,因为我们内部语言确实很多,所以开源没办法做到开箱即用。
另外一个就是我们的服务质量监控,我们对目前云平台对外提供的所有服务 API 都有实时监控,我们有一些在各地机房的探针在实时探测我们服务的质量。
另外基于我们的统一监控基础设施,如果说作为一个应用,有定制化的监控需求,可以通过统一的基础设施来实现数据的上报。然后再监控 portal 上可以通过图表组件,可以把自己上传的数据,通过图标来实现对监控数据的图形化的展示,非常灵活。
上面这是我们内部的告警平台,我们把内部所有的告警做了汇聚。关于告警风暴的过滤我觉得还可以,结合逐步优化的告警策略专家系统,基本上能过滤到只剩 5%,1000 条告警里只有 50 条会真正发出去,这块由于业内没有太多数据,所以没法横向对比,但是我们内部还是比较满意。
另外我刚才提到,老板或者研发 leader 这个层面,其实他们觉得用这个东西好用与否,或者对他们而言在成本和效益上有没有真正的提升是需要一个具体可量化的感受的。所以,我觉得研发质量以及交付效率和交付产品性能和质量的可度量的原则是非常重要的。所以说我们的研发质量,像覆盖率这样的数据可以通过扫描工具,实时以看板的形式呈现给老板。像代码的安全风险、变更的故障比例,老板一看就知道哪些业务做得好哪些做得不好。自然就可以驱动大家代码质量的提升。另外,我们可以把性能量化,你的平台和上周的同比,和本周的环比,这些相关数据可以实时呈现出来,这样老板就可以给团队下一个 KPI,你的性能必须要提升 20% 或 30%。现在就可以有一个比较量化的手段去做这件事。
DevOps 有持续反馈的实践,我们按照事前、事中、事后这一套端到端可用性方案提升闭环。事前通过我们的压力测试,通过我们的预发布环境,在用户发现问题之前提前发现问题,事中我们可以通过检查监控是不是足够灵敏。当然事中发现问题,我们还检测我们的干预手段是否达到我的目标,我能不能在发生问题之后,第一时间将问题的影响降到最小。在做完这一套完整的动作之后,再去做总结,刚才的手段里哪个环节是做得不好的,哪个是需要在事前场景里增加检测的,做完总结之后再反馈给事前验证。这是一个完整的端到端闭环,这样就可以持续去提升我们平台的可用性。
Service Mesh 在去年下半年开始云计算领域比较热门的技术,中文翻译成服务网格,他是为了解决为服务化后服务实例间通信和服务治理异常复杂的问题。也就是实现服务和服务通信基础设施的解耦。我们怎样能实现业务开发人员不用关注调用的服务在哪里,不用关注怎么样去做限流、怎样保证服务的重试?业务人员只需要开发代码就好?service mesh 就是将服务治理的这些工具完全和服务本身的业务逻辑解耦。
service Mesh 当前比较主流的实现就是谷歌为主导的 Istio+envoy,我们的方案也是基于这一套。但是我们做了一些改造,因为我们的业务里面有一部分业务是非 k8s 的,所以我们必须提供一套同时兼容 k8s 和非 k8s 的微服务基础设施。这里,我们也参考了 Ucloud 提出一套方案。Istio 作为控制平面,主要有三大模块,一个叫做 pilot,做是做控制策略下发以及和用户交互的。另外一个 mixer,主要是实现一些后端服务和应用解耦的接口。还有一个叫做 citadel,主要是做安全权限管理的,Istio 主要是依赖 k8s 的服务治理这一部分,另外当前 mixer 对性能有所影响,还有我们都是在内部通信,安全级别不用那么高,所以,我们只抽取 pilot 来用,mixer 和 citadel 都去调,链路监控和其他监控都用我们自己研发的那一套。然后为 pilot 写了一个 etcd 的 adpater,把数据都存储在外围的 etcd 里面。应用启动后先到 etcd 里面进行服务注册,并保持监控检测的心跳连接。这样就实现了和 kubernets 的解耦。
但是我们发现在实际的实践中,这样改造成本和运维成本还是挺高的,为了脱离 K8S 代价看起来很美好,但是实际的要付出很大的代价,所以想要享受技术的红利,基础设施也要跟得上才行。为什么代价很大呢,虽然没有使用 kubernetes,但因为需要模拟 k8s 的 sidecar 架构,所以而是使用 docker compose 来进行编排管理。但是这样做也是没有办法的办法,为了统一基础设施,兼容非 Kubernetes 业务,必须做出一些妥协。但这也是过渡方案吧,后续我们还是会跟随社区朝着 Istio 大版本的迭代,我们只是在做一些上层的开发。
刚才提到边缘计算,那什么是边缘计算呢,这里做个粗暴间的介绍,边缘计算其实就是把云端的功能完整搬到离客户设备最近的地方为设备提供服务,我举个例子,我们在工业互联网的一些客户里接触到有些机床设备每天产生的数据量大概在 10TG 左右,如果把这些数据全部回传到云端是非常困难的。还有自动驾驶,自动驾驶如果断网等极端情况就失效了那就太可怕了,所以自动驾驶的场景、包括工业互联网、智慧园区等场景下它大部分计算都需要在车载系统或者车间旁边的服务器里面,处理之后直接回传给设备,这样确保它的时延低,同时安全性高,因为数据没有传到云端。另外有些厂家国外的设备都是很敏感的,都不会让你存到云端去。
我们提供 OneNET Edge 提供了很多协议的接入,可以接大部分协议的工业的设备或者传统物联网设备,边缘计算可以支持给设备下发命令,规则引擎,报警通知,流式计算。北向通过 API 实现数据北向数据的推送,可以推给客户的 MES 或者资产管理的系统。另外我们还支持云端训练好的 AI 算法模型,直接在 oneNET Edge 上运行。另外 OneNET Edge 是基于 kubernetes 的,所以可以很方便的在远程运维。客户的技术支撑可以做得更好。OneNET Edge 还支持可拔插的分布式部署,可以根据客户现场的计算资源灵活的选择需要部署的模块,如果仅仅部署核心模型的话,可以在一个资源很受限的网关里面就可以实现部署。这里面容器和 Kubernetes 为我们提供了很好的环境一致性,以及可编排的特性,增强了业务的灵活性。
Serverless 在边缘计算业务实践的 Open FaaS,我们把关注的资源粒度从传统的虚拟机到容器,再到函数级别,有了函数计算(FaaS)用户只需要写一个函数,这个函数提交到云端,云端启动过后,函数会输入参数获取到。在这个过程中用户完全不需要运维人员,因为他只写了一个函数,云平台运行就可以了。同时,我是按照调用次数来收费的,晚上没有人调用就不收费,但是传统的云计算是达不到的。FaaS 函数计算的这种场景从资源的角度来讲,是非常节约我们的资源。另外,事件驱动,客户有一些私有化的定制协议,这些协议需要去解析它的协议的报文,不可能每一个协议都要写接入侧的服务,有了 FaaS 之后,我自己写一个 FaaS 函数计算就可以了,不管什么私有协议,只要是基于 TCP 上来的连接,我都可以自己写一个 FaaS 函数解析报文,来获取你的业务逻辑来做计算。FaaS 在边缘计算这一侧是有很多潜在的使用场景的。
以 Open FaaS 为例,首先用户编写一个函数,然后利用 openfaas 打包工具会将用户的函数以及 openFaaS 提供的默认模块 watch dog 打包在一起组成一个容器镜像。当前端用户通过 HTTP 请求调某个函数时,首先网关会接收这个 HTTP 请求,网关这里会监控某个函数的调用请求量,实时决定现在 TPS 是否已经达到某个阈值,若超过就自动扩展后端的函数对应启动的容器数量。网关将请求转发给 provider,provider 知道我写的 A 函数、B 函数在哪儿被部署,会把请求转到我们后端真实的函数对应的某个容器实例上,实现对函数调用。这个过程当中,你只写函数,可以根据监控的数据来实现。这样可以根据业务的并发量级在用户无感知的情况下实现业务函数的自动缩扩容。当然没有用户就直接把它缩为零。而且我的收费模式可以通过调用次数来实现收费,这彻底改变了大家对于云计算商业模式的观念。对于 Open FaaS 的改造,通过事件驱动的方式就可以实现对 Open FaaS 的调用。主要是增加对 kafka 的支持,因为他原生只提供 rest 调用方式。另外我们对 faaS 的性能也做了多处优化。
最后和大家分享我们未来需要解决的三个挑战。第一,混合云(云边一体)的管理能力:怎么实现在边缘端,或者私有云里用户去创建一个服务,但是这个服务有可能在公有云里,然后两边组成混合云的架构为客户提供服务,这是我们正在为之努力的地方。第二,多数据中心(多 Kubernetes 集群)的统一管理能力。第三,对 Iaas 与 PaaS 统一调度管理的能力做进一步融合,接下来我们也会做一些探索和实践。
我今天的分享到这里,谢谢大家。
作者介绍:
姜仁杰,毕业于东北大学,现就职于中移物联网有限公司,负责物联网开放平台基础设施研发。现担任开放平台基础设施团队技术负责人,主要负责 OneNET 云原生基础设施研发。
本文转载自公众号七牛云(ID:qiniutek)。
原文链接:
https://mp.weixin.qq.com/s/WjyDnbS6eSQGg7kSRGfC4A
评论