跳转至

首页

ZStack的产品化之路

在浅黑科技《ZStack:这群做云的人有点“轴”》一文中,作者史中提到,这是一篇国产云计算佼佼者ZStack的创业史,文中记录了因为热爱而聚集起来的最早一批ZStacker,他们生活没有退路,但热爱未有止息。

实际上,这群人不止是做云“轴”,还很有趣呢。比如什么猫本轴海带,70后知识储备的90后......让我们走进《ZStacker说》专栏,一起看看这些有趣的ZStacker叭。

第四期人物故事:ZStack解决方案与产品架构师 蒋迪,一个70后脸的90后(笔者自定义标签),曾主导设计ZStack Mini、GPU池化、智能网卡适配、弹性裸金属等重点产品和功能原型。

今年是我工作的第10年,距离我第一次体验ZStack约莫过去了6年,在ZStack大家庭也近5年了,对私有云产品也有一些自己的拙见,希望可以借着这篇文章分享给大家。

又不是不能用

我的第一份工作就是做基于KVM的VDI,当时虚拟化平台的选择有很多,那时国外某开源云架构在国内正如火如荼,所以我也考虑过使用它作为基础虚拟化平台,但当我按照它的文档吭哧吭哧搭出来用了两天后我就决定放弃了,因为当时从文档、部署、功能、运维、升级等等各个角度来看,它暂时没有作为产品的良好基础。

但后来发现各地项目一提云就是它,我觉得或许是我自身的问题,于是咨询了几个朋友,得到的答案都是“管它好不好,大家都在用,项目多你怕啥”。经过再三考虑,本着对产品化的一丝朴素坚持,我最终还是决定放弃它了,后来事实证明这个选择也算正确。

傲娇的产品化与共同成长的客户

中间我把早几年积累的经验和知识总结成了一本书——《KVM私有云架构设计与实践》,机缘巧合这本书让ZStack的两位创始人张鑫和康总看到了,就邀请我来到ZStack。来到ZStack以后,除了见识到作为一个创业公司5年内从几十人到数百人规模的成长历程外,也对to B的企业产品有了更深刻的理解。

在ZStack的头两年我作为售前,会跟着不同销售全国跑,一起开疆拓土,比原先在研发岗有更多机会接触不同的一线客户,了解他们的各种使用场景。期间项目商机虽然很多,但ZStack作为一款不具备行业属性的私有化的IaaS标准产品,起初在某些项目中是有些吃亏的。那段时间国内OpenStack公司已经把客户市场教育的差不多了,经常有客户会问:你能不能定制,不能;你能不能代运维,不能;能不能提供PaaS和大数据,不能;我想搞个跟AWS一样的云你们能接吗?哈哈今天天气不错。

ZStack最让我欣赏的就是这种不做项目制、搞标准化的产品“气质”,有些傲娇但是又有自己的矜持,这为后面一些典型案例奠定了一个长久的基础。比如在做某手机一线供应链客户时,他们会拿ZStack对标V记产品,对产品该长什么样有自己的认知,对细节的把控也很强。比如:做个配置修改你让我登陆Linux改配置文件?对接商业SAN存储你让我选你们适配过驱动的?产品不支持在线升级?安装部署得你们上门?服务器还得用你们都兼容过的?对不起出门左拐厂牌交给门卫。

在甲方这样独立、自主的理念要求下我们PK掉一众竞争对手并成功进入他们的生产环境。在后续的跟进中他们也提了很多中肯的建(需)议(求),并对ZStack表示高度肯定,也理解我们并不会把所有建议都做到产品中的“傲娇”态度,因为在其他客户场景中可能难以适用。拥有像这样相互认可并一起成长的客户,我觉得对产品打磨十分关键。

后来的很多项目证明这种产品“傲娇”是利远远大于弊的,前面客户提的需求和建议在我们向其他客户输出标准产品时提供了很多潜在帮助,在这几年的信创项目中体现得更为明显,最典型的几个比如国密产品标准化、密评功能模块化等。

做好技术产品化交付的“最后一公里”

云计算是IT技术的集大成者之一,比如AWS上不断有一些既陌生又熟悉的新产品出现,像物联网、量子计算、机器人、卫星通信、AR/VR等。公有云可以把这些东西以成熟的产品交互呈现给用户,然后由公有云厂商承担复杂的后台运维,但私有云很多场景下并不能这样。有些大项目乙方可以代运维,但是头发尖的客户能有多少呢?更多不断涌现且可持续性发展的往往是一些所谓的小项目,而这些项目的运维往往是用户或者渠道商,所以私有云面向的最终用户应该有两种,一是最终用户,二是运维人员。因此,我们做产品要把实现的复杂性隐藏掉,从而让用户集中关注他最该关注的事儿上。

既然认定了市场,那做出的产品就要去迎合这个市场的用户,做某个领域的技术和做某个领域的产品是两码事儿,怎样在提供技术的同时又充分体现“人文关怀”也是一个“匠人”活儿。比如ZStack Mini的定位是面向工业一线场景,那么我们产品设计时要考虑到一线人员的实际IT能力,所以交互一定要足够具象,比如硬盘在哪个位置、虚拟机启动在哪台物理上、USB设备插在哪一个口上等等一些细节问题,有了这个基础才能让用户在使用尽管看起来陌生的虚拟化容错技术时有一种“一切尽在掌握中”的感觉。

另外在做异构计算的产品适配时,针对像GPU、DPU、智能网卡这些用户比较容易体验到IT工程技术发展成果的设备,我们除了要考虑把技术集成到ZStack并合理的提供出来,更要花费大量的精力思考如何把这些技术做得易用,包括安装、配置、升级等等。

举个例子,业界比较看好的vDPA方案,它能让用户在获得与SR-IOV方案媲美的虚拟网卡性能的同时,解决SR-IOV虚拟机难以热迁移的问题。听起来十分美好,但是实际落地时事情远非按照文档把技术堆出来给用户就完事儿这么简单。我们需要考虑DPDK相关驱动和配置什么时候下发安装、OVS网络要不要与已有LinuxBridge集群主机复用或者允许热升级,如果客户要外接控制器我们应提供怎样的接口、如果使用网卡软vDPA那么牺牲的一个CPU核应该怎样向用户呈现或解释、更换网卡时平台配置是否要自动适配等等,这样一些看起来与主要提供的技术目标关系不大且很繁琐的特性,正是走好技术产品化交付“最后一公里”要克服的困难,也能让用户切实感受到被尊重。

信创不仅仅要“能用”,更要“好用”

关于产品其实我有一箩筐想说的话,但在今天的国际形势之下,更想聊一聊信创的问题。大家看新闻应该都知道,最近俄罗斯也打算搞“局域网”了,他们很早就规划逐步用国产替代基础设施中依赖的进口软硬件了。“以人为鉴,可以明得失;以史为鉴,可以知兴替”,信创软硬件被应用到关键基础设施已经成为趋势。但如何选择产品呢?我的答案是:不仅要“正确”,更要“好用”。

在这两个原则的框定下,ZStack自研的产品核心以及长期以来坚持的产品化路线刚好能够把它推进这个象限。这句话怎么理解呢?因为基础设施的很多技术确实存在地缘壁垒,信创初期十分艰辛,做出来的东西可能仅仅达到“能用”的程度,但随着市场的发展,这些产品不仅在功能上能满足,在性能上也开始有指标超过国外同行了。私有云产品市场也是如此,初期确有很多国外开源云架构换皮产品来充数,仅仅达到“能用”的标准,但随着客户要求的不断提高,这些厂商开始有心无力。事实证明,非自研的架构核心改起来都非常费劲。

而从我有限的角度来看,ZStack可能是市面上为数不多全部适配了主流信创CPU与服务器的私有云软件产品公司,甚至在不支持硬件加速的虚拟化芯片问题上,ZStack也可以通过“弹性裸金属”让这些服务器顺利“上云”,达到让物理机享受与普通云主机一样的云盘、云网络并同池管理的目的。加之公司有强劲的QA团队保证(插一句,ZStack的QA人均超过10台物理服务器,比研发都“富有”,他们的理念和技术也很硬核),ZStack的信创版本质量也能得到充分保证。在目前的信创实际项目客户看来,ZStack的云产品已经远超“能用”的标准,而在“好用”的赛道加速奔跑了。

产品如何定价的模型讨论

昨天跟人聊到这个问题,但是从经验上说,定价似乎需要考虑很多,但也好像不需要考虑一样。定价格有一些已有的规律,比如产品独领风骚然后按毛利去定的、红海市场跟随友商打价格的、为了扩张亏本卖的等等。经验这种东西会很有效,但它也是阻止破圈的罪魁祸首。所以这篇文章尝试建立一个代理人模型从尽可能多的角度去探索,毕竟这是一个系统性的问题,我们不讲经验,一两条经验不足以适配所有问题,干了40年的老板也不一定解决新场景遇到的问题,要不然百年老店不是又比现在多了一些。

当然,我仍然会建立一个合适的动态模型来模拟尽可能多的情况,如果是沙盘推演也没有问题,只是可能局限性比较大,不能把一些极端的变量组合考虑进去。设计的时候尽量遵循ODD原则(overview, design, detail),以保证覆盖现实情况的同时模拟出更多意外。

这里我们抛开单个产品差异化定价策略,即可以把产品拆成很细的定价策略,比如一块盘按照不同iops和容量租出去最大化利益,只讨论一块固有iops和容量的情况,因为这种拆分算利益的话,更适合用最优解公式而不是建模分析,况且现在差异化定价你会别人也会,最后难免都是同质竞争。

设计

以我熟悉的云计算为例,首先我们尽可能多的列出agent,最明显的就是产品、客户、厂商、供应商,但是这还不够,有些过度抽象了。(我们暂且忽略渠道,主要是因为渠道与云厂商体量在实际情况中基本保持一致,所以这点确实可以忽略)

那接下来我们加入更多agent,产品嘛单纯一些只有一类,客户这一类金融行业客户、游戏行业客户、制造行业客户,厂商的话主要考虑外部竞争和内部团队(云计算部门的集团投入政策、销售体系等),即会有几个体量、质量、策略等不同的厂商agent,厂商除了考虑同类供应商,也要考虑它的上下游,比如代工厂、圆晶厂、渠道商这些(方便实现简化保留下游,仅为防止泰国又洪水产品生命周期有影响)。

梗概

至此,我们已经在这个世界里已经可以描述一个完整的故事了,某个客户(可控数量)向某个云厂商(可控数量)购买最多N个产品(有生命周期),客户会根据自己的偏好选择厂商,厂商提供的产品受限于供应商(价格极低),如果客户技术能力强或者价格敏感度高可能会直接向供应商下单(供应商参与竞争,适用于OEM产品),最后我们的输出是某个厂商在未来一段时间内的市场表现变化,包括收益和客户占有率。

属性与动作

客户

列出尽可能多的agent以后,我们开始构建每个agent的属性和行为。由于我不想写那么多一个个解释,所以列几个意思一下,以金融客户为例(属性值和动作来源于市场销售记录统计,无法确定的值没关系,模拟的时候机器可以范围内随机探索)。

1
2
3
4
5
6
7
产品价格敏感性:低(0.2)
产品质量要求:中(0.5)
服务质量要求:高(0.8)
客户直销忠诚度:中(0.0-1)
客户渠道销售忠诚度:中(0.0-1)
IT技术能力:中(0.5)
受他人影响程度:高(0.7)

然后是动作,这些动作暂且适用于所有客户agent。

- 客户的属性随着时间的增长保持不变 - 客户会根据自己的属性偏好选择厂商产品,各个属性加权值决定产品,比如质量要求高的会喜欢产品综合质量好一些的、渠道忠诚度高的会喜欢渠道多的、IT技术能力低的会喜欢厂商服务好的 - 客户的购买行为除了在与云厂商直接,也可以发生在与供应商之间
- 客户的某属性超过一定阈值的时候(比如忠诚度),虽然所有属性加权值不是最佳,但会导致其这次仍然选择上一家
- 客户的忠诚度会随着历年选择厂商的变化而变化

产品

列出产品的属性,这里可以先定义这么几个。

1
2
3
4
5
6
7
8
9
产品价格:可控变量,即客户每天使用需要付出的价格  
产品状态:在厂、待售、使用、结束(这里假设每个产品从售出便不会再次回到产品池)  
产品用户:产品用户
已经销售:是否已经销售到客户
产品成本:与供应链相关
产品质量:随时间、客户增加而增加,有一个逐步完善的过程
产品销售厂商:产品销售厂商  
产品生产厂商:产品生产厂商
生命周期:产品从售出开始则开始消耗

厂商

然后是厂商的属性。

1
2
3
销售策略:盈利、求同、激进  
产品最大数量:对应厂商体量  
产品成本:与供应商有关

供应商

最后就是供应商的属性,为了减少复杂度,这里我们只有两类供应商,即可直接面向客户以及不可直接面向客户。

1
2
3
4
销售策略:盈利(供应商不赚就是亏)  
产品供应周期:每天能够生产的产品数量  
产品生产成本:可变量  
可直销:是、否

再加一些全局变量进去,比如从Gartner的趋势报告里把云计算、各类产品的每年增长也算进去,主要操控的变量是某个或多个厂商的定价范围(0-100)。

周期事件

TBD 一个周期内,会发生哪些事件呢?

产品:
客户:
厂商:
供应商:

模拟

预期

在开始之前,我们根据经验应该是对这个世界有一些经验预期的,包括:

1
2
3
4
5
6
7
8
一定范围内,定价不能直接决定市场占有率;  
产品做的晚的厂商即使定价再低也只能抢得一定份额的市场;  
供应商供货不足时,体量大的厂商更能抗住黑天鹅事件从而保证客户产品交付,从而获得更高的客户忠诚度;  
动态选择灵活的定价(销售)策略即使起步晚,也可以抢夺一部分可观的市场;  
价格敏感、技术能力强、忠诚度低的客户更容易从供应商处买;  
集团策略影响云厂商定价策略选择;  
在没被针对的情况下,小厂商初期可以打价格战争夺部分客户后,不会赚甚至是亏,但获取一定客户后再改变价格策略是可以盈利的;  
因为不同阶段采取不同的定价策略会影响市场表现,那么作为云厂商在期间的前端销售和供应商谈判策略也不尽相同,比如产品初期的时候很难从供应商要低价,平价甚至亏本抢占市场后可以再向供应商谈判出更低成本价;

行为空间模拟

最后我们来看看模拟的动态情况。

tbd model simulation

tbd 由结果我们先看到几种现象。。。

tbd 然后我们把自己的实际情况带入进去。。。

tbd

tbd 看的多了,再结合dikw模型,结论就是直觉可能就是对的。但是要给人展示数字,我们可以从各种渠道快速填充数字,从数字到推论,只是让人觉得你可信,至于你自己信或不信,就是另外一码事儿了。。。最后我们要把数字与经验结合起来,就是出几个概率数字,即未来几年内我们应该采取怎样的定价策略(保持毛利、争夺市场、自动动态调整)然后有百分之多少的概率占去多少这个产品的市场获得多少利益,根据概率做选择,虽然无法确信,但也不会犯错,平平淡淡才是真。

关于产品的一点思考

最近在做一些小东西,但是也没匀出来时间写点啥,趁机整理整理吧。当然不能太抽象,太抽象就容易形而上学,而且让人觉得学究派。

一个系统甭管是啥,但凡需要作为产品输出,那就要有一些属性的,现代汉语对它的释义也挺准确的——“生产出来的物品”。

作为大千产品的用户,我有一些直观的体验,自己在做的时候也努力带给别人同样的体验。

暂时先总结这么几个。

场景需求优先:先满足我的原始(original)需求,即我这个需求的动力是什么,然后再扩展。

低学习成本:一定不要让我在使用的过程中老是咨询厂家、翻看说明书,对to B而言就是你不要老让厂商帮你运维。

无入侵:产品提供的服务不要给我造成额外困扰。

行为尊重:用户做的动作里哪些是需要的,哪些是多余的,产品行为里哪些是别人要看的,哪些别人甚至都不需要知道,想的越多,客户越觉得被尊重。

不要自大:厂商不要自大,做一个领域,和做这个领域的产品,是两码事儿。见过自诩很懂某领域的人,但是做的工作极难批量复制,那不叫卖产品叫卖人天。

不要遵守原则:只要保证客户人财安全,你可以随意创新,不要管别人的这黄金法则那必胜定律,用户的认知从长远来看可能都是错的。

可配置:产品化与某些场景追求的高性能并不冲突,一切皆可为配置。

测试即产品:毫不夸张,没有靠谱的测试团队那产品必然不行,不要吝啬在测试上的资源,他们可以以较小成本帮你发现成数以万计个潜在问题,也不要把客户当测试,你会很难堪。

隐藏复杂性:产品内部的行为可以很复杂,但是对客户呈现的一定是简单直白的行为,没人关心你的内部实现。

社会责任感:无论to B还是C的生意,做的东西要有严谨生命周期、升级策略、迁移方法,要不然就是对客户不负责像Google那样丢失B/C类用户的甩手掌柜。

实时操作系统中应用K8S

背景

想做这个东西的背景也很简单,就是KVM虚拟化里配上国产还是VxWorks的实时操作系统,实时性都比物理机差好几倍,无法满足某些客户的需求,常规的一些优化手段抓破头也不行了。看过WindRiver的StarlingX觉得它们的无论延迟还是抖动的控制都相对好一些,但是VxWorks本身是个黑盒子(可能对于某些有源码的人不是。。),所以就只能跳出来看这个问题,为了满足客户的需求,批量管理运维、快速发布回收、状态实时监控,都21世纪了我为什么要用虚拟化呢?(后来事实证明大家也很少用虚拟化做这个事儿。。)

那就实时Linux系统配K8s,满足大规模、边缘、嵌入式场景,雷达、舰载、攻防。。。而且这个场景下想象空间比虚拟化大点。

准备

OS:RHEL 8.4 with rt kernel

测试

懒了,直接上测试结果以演示容器配RTLINUX是否值得投入,如果性能满足需求,那做这个市场还需要个牌照和资质,不过问题不大。

裸金属笔记

裸金属相关,简单点就是尽量不用计算虚拟化。


动手做自己的Nitro SmartNIC(FPGA/ARM-based Bare Metal Hypervisor(2021-02-25)

0. BackGround

裸金属服务很酷,甲方都想要,但是最好不要有绑定。BlueField 1/2、AWS Nitro、Aliyun X-Dragon MOC之类的智能网卡也不错,虽然ZStack已经纯软件实现了类似功能,但是这篇文章仍然会探索一个如何低成本(不到100块)的“智能网卡”方案(要不然前期的调研都白瞎了)。

做弹性裸金属并不难,但是要高性能的同时又要安全,而且在私有云、产品化的语境下,我们就需要好好思考一番了。

1. 功能定义

1.1. 带外管理

带外管理也不是个问题,如果:

  1. 服务器自带BMC。
  2. 你有能力让服务器厂商给你定制,因为你需要定制BIOS部分功能以让其在启动时认到智能网卡提供的虚拟设备。
  3. 自己做OpenBMC。

但是,由于多数用户没有让服务器厂商高度定制服务器的能力,因而我们需要在“无米”的状态下做“炊”。

1.1.1. 电源管理

通过“智能网卡”我们至少要能实现主机的开关机,这个相对来说还比较容易实现,无论何种主板,电源控制接口现在服务器上都有,若干个高/低电平就可以控制。

但是考虑到集群断电的情况,“智能网卡”要优先启动才能进一步控制它管理的物理机,所以这个设备我们一定要轻、快、稳。

如果使用服务器内PCIE供电,那么我们又要修改BIOS来保证智能网卡优先启动,但是这个。。。成本不止100块了。

所以考虑使用独立供电的嵌入式设备,无论使用插到服务器PCIE插槽上的ARM/FPGA/X86 SoC还是树莓派,我们都要给它独立供电。

1.1.2. 与主机通信

这里的通信仅仅涉及控制面的内容,数据面(网络、存储)不涉及。

我们尊重传统,仅考虑两种情况,即与主机OS通信和与主机设备通信。

前者一个agent走TCP/IP就能搞定,后者我们需要与主板的I3CI2C/SPI接口通信。

1.2. 设备模拟/透传

存储

存储侧我们目前可以直接提供的baremetal设备有 SCSI(iSCSI)、NVMe(oF)、VirtIO等。

由于产品化必须考虑到适配各种硬件的问题,所以我们不会定制修改BIOS,这里只要一个小小的trick即可让服务器从智能网卡提供的vda或者其他接口的“虚拟”硬盘启动,从而保证云平台存储资源可以以较高性能提供给baremetal。

Option Rom

Option Rom 也是智能网卡带的选项了,启动后可以直接认到virtio/nvme的虚拟硬盘。

网络

网络多数情况下是问题但又不是问题,我们选择智能网卡的原因是因为它可以解决大多数问题。虚拟网络资源直接给物理机的目的可以很容易地通过SDN交换机实现,但是我们既然用了一个智能网卡设备那么就应该通过它来回避各种外部环境仍然需要定制的问题。以BF2为例,它内部集成的ovs-dpdk以及Mellanox传统的内部虚拟交换技术加持,我们可以给baremetal一个“虚拟”接口,但是所有流量都在云平台的管控下,用户极难自行修改。

如果不选择智能网卡,那么只有SDN交换机和系统内SDN两种方案,SDN交换机甚至比智能网卡的适配都简单,技术不是难点,同智能网卡一样你很难说服客户的采购来一套裸金属专用的SDN交换机,更不要说这个交换机不在他们的网工管辖范围内了。

那么只剩系统内的overlay网络接入方案了,Linux一直不是问题,Windows系统需要agent做一些小工作才可以,即使用户自己改了,我们也可以“内挂”anti-spoofing。

1.3. Hypervisor模拟

“智能网卡”中要模拟hypervisor,这里的模拟是为了让多数云平台的agent比如libvirt或者基于libvirt的定制agent能够对弹性裸金属设备的调用行为与虚拟机保持一致。为什么要做这个工作呢,我单独的控制面不行吗?

也行,但是不酷,更何况你后续的存储与网络设备不仅给裸金属也要给虚拟机,两套API两套数据库管理同一个网络/存储就是在给云平台的管控面开发找事儿。

所以这个我们一般要对agent(libvirt)做一些修改,这个难度相比下来不大。

2.1. Proof of Concept

2.1. ARM or X86作为智能网卡

如果使用ARM或者X86主机作为“智能网卡”,那么存储方案有iSCSI和NVMe-over-TCP,网络方案目前看只有系统内SDN的方法了,好处在于“智能网卡”的门槛低。

我们先做一个OpenBMC的原型机,准备如下材料:

笔记本; 树莓派/NVIDIA Jeston; 视频采集卡; 杜邦线; 网线; rtl-sdr(谁能拒绝一个可以听广播看电视的裸金属呢);

当然,一台服务器也是必要的。。。不会吧,你家里连台服务器都没有?你还做锤子钢铁侠哦?赶紧上咸鱼500块买个二手服务器吧,不想做钢铁侠了还可以卖掉。

算了,毕竟太吵,一个ATX或者其他类型主板的台式机就可以了。

TBD

2.2. FPGA ARM SoC作为智能网卡(有点小贵,1000多块,但是来都来了)

1000多一块的有PCI-E插槽的Xilinx ARM SoC开发版,贵,但是你可以基于PCI/PCI-E接口实现独立的网络、存储,非常有意思,但是难度在于FPGA编程。

不过还好,我们先尝试用Pynq写一些简单的PCI/PCI-E通信,然后再堆上复杂的,但是中间会有很多IP我们要购买,没钱怎么整,社区找现成的,low点,能用。

因为我们的目标是要基于这个FPGA实现存储和网络设备的接入,那么总归是一个大点的工程,如果做的先进点实现virtio网络/存储的接入,那对于提供虚拟化的云平台将善莫大焉。


"Windows中使用overlay网络的一些方案" "2020-05-21"

引言

21世纪了,智能网卡还是贵,交换机客户没法直接买,软件技术栈都好找,性能再加强,ebpf不错,要是Windows的Linux子系统里支持这个那软裸金属方案至此可以画上一个句(分)号了。

关于如何在Windows裸金属中给用户交付流畅且易配置的云平台overlay网络,从而跟虚拟化打通,也是个最近要考虑的点。

SDN交换机与智能网卡

我们可以用国内品牌,他们也提供ovs接口,but,对于小体量的客户或者采购严格的客户就很难,仅适合自有IDC且有决心的客户。

为了使用一个功能,软件绑定就算了,硬件你还要我买你的,固定资产无法二次利用,别想了。

GRE/VXLAN(Windows)

Windows从08/12后自带了NVGRE,VXLAN的话是从16开始支持,听起来也不错,所以这个对于新晋用户是可以接受的

OVS

Windows下有ovs,但是仅支持2012后的,这样就没法解决Windows2008的问题(再过几年就不用操心这个问题了),当然主要的问题还是没有官方背书。


"使用Xilinx/Intel FPGA加速虚拟化" "2019-04-29"

UPDATE: 老王的笔记中也总结了一些关于devconf的内容。

This article is just a collection of ideas and posts.

Recently I was doing some performance-tunning of QEMU/KVM with kinds of pure-software ways. However, it ended with the existence of QEMU/KVM's process load.

I just remembered that I used to do some co-sim work with National Instruments LabView about ten years ago...(during college life...fk...I'm still young...)

Trial No.1

TBD: Start QEMU instance(s) with passthrough-ed PCI(PCI-SRIOV) devices like ethernet controller or NVMe controller designed in PCI FPGA to offload the emulated works.

Trial No.2

TBD: Start QEMU instance with devices ported to passthrough-ed PCI FPGA as many as possible, i.e. usb controller, ethernet controller and etc..(Like a dock with kinds of devices...)

But I think it will be replaced by Trial No.1.

Trial No.3

TBD: Co-Sim.

Trial No.4

SoC FPGA, as DOM0.

Trial No.5

ASIC offload with slight host management.

References

[1] Running Xilinx in QEMU, https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842060/QEMU

[2] Building Xen Hypervisor with Petalinux 2019.1, https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/99188792/Building+Xen+Hypervisor+with+Petalinux+2019.1

[3] QEMU SystemC and TLM CoSimulation, https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842109/QEMU+SystemC+and+TLM+CoSimulation


"Windows中使用eBPF" "2022-02-10"

背景

也挺有意思的,前年念叨着Windows内的SDN方案咋做,去年微软终于就搞了个eBPF for Windows,如此以来结合Windows新版本自带的NVGRE/VxLAN网络,安全组、EIP、LB啥的在纯软裸金属里都好说了。

另外,迫于适配智能与半智能网卡的压力,ZStack已经提供了ovs与linux bridge两个技术栈的网络(新建集群的时候可以选,虽然不是第一个但早些时候收到的需求确实不硬开发也忙。。),所以现在看起来一切都很合理。

当然,产品的东西跟新技术并不是什么强绑定关系,技术只是锦上添花实现产品的工具,稳定优先。

测试

编译eBPF for Windows

测试程序

VxLAN/NVGRE集成


title: "Xilinx FPGA中应用P4网络数据面编程" date: 2019-07-11 categories: - "cloud-infra" - "devices"


0. Background

As we all know, P4 is about to be the future of OpenFlow 2.0, and to achieve an totally software defined network with programmable control plane and data plane.

1. Basic Knowledge

Since we've got P4 working on X86 server

In SDN controller ONOS.

2. Software/Hardware Plant

2.1. Pureway: P4 bitstream

2.2. Easyway: P4 on PetaLinux

3. Further Exploration

虚拟桌面中通过RDMA进行GPU跨节点调用从而加速渲染

许久没关注过VDI了,一直坚持的观点就是协议要牛逼,否则就是渣。

VOI、IDV都不太行,GPU本机显示还是有些小问题,要么远程的,要么就没有虚拟化。

直到离开VDI行业三年多后发现还有这个炫酷的东西满足了当时我对单机虚拟化的期望,https://looking-glass.io,虚拟机与宿主机可以共享显示(iGPU),或者独占显示但是键鼠仍然与原生一致。

PS:ArchLinux社区万岁,这是原文

之前Intel的老板说用iGVT可以,但是仅限于Intel集显,没有可复制性。现在发现这玩意儿以后,关于边缘计算的场景真的又可以展开一些了,朋友,之前机场工控机虚拟化管理还要大屏的需求我们再聊一聊?

原理说复杂也不复杂,作者思路从被广泛采用的桌面截取(OBS、DX API、NVIDIA Stream)到共享内存(IVSHMEM),纯内存交换。

很有意义,远程桌面协议换成共享内存协议,然后可以进一步用RDMA,再配上virtio-gpu,就可以跨节点渲染了,虚拟化版本的virgl。

NVMe in the Cloud(ZStack),(适合)云原生的存储

NVMe作为新的存储协议,更能将新的存储介质的性能发挥出来,与此同时,与SCSI存储对等的NVMeOverRDMA和NVMeOverTCP也已经开始在数据中心中崭露头角(忽略FC,发展太慢了)。 传统云平台中的对这些存储设备的使用是没有任何问题的,但是在不改变存储对接架构的情况下发挥出其原生性能则是一个挑战。 关于瓶颈的问题,我们可以从不同的存储对接路径去分析。

当然,不同于公有云的机器完全自定义,硬件自己随便攒,私有云为了要达成产品化需要考虑的因素比公有云更为繁杂(当然在私有云大规模这个方向上就弱很多了)。

NVMeOverTCP的好处除了其性能之外,还有就是万兆以上线速,有多少来多少。

作为对比,我们使用Linux新版本自带的NVMe over TCP/RoCEv2 target。

硬件测试设备与软件:LightBits, Linux NVMe over TCP target, Linux NVMe over ROCEv2 target

软件测试方法:https://blogs.oracle.com/linux/nvme-over-tcp

测试客户端:100Gb x 2、25Gb x 4

测试云平台:ZStack 3.8,io_uring,spdk

对接方法:

Direct to Guest

PassThrough

DirectConnect

Via Host

Cluster Filesystem

Shared Block

ARM/X86服务器的安卓市场(虚拟化、容器)

0. 背景

随着国产化进程的推进,相当的应用已经可在国产化服务器(ARM/X86)上运行,本文将使用容器以及虚拟化两种技术对ARM/X86服务器上运行高性能的Android桌面进行探索。

调研了一圈实现,业界性价比最高的还是用板卡。。但是初始研究成本高一些,决心做的话可以先买一些现成的深圳货,但是对于入门的厂商来说还是用arm服务器跑容器合适,毕竟是安卓。

1. ARM/X86服务器

1.1. 虚拟化

使用X86服务器去虚拟化Android的厂商确实不多,社区有提供X86版本Android模,使用X86去模拟ARM版本的Android几乎没人做(效率极差)。

但是随着国内这几年ARM服务器市场上来,不少厂商早就开始探索ARM服务器去虚拟ARM版Android了,虽然效率较X86有很大提升,但是相比容器技术代价仍然很高,模拟出的手机定价低导致大家都是探索性的尝试。

1.2. 容器

这已经是一个较为成熟的技术了,但是缺点在于虚拟出的设备不完善。

Docker-Android

Anbox(LXC)

Xdroid

2. GPU

NVIDIA

Mali

3. 桌面协议

凡上上规模的Android模拟都需要成熟的桌面协议,而这又与他采用GPU设备相关。

由于qemu的ARM模拟的VGA设备由于其天生架构问题,不能正常使用,因而暂时需要使用virtio-vga设备方可显示(https://www.linux-kvm.org//blog/images/0/09/Qemu-gfx-2016.pdf)。

3.1. 带内协议

VNC

SPICE

RDP/ICA

PCoIP

3.2. 带外协议

VNC

SPICE

PCoIP--- title: "Building the infrastructure for cloud security" date: 2015-02-08 categories: - "cloud-infra"


Host TPM Attesation Mt. Wilson Geo-tag HyTrust McAfee ePO

VM management SSO SDN VLAN Firewall

VM Appliance Mystery Hill

title: "Home-based hybridcloud(家庭作坊式混合云)" date: 2017-10-24 categories: - "cloud-infra" - "linux-admin"


名字起的不好听,不过无所谓,也是混合云了,做到了什么地步呢? 在数据层面,家中机器和linode以及gcp公有云全通,任意地点的客户端可以通过局域网地址访问家中和公有云,而这一且,只需要一个公网IP。那么如何组建呢?

  1. 选择一个趁手的VPN,这里我使用的是SoftEther,全平台全功能,图形界面客户端全都有,自带域名反向解析,自带公网,又那么稳定,为啥不用。 只要在家中的一台PC上装好服务端,把5555端口通过路由器(有公网IP)映射出去即可完成VPN服务器的搭建。

  2. Linode服务器集群选择一台作为网关(边界路由器),负责作为客户端接入VPN服务器,那么它就有了192.168.0段的地址,其它机器上因为linode没有VPC的概念,所以得加条到192.168.0.0/24的路由。

  3. 总结下来,接入到home的VPN服务器会给所有客户端一个home的IP地址,然后加的路由表(使linode集群的10段暴露出去)都围绕这个地址展开达到互通的目的。

  4. 目前我把linode上分散在全球8个机房的私有服务器都加了进来,当然,安全线路。尝试了一次kcptun加速VPN连接,但是linux下失败了,windows成功。

这是图,PC-Server为VPN服务器,LINODE为公有云,也加入了Google的公有云进去(没画),Windows-PC为个人服务器。

联通之后,Google的CDN、DNS可以混合到Linode去使用了,再展开点,大数据、数据库都可以结合Linode去跑了。

Agent based modeling相关


TensorFlow in NetLogo, Make Your Agent More Intelligent

0. Background

NetLogo is a very useful tools for ABM, and Python is also a handful language for building proof of concept.

In this post I will show you how to call python language in NetLogo. For more information please follow here.

1. NetLogo version

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
breed [data-points data-point]
breed [centroids centroid]

globals [
  any-centroids-moved?
]

to setup
  clear-all
  set-default-shape data-points "circle"
  set-default-shape centroids "x"
  generate-clusters
  reset-centroids
end

to generate-clusters
  let cluster-std-dev 20 - num-clusters
  let cluster-size num-data-points / num-clusters
  repeat num-clusters [
    let center-x random-xcor / 1.5
    let center-y random-ycor / 1.5
    create-data-points cluster-size [
      setxy center-x center-y
      set heading random 360
      fd abs random-normal 0 (cluster-std-dev / 2) ;; Divide by two because abs doubles the width
    ]
  ]
end

to reset-centroids
  set any-centroids-moved? true
  ask data-points [ set color grey ]

  let colors base-colors
  ask centroids [die]
  create-centroids num-centroids [
    move-to one-of data-points
    set size 5
    set color last colors + 1
    set colors butlast colors
  ]
  clear-all-plots
  reset-ticks
end

to go
  if not any-centroids-moved? [stop]
  set any-centroids-moved? false
  assign-clusters
  update-clusters
  tick
end

to assign-clusters
  ask data-points [set color [color] of closest-centroid - 2]
end

to update-clusters
  let movement-threshold 0.1
  ask centroids [
    let my-points data-points with [ shade-of? color [ color ] of myself ]
    if any? my-points [
      let new-xcor mean [ xcor ] of my-points
      let new-ycor mean [ ycor ] of my-points
      if distancexy new-xcor new-ycor > movement-threshold [
        set any-centroids-moved? true
      ]
      setxy new-xcor new-ycor
    ]
  ]
  update-plots
end

to-report closest-centroid
  report min-one-of centroids [ distance myself ]
end

to-report square-deviation
  report sum [ (distance myself) ^ 2 ] of data-points with [ closest-centroid = myself ]
end

; Copyright 2014 Uri Wilensky.
; See Info tab for full copyright and license.

2. TensorFlow version

TensorFlow version: 1.14

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import numpy as np
import tensorflow as tf

num-points = 100
dimensions = 2
points = np.random.uniform(0, 1000, [num-points, dimensions])

def input-fn():
  return tf.compat.v1.train.limit-epochs(
      tf.convert-to-tensor(points, dtype=tf.float32), num-epochs=1)

num-clusters = 5
kmeans = tf.contrib.factorization.KMeansClustering(
    num-clusters=num-clusters, use-mini-batch=False)

# train
num-iterations = 10
previous-centers = None
for - in xrange(num-iterations):
  kmeans.train(input-fn)
  cluster-centers = kmeans.cluster-centers()
  if previous-centers is not None:
    print 'delta:', cluster-centers - previous-centers
  previous-centers = cluster-centers
  print 'score:', kmeans.score(input-fn)
print 'cluster centers:', cluster-centers

# map the input points to their clusters
cluster-indices = list(kmeans.predict-cluster-index(input-fn))
for i, point in enumerate(points):
  cluster-index = cluster-indices[i]
  center = cluster-centers[cluster-index]
  print 'point:', point, 'is in cluster', cluster-index, 'centered at', center

3. NetLogo with Python Extension version

Here's the snapshot.

And here's the code.

extensions [ py ]

breed [data-points data-point] breed [centroids centroid]

data-points-own [ cluster-id ]

centroids-own [ cluster-id centx centy ]

globals [ testoutput centroid-list ]

to setup clear-all py:setup py:python (py:run "import tensorflow as tf" "import numpy as np" ) set testoutput py:runresult "1" py:set "testoutput" testoutput set-default-shape data-points "circle" set-default-shape centroids "x" generate-clusters ; For python py:set "num-points" num-clusters py:set "points" [list xcor ycor] of data-points py:set "num-clusters" num-clusters py:set "num-round" num-round if debug = True [ py:run "print('Points Cordinates:', points)" ;for debug ] ;reset-centroids end

to generate-clusters set testoutput py:runresult "testoutput + 1" let cluster-std-dev cluster-range let cluster-size num-data-points / num-clusters repeat num-clusters [ let center-x random-xcor / 1.5 let center-y random-ycor / 1.5 create-data-points cluster-size [ setxy center-x center-y set heading random 360 fd abs random-normal 0 (cluster-std-dev / 2) ] ] end

to train ; Cluster center (py:run "points = np.asarray(points)" "def input-fn():" " return tf.compat.v1.train.limit-epochs(tf.convert-to-tensor(points, dtype=tf.float32), num-epochs=1)" "kmeans = tf.contrib.factorization.KMeansClustering(num-clusters=num-clusters, use-mini-batch=False)" "num-iterations = num-round" "previous-centers = None" "for - in range(num-iterations):" " kmeans.train(input-fn)" " cluster-centers = kmeans.cluster-centers()" " if previous-centers is not None:" " print(('delta:', cluster-centers - previous-centers))" " previous-centers = cluster-centers" " print(('score:', kmeans.score(input-fn)))" "print(('cluster centers:', cluster-centers))" "# map the input points to their clusters" "cluster-indices = list(kmeans.predict-cluster-index(input-fn))" "print('cluster indices: ', cluster-indices)" "for i, point in enumerate(points):" " cluster-index = cluster-indices[i]" " center = cluster-centers[cluster-index]" " print(('point:', point, 'is in cluster', cluster-index, 'centered at', center))" ) end

to show-shape set centroid-list py:runresult "cluster-centers" foreach centroid-list [ x -> create-centroids 1 [ set xcor ( item 0 x ) set ycor ( item 1 x ) set size 3 set color white ] ] end

Ref:

[1] https://www.altoros.com/blog/using-k-means-clustering-in-tensorflow/

[2] https://www.tensorflow.org/api-docs/python/tf/contrib/factorization/KMeansClustering

Filecoin 搭建

本文旨在避坑,本人作为矿工时期会保持更新。

1. 硬件与存储配置

需要的机器整体分为三种,包括主节点lotus(同步主网)、矿工节点miner()

管理节点(node200)

  • CPU Intel 4110R x 2

  • 内存128G

  • 无限卡

  • 128G系统盘(M.2)

主节点与矿工节点(node201)

  • CPU Intel 4110R x 2

  • 内存256G

  • 无显卡

工作节点1(node202)

  • CPU Intel 4110 x 2

  • 内存372G

工作节点2(node203)

  • CPU AMD 7302 x 2

  • Driver: NVIDIA-Linux-x86_64-460.91.03.run

2. 编译

我们需要根据不同的CPU型号来编译不同的二进制文件,源码文件建议放在共享目录中,如果机器数量足够多二进制文件也需要单独存放减少编译负担。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/bin/bash
set -x
VERSION=v1.11.1
source /root/env-lotus
source /root/env-proxy
#curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
#wget -c https://golang.org/dl/go1.16.7.linux-amd64.tar.gz -O - | sudo tar -xz -C /usr/local
#echo "export PATH=$PATH:/usr/local/go/bin" >> ~/.bashrc && source ~/.bashrc

cd /filecoin/cache/build/lotus
make clean
git checkout master
git pull
git checkout $VERSION
git submodule deinit --all
git submodule update --init
# Some older Intel and AMD processors WITHOUT the ADX instruction support may panic with illegal instruction errors.
LSCPU=$(lscpu|grep -i adx)
if [[ $? == 0 ]]
then
    echo "Instruction ADX detected."
else
    export CGO_CFLAGS_ALLOW="-D__BLST_PORTABLE__"
    export CGO_CFLAGS="-D__BLST_PORTABLE__"
fi
# If you have an AMD Zen or Intel Ice Lake CPU (or later), ENABLE the use of SHA extensions by adding these two environment variables:
LSCPU=$(lscpu|grep -i ' sha')
if [[ $? == 0 ]]
then
    echo "Instruction SHA detected."
    export RUSTFLAGS="-C target-cpu=native -g"
    export FFI_BUILD_FROM_SOURCE=1
fi
make -j16
make lotus-bench
make install
export https_proxy=

3. 分角色配置

主节点与矿工节点(node201)

这里我们的主节点与矿工节点使用同一台主机,其环境变量配置如下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
export BELLMAN_CPU_UTILIZATION=0.875
export FIL_PROOFS_MAXIMIZE_CACHING=1
export FIL_PROOFS_USE_GPU_COLUMN_BUILDER=0
export FIL_PROOFS_USE_GPU_TREE_BUILDER=0
export FIL_PROOFS_USE_MULTICORE_SDR=1
export FIL_PROOFS_SDR_PARENTS_CACHE_SIZE=1073741824
#export RUST_BACKTRACE=full
#export RUST_LOG=debug

export FULLNODE_API_INFO="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJyZWFkIiwid3JpdGUiLCJzaWduIiwiYWRtaW4iXX0.Wq0nVk1xEpwsrQhfxpk2Vb5lBS07NeJ6o4ZJRGoQuic:/ip4/192.168.0.101/tcp/1234/http"
export MINER_API_INFO="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJBbGxvdyI6WyJyZWFkIiwid3JpdGUiLCJzaWduIiwiYWRtaW4iXX0.c6SQus7UjC4rh-OKhi45f3RGr9UyH8jURrDsA521ZQ8:/ip4/192.168.0.101/tcp/2345/http"

export LOTUS_PATH=/filecoin/data/node/ # When using a local node.
export LOTUS_MINER_PATH=/filecoin/data/miner/
export LOTUS_WORKER_PATH=/filecoin/data/worker/

export FIL_PROOFS_PARAMETER_CACHE=/filecoin/cache/parameter/
export FIL_PROOFS_PARENT_CACHE=/filecoin/cache/parent/
export TMPDIR=/filecoin/cache/tmp/


export IPFS_GATEWAY=https://proof-parameters.s3.cn-south-1.jdcloud-oss.com/ipfs/
export GOPROXY=https://goproxy.cn

3. 测试

1
编译完成后,需要对机器的能力进行简单测试,防止某些配置情况导致

3. 过程控制

虽然lotus的调度过程非常的傻,网上也有不少的文章都说对lotus的封装调度进行了优化,但是它一般是建立在机器数量较多的前提下,对于数量较少单个机器同时承载多个角色的情况,我们可以观察每个扇区在不同过程的表现来进行适当控制。

每个扇区在不同过程的消耗可以参考Task resource table。封装整体分为PreCommit与Commit两个过程,每个过程中又有两个不同阶段。其中,P1扇区可以并发,P2可以并发但会独占某个GPU,C1过程很快且可以并发,C2过程独占某个GPU且会排斥除AP外的其他任何新增阶段。

以扇区作为sectorsAgent,机器作为workerAgent,那么我们先定义sectorAgent的行为(为方便计算,假设每个扇区封装过程中占用空间为500G,不同的lotus版本、机器配置扇区封装过程表现的现象可能不同)。

1
2
3
4
5
6
sectorAgent:
AP -> P1(6h, 60G MEM) -> P2(2h, 20G MEM, GPU, Parallel) -> PreCommitAggregate -> C1(0.5h, 1G MEM) -> C2(1-2h, 200G MEM, only Parallel with GPU) -> SubmitCommitAggregate -> Submit

workerAgent:
Worker1(CPU only, 376G MEM)
Worker2(wtih GPU, 1T MEM)