9 月 7 日下午,在深圳南山软件产业基地,腾讯云 K8S & 云原生技术开放日成功落幕,来自腾讯、灵雀云、超参数科技、虎牙等资深技术专家与现场开发者共同探讨企业落地 K8S 的过程中遇到的难点以及解决问题的方法。
K8S 逐渐成为容器编排的标准,越来越多的实现方式和使用方式已经成为了标准化的流程,但是在应用容器化、DevOps、监控、性能调优、发布方式等方面仍存在一些技术难点。在学习和实施容器交付的时候,我们对于 K8S 的认知和理解多少会存在一些偏差;在一些项目落地实施时,开发者经常会对 K8S 本身没有包含的问题或者是没有解决的问题而感到束手无策。腾讯云 K8S & 云原生技术开放日邀请多位技术专家,就和大家聊聊在 K8S 中存在哪些问题,以及如何解决这些问题。
以下内容摘选自部分演讲速记,完整速记、音频和 PPT 请扫描文末二维码获取。
灵雀云微服务架构师 贺洪龙
为什么要上云原生?这是灵雀云微服务架构师贺洪龙老师在演讲开始时问大家的问题。其实,传统的架构转向 DevOps 的架构,有点像以前 C/S 架构转向 B/S 架构,这是一个必然的趋势。不只是互联网公司适合用云原生,其实传统企业一样适用,像中石油、海关总署、一些央企或者是大型的部委,他们现在也非常关心整个核心系统的更新换代,这个需求并不是来源于业务或者技术的角度,部分是出于管理的角度。实现云原生要做到两点:一是能够统一企业所有内部的应用架构,包括中间件都可以统一;二是要做旧系统的迁移。比如一个部委的核心系统可能是 10 年前开发的,而如果开发一个新的核心系统要上线的话,开发周期有可能要两年。那么迁移的时候,原系统下有几百个子系统,如果还是采用单体结构,实现难度非常大。而且现在政府的系统其实对于互联网的需求很多,以前一套系统可以跑 10 年不用更新,现在的系统分分钟要修改、要迭代。因此对云原生架构的需求就变得非常强烈。
DevOps 的价值体现在哪里?
一是可以快速投放市场。有多快?每天迭代 N 个版本,贺洪龙提到,「我记得是 2016 年,某银行信用卡中心一周时间迭代了 183 次,每天差不多有几十次的小版本迭代,用蓝绿版本迭代,这样频繁的发布也只有通过 DevOps 才能实现。因为这个银行信用卡中心的运维服务器开发得很早,从 2014 年就开始做了,最开始是跑虚拟机。据我所知,做发布的兄弟们三个月走一批人,经常需要通宵,他们都受不了;相反,用容器来做,基本上可以不用加班,用两套环境,一套蓝、一套绿,下午做好部署,晚上一切网络就可以了。」
二是降低成本。有 DevOps 工具之后,可以减少人工投入,进而减少因停机时间带来的损失。以手机制造厂商为例,他们的应用要发布,中间如果要停机,停一个小时损失 300 万。如果发布要 4 个小时,那就是 1200 万。而手机制造厂商的 IT 部门一年的投入也就一个亿。所以,通过 DevOps 基本上可以把 IT 的投入赚回来,这就是 DevOps 的价值体现。
三是 DevOps 可以让开发者不用做一些低价值的事情,包括安装、部署、配置都可以用工具来做。DevOps 可以让运维人员做一些更高端的事情,类似于运维架构师的角色。DevOps 平台可以满足整个生命周期管理的需求,从最早的项目管理、需求再到构建、代码,到最后运维。
腾讯高级工程师 卢承山
腾讯高级工程师卢承山从实践的角度,重点介绍了云智中枢 AI 中台的建设思路,该平台要打通设备、数据、上层的应用,让应用开发者基于该平台,通过服务编排减少用户的开发量。
云智中枢 AI 平台是从 0 到 1 构建是思路是:
(1)技术选型,比如用什么微服务框架,用什么容器平台。
(2)算法,算法可能有上百种,如何接入,并且发布成一个应用。
(3)AI 产品怎么落地。还有一个持续交付的问题。
很明确的是,用容器、微服务已经是一个趋势了。在架构选型方面,腾讯云容器服务 TKE 基于其强大的 K8S 的原生能力,同时对整个交付集成有一套完整的体系。
腾讯云最新推出的企业级容器云平台 TKE(Tencent Kubernetes Engine )基于成熟的 Kubernetes 技术和生态,能够帮助企业快速构建自身的私有化容器管理平台。TKE 企业版在架构设计过程中作了针对性优化,通过采用与腾讯公有云容器服务一致的架构和管理模式,可以帮助企业在私有化管理容器服务的同时,便捷地打通云上的容器服务并获得一致的管理体验,实现混合云部署。
另外,TKE 企业版还充分利用了腾讯内部微信、QQ、游戏等重量级业务在容器使用方面的经验,例如 GPU 虚拟化用于解决 GPU 共享问题 ;TAPP 应用管理用于让服务管理更加精细化、发布过程更加可控 ; 在离线混部技术提升资源利用率降低成本等。
腾讯自己开发的服务,包括算法服务,都能接到 K8S 里面去,其实这个已经比较成熟了,但是有些组件,包括一些存储性的东西,分布式文件存储或者 MySQL 存储等等,业界也有相关的方案,但是从整个的稳定性来说,存储目前还是用的物理机的方式,除了服务以外的存储还是用的物理机。那怎么接入算法?最原始的方式可能是让它提供二进制包或者类似的方式来帮它做。我们最终提供的就是镜像制作的方式,最终都是通过镜像。如果用户提供了一个二进制包,怎么帮他们做镜像?这里其实有两种对接方式,第一种直接对接其镜像。这是最简单的,也有容器平台。第二种是自动构建镜像。比如说它还是物理机或者是虚拟机的方式,它提供的可能是一些包,我们帮它自动做镜像。我们把每个环境抽象成一个组件,比如说你需要 JDK、OpenSL 等等环境,我们把它抽象成一些组件,你只需要把包选出来在你的页面上,这里就是一个可视化的操作,你可以在我们的平台构成完做成你的镜像,把你的二进制包上传。
这里有个难点,怎么缩短镜像制作的耗时?一个原始的 GCC 编译可能需要一个小时,CUDA 的安装也需要 20 分钟,做一个镜像如果环境变复杂,是不是需要一两个小时才能做一个镜像。那怎么缩短时间?思路是:第一次制作有可能确实需要花这么长时间。另外,腾讯****也抽象了几点,把 GCC、CUDA 和镜像的版本做了绑定,因为是常用的,所以会做成基础镜像,每个用户制作的内容都会在后台分析,用户最耗时的以及最频繁使用的,可以在后台帮你分析,做成一个模板镜像,下次做的时候不会基于 Linux 来做,它可以基于镜像模板机来做,它的耗时明显就会减少。
卢承山也介绍了 GPU 虚拟化的难点,并具体解释了腾讯和英伟达在 GPU 虚拟化上的不同。怎么在容器内使用 CUDA?容器可以做到 CPU 内存和 CPU 核的隔离,包括细分到 0.01。GPU 的最底层是 GPU 的设备,上面是 GPU 运行的环境。
腾讯是做法是:
一、最底层的两层是在物理机层面的,需要把它挂到容器上,最上层的 CUDA 是在镜像层面做的。
二、解决在使用容器过程中 License 的问题。
算法服务和普通服务不同的地方在于,算法厂商不希望这个服务你拿去就用,它有一些鉴权,不可能把服务给你。最早都是物理机过来的,它依赖物理机设备上的东西。怎么把这些东西挂到容器内,它依赖 MAC 地址,而容器的 MAC 地址是虚拟的。腾讯在这里面做了一部分改造,把物理机挂到容器,然后再做 License 的鉴权。
GPU 虚拟化也涉及一些选型问题,英伟达 GPU 虚拟化存在一些问题:
第一是物理层面,英伟达是在 CUDA 的驱动层面来做的,虽然性能很好,但由于是在虚拟机层面做的,因而不适合容器。
第二是它不开源,而且收费。既然不开源,出现各种问题你就很难去查。
另外,英伟达基于 MPS 做了一个软件的 GPU 虚拟化,要求必须平均分配,这会造成资源的浪费。比如,它是把一张卡虚拟成 0.01 之类的。使用一张卡其实很浪费,以一张 P40 的卡为例,很有可能你的算法根本用不到。基于这个痛点:腾讯做了一个选型,也是在 CUDA 层面上做了一层,所有的调用都是转到这个后面,再去调 CUDA 的底层,但是我们这个不会对 CUDA 底层的东西做任何改动,只是中间加了一层。
- - - - - -
超参数科技高级研发工程师 朱恒满
超参数科技高级研发工程师朱恒满从 AI 与游戏的角度,讲解了游戏 AI 在实践中遇到的难点以及解决问题的思路。游戏 AI 近些年来在学术界已经有了很多的探索,在最近几年出现了比较显著的成果。2013 年 deepmind 在 Atari 的游戏上超过了人类,但是在当时并没有引起很大的轰动,在 2016 年 AlphaGo 击败了国际顶尖的围棋选手,使得 AI 有了很大的进展。最近,deepmind 和 OpenAI 分别在 rts 和 moba 游戏里面战胜了职业选手,资源不断升级,规模也是越来越大。
游戏 AI 的实验流程:首先在本地是一些算法的设计、迭代,包括一开始去体验游戏,感受游戏需要怎样的特征,设计怎么样的流程更好;然后是模型的参数调整,做一些小范围的参数设置;接下来就是做一些大规模的实验。强化学习主要是 CPU 和 GPU 混合的异构的计算,规模会比较庞大。那么,现在 AI 真实对战的能力指标是不是已经达到我们的预期了?如果达到预期,实验就可能会停止;如果达不到,就会再回溯到之前的各个模块,看看在特征方面有没有什么需要改变;最后就是保存模型。
那为什么要做一个平台化?
首先是因为计算模式的复杂性。目前,强化学习在 K8S 上的编排模块比较多,包括 GPU、CPU 生产数据等方面,还有中间做了一些缓存。这么复杂的模式,如果没有做平台化,需要写很多的脚本,对于个人而言,很难掌握大规模、复杂的系统。另外,比较重要的一点是计算模式需要能够被复用。整个迭代流程更多的可能是修改参数,或者是一些模型、特征,其实整体的框架是不会动的,这就需要提供一些可复用的计算模式,进而可以提供对算法模型来说更加直接的分布式能力。
其次是资源需要被更高效地管理和利用,这也是 K8S 赋予的能力。如果是个人或者团队分配机器,利用率是很低的,包括自己的业务可能需要去协商可以用哪些机器,这个流程非常拖沓。同时,也存在资源竞争的问题,比如两个人都想用 GPU,一台虚拟化的机器只有一张卡,怎么分配?还有就是个人很难管理这么大量的机器。
最后,平台的通用化分析能力,可以开放给算法同学,包括算法的监控,硬件和业务的监控。另外,在日志处理方面,通过日志去判断一个 AI 是不是已经达到了能力上的需求,这里会有一些指标,包括模型方面的要求;还可以做日常定位的工作;在数据管理方面,训练数据和模型都需要做管理。
虎牙直播高级开发工程师 王玉君
因为虎牙直播业务方面的特性,它有很多业务是部署在边缘节点,因为涉及到主播推流等,对网络质量要求比较高,也在尝试边缘机房的建设。目前,虎牙有一些测试的机房,预计会在今年 Q4 完成生产环境的建设。这是目前的现状:虎牙现在 Node 机房有 700+ 物理机,Pod 有 7000 多,应用程序在 350+,这些数据还在不断增加。有时候有一些赛事需要紧急扩容,一天就会扩容 100 台,虎牙会根据实际的业务情况来增减。
虎牙直播高级开发工程师王玉君分析了虎牙直播应用 K8S 的背景以及目前实践的一些思考。虎牙现在有一些 K8S 集群是搭建在公有云平台上的,目前用到了腾讯云、阿里云、AWS。对比这三家,腾讯云 TKE 可以大幅节约成本。比如说一台虚拟机上跑 10 个容器和跑 30 个容器是有本质差别的。虎牙当时也实践了不同的平台,在腾讯云 TKE 上,一台虚拟机可以跑到将近 40 个容器,它还可以提供更多的密度。
通常情况下,K8S 如果直接提供给业务方,API 等方面用起来不是很方便,包括一些 CI/CD 的流程,如果没有把业务打通,用户是不愿意迁移上来的,因为要考虑自己的应用性成本,包括后期的部署,一些变更的成本等。虎牙一站式服务可以实现从代码编译到部署,所有的环节都帮助用户在页面上实现,用户只要在页面上点一下,就可以在很短的时间内把新版本发布。
之前有用户不愿意上云,担心业务被其他人影响。虎牙使用了 TC 限速策略,做了一些容器的限速,有稍微的改动。如下图所示,左边底下这些三角形是容器,出向限速在左边,右边是入向限速,底下蓝色的方框是 TC 的模块。如果这个网卡是 1000M,左边这个图有两个方块,虎牙做了一些优化。因为机房用 BGP 的模式,要保证它有一个独享的带宽,不能被其它所干扰,否则对路由有影响。右边这部分就通过 filter 分给不同的容器,然后有一些不同的策略。右边这一块只是限出不限入,也是用开源的方案,通过一个网卡转发,网卡数据包进来,再出去,通过限制网卡的出速,相当于限制了容器进来的速度。
那么,边缘节点如何接入?
如下图所示,左下是数据中心,master 跑在数据中心里面,边缘节点分布在各个地方,它如何接入数据中心呢?图中右边这部分是通过公网直接接入集群,这种方式有很多风险,比较严重依赖虎牙自研的防火墙设备。比如说 K8S 的业务运维或者是系统运维,在扩容边缘节点的时候,它会先跟安全部门进行申请,开白名单,然后接入才能成功,跨部门的沟通是非常影响效率的。左边这一块是通过 IPsec VPN 的方式直接接入边缘节点,这种方式是比较依赖一个边缘网关、EdgeHub。另外它使用 VPN,在同样的链路下,它会有一些性能上的损耗。
基于这一点,虎牙结合 K8S 的特性做了一些边缘节点更新的方案:
(1)用户可以直接通过公网接入。
(2)系统管理员不需要找安全部门开白名单。
通过 kubectl 或者 Restful API 向 master API 发起一个授权,进而推送一个资源,安全资源有变更时,会把配置后的信息发送到一个源数据服务,源数据服务会实时更新该插件上的防火墙配置,业务的节点就会比较快速地接入集群。这样做的好处是:边缘节点分布在各个地方,edge mate 可以进行统一的管理,它会把边缘配置下发到各个节点,然后对自身进行配置,提供一种边缘集群的对外访问能力。
另外,原地升级是对 K8S 比较好的一个补充。如果要进行升级,按照 K8S 现在的方式,会把 pod 销毁重建,这样业务是不答应的,所以原地升级可以 pod 不变,业务容器也不动,只是把 Sidecar 容器做一个更改。当集群的规模到一定的程度之后,有很多的业务要进行更新操作,更新的时候会对调度器带来一些压力,这是可以完全避免的。从这一点上看,K8S 原生设计上对规模比较大的集群还需要一定的优化。从资源锁定的角度,资源不足的时候被内部抢占,也可以通过原地升级来解决,因为 Pod 根本没有销毁,所以 pod 的立面没有改变,其它的 pod 不会调到这一台物理机上,不能达到 pod 锁定的目的。
腾讯高级工程师 杜扬浩
Harbor 是目前唯一的一个也是最流行的一个开源企业级镜像仓库解决方案。Harbor 除了包含最原始的镜像功能以外,还包含用户图形界面,以及它的认证、鉴权模型;同时,它还支持病毒扫描、镜像的复制。另外它也支持一个 RestfulAPI,这对企业来说是非常重要。最后 Harbor 也比较好部署,现在 Harbor 支持两种部署模式。
腾讯高级工程师杜扬浩在演讲中主要介绍了 Harbor 的优势以及应用过程中的经验。他提到,目前 API 可以满足大部分企业的需求,但是随着企业的业务越来越复杂,应用越来越多,原有的 API 就有点不够了。杜扬浩举例说,「我查询过一个仓库所有的镜像列表,它最开始提供的 API 里面并没有企业用户所需要的一些信息,比如需要对某个用户进行过滤,或者对某个字段进行过滤,这时候它的 API 就不能满足企业用户的需求。」
这时候就有一个问题,怎么在不改变 Harbor 的情况下来适应企业级的需求?
有两种方案:第一种是内嵌式的修改方案。直接修改 Harbor API,让 Harbor 实现 API;另一种是非侵入式的方案。在 Harbor 的外面另外配置一个适配器,所有对 Harbor 的适配操作全部通过 Harbor Adapter 改造,无需修改 Harbor。
这两种方案相比,使用非侵入的方案,需要几百行代码来完成这个逻辑,如果用修改 Harbor 代码的方式,可以通过几行代码实现一个非常简单的功能。但是内嵌式的方案有一个很大的缺点,它对 Harbor 是有侵入的,当 Harbor 升级、修改比较多的时候,维护成本随之会增加,有可能当 Harbor 进行了一个版本升级的时候,企业内定制的 Harbor 也需要进行升级,就需要一个完整的路径来进行升级的工作。
对于非侵入式的 Harbor 修改方案来说,优点也很明显,唯一需要注意的是 API 的向下兼容。如果它的 API 不能实现向下兼容,就需要进行适配,它的缺点就是一个效率问题:可能一个很简单的操作,就需要很麻烦地拼凑才能实现同样的效果。还有就是对一些有状态的数据的操作,比如需要在 Harbor 原有的数据的模型下再插入一些数据,在外部就不是那么好做,还需要在里面存储一份数据,这份数据还要和 Harbor 原有的数据合并,这并不适合采用侵入式方案。综合来说,在满足性能要求的情况下,可以接受非侵入式对 HarborAPI 调用的损失。但更值得关心的是,这种升级所带来的维护成本。因为这种非侵入的方案有利于 Harbor 的升级和维护,当开源的 Harbor 升级的时候,可以用很少的工作量完成 Harbor 的迁移和升级。
Harbor 虽然支持完善的认证和鉴权机制,但是企业内部一般都有自己定制的认证和鉴权逻辑,而这些特殊逻辑是无法通过 Harbor 现有的方式来兼容的。怎么在不修改 Harbor 的情况下进行认证和鉴权?
首先是无侵入的认证和鉴权。它的核心就是把认证和鉴权从 Harbor 内部迁移到 Harbor 外部。现在的流程是平台调用认证中心,由企业的认证中心来完成这个认证和鉴权,当认证和鉴权通过之后,再调用 Harbor 的 API 来执行相关的操作。执行完相关的操作之后,还需要把对应的 RBAC 的资源写入到认证中心,这样就可以实现对 Harbor 的无侵入认证和鉴权修改方案。API 的认证、鉴权无侵入方案存在的一个问题就是,它不能兼容 docker 命令行,因为它不是使用我们的平台 API,它是由 dockdemo 加入,所以这里面还要对认证和鉴权的命令行做一个无侵入方案。
在企业生产环境里如果需要部署 Harbor,要进行高并发来压测一下。杜扬浩在演讲里对比了基于普通的 CephFS、基于对象存储和文件存储这三个环境的压测对比。
Harbor Ceph FS 压测
Harbor Rook FS 压测
Harbor Rook Ceph RGW 压测
通过压测数据得出结论:随着并发量的增加,三种存储平均拉取时间都在增加,而且成功率也是越来越低。10 个并发的时候是 100%,30 个并发是 92%,600 个并发是 73%,当然这里面很大的原因是 Harbor 本身的 bug 问题。可以认为 rook 的文件系统和普通用物理机搭建的文件系统性能接近,rook 的对象存储的性能是远高于 rook 搭建的文件系统的。
除了刚才提到的对象存储的性能本身就优于文件系统之外,为什么 Harbor 压测结果有这么高性能的提升?
经分析可知:一方面,Harbor 切换了对象存储之后,它在与 docker 交互的过程中会采用一个重镜像的技术,这样流量就从 Harbor 切换到对象存储的服务里面来,Harbor 就不需要中转数据,节省了 Harbor 自己的一些资源以及时间。另一方面,数据由 Harbor 切到对象存储之后,流量瓶颈和并发瓶颈就由 Harbor 转到了对象存储,所以,基于上面的两个原因,就导致了 Harbor 在切换对象存储之后,它的性能有了一个质的提升。
还有比较重要的一点是关于 ceph 文件系统的备份还原。对于 Harbor 的 ceph 文件系统来说,Harbor 的数据实际上是落地在文件系统的某一个路径上,这里备份的原理就很简单:通过 PV 获取到它的路径,然后把这个路径 mount 到本地的文件系统,通过这个文件系统进行一个压缩或者备份。文件系统的还原就是刚才备份的一个逆过程,只需要把备份的数据打入到刚才 mount 的文件系统里面就可以了。
对于 ceph 的对象存储来说,它的备份还原的原理实际上是一样的,但是它的具体实现就有点区别:因为对于对象存储来说,它的数据不是保存在某个路径下,而是保存在对象存储的 bucket 的概念中,所以如果要对 Harbor 的对象存储进行备份还原,就需要对这个对象存储中 Harbor 所对应的 bucket 数据进行备份还原。
在现场提问环节,部分参会者也问到了关于腾讯云容器服务 TKE 的问题,为什么选择 TKE?开源自建 K8S 与 TKE 的对比如下:
评论