11月4日,开放基础设施峰会在上海世博中心隆重召开,会议第一天就成功吸引数千名集聚一堂,共同构建用户所需的开源基础设施以支持在边缘计算、持续集成/持续交付(CI / CD)、人工智能(AI)、高性能计算(HPC)等领域的应用。与往届一样,小编会从参与者的角度为大家带来重要的会议信息,今天将第一天主论坛的精彩内容分享一二。


本次Open Infrastructure summit是从第一次奥斯丁峰会以来首次登陆中国大陆,国内的云厂商做东,在本次的赞助商中,国内的云厂商也占据了半壁江山,九州云作为黄金会员给与了基金会大力的支持。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


市场预测:用数据说话


在当前的中美关系的背景下,基金会坚持把峰会举办地点定在了上海,说明基金会更加关注亚洲的市场,更加关注OpenStack在中国的发展。在面对市场上“唱衰”OpenStack的噪音,本次峰会给出了大量的统计数据,本次峰会的Keynote上,基金会预测到2023年亚太地区的OpenStack市场体量还会再增加36%。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


并且,基金会预测到了2023年全球商业规模将达到7.7Billion USD的市场,这证明了在开源的基础设施架构的整个体量来说,还是非常巨大的。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


Open Infra集成了容器和OpenStack,在容器市场蓬勃发展的同时,也带动了OpenStack的发展,两者全球合并的市场规模在2023年将达到12billion的规模。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


另外,基金会给出了这几年OpenStack市场的规模,从2015年的1.27Billion,到今年2019年的3.39Billion,以及在规模了有了巨大的增加,另外下图还预测了从2019年的市场规模到2023年的增加预测,即OpenStack市场的规模在下一个4年会持续增长,并且会比2019年的市场规模增加一倍之巨。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


基金会给出了一个统计,目前OpenStack已经管理了上千万个计算内核,而且还在不断增长,图中是使用了OpenStack服务的用户,OpenStack作为全球前三的开源组织,经过多年社区运营和开发人员的努力,逐渐成为了云计算操作系统的标准,取得了市场的认可和用户的信任。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


坚持开源,开源推动创新


OpenStack还会继续坚持开源,秉承着“开源推动创新”的理念,开源才能聚集全球大量优秀的开发者,开源才能赋能产品的持续创新能力,开源才能满足自主可控取得用户的信任。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


在最新版本Train项目上,来自各个国家的贡献者,来自中国的贡献者已经非常接近于美国了,正是基金会看到了大量优秀的来自中国的开发人员,由此在上海举办的峰会上重点强调中国的市场和贡献者是不容忽视的,正是大量的来自中国的开发者和优秀的案例,才能保证OpenStack社区持久的活力。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


媲美公有云


OpenStack除了适用于私有云,其实目前来说,OpenStack具备了公有云的成熟的能力,在全球范围来说,OpenStack已经成功帮助了70多个数据中心提供了公有云的解决方案,这证明了OpenStack拥有不输于商业产品的稳定性和高可用性。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


欧洲核子研究组织CERN


CERN很早就将IT的基础设施架构采用了OpenStack进行管理,目前云平台的规模已经上升到291.4k个物理CPU核。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


国内三大运营商同台分享


本次峰会最大的特点是中国的三大运营商中国电信、中国移动、中国联通同台介绍OpenStack给运营商带来了哪些好处,主要是针对OpenStack开放架构和强大的社区开发能力,并且可以增加IT资源的利用效率,特别是近两年,面对5G、边缘计算旺盛的需求,三大运营商都在研究StarlingX边缘计算项目,并且也在展开一些试点。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


三大顶级项目最新动态


Airship是一组用于自动化云配置和管理的开源工具。Airship提供了一个声明性框架,用于定义和管理开放式基础架构工具和底层硬件的生命周期。这些工具包括用于虚拟机的OpenStack,用于容器编排的Kubernetes和用于裸机的MaaS,并计划支持OpenStack Ironic,即Airship是一种管理工具,可以用于管理数据中心中目前繁杂的裸机、IaaS、PaaS平台。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


kata containers是由OpenStack基金会管理,但独立于OpenStack项目之外的容器项目。它是一个可以使用容器镜像以超轻量级虚机的形式创建容器的运行时工具。百度利用Kata管理了大量的容器来对外提供服务,并为百度节省了大量的IT资源。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


StarlingX 2.0通过实现集成OpenStack和Kubernetes强化平台的交付,为混合工作负载提供灵活性、稳健性以及相关支持,进而利用构建块来构建开源基础设施。


九州云黄舒泉作为技术委员会成员介绍了“StarlingX项目旨在为边缘计算重新配置经过验证的云技术,在大规模分布式计算环境中提供成熟且稳健的云平台。StarlingX是适用于裸机、虚拟机和容器化部署环境的完整边缘云基础设施平台,适用于对高可用性(HA)、服务质量(QoS)、性能和低延迟等有严格要求的应用场景。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?



END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。


开放基础设施上海峰会 | 中国首秀会送出哪些重磅内容呢?


点击“阅读原文”,了解九州云议题详情!


《赋能故事》编者按:

从云计算到边缘计算,九州云始终相信“开源·赋能变革”。7年时间里,九州云不断突破和超越,用开源技术创造了一个又一个精彩的赋能故事。

2019年10月,九州云《赋能故事》系列正式推出,我们将用一个个经典的客户案例故事,为您展现不一样的九州云产品、不一样的九州云服务。

 

曾几何时,股票是人们发财和一夜暴富的手段,那时的人们用拷克箱来装实物股票,数目大的股民需要用麻袋装实物股票到交易所办理转让过户手续……

 

曾几何时,办理交易的人们需要到窗口排队,远远望去像极了一条条“长龙”,场面十分壮观,那时的交易工作需要大量的人力来完成……

 

曾几何时,中国的证券行业正处于熊市,那时电话委托、网上交易取代了传统的交易方式,券商的IT工程师们“马不停蹄”地奔走于各大城市,调研自己所在券商公司各地营业厅的交易以及系统运行情况,一轮又一轮扩容相应的IT系统……

 

而今,对于跃然云上的华金证券来说,那样的日子已经一去不复返了。

赋能故事 | 3年匠心“智”造,铸就华金证券上云梦

华金证券股份有限公司(以下简称:“华金证券”)前身是设立于2000年9月的上海久联证券经纪有限责任公司,而后经历引进战投、增资扩股、股份改制等一系列事宜,2016年12月正式更名为华金证券。作为一家拥有全牌照的综合性证券公司,华金证券业务范围涵盖证券承销与保荐、证券资产管理、证券经纪、证券自营、另类投资等诸多领域。

 

目前,华金证券业务主要依托股票期权、沪港通、期货、私募、债券投资、新三板、投资银行等板块,重点围绕“三大引擎+两大支撑”,即:以固定收益、资产管理、投资银行为主导业务,以经纪(含融资融券)、研究销售为核心支撑业务,立足沪上金融制高点,依托珠海横琴区位、政策优势,欲通过创新与互联网金融的发展方向,走出一条多元化、国际化的道路,然而证券企业的创新之路并不好走。

 

“互联网+”带来的“焦虑” 用私有云“破局”

 

2016年前后,“互联网+”概念引发了全民狂欢。所谓“互联网+”就是“互联网+各个传统行业”,但这并不是简单的相加,而是利用信息通信技术以及互联网平台,让互联网与传统行业进行深度融合,创造新的发展生态。证券作为金融业的大龙头,自然也被推向了“互联网+”的风口,众多公司把一部分业务搬到了线上,例如网上开户、网上金融商场等,华金证券也在“互联网+”的浪潮下,不断利用最新技术升级产品和业务,从而提升用户体验。

 

然而,“互联网+”犹如硬币的正反两面,给用户带来良好体验的同时,对行业的技术架构也提出了新的要求:产品迭代越来越快、交易量峰值无法预测等挑战要求证券企业必须尽快利用IT技术提升自身信息化水平,这时候,云计算无疑是最佳选择。

 

为什么说云计算是最优解?有数据显示,2016年前后,云计算逐步向以金融行业为代表的传统行业加速渗透,证券领域中应用私有云IaaS的企业逐年增多,加速系统上线、降低成本、提升运维效率是他们建设私有云的主要驱动力。

 

面对如此形势,华金证券结合自身业务特点,决定在上海小范围采用新型技术加速业务发展的思路下,开展内部私有云建设。在云计算飞速发展的当下,立体式的金融服务平台需要有一个强大的后端支撑平台,对于在金融投资数据服务领域快速发展的华金证券来说更是如此。

 

私有云建设之路困难重重

 

当时,华金证券对国内外现有的云平台服务做了细致的测试和对比,涉及经济性、自主可控性、未来发展趋势等多个方面,对比之后最终选择采用OpenStack技术路线来构建私有云。华金证券希望通过逐步上云的策略和开放的技术架构,建设有行业有特色的证券私有云,为集团内部提供一套完整且高效的金融IT服务能力。

 

私有云平台需要承载多个任务:为IT运维部门提供一整套完整的IT基础设施、基础IT资源管理系统,为IT开发人员和第三方解决方案厂商提供云平台标准接口,为内部业务人员和外部客户提供应用数据服务。整个云平台从架构上要符合云计算未来的建设标准,提供标准的对外接口和可扩展能力。对于华金证券来说,要建设这样一个私有云平台是有一定难度的:

 

首先是云平台的部署和扩展方面,华金证券将建设互联网金融业务云平台,如何通过该平台为金融行业提供互联网金融业务开展所需的软件服务、基础架构服务;

 

其次是定制化开发服务方面,如何缩短系统开发周期、实现产品的快速迭代,最大程度地满足市场需求和用户体验;

 

再次是计费计量方面,如何根据客户的使用量进行按需计费和计量,实现按需的弹性资源供给;

 

最后是高标准运维支持服务(SLA:99.99%)方面,如何确保各计算节点和控制节点在交易时段内全年累计达到99.99%的可用性。

 

除了面对上述困难之外,华金证券内部也缺乏专业的技术人员,处理云平台日常运维管理中存在的问题。

 

基于九州云解决方案打造健壮的私有云平台

 

为了解决上述难题,华金证券找到了九州云。根据华金证券云平台的建设成本、开放架构以及所面临的难题,九州云为其提供了一套高效的解决方案:从物理层、虚拟化层、管理层、业务层、运维监控层和用户层面,以OpenStack核心组件为基础进行管理,通过分期建设的方式,帮助华金证券逐步构建私有云平台。

 

第一阶段采用 OpenStack 成熟的模块,把计算虚拟化、存储虚拟化进行统一管理,并结合开源的监控工具完成对整个私有云业务系统的监控。整个云平台从资源上通过OpenStack管理平台整合了原有的计算、存储、网络的管理,为华金证券的业务提供了标准的IaaS的API服务。通过九州云的Animbus服务门户,让管理员可以通过统一门户为企业IT管理人员提供自助服务。整个私有云平台在构建初期就考虑到平台的稳定性,云控制部分采用多节点、高可用的方式,整体解决方案遵循以下设计原则:

 

计算资源池资源池架构标准化与充分整合以降低运维成本,提高资源池的运行保障效率,通过资源池的设计实现计算资源弹性化,缩短服务部署时间以提升业务竞争能力。从安全可靠、适应性、可扩展性、实用性、先进性、高效性、标准化、易管理的角度出发,通过业界领先的方法论和对金融行业应用业务的理解,并参照金融业界最佳实践经验来规划计算资源池。

 

存储资源池根据金融业务的特点,存储资源池的设计需要从数据安全性、性能以及可扩展性进行设计,遵循架构灵活性、易管理、资源调配统一性和便捷性、数据保护性、存储层次化,多样性等原则。存储资源池的设计需要纳管传统商业存储(例如:SAN、NAS),同时需要在扩展性方面对软件定义、分布式存储作为业务的扩展,实现多种存储的统一设计和统一管理。

 

网络资源池采用“先分层,后分区”的设计思路,根据不同业务功能区域的隔离需求,整个网络系统按照整体业务流向划分为外联接入层、网络交换层、核心网络层、存储区域层。同时,为了更好的支持云平台的运行管理,将网络分为服务、业务、管理3个网络平面,通过层与平面结合形成7个区域,各业务区域之间实现网络逻辑隔离,有利于系统的拓展,也便于日后的运维管理,同时也为业务的拓展奠定基础,只需增加相应功能区域的设备就可以满足新业务的网络通讯需求。

 

另外,证券企业有大量的业务系统需要和硬件的USB-KEY进行通讯,在本方案中,需要把原有的USB-KEY的业务系统逐步迁移到整个私有云平台上。考虑到今后对USB-KEY的统一管理,在私有云平台控制节点上接入应用平台所需要的USB-KEY,通过IP网络挂载给私有云平台的虚拟机,从而提供基于KEY的安全认证。考虑到USB-KEY业务的连续性,在两个控制节点同时具备接入USB-KEY的能力,在必要的情况下,可以切换USB-KEY到备份节点。

 

在云平台运维方面,通过Zabbix+ELK的方式,从物理设备、基础OpenStack 服务、存储服务等多个维度对整个平台的监控状况做一个合理的评估,并通过Grafana为运维人员提供统一的监控展现平台。

 

在上述设计原则的指导下,华金证券IaaS基础支撑云平台整体高可用架构的设计如下图所示:

 

赋能故事 | 3年匠心“智”造,铸就华金证券上云梦

IaaS基础支撑云平台整体高可用架构设计图

 

如上图,华金证券云平台底层基于计算存储融合的x86服务器以及网络交换设备的部署,通过虚拟化技术整合,基于超融合架构,实现计算资源池、存储资源池和网络资源池构建。超融合技术将x86服务器的本地存储资源汇集成统一的存储资源池,通过网络路径冗余、网络分平面设计、存储多副本、小IO聚合、自动负载均衡等高可用技术实现高可靠的云计算资源池建设;上层通过云资源管理平台建设实现用户管理、运维和运营管理、开发管理、安全管理、日志管理以及计费管理等功能。通过IAAS云平台提供的云主机或容器以支撑上层业务系统相关模块的部署和运行。

 

云平台计算资源通过虚拟化管理软件实现资源池化,主要用于提供CPU、内存等计算资源以承载业务应用,基于硬件服务器自身的双电源、RAID卡等机制实现设备的高可用性。

 

云平台存储资源IaaS云架构实现存储和计算资源的融合,即每台x86服务器既是计算节点,又是存储节点,通过分布式存储引擎将每台节点机本地不同访问速率的硬盘融合成全局的存储资源池,用于存放云主机镜像以及业务数据等;通过分布式存储引擎构建的存储资源池具备分布式架构,通过软件定义方式实现分布式集群HA、分布式无状态机头、分布式智能Cache(冷热数据分离)及数据的多副本存取机制。

 

云平台网络资源每台IaaS管理服务器和计算服务器的万兆和千兆网卡和外置的万兆以及千兆以太网交换机提供云平台的高冗余网络架构。

 

云平台管理用于对云平台的资源池进行统一的调度和管理,以HA方式部署在管理节点服务器组成的集群上。云管理可对资源池中所有节点上的资源进行统一管理并提供web接口给管理员和用户,以实现访问门户的负载均衡和高可用。

 

全方位提高经济效益和业务效率

 

IaaS云平台上线之后,华金证券的研发测试系统、部分交易系统、办公系统逐步迁移到了该平台上。由于最初选择采用九州云提供的云平台解决方案,在过去3年多的时间里,IaaS云平台给华金证券带来了巨大的经济效益,与此同时,公司的业务效率也得到了全面提升:

 

资源使用率得到大幅度提升以传统开发测试环境为例,服务器CPU使用率通常不足10%(业界平均),而通过云平台虚拟化以及资源共享调配的手段可以将CPU使用率提高到60%以上,同时也提高了空间、能源的使用效率。

 

应用部署效率得到有效提升在传统开发测试中,大量工作花费在基础设施供应上,而通过云平台自动化实现了自动供应,将原来数周的供应时间降为数分钟,极大提高了应用部署上线时间,减少工作量的同时,缩短了新业务上市周期,从而使得华金证券的业务在竞争中夺得先机。

 

解放人力,提升了单位人工生产力由于云平台采纳了自动化方式,以机器替代了人工工作,从而提升了部分工作效率。另外,通过自助化方式的申请资源,相当于将许多基础设施工作“众包”给最终用户,不但减少了中间环节,还极大解放了运维人员的生产力,把他们从繁重的重复劳动中解放出来,投入到更加高附加值的工作中去,资源得到了合理配置。

 

IT管理水平得到大幅度提升云平台通过统一自助门户管理资源,所有管理方法通过流程化手段固化,使得管理理念得以贯彻落实,降低了由于传统IT管理中存在的“灰色地带”而导致的资源浪费。此外,人员知识技能以自动化脚本的方式被重复使用,降低了企业的人力资源成本。由于云平台自带配置管理、告警、报表和仪表盘工具等,这为IT运维和管理辅助决策提供了现成的工具。

 

提升IT合规水平,降低了风险发生的概率由于云平台采纳了自动化、流程化等辅助手段减少了人工操作,从而降低了由于人工失误带来的潜在风险。有了标准化流程保障,使得人为违规的可能性降低,再次降低了风险发生的概率,从而降低了企业所需承担风险的隐性成本。

 

如今,云计算已经成为证券机构“技术引领业务”转型中的推动者,华金证券上云的案例为其他证券机构上云提供了有效借鉴。在过去3年多的时间里,九州云在为华金证券提供服务的同时,也见证了其一步一脚印踏入云端的辛路历程。未来,九州云在不断进行技术创新的同时,把以往累积的丰富经验和能力输出给更多行业客户,最大限度地发挥自身价值,为更多行业赋能。

 

 

END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。

赋能故事 | 3年匠心“智”造,铸就华金证券上云梦

点击“阅读原文”,了解九州云更多信息!

2019年9月20日,边缘计算深度交流会StarlingX2.0发布庆功会将在北京举行,Intel、风河、烽火、九州云、联通云、联通研究院、中国移动、中国银联等企业均出席,并带来精彩分享。欢迎扫描二维码进行注册,报名参与本次活动。


边缘计算深度交流会StarlingX2.0发布庆功会



END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。


边缘计算深度交流会StarlingX2.0发布庆功会


点击“阅读原文”,了解StarlingX 2.0版本!



StarlingX社区发布2.0版本!


StarlingX,一个专注于对低延迟和高性能应用进行优化的开源边缘计算及物联网云平台,今天正式发布其2.0版本。2018年发布的StarlingX 1.0在专用物理服务器上提供了强化的OpenStack平台,StarlingX 2.0通过实现集成OpenStack和Kubernetes强化平台的交付,为混合工作负载提供灵活性、稳健性以及相关支持,进而利用构建块来构建开源基础设施。


点击文末“阅读原文”,

或登陆官网 git.starlingx.io/starlingx

可下载StarlingX 2.0


StarlingX项目旨在为边缘计算重新配置经过验证的云技术,在大规模分布式计算环境中提供成熟且稳健的云平台。StarlingX是适用于裸机、虚拟机和容器化部署环境的完整边缘云基础设施平台,适用于对高可用性(HA)、服务质量(QoS)、性能和低延迟等有严格要求的应用场景。


StarlingX通过利用Ceph, Linux, KVM, OpenStack和Kubernetes等其他开源项目的组件,并通过添加配置和故障管理等服务对这些组件加以完善,可同时满足运营商和行业应用对边缘计算的严格要求。应用案例包括基于交通运输的物联网应用,工业自动化,5G,智能建筑与智慧城市,自动驾驶,定位零售业,虚拟化无线接入网络(vRAN),增强现实和虚拟现实,高清媒体内容分发,监测,医疗成像、诊断和监测,以及通用型客户终端设备(uCPE)等。


  StarlingX 2.0的主要特性  

●       在专用物理服务器上集成Kubernetes和OpenStack的强化云原生平台

●       基于Stein版本的容器化OpenStack

●       容器化工作负载的边缘应用场景基于Kubernetes


StarlingX与OpenStack的代码库密切相关,随着新版StarlingX的推出,Out-of-tree补丁持续减少,并计划在今年秋季即将发布的Train版本中将其完全消除。


StarlingX社区正不断成长,今天发布的新版本包含来自132位贡献者的2365次代码提交,其中包括来自九州云、中国银联、烽火、英特尔、InerDynamix、红帽、SUSE和风河等企业的开发者。诚挚邀请业内用户、运营者和开发者们试用新版软件,并加入StarlingX社区的IRC(Freenode上的#starlingx)和邮件列表(lists.starlingx.io),进行及时的社区交流与反馈。


了解StarlingX社区在开源基础设施上海峰会的活动日程

StarlingX社区成员将齐聚11月4-6日在上海举行的开源基础设施峰会,

  相关峰会议题如下  

●       一种可协助进行目标识别的边缘框架(Joy Liu, Ruoyu Ying, Shane Wang)

●       中国联通采用边缘编排系统在5G环境中管理StarlingX、K8S及OpenStack边缘数据中心(Dan Chen, Li Kai, Wei Hu)

●       扩展:边缘计算工作组更新(Beth Cohen, David Paterson, Gergely Csatari, Ildiko Vancsa, Shuquan Huang)

●       中国电信运营商眼中的边缘计算(Dan Chen, Shuquan Huang, Qihui Zhao, Wei Hu, Yongbing Fan)

●       如何实现电信运营商多异构边缘云的协同与管理(Shuquan Huang, Tao Jiang, Qihui Zhao)

●       StarlingX:边缘硬件加速驱动的网络策略(Chenjie Xu, Yingnan Chen)

●       非接触式支付系统的安全边缘基础设施(Haitao Wang, Lijun Zu, Yih Leong Sun)

●       可支持Kubernetes和/或OpenStack边缘云的StarlingX混合分布式云平台(Brent Rowsell, Greg Waines)

访问以下链接,详细了解StarlingX社区在开源基础设施上海峰会的活动日程:

https://www.starlingx.io/blog/starlingx-shanghai-schedule-blog.html


业内评价

九州云 – 黄舒泉, 解决方案架构总监:

“5G正成为现实,很开心看到StarlingX 2.0的发布,现在正是采用StarlingX构建边缘云基础设施平台实现5G低延迟和高性能应用的好时机。九州云将持续为StarlingX社区做贡献,助力5G部署。”


英特尔 – Mark Skarpness, 数据中心系统栈工程总监,英特尔架构、图形及软件部副总裁:

“StarlingX社区自成立以来已在短时间内取得了显著进展,在将项目代码库与OpenStack Stein进行融合的同时,还添加了新的功能。StarlingX 2.0将云原生服务带到边缘计算,不仅消除了技术债,还为边缘计算的持续创新创建了一个高效能的平台。”


OpenStack基金会 – Iidiko Vancsa,生态技术主管:

“运行和管理混合工作负载对边缘环境至关重要。新的StarlingX平台是一个很好的应用实例,OpenStack服务在容器化平台中应用的同时,还可提供统一的接口来管理最适合您的边缘应用程序的工作负载类型。”


风河 – Glenn Seiler,开源战略副总裁:

“这是StarlingX项目的一个关键里程碑,在那些对基础设施有严格要求的行业看来,边缘云技术向前迈出了重要一步。StarlingX现在可为有低延迟需求的分布式边缘云用例交付容器和基于VM的工作负载。风河致力于与社区合作,进一步推动边缘云技术的发展。”


关于StarlingX

StarlingX是一个专注于对低延迟和高性能应用进行优化的开源边缘计算和物联网云平台,提供可伸缩的、高度可靠的边缘基础设施,已经过测试,可作为完整的软件栈使用。其应用范围包括工业物联网、电信、视频传输以及其他有超低延迟要求的应用领域。StarlingX可兼容不同的开源组件,可为故障管理和服务管理提供独特项目组件,以确保用户应用程序的高可用性。StarlingX代码库蓄势待发,随时准备部署边缘计算可扩展解决方案。

该项目由OpenStack基金会托管,更多StarlingX详情请访问www.starlingx.io


Nova Conductor


Conductor 服务作为 Nova 核心部件之一最初在 Grizzly 版本中发布,在整个 Nova 中充当着组织者的角色。主要提供了 3 个功能:


  • nova-conductor 连接了 nova-api、nova-compute 和 nova-scheduler 服务,提供了 长时任务编排(Task Orchestration)功能。Nova 将所有耗时长,跨节点,易出错但相对固定的处理流程抽象成 Task,包括启动虚拟机、冷迁移和热迁移等。Conductor 作为 Task 的组织者,在执行 Task 的时候 Conductor 会一直追踪它的状态,并且能够执行错误处理、恢复等一系列工作。


  • nova-conductor 为 nova-computee 提供了 数据库的代理访问机制。因为计算节点是 OpenStack 云环境中与用户业务接触最近、数据最多、最容易被攻击的目标,所以 nova-compute 被设计成无法直接访问数据库,以此来保障数据库的安全。


  • nova-conductor 为版本较旧的 nova-compute 提供了 数据库版本向下兼容性。OpenStack 作为一个分布式系统,不同的服务可能运行在不同的代码版本上,在这些模块通信的过程中,Conductor 为传输的数据对象提供了版本兼容功能。让处于不同版本的 Nova 服务能够识别 RPC 请求中数据对象的版本,并完成不兼容的对象转换。但需要注意的是,这种兼容性是向下的。


Conductor 的代码包目录结构


  1. [root@localhost nova]# tree conductor/

  2. conductor/

  3. ├── api.py

  4. ├── __init__.py

  5. ├── manager.py

  6. ├── rpcapi.py

  7. └── tasks

  8. ├── base.py

  9. ├── __init__.py

  10. ├── live_migrate.py

  11. └── migrate.py


其中,在 manager 模块中主要实现了 ComputeTaskManager 任务编排封装类和 ConductorManager 数据库访问代理封装类。


数据库访问代理机制


Conductor 实现的数据库访问代理机制带来的好处:


  • 为 nova-compute 服务的数据库访问提供了一层额外的安全保障。


  • 在保证 Conductor API 兼容性的前提下,数据库 schema 升级的同时不需要升级 nova-compute 的代码版本。


  • nova-compute 可以通过创建多个协程来使用非阻塞的 nova-conductor RPC 调用。


需要注意的是,nova-conductor 作为代理服务成为了 nova-compute 访问数据库速度的瓶颈,好在由于 Conductor 服务是无状态服务,所以在性能和稳定性要求较高的环境中可以任意横向扩展 Conductor 节点的数量。


Versioned Object Model 机制


Versioned Object Model(版本化对象模型)机制在 Icehouse 版本被引入。Object Model 将每一张数据库表都与一个 Object 对应,将对数据库表的操作都封装到 Object 实例中,需要通过 Object 实例来进行数据库的操作。这听起来了 ORM 很相似,但实际上 Object Model 是比 ORM 更上一层的封装。ORM 只是单纯将数据库表结构映射成为了一个 Python 对象,但 Object Model 是在此之上做了更多的数据库操作实践和优化,Object Model 使用面向对象的思想对数据进行了封装,并为封装的数据提供了数据库代理、RPC 向下版本兼容、流量优化等一些列高级特性。


  • Nova 数据库访问方式与对象构建过程解耦:Object Model 支持 remote 和 local 两种数据库访问方式,并非成功构建了 Object 就可以直接操作数据库,在 nova-compute 中通一个 Object 来执行数据库操作实际上是远程的,是一种间接的数据库访问。这是实现数据库访问代理功能的关键。


  • nova-compute 和数据库的在线升级:nova-compute 通过 RPC 传递 Object 到 nova-conductor 时,Object 会维护一个版本号。假设 nova-compute 传递的是一个低版本的 Object,那么 nova-conductor 就会对该 Object 进行版本兼容处理,使得低版本的 Object 也能如常对高版本 DB schema 进行操作。


  • 对象属性类型的声明:Python 是一门动态的强类型解释语言,Python 不具有对象类型声明语句,这是 Python 轻便简单的根本,也是 Python 难以支撑开发超大型项目的病因。在 Web API 层面,我们可以通过 validation.schema 和 view_builder 来严格规范输入、输出的数据结构。而在后端程序的内部实现,我们则可以通过 Object Model 来实现对 Object 每个属性字段的类型声明,这帮助我们编写出来的程序具有更好的可读性和稳定性。


  • 减少写入数据库的数据量:Object Model 支持增量更新数据库记录属性值,而无需将整个对象的所有属性都更新一遍,每个 Object 都具有一个 _change_field 实例属性用来记录变化的值。


  1. def remotable(fn):

  2. """Decorator for remotable object methods."""

  3. @six.wraps(fn)

  4. def wrapper(self, *args, **kwargs):

  5. ctxt = self._context

  6. if ctxt is None:

  7. raise exception.OrphanedObjectError(method=fn.__name__,

  8. objtype=self.obj_name())

  9. if self.indirection_api:

  10. # indirection_api: 间接数据库访问 API,就是 conductor_rpcapi.ConductorAPI()

  11. # object_action: remotable 装饰器中调用,Versioned Object 实例通过这个方法来远程访问数据库

  12. # 相对的,object_class_action_versions: remotable_classmethod 装饰器中调用,Versioned Object 类通过这个方法来远程访问数据库

  13. updates, result = self.indirection_api.object_action(

  14. ctxt, self, fn.__name__, args, kwargs)

  15. for key, value in six.iteritems(updates):

  16. if key in self.fields:

  17. field = self.fields[key]

  18. # NOTE(ndipanov): Since VersionedObjectSerializer will have

  19. # deserialized any object fields into objects already,

  20. # we do not try to deserialize them again here.

  21. if isinstance(value, VersionedObject):

  22. setattr(self, key, value)

  23. else:

  24. setattr(self, key,

  25. field.from_primitive(self, key, value))

  26. # obj_reset_changes 重新设置 change 数据

  27. # 相对的,obj_get_changes 获取 change 数据

  28. self.obj_reset_changes()

  29. # _changed_fields 存放增量更新的数据

  30. self._changed_fields = set(updates.get('obj_what_changed', []))

  31. return result

  32. else:

  33. return fn(self, *args, **kwargs)


  34. wrapper.remotable = True

  35. wrapper.original_fn = fn

  36. return wrapper


END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。


技术周 | Nova Conductor Versioned Object Model 机制


点击“阅读原文”,了解九州云更多信息!

虚拟存储器系统


在早期的计算机系统中,程序员会直接对主存储器的物理地址进行操作,这种编程方式导致了当程序出现寻址错误时有可能会导致整个系统崩溃,当一个进程出现寻址错误时也可能会导致另一个进程崩溃。显然,直接操作主存的物理地址不是一个好的方法。而且,由于不存在分页或分段的存储空间管理手段,所以 CPU 寻址宽度就成为了存储容量的限制,例如:32 位 CPU 只支持 4GB 内存的寻址。这导致了该计算机无法运行存储空间需求大于实际内存容量的应用程序。


为了解决这些问题,现代计算机系统通过操作系统和硬件的结合,把主存储器和辅存储器从逻辑上统一成了一个整体,这就是虚拟存储器,或称为虚拟存储系统。虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的和私有的地址空间。


虚拟存储器的两大特点:


  • 允许用户程序使用比实际主存空间大得多的空间来访问主存

  • 每次访存都要进行虚实地址转换。


理地址,即物理主存的地址空间主存被组织成一个由 M 个连续的、字节大小的单元组成的数组,每字节都有一个唯一的物理地址(Physical Address,PA)。第一个字节的地址为 0,接下来的字节的地址为 1,依此类推。给定这种简单的结构,CPU 访问存储器的最自然的方式就是使用物理地址,即物理寻址。


虚拟地址,即虚拟存储地址空间,它能够让应用程序误以为自己拥有一块连续可用的 “物理” 地址,但实际上从程序视角所见的都是虚拟地址,而且这些虚拟地址对应的物理主存空间通常可能是碎片的,甚至有部分数据还可能会被暂时储存在外部磁盘设备上,在需要时才进行数据交换。


虚拟存储器的核心思路是根据程序运行时的局部性原理,一个程序运行时,在一小段时间内,只会用到程序和数据的很小一部分,仅把这部分程序和数据装入主存即可,更多的部分可以在需要用到时随时从辅存调入主存。在操作系统和相应硬件的支持下,数据在辅存和主存之间按程序运行的需要自动成批量地完成交换。


页式虚拟存储器


在页式虚拟存储器中,通过将虚拟存储空间分割成为了大小固定的虚拟页(Vitual Page,VP),简称虚页,每个虚拟页的大小为 P=2^n 字节。类似地,物理存储空间被分割为物理页(Physical Page,PP)也称为页帧(Page Frame),简称实页,大小也为 P 字节。


同任何缓存设计一样,虚拟存储器系统必须有某种方法来判定一个虚拟页是否存放在物理主存的某个地方。如果存在,系统还必须确定这个虚拟页存放在哪个物理页中。如果物理主存不命中,系统必须判断这个虚拟页存放在磁盘的哪个位置中,并在物理主存中选择一个牺牲页,然后将目标虚拟页从磁盘拷贝到物理主存中,替换掉牺牲页。这些功能是由许多软硬件联合提供,包括操作系统软件,MMU(存储器管理单元)地址翻译硬件和一个存放在物理主存中的叫做页表(Page Table)的数据结构,页表将虚拟页映射到物理页。页表的本质就是一个页表条目(Page Table Entry,PTE)数组。


CPU 通过虚拟地址(Virtual Address,VA)来访问存储空间,这个虚拟地址在被送到存储器之前需要先转换成适当的物理地址。将一个虚拟地址转换为物理地址的任务叫做地址翻译(Address Translation)。就像异常处理一样,地址翻译需要 CPU 硬件和操作系统之间的紧密合作。比如:Linux 操作系统的交换空间(Swap Space)。如果当 CPU 寻址时发现虚拟地址找不到对应的物理地址,那么就会触发一个异常并挂起寻址错误的进程。在这个过程中,对其他进程没有任何影响。


虚拟地址与物理地址之间的转换主要有 CPU 芯片上内嵌的存储器管理单元(Memory Management Unit,MMU)完成,它是一个专用的硬件,利用存放在主存中的查询表(地址映射表)来动态翻译虚拟地址,该表的内容由操作系统管理。


当页表已经存放在主存中,那么当 CPU 访问(虚拟)存储器时,首先要查询页面得到物理主存地址之后再访问主存完成存取。显然,地址转换机制让 CPU 多了一次访问主存的操作,相当于访问速度下降一半。而且当发生页面失效时,还要进行主存-辅助的页面交换,那么 CPU 访问主存的次数就更多了。为了解决这个问题,在一些影响访问速度的关键地方引入了硬件的支持。例如:采用按内容查找的相联存储器并行查找。此外,还进一步提出了 “快表” 的概念。把页表中最活跃的部分存放在快速存储器中组成快表,是减少 CPU 访问时间开销的一种方法。


快表由硬件(门电路和触发器)组成,属于 MMU 的部件之一,通常称为转换旁路缓冲器(Translation lookaside buffer,TLB)。TLB 的本质也是一个 Cache,它比页表小得多,一般在 16 个条目 ~ 128 个条目之间,快表只是页表的一个小小的副本。查表时,带着虚页好同时差快表和慢表(原页面),当在快表中找打条目时,则马上返回主存物理地址到主存地址寄存器,并使慢表查询作废。此时,虽然使用了虚拟存储器但实际上 CPU 访问主存的速度几乎没有下降(CPU 不再需要多次访问主存)。如果快表不命中,则需要花费一个访主存时间查慢表,然后再返回主存物理地址到主存地址寄存器,并将此条目送入到快表中,替换到快表的某一行条目。


大页内存


在页式虚拟存储器中,会在虚拟存储空间和物理主存空间都分割为一个个固定大小的页,为线程分配内存是也是以页为单位。比如:页的大小为 4K,那么 4GB 存储空间就需要 4GB/4KB=1M 条记录,即有 100 多万个 4KB 的页。我们可以相待,如果页太小了,那么就会产生大量的页表条目,降低了查询速度的同时还浪费了存放页面的主存空间;但如果页太大了,又会容易造成浪费,原因就跟段式存储管理方式一般。所以 Linux 操作系统默认的页大小就是 4KB,可以通过指令查看:


  1. $ getconf PAGE_SIZE

  2. 4096


但在某些对性能要求非常苛刻的场景中,页面会被设置得非常的大,比如:1GB、甚至几十 GB,这些页被称之为 “大页”(Huge Page)。大页能够提升性能的主要原因有以下几点:


  • 减少页表条目,加快检索速度。


  • 提升 TLB 快表的命中率,TLB 一般拥有 16 ~ 128 个条目之间,也就是说当大页为 1GB 的时候,TLB 能够对应 16GB ~ 128GB 之间的存储空间。


值得注意的是,首先使用大页的同时一般会禁止主存-辅存页面交换,原因跟段式存储管理方式一样,大容量交换会让辅存读写成为 CPU 处理的瓶颈。再一个就是大页也会使得页内地址检索的速度变慢,所以并非是页面的容量越大越好,而是需要对应用程序进行大量的测试取得页面容量与性能的曲线峰值才对。


启用 HugePage 的优点


  • 无需交换,不存在页面由于内存空间不足而换入换出的问题。

  • 减轻 TLB Cache 的压力,也就是降低了 CPU Cache 可缓存的地址映射压力。

  • 降低 Page Table 的负载。

  • 消除 Page Table 地查找负载。

  • 提高内存的整体性能。


Linux 服务器的大页内存设置


在 Linux 中,物理内存是以页为单位来管理的。页的大小为 4096 字节。1MB 的内存能划分为 256 页;1GB 则等同于 256000 页。CPU 中有一个内置的内存管理单元(MMU),用于存储这些页的列表(页表),每页都有一个对应的入口地址。在这种情况下,内存管理单元的大小(注:实际上是页表的大小)决定了服务器能使用的最大内存大小。


如果为服务器分配的内存远大于现有内存管理单元能管理的量,则会造成内存的浪费。CentOS 6 中为解决这个问题,使用了大页面的方式。简单来说,大页面即大小为 2MB 或者 1GB 的页。2MB 的页适用于管理 GB 级单位的内存;1GB 的页适用于 TB 级单位的内存。


手动去管理大页面较麻烦,往往需要更改代码。为了便于系统管理员和开发人员使用, CentOS 引入了 transparent huge pages (简称 THP )的概念。THP 是一个抽象层,其自动化了创建,管理和使用大页面的大多数步骤。


大页面配置需要连续的内存空间,因此在开机时就分配是最可靠的设置方式。配置大页面的参数有:


  • hugepages :在内核中定义了开机启动时就分配的永久大页面的数量。默认为 0,即不分配。只有当系统有足够的连续可用页时,分配才会成功。由该参数保留的页不能用于其他用途。


  • hugepagesz:在内核中定义了开机启动时分配的大页面的大小。可选值为 2MB 和 1GB 。默认是 2MB 。


  • default_hugepagesz:在内核中定义了开机启动时分配的大页面的默认大小。


要调整页的尺寸,必须将配置以参数格式写入到 Linux 操作系统启动命令中。如要为系统配置 10 个 1GB 的大页面,则启动命令中要包含:default_hugepagesz=1Ghugepagesz=1Ghugepages=10。配置 1GB 的大页面,CPU 特性需要支持 pdpe1gb ,系统内核也需要支持。e.g.


  1. grub


  2. GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX default_hugepagesz=1G hugepagesz=1G hugepages=100"


查看大页的相关配置:


  1. $ sysctl -a | grep -I huge


  2. $ cat /proc/meminfo | grep -i Huge


配置大页面后,系统在开机启动时会首选尝试在内存中找到并预留连续的大小为 hugepages *hugepagesz的内存空间。如果内存空间不满足,则启动会报错 KernelPanic,Outof Memory 等错误。


使用大页面后,能减少系统管理和访问页的时间(扩大了 TLB 快页表查询的内存地址范围);内核中的 swap 守护进程也不会管理大页面占用的这部分空间。合理设置大页面能减少内存操作的负担,减少访问页表造成性能瓶颈的可能性,从而提升系统性能。


如只配置了一个大小的大页面,可以通过 /proc/meminfo 中的 HugepagesizeHugePages_Total 计算出大页面所在内存空间的大小。这部分空间会被算到已用的内存空间里,即使还未真正被使用。因此,用户可能观察到下面现象:使用 free 命令查看已用内存很大,但 top 或者 ps 中看到 %mem 的使用总量加起来却很少。


注意:一般情况下,配置的大页面可能主要供特定的应用程序或服务使用,其他进程是无法共享这部分空间的(如 Oracle SGA )。请根据系统物理内存和应用需求来设置合适的大小,避免大页面使用的浪费;以及造成其他进程因竞争剩余可用内存而出现内存溢出的错误,进而导致系统崩溃的现象。


Nova 虚拟机的大页内存设置


绝大多数现代 CPU 都支持多种内存页尺寸,从 4KB 到 2M/4M,最大可以达到 1GB。所有 CPU 都默认使用最小的 4KB 页,如果具有较大的内存可以选择启用大页内存进行分配,这将会明显减少 CPU 的页表项,因此会增加 TLB 页表缓存的命中率,降低内存访问延迟。如果操作系统使用默认的小页内存,随着运行时间,系统会出现越来越多的碎片,以至于后来难以申请到大页的内存。在大页内存大小越大时,该问题越严重。因此,如果当你有使用大页内存的需求时,最好的办法是在系统启动时就预留好内存空间。当前的 Linux 内核不允许针对特定的 NUMA 节点进行这样的设定,不过,在不久的将来这个限制将被取消。更进一步的限制是,由于 MMIO 空洞的存在,内存开始的 1GB 不能使用 1GB 的大页。


Linux 内核已经支持 THP(Transparent Huge Pages,透明巨型页)特性,该特性会尝试为应用程序预分配大页内存。依赖该特性的一个问题是,虚拟机的拥有者并不能保证给虚拟机使用的是大页内存还是小页内存。


内存块是直接指定给特定的 NUMA 单元的,这就意味着大页内存也是直接指定在 NUMA 单元上的。因此在 NUMA 单元上分配虚拟机时,计算服务需要考虑在 NUMA 单元或者主机上可能会用到的大页内存。为虚拟机内存启用大页内存时,可以不用考虑虚拟机操作系统是否会使用。


Linux 内核有一项特性,叫做内核共享存储(KSM),该特性使得不同的 CPU 可以共享相同内容的内存页。内核会主动扫描内存,合并内容相同的内存页。如果有 CPU 改变这个共享的内存页时,会采用写时复制(COW)的方式写入新的内存页。当一台主机上的多台虚拟机使用相同操作系统或者虚拟机使用很多相同内容内存页时,KSM 可以显著提高内存的利用率。因为内存扫描的消耗,使用 KSM 的代价是增加了 CPU 的负载,并且如果虚拟机突然做写操作时,会引发大量共享的页面,此时会存在潜在的内存压力峰值。虚拟化管理层必须因此积极地监控内存压力情况并做好现有虚拟机迁移到其他主机的准备,如果内存压力超过一定的水平限制,将会引发大量不可预知的 Swap 操作,甚至引发 OOM。所以在性能要求严格的场景中,我们建议关闭内存共享特性。


计算节点可以配置 CPU 与内存的超配比例,但是一旦使用了大页内存,内存便不能再进行超配。因为当使用大页内存时,虚拟机内存页必须与主机内存页一一映射,并且主机操作系统能通过 Swap 分区分配大页内存,这也排除了内存超配的可能。大页内存的使用,意味着需要支持内存作为专用资源的虚拟机类型。


尽管设置专用资源时,不会超配内存与 CPU,但是 CPU 与内存的资源仍然需要主机操作系统提前预留。如果使用大页内存,必须在主机操作系统中明确预留。对于 CPU 则有一些灵活性。因为尽管使用专用资源绑定 CPU,主机操作系统依然会使用这些 CPU 的一些时间。不管怎么样,最好可以预留一定的物理 CPU 专门为主机操作系统服务,以避免操作系统过多占用虚拟机 CPU,而造成对虚拟机性能的影响。Nova可以保留一部分 CPU 专门为操作系统服务,这部分功能将会在后续的设计中加强。


允许内存超配时,超出主机内存的部分将会使用到 Swap。ZSWAP 特性允许压缩内存页被写入 Swap 设备,这样可以大量减少 Swap 设备的 I/O 执行,减少了交换主机内存页面中固有的性能下降。Swap 会影响主机整体 I/O 性能,所以尽量不要把需要专用内存的虚拟机机与允许内存超配的虚拟机放在同一台物理主机上。如果专用 CPU 的虚拟机与允许超配的虚拟机竞争 CPU,由于 Cache 的影响,将会严重影响专用 CPU 的虚拟机的性能,特别在同一个 NUMA 单元上时。因此,最好将使用专用 CPU 的虚拟机与允许超配的虚拟机放在不同的主机上,其次是不同的 NUMA 单元上。


关于虚拟机在主机上的 CPU 与内存的布局决策,也会影响其他的主机资源分配。例如,PCI 设备与 NUMA 单元关系密切,PCI 设备的 DMA 操作使用的内存最好在本地 NUMA 单元上。因此,在哪个 NUMA 单元上分配虚拟机,将会影响到 PCI 设备的分配。


Nova 内存页设置


  1. openstack flavor set FLAVOR-NAME

  2. --property hw:mem_page_size=PAGE_SIZE


PAGE_SIZE


  • small (default):使用最小的 page size,e.g. x86 平台的 4KB。

  • large:只使用最大的 page size,e.g. x86 平台的 2MB 或 1GB。

  • any:取决于 Hypervisor 类型。如果是 Libvirt 的话,会根据服务器的大页内存设置进行决策,优先使用大的大页,依次递减。

  • pagesize:指定具体的 pape size,e.g. 4KB、2MB、2048、1GB。


e.g.

  1. openstack flavor create --vcpus 2 --ram 2048 --disk 40

  2. --property hw:mem_page_size=2MB Flavor1


  3. openstack flavor create --vcpus 2 --ram 2048 --disk 40

  4. --property hw:mem_page_size=1GB Flavor2


NOTELarge pages can be enabled for guest RAM without any regard to whether the guest OS will use them or not. If the guest OS chooses not to use huge pages, it will merely see small pages as before. Conversely, if a guest OS does intend to use huge pages, it is very important that the guest RAM be backed by huge pages. Otherwise, the guest OS will not be getting the performance benefit it is expecting.


手动为 KVM 虚拟机中设置大页内存(http://www.linux-kvm.org/page/UsingLargePages):


  1. # 2G 内存设置 256

  2. # 4G 内存设置 512

  3. # 8G 内存设置 1024


  4. echo 1024 > /proc/sys/vm/nr_hugepages


END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。


技术周 | OpenStack 高性能虚拟机之大页内存


点击“阅读原文”,了解九州云更多信息!

概览


技术周 | Kuryr对接之Baremetal containers networking


packstack安装openstack


准备


控制节点与计算节点同时运行。

关闭防火墙

1.  systemctl stop firewalld  

2.  systemctl disable firewalld  

 

关闭SELinux

1.  sed -i ‘s#SELINUX=enforcing#SELINUX=disabled#g’ /etc/selinux/config  

2.  setenforce 0  

 

修改yum源

1.  yum -y install wget  

2.  wget http://mirrors.aliyun.com/repo/Centos-7.repo  

3.  yum update  

 

下载安装包


控制节点与计算节点同时运行。

1.  yum install -y centos-release-openstack-rocky  

2.  yum install -y openstack-packstack  

 

控制节点生成并修改answer文件


控制节点运行下述命令生成answer file。

1.  packstack –gen-answer-file answer.txt  

修改生成的answer.txt,根据实际控制节点与计算节点的IP,修改下述信息。

1.  #关闭非必须组件减少安装时间  

2.  CONFIG_CINDER_INSTALL=n  

3.  CONFIG_MANILA_INSTALL=n  

4.  CONFIG_SWIFT_INSTALL=n  

5.  CONFIG_AODH_INSTALL=n  

6.  CONFIG_CONTROLLER_HOST=<控制、网络节点IP>  

7.  CONFIG_COMPUTE_HOSTS=<计算节点IP>  

8.  CONFIG_NETWORK_HOSTS=<控制、网络节点IP>  

9.  #启用LB  

10.CONFIG_LBAAS_INSTALL=y  

11.CONFIG_NEUTRON_METERING_AGENT_INSTALL=n  

12.CONFIG_NEUTRON_ML2_TYPE_DRIVERS=vxlan,flat  

13.CONFIG_NEUTRON_ML2_TENANT_NETWORK_TYPES=vxlan  

14.#将默认的OVN backend切换为ovs  

15.CONFIG_NEUTRON_ML2_MECHANISM_DRIVERS=openvswitch  

16.CONFIG_NEUTRON_L2_AGENT=openvswitch  

 

控制节点运行安装


1.  packstack –answer-file answer.txt  


准备openstack中K8S所需项目、用户及网络信


创建K8S所需资源可以在dashboard中进行,也可以直接通过命令行操作。


创建K8S专用的项目,用户信息

1.  openstack project create k8s  

2.  openstack user create –password 99cloud k8s-user  

3.  openstack role add –project k8s –user k8s-user admin  


在K8S项目下创建pod 网络子网及service 网络子网

1.  openstack network create pod_network  

2.  openstack network create service_network  

3.  openstack subnet create –ip-version 4 –subnet-range 10.1.0.0/16 –network pod_network pod_subnet  

4.  openstack subnet create –ip-version 4 –subnet-range 10.2.0.0/16 –network service_network service_subnet  


在K8S项目路由器连接pod网络子网与service网络子网


1.  openstack router create k8s-router  

2.  openstack router add subnet k8s-router pod_subnet  

3.  openstack router add subnet k8s-router service_subnet  


在K8S项目创建pod安全组


1.  openstack security group create service_pod_access_sg  

2.  openstack security group rule create –remote-ip 10.1.0.0/16 –ethertype IPv4 –protocol tcp service_pod_access_sg  

3.  openstack security group rule create –remote-ip 10.2.0.0/16 –ethertype IPv4 –protocol tcp service_pod_access_sg  


注意,这里的创建的project id,user name,password,pod subnet id,service subnet id,security group id均需要记录,用于后期配置kuryr controller。

 

kubeadm安装Kubernetes

准备

master节点


以下操作在master节点和work 节点均执行。

关闭虚拟内存

1.  swapoff -a  

2.  sed -i ‘s/.*swap.*/#&/’ /etc/fstab  

配置转发参数

1.  cat <<EOF >  /etc/sysctl.d/k8s.conf  

2.  net.bridge.bridge-nf-call-ip6tables = 1  

3.  net.bridge.bridge-nf-call-iptables = 1  

4.  EOF  

5.  sysctl –system  

配置kubernetes阿里源

1.  cat <<EOF > /etc/yum.repos.d/kubernetes.repo  

2.  [kubernetes]  

3.  name=Kubernetes  

4.  baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/  

5.  enabled=1  

6.  gpgcheck=1  

7.  repo_gpgcheck=1  

8.  gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg  

9.  EOF  

设置docker源

1.  wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -P /etc/yum.repos.d/  

安装docker

1.  yum install docker-ce-18.06.1.ce -y  

 

设置镜像仓库加速

1.  sudo mkdir -p /etc/docker  

2.  sudo tee /etc/docker/daemon.json <<-‘EOF’  

3.  {  

4.    “registry-mirrors”: [“https://hdi5v8p1.mirror.aliyuncs.com”]  

5.  }  

6.  EOF  

 

启动docker

1.  systemctl daemon-reload  

2.  systemctl enable docker  

3.  systemctl start docker  

安装kubernetes相关组件

1.  yum install kubelet-1.12.2 kubeadm-1.12.2 kubectl-1.12.2 kubernetes-cni-0.6.0 -y  

2.  systemctl enable kubelet && systemctl start kubelet  

开启IPVS

加载ipvs内核,使node节点kube-proxy支持ipvs代理规则。

1.  modprobe ip_vs_rr  

2.  modprobe ip_vs_wrr  

3.  modprobe ip_vs_sh  

4.    

5.  cat <<EOF >> /etc/rc.local  

6.  modprobe ip_vs_rr  

7.  modprobe ip_vs_wrr  

8.  modprobe ip_vs_sh  

9.  EOF  

 

下载镜像


1.  cat <<EOF >> master.sh  

2.  #!/bin/bash  

3.  kube_version=:v1.12.2  

4.  kube_images=(kube-proxy kube-scheduler kube-controller-manager kube-apiserver)  

5.  addon_images=(etcd-amd64:3.2.24 coredns:1.2.2 pause-amd64:3.1)  

6.    

7.  for imageName in ${kube_images[@]} ; do  

8.    docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version  

9.    docker image tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version k8s.gcr.io/$imageName$kube_version  

10.  docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName-amd64$kube_version  

11.done  

12.  

13.for imageName in ${addon_images[@]} ; do  

14.  docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName  

15.  docker image tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName k8s.gcr.io/$imageName  

16.  docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName  

17.done  

18.  

19.docker tag k8s.gcr.io/etcd-amd64:3.2.24 k8s.gcr.io/etcd:3.2.24  

20.docker image rm k8s.gcr.io/etcd-amd64:3.2.24  

21.docker tag k8s.gcr.io/pause-amd64:3.1 k8s.gcr.io/pause:3.1  

22.docker image rm k8s.gcr.io/pause-amd64:3.1  

23.EOF  

24.  

25.chmod u+x master.sh  

26../master.sh  


kubeadm init安装master节点


注意这里的pod network cidr与service cidr必须和前文中创建的openstack中pod subnet cidr及service subnet cidr保持一致。


1.kubeadm init –kubernetes-version=v1.12.2 –pod-network-cidr=10.1.0.0/16 –service-cidr=10.2.0.0/16  在成功运行该命令后会输出类似如下图所示的结果:


技术周 | Kuryr对接之Baremetal containers networking


①  表示kubernetes master节点安装成功。

②  根据命令执行同样操作。

③  记录该指令,用于后期添加kubernetes node节点。


配置flannel


这里配置flannel网络插件,仅用于对接kuryr前简单验证kubernetes功能是否正常。


下载配置文件


1.  curl -LO https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml  

 

修改pod network cidr

1.  sed -i “s/10.244.0.0/10.1.0.0/g” kube-flannel.yml  

 

启动flannel

1.  kubectl apply -f kube-flannel.yml  


设置API代理

1.  kubectl proxy –port=8080 –accept-hosts=’.*’ –address=’0.0.0.0′  

 

node节点


下载镜像

1.  cat <<EOF >> node01.sh  

2.  #!/bin/bash  

3.  kube_version=:v1.12.2  

4.  coredns_version=1.2.2  

5.  pause_version=3.1  

6.    

7.  docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64$kube_version  

8.  docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64$kube_version k8s.gcr.io/kube-proxy$kube_version  

9.  docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy-amd64$kube_version  

10.  

11.docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:$pause_version  

12.docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:$pause_version k8s.gcr.io/pause:$pause_version  

13.docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/pause-amd64:$pause_version  

14.  

15.docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$coredns_version  

16.docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$coredns_version k8s.gcr.io/coredns:$coredns_version  

17.docker image rm registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$coredns_version  

18.EOF  

19.  

20.chmod u+x node01.sh  

21../node01.sh  

 

添加node节点


使用在master节点安装成功后保存的hubedem join命令,添加node节点。

1.  kubeadm join 192.168.1.12:6443 –token lgbnlx.ehciqy1p1rpu6g6g –discovery-token-ca-cert-hash sha256:0acd9f6c7afcab4f4a0ebc1a1dd064f32ef09113829a30ce51dea9822d2f4afd  

 

验证


在master节点运行下述命令可以看到node节点被正确加入

1.  [root@kuryra-1 ~]# kubectl get nodes  

2.  NAME       STATUS   ROLES    AGE   VERSION  

3.  kuryra-1   Ready    master   21h   v1.12.2  

4.  kuryra-2   Ready    <none>   21h   v1.12.2  

 

安装配置kuryr


安装kuryr-k8s-controller


安装

1.  mkdir kuryr-k8s-controller  

2.  cd kuryr-k8s-controller  

3.  virtualenv env  

4.  git clone https://git.openstack.org/openstack/kuryr-kubernetes -b stable/rocky  

5.  . env/bin/activate  

6.  pip install -e kuryr-kubernetes  

 

配置

1.  cd kuryr-kubernetes  

2.  ./tools/generate_config_file_samples.sh  

3.  mkdir /etc/kuryr  

4.  cp etc/kuryr.conf.sample /etc/kuryr/kuryr.conf  

这里需要修改配置文件kuryr.conf。具体配置项需根据上文中在openstack内创建的用于K8S环境的信息填写。

1.  [DEFAULT]  

2.  use_stderr = true  

3.  bindir = /usr/local/libexec/kuryr  

4.    

5.  [kubernetes]  

6.  api_root = http://192.168.1.11:8080  

7.    

8.  [neutron]  

9.  # 需根据上文章节中创建的项目、用户信息填写  

10.auth_url = http://192.168.1.11:5000/v3  

11.username = k8s-user  

12.user_domain_name = Default  

13.password = 99cloud  

14.project_name = ks  

15.project_domain_name = Default  

16.auth_type = password  

17.  

18.[neutron_defaults]  

19.ovs_bridge = br-int  

20.# 下面的网络资源ID需根据上文章节中创建的资源ID填写  

21.pod_security_groups = a19813e3-f5bc-41d9-9a1f-54133facb6da  

22.pod_subnet = 53f5b742-482b-40b6-b5d0-bf041e98270c  

23.project = aced9738cfd44562a22235b1cb6f7993  

24.service_subnet = d69dae26-d750-42f0-b844-5eb78a6bb873  

 

运行

1.  kuryr-k8s-controller –config-file /etc/kuryr/kuryr.conf -d  


安装kuryr-cni


安装

1.  mkdir kuryr-k8s-cni  

2.  cd kuryr-k8s-cni  

3.  virtualenv env  

4.  . env/bin/activate  

5.  git clone https://git.openstack.org/openstack/kuryr-kubernetes -b stable/rocky  

6.  pip install -e kuryr-kubernetes  

 

配置

1.  cd kuryr-kubernetes  

2.  ./tools/generate_config_file_samples.sh  

3.  mkdir /etc/kuryr  

4.  cp etc/kuryr.conf.sample /etc/kuryr/kuryr.conf  

此处需要修改配置文件kuryr.conf。

1.  [DEFAULT]  

2.  use_stderr = true  

3.  bindir = /usr/local/libexec/kuryr  

4.  lock_path=/var/lib/kuryr/tmp  

5.     

6.  [kubernetes]  

7.  # 填k8s master的IP  

8.  api_root = http://192.168.1.11:8080  

 

修改cni配置


执行下述命令。

1.  mkdir -p /opt/cni/bin  

2.  ln -s $(which kuryr-cni) /opt/cni/bin/  

由于前文安装k8s时已经安装过flannel,这里/opt/cni/bin目录已经存在。新增/etc/cni/net.d/10-kuryr.conf文件,按如下信息修改配置文件,同时删除同目录下flannel的配置文件。

1.  {  

2.      “cniVersion”: “0.3.1”,  

3.      “name”: “kuryr”,  

4.      “type”: “kuryr-cni”,  

5.      “kuryr_conf”: “/etc/kuryr/kuryr.conf”,  

6.      “debug”: true  

7.  }  

安装相应依赖包

1.  sudo pip install ‘oslo.privsep>=1.20.0’ ‘os-vif>=1.5.0’  

运行

1.  kuryr-daemon –config-file /etc/kuryr/kuryr.conf -d  

 


END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。


技术周 | Kuryr对接之Baremetal containers networking


点击“阅读原文”,了解九州云更多信息!

昨日,官方正式公布了OpenInfra上海峰会的完整议程,九州云携手中国联通、中国移动研究院、诺基亚、中兴、戴尔、Verizon等合作伙伴提交的五大议题全数入选,向业界分享开源最佳实践和创新。

——导言


重磅消息!九州云五大议题入选OpenInfra上海峰会!


11月4-6日,OpenInfra全球峰会将首次来到中国,在上海世博中心向来自全球的IT领袖、服务提供商、应用开发者、社区贡献者、电信运营商等展现开源的风采。


据官方透露,此次OpenInfra上海峰会将展示一系列开源项目,如Ceph, Kubernetes, ONAP,OPNFV等,包括OpenStack基金会托管的开源项目:OpenStack、Airship、Kata Containers、StarlingX和Zuul。


峰会议程包括10个专题:人工智能(AI)、机器学习(ML)和高性能计算(HPC);容器基础设施;持续集成/持续交付(CI/CD);5G、网络功能虚拟化(NFV)、边缘计算;新手入门;开放式开发;私有云和混合云;公有云;安全性;实践工坊。涵盖了OpenStack、Kata Containers、Kubernetes、Hadoop以及StarlingX等30+开源项目的应用案例、专题报告和现场演示。  


在此次OpenInfra上海峰会现场,九州云将分享五大议题,与业界共同谋划开源基础设施的未来。


1


重磅消息!九州云五大议题入选OpenInfra上海峰会!

范桂飓

重磅消息!九州云五大议题入选OpenInfra上海峰会!

俞谦

重磅消息!九州云五大议题入选OpenInfra上海峰会!

白永君

      

OpenStack和Kubernetes的统一监控和秒级告警方案

Unified monitoring and second-level alarm scheme for OpenStack and Kubernetes


演讲者:范桂飓、俞谦、白永君

内容简介:在愈演愈烈的多云趋势下,统一的、松耦合的、迅速响应的监控告警方案,是复杂多样的云生产环境所亟需的。传统 OpenStack 的 Telemetry 架构无法延伸开来对诸如底层物理基础架构、Kubernetes 资源和其他云集群的监控,同时随着集群规模的增大,如何进行快速的告警响应也是关键问题。


我们提出了一种体系结构,通过对 Prometheus-operator 的优化,对多云下的各种资源进行统一采集管理,解决了存储的持久化问题,能够对节点、集群服务、虚拟机整个纵向栈的故障进行秒级告警,并提供了多种 Exporter 及整套监控的自动化部署方案。目前,我们已将其应用到具有 500 台物理服务器的生产环境中。


2


重磅消息!九州云五大议题入选OpenInfra上海峰会!

黄舒泉

重磅消息!九州云五大议题入选OpenInfra上海峰会!

   Ildiko Vancsa

重磅消息!九州云五大议题入选OpenInfra上海峰会!

   David Paterson

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Gergely Csatari

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Beth Cohen

                            

扩大范围:边缘计算工作组更新

Expanding Scope: Edge Computing Working Group Update


演讲者:黄舒泉、Ildiko Vancsa(OpenStack基金会)、David Paterson(Dell EMC)、Gergely Csatari(Nokia)、Beth Cohen(Verizon)


内容简介:边缘计算工作组继续致力于定义边缘计算的使用案例,明确不同项目之间的协同,并且基于已定义的使用案例来构建出可供参考的边缘应用架构。你可以在工作组讨论的时候加入我们,了解我们在过去的一年中是如何与 OpenStack、Open Infrastructure 以及其他开源社区进行合作的,还可以了解我们将在明年开展的工作。


3

 

重磅消息!九州云五大议题入选OpenInfra上海峰会!

黄舒泉

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Qihui Zhao

重磅消息!九州云五大议题入选OpenInfra上海峰会!

tao jiang

 

如何实现电信营运商多异构边缘云的协同与管理?

How to achieve coordination and management of heterogeneous and multi-vendor cloud on telco edge?


演讲者:黄舒泉、Qihui Zhao(中国移动研究院)、tao jiang(中兴)


内容简介:电信运营商可以在边缘提供网络服务、MEC 计算能力、IaaS、PaaS、SaaS 和许多其他的服务。边缘基础设施则是所有这些上层服务的底层支撑。电信的边缘基础设施与核心基础设施有很大的不同,后者只会拥有少量的云和解决方案,相比之下边缘基础设施则更加的开放和多样化。电信边缘云的数量和类型都要多于核心云。如何管理这些异构的,来自多家云服务提供商的边缘云将会是电信运营商在边缘上提供各类云和服务时需要面临的问题。


在本次会议中,我们将会介绍边缘云的体系结构,还会介绍几个现存的与异构边缘云相关的解决方案,以及我们在探索边缘云管理和集中式 O&M 解决方案时所遇到的一些问题和经验。


4


重磅消息!九州云五大议题入选OpenInfra上海峰会!

黄舒泉

重磅消息!九州云五大议题入选OpenInfra上海峰会!

陈丹

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Qihui Zhao

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Yongbing Fan

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Wei Hu

   

中国电信运营商是如何看待边缘计算的?

How China Telco Carriers think of Edge Computing?


演讲者:黄舒泉、陈丹(中国联通)、Qihui Zhao(中国移动研究院)、Yongbing Fan、Wei Hu


内容简介:在数字化转型浪潮与 5G 到来的前夕,传统网络通信架构面临着如何处理海量边缘数据的巨大压力。同时,大数据和人工智能(AI)等创新型应用也需要在边缘网络上提供更加强大的支持。


中国移动,中国联通和中国电信,三大中国电信运营商都在积极地推动着基于自身业务特点所探索出来的边缘计算实践经验,为即将到来的 5G 时代做好准备。


我们希望邀请这些运营商的代表来讲述他们对即将到来的边缘计算和 5G 时代的看法,并分享一些这方面的实践,如:StarlingX 功能评测和 POCs。


5


重磅消息!九州云五大议题入选OpenInfra上海峰会!

李开

重磅消息!九州云五大议题入选OpenInfra上海峰会!

陈丹

重磅消息!九州云五大议题入选OpenInfra上海峰会!

Wei Hu

  

中国联通使用边缘编排系统在 5G 环境中管理 StarlingX、K8S 和 OpenStack 边缘数据中心

China Unicom’s edge Orchestration system in 5G to manage StarlingX, K8S and OpenStack edgeDC


演讲者:李开、陈丹(中国联通)、Wei Hu


内容简介:该主题旨在演示中国联通的边缘管理与编排(Edge-MANO)系统如何在 5G 环境中管理基于 StarlingX、K8S 和 OpenStack 的 3 类边缘站点。我们将演示其中的一些功能,例如:TOSCA(The de-facto edge app descriptor from carriers)的软件包分发,边缘资源编排和边缘应用程序的生命周期管理(deployment, scaling-up, scaling-down and seamless upgrading)能力。我们还将介绍一些与边缘相关的后端设计,例如:怎么为 VM-Based 或 Cloud-Native 的应用程序设计 MEAD(Mobile Edge Application Descriptor),以及针对 5G PNFs/VNFs 的 NFVO/VNFM 协同设计。


从以上五大议题可以看到,大多为偏向边缘计算内容。随着5G概念的出现,逐渐成熟强大的OpenStack开始从云计算延伸到了边缘计算领域,奠定了边缘计算的架构和基础。而在OpenStack方面领先的九州云也敏锐地捕捉到了边缘计算的“风口”。


近两年九州云确立了边缘计算的战略方向,并将自身在OpenStack领域的优势延续到了边缘计算领域。实现了边缘IaaS、边缘CaaS、边缘PaaS、边缘MANO、边缘SD-WAN等多项技术突破,并深化了“边缘云解决方案”赛道,成长为边缘计算领域的一匹“黑马”。


在此次峰会上,除OpenStack相关话题外,九州云将更多的向业界同行分享边缘计算的生产需求和实战经验, 与业界共建开源基础设施新生态。


OpenInfra上海峰会完整议程:请点击这里

九州云五大议题详情全览:请点击这里



END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。


重磅消息!九州云五大议题入选OpenInfra上海峰会!


点击“阅读原文”,查看OpenInfra上海峰会完整议程!

技术周 | StarlingX overview和功能点详解

介绍StarlingX之前需要先介绍一下StarlingX的前身。早在2014年风河就成立了TitaniumCloud生态系统项目,设计目标就是要成为电信网络应用软件理想的云操作系统平台,以最高的可靠性地运行网络虚拟化功能。StarlingX是面向边缘计算场景的多功能性的基础设施堆栈,由于StarlingX是从WindRiver产品开源产生的,而WindRiver的这款Titanium Cloud已经从成立到现在有5年时间之久的发展,Titanium Cloud算是一款比较成熟的产品了,因此即使到今年7月份为止,StarlingX仅仅发布了第一个版本,StarlingX也具备一定条件的生产化使用基础。

 

StarlingX既是一个开发项目又是一个集成项目。它将新服务与更多开源项目结合到一个总体边缘云软件堆栈中。由于风河Titanium Cloud平台在性能、可用性上都有了比较高的提升。目前风河的软件可以在通用服务器硬件上实现电信级的性能;提供的NFV平台可以达到6个9,完全满足电信级要求。而StarlingX基于该风河的商业产品进行开源优化形成,因此StaringX也继承了Titanium Cloud的优点。

 

StarlingX主要面向的场景是工业IoT、电信、视频业务等对延迟要求较高的业务。并且基于Titanium Cloud,StarlingX提供了性能兼顾高可用的特点。

 

StarlingX最初的代码是由英特尔和Wind River提供,目前StarlingX项目由OpenStack Foundation托管代码,StarlingX目前与领先的开源项目(包含OpenStack、Ceph和OVS)相结合。StarlingX在2018年10月才release了第一个版本,因此StarlingX是一个非常年轻的项目。

 

对于一些想了解边缘计算云更详细的资料的同学,OpenStack社区发表了边缘计算的白皮书,介绍了边缘计算云的起因,挑战,解决思路和应用场景,链接如下:

https://www.openstack.org/edge-computing/cloud-edge-computing-beyond-the-data-center?lang=en_US

 

白皮书总结到,一个成熟的边缘计算云是面向于开发者和应用的,并把基础设施的资源下沉到边缘网络上。那么如何定义边缘计算呢?最重要的一点就是延迟,即从各类终端、最终应用到边缘云的网络延迟需要小于20ms。

 

第二部分介绍的是StarlingX的功能点, StarlingX由于包含了OpenStack,因此OpenStack的功能点StarlingX同样具备,但是以下功能点是与OpenStack不一样的地方。

技术周 | StarlingX overview和功能点详解

Configuration Management

配置管理功能在边缘云基础设施架构中变得非常重要,特别是在管理大量的远端节点的时候,因为有些远处的节点,不太方便直接对其进行配置。因此借助于Configuration Management功能点,可以方便地对远端的物理服务器进行配置管理,配置管理中包含了CPU、GPU、内存、Huge pages,crypto/compression PCIE配置等。

 

Fault Management

这个组件是可以统计报警和查看log,并且同时包括了中心云和边缘云的物理资源和虚拟资源,并且在Horizon上都可以进行查看,监控的方面比OpenStack更广。

 

Host Management

这个组件可以检查虚拟主机的状态,并在主机关机的情况下尝试自动重启,并根据集群状态、关键进程、资源的阈值、物理主机的故障等来使用不同的调度策略来进行对虚拟机的重启。

 

Service Management

该功能点提供了服务的高可用,使用了多路通道来避免通信的断开和服务的脑裂问题,基于StarlingX本身服务的active/passive状态的切换来保障服务的高可用,并对服务的状态进行监控。

 

Software Management

从kernel到OpenStack服务的全栈软件包升级,该功能可以实现滚动升级,比如在需要对物理服务器关机的情况下实现对虚拟机的热迁移的情况,该功能在StarlingX中仅需要在horizon界面上进行操作,该热迁移可以自动把需要更新软件包主机上的虚拟机或者容器事先迁移到可用的主机,并在更新完成之后,再自动将资源分配到更新完成的主机上,该功能提供了对升级时候的虚拟机关机问题的生命周期管理的机制。

 

第三部分是StarlingX的整体架构,StarlingX基于OpenStack组件,并进行功能的增强,提供了上述5个核心功能点的能力。

 

OSS全称为Operation support system是指运营支撑系统,BSS全称为Businesssupport system,BSS系统包括客户关系管理、数据采集系统、计费帐务、综合结算、营销支撑这些功能模块。StarlingX的上述功能点可以赋能这些系统,提供更全功能的基础设施架构。

 

在计算节点上对底层的KVM进行了优化,在网络部分引进了SR-IOV、OVS-DPDK、Intel网络加速方案,使得在计算节点的能力有了质的提供,如果说上述几个功能点提供了鲁棒性和高可用性,对底层组件的优化则是提升了整体边缘云的性能。存储节点仍然是集成了业界优秀的分布式存储方案Ceph,并提供了多种存储解决方案,可以通过分布式、集中式和商务SAN存储的融合,来保障运营商级别的存储高可用。

技术周 | StarlingX overview和功能点详解

分组核心网EPC(EvolvedPacket Core),该系统的特点为仅有分组域而无电路域、基于全IP结构、控制与承载分离且网络结构扁平化,其中主要包含MME、SGW、PGW、PCRF等网元。其中SGW和PGW常常合设并被称为SAE-GW。

 

CPE,英文全称为Customer Premise Equipment ,实际是一种接收移动信号并以无线WIFI信号转发出来的的移动信号接入设备,它也是一种将高速4G或者5G信号转换成WiFi信号的设备,可支持同时上网的移动终端数量也较多。CPE可大量应用于农村,城镇,医院,单位,工厂,小区等无线网络接入,能节省铺设有线网络的费用。

 

在对于上层的虚拟网元接口VNFs方面,StarlingX可以提供通过在虚拟机中部署虚拟的EPC、CPE来实现对电信网元的支撑。

 

StarlingX社区目前在进行对容器的支持,以后可以同时在边缘处给用户提供虚拟机和容器两种资源,同时还将开发在不同操作系统中部署StarlingX系统的能力。

 

 

END

九州云成立于2012年,是中国早期从事开放基础架构服务的专业公司。成立七年,秉承“开源 · 赋能变革”的理念,不断夯实自身实力,先后为政府、金融、运营商、能源、制造业、商业、交通、物流、教育、医疗等各行业的企业级客户提供高质量的开放基础架构服务。目前拥有国家电网、南方电网广东公司、中国人民银行、中国银联、中国移动、中国电信、中国联通、中国资源卫星、eBay、国际陆港集团、中国人寿、万达信息、东风汽车、诺基亚等众多重量级客户,被用户认可为最值得信赖的合作伙伴。

技术周 | StarlingX overview和功能点详解

点击“阅读原文”,了解九州云更多信息!

前文

我非要捅穿这 Neutron(一)底层网络实现模型篇

Neutron 的资源模型

Network

Network 是 Network Connectivity as s Service 的 “根” 操作对象,是 Neutron 对二层网络的抽象,包含了用户对「大二层」网络的一切想象,支持 Local、 Flat、 VLAN、 VXLAN、 GRE、 Geneve 等多种网络类型并不断扩充。如果将 Network 映射到现实世界的话,它就相当于一个巨大的交换机:从介质的角度,它拥有许多端口;从网络的角度,它划分广播域;从功能的角度,它提供了 “隔离” 和 “转发”。

在《Networking 基本术语/概念》一文中,我们已经记录了关于大二层网络的介绍,这里不再赘述。

Neutron 网络概念的定义和类型花样之多,令人眼花缭乱。我们姑且从几个不同的方面对 “网络” 做一个分类归纳,区分理解。

从网络实现模型分层的角度看

  • 本地网络(br-int)

  • 租户网络(br-ethX/br-tun)

  • 外部网络(br-ex)

从网络实现技术的角度看

  • 非隧道网络(Local、Flat、VLAN)

  • 隧道网络(VxLAN、GRE、Geneve)

从网络从属关系的角度看

  • 运营商(物理)网络

  • 租户网络

从 Neutron 所追求的「多租户隔离多平面网络」实现来看,我们可以感受到每一个 Network 都应该具有以下 3 个核心要素,我将其称之为 “核心三要素”:

  • Network Type

  • VID Range

  • Physical Network Mapping

接下来的内容,主要就是围绕这三个核心要素展开。

运营商网络和租户网络

本章节我们要使用的就是第三种视角。所谓 “从属” 即是 “属于谁”:由 Neutron 创建的,属于 Neutron 管理范畴的网络,我们称之为租户网络(Tenant Network);属于运营商(e.g. OpenStack 平台的运营者)原有的,Neutron 无法管理、只能映射(记录)的网络,称之为运营商网络( Provider Network)。两种网络都采用了 Network 资源模型,从模型的角度来看,两者的区别在于是否会持久化下列三个字段属性值(运营商网络具有,租户网络反之):

  • provider:network_ type (string) — The type of physical network that this network is mapped to.

  • provider:physical_network (string) — The physical network where this network is implemented.

  • provider:segmentation_id (int) — The ID of the isolated segment on the physical network.

首先需要提出的问题是:为什么要区分租户网络和运营商网络?这是因为单存的 Neutron(虚拟网络)本身只是一座孤岛,如果希望与外界取得联系,就需要依赖于公共设施(e.g. 移动通信网络、桥梁)的支持。虽然 Neutron 对这些公共设施没有控制权,但却可以使用(e.g. 购买手机号码)它们,所以 Neutron 要创建一个 Network 资源对象来存储这些(运营商网络)信息。而存储的地方就是上述的 3 个字段了。

举例说明运营商网络的应用场景:用户希望 OpenStack 中的 VMs 与产品部(VLAN 10=100)的若干台个人电脑处于同一个二层网络,那么用户可以为这些 VMs 创建一个 VLAN ID=100 的运营商网络 p-network1,并且填入下列字段的值。

  • provider:network_ type ==> VLAN

  • provider:physical_network ==> “产品部网络”

  • provider:segmentation_id ==> 100

NOTE:以上只是举例,实际这三个字段的值并非如此。

需要注意的是,上述例子中无论是 VLAN 类型的网络,还是 VLAN ID=100 都并非是 Neutron 创建的,而是运营商本来就已经存在的网络,Neutron 只是创建了一个 Network 资源类型并记录下这些运营商网络的信息,继而进一步使用这个运营商网络的特性而已。

简而言之,运营商网络的作用就是为了让 Neutron 内部的虚拟网络可以与物理网络连接起来。运营商网络是运营商的某个物理网络在 Neutron 上的延伸,Neutron 租户无法管理这个物理网络的生命周期

创建运营商网络

创建运营商网络有两个要点:一是只能有管理员创建,二是需要手动填写 “核心三要素”。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

上图为通过 admin 创建一个 VLAN 类型的运营商网络,填写的三个表单就对应了 “核心三要素” 并存储到数据库中 networks 表的 provider:network_ type、provider:physicalnetwork、provider:segmentationid 字段中。“核心三要素” 中的 Network Type 和 VID Range 很好理解,两者描述了运营商网络的特征。但 Physical Network Mapping 的意义你或许会感到迷惑,其实它描述的是 Neutron Network 应该如何接入运营商实际的物理网络。直白的说,就是 Neutron Network 要通过哪一张 “网卡” 来接入到实际的运营商网络中。

但为什么上图 “物理网络” 表单项填写的 “网卡” 名称是 “public” 呢?其实 “public” 是 Neutron 实现的一种 Label 机制,本质是一个 Key-Value Mapping,将便于人类理解的 Label Name 与实际的 Physical Network 隐射起来,这就是所谓的 Physical Network Mapping。几乎所有的物理网络是使用 Label 的方式来标的。而这个 Physical Network Mapping 就定义在 Neutron OvS(本文以 OvS 为例)的配置文件中。e.g.

  1. # /etc/neutron/plugins/ml2/openvswitch_agent.ini


  2. bridge_mappings = physnet1:br-ethx1, physnet2:br-ethx2

那为什么 Lable “public” 对应的 Physical Network 是 “br-ethx1” 而不是一张具体的物理网卡名称(e.g. eth0)呢?这个问题其实我们在 Neutron 的网络实现模型已经提到过,因为 OvS Bridge 会将物理服务器上的物理网卡挂载到 OvS br-ethX(IP 地址也在此),所以 Physical Network 填入的是 br-ethX 而不是 eth0。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

上图为创建一个 VxLAN 类型的运营商网络。奇怪的是为什么没有了 “物理网络” 这个表单项呢?这还是要说到 Physical Network Mapping(provider:physical_network)描述的是 Neutron Network 应该如何接入到实际的运营商网络,由于 Flat、VLAN 等非隧道网络类型本质是一个二层网络,所以需要指定 “网卡” 才能让二层的数据帧流入运营商网络。但像 VxLAN、GRE 之类的隧道网络类型的实现原理是基于三层 IP 协议的,所以隧道网络能否与运营商网络互通的关键是隧道外层封装 IP 地址是否填写正确,而非一张 “网卡”。

再次强调一下创建运营商网络的要点:

1. 只能由管理员创建

2. 需要手动填写 “核心三要素”,并持久化到数据库中

  • 非隧道网络类型:需要传入 Physical Network Mapping(provider:physical_network)字段值,描述 Neutron Network 接入运营商网络的 “网卡(br-ethX)”。

  • 隧道网络类型:只需要保证节点上已经定义好了与运营商网络对应的 Tunnel 端口 IP 地址并且三层网络通信无障碍即可。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

上图为创建一个 Flat 类型的运营商网络。Flat(扁平)类型网络是没有 VID 的,不想 VLAN 类型在网络包从 Bridge 发出前还是打 VLAN tag 并进行内外 VID 转换。Flat 的网络包就是一个 Untag 网络包,直接接入物理网络,只需要告诉它用哪一张 “网卡(物理网络)” 即可。

创建租户网络

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

上图为创建一个租户网络,可见并没有填入 “核心三要素” 的表单项。这是因为 Neutron 认为:对于租户创建自己的网络而言,租户希望得到的只是一个二层网络,至于这个二层网络是由 VLAN 提供的或由 VxLAN 提供的并无所谓,VID 是多少也并无所谓,Physical Network 是怎么 Mapping 的就更无所谓了。

一言以蔽之,租户无需关心这个 Network(二层网络)的底层实现细节。Neutron 只有做到了这一点,才能称之为 “服务”!这不禁让我想起柯达公司的一句经典广告语 —— 你只管快门,其余我来!

但话又说回来,租户自然是不必操心这些细节,但云平台管理员可不行。云平台管理员是可以通过 Neutron 的配置文件来声明定义 “核心三要素” 的。e.g.

  1. [ml2]

  2. ...

  3. tenant_network_types = vlan,vxlan

  4. mechanism_drivers = openvswitch,linuxbridge


  5. [securitygroup]

  6. firewall_driver = openvswitch


  7. [ovs]

  8. datapath_type = system

  9. bridge_mappings = public:br-ex,

  10. tunnel_bridge = br-tun

  11. local_ip = 172.18.22.200


  12. [ml2_type_flat]

  13. flat_networks = public,


  14. [ml2_type_vlan]

  15. network_vlan_ranges = public:3001:4000,


  16. [ml2_type_geneve]

  17. vni_ranges = 1:1000


  18. [ml2_type_gre]

  19. tunnel_id_ranges = 1:1000


  20. [ml2_type_vxlan]

  21. vni_ranges = 1:1000

所以,就租户网络而言,其 “核心三要素” 是不需要持久化到数据库中的,也就不具有 provider:network_ type、provider:physicalnetwork、provider:segmentationid 这三个字段值了。再一个就是从配置中可以看出,只有非隧道类型是需要填写 “物理网络” Lable 的。

创建外部网络

创建外部网络(能够访问公网的网络)属于运营商网络的另一种应用场景。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

实际上所谓的外部网络和运营商网络的底层实现并无区别,不同之处在于外部网络具有分配 Floating IP 的功能,即外部网络在网络节点的 qrouter-XXX namespace 中配置的 iptables 的 NAT(SNAT/DNAT)功能,使得内部虚拟机得以访问到外部公网。

Network 小结

Network 是 Neutron 的二层网络资源模型,对外提供二层网络的服务接口(创建、删除二层网络)。租户可以通过这个接口来创建专属于自己的租户网络,管理员可以通过这个接口来创建(对接)Neutron 所无法管理的运营商的物理网络与外部网络。

从资源的角度来看,租户网络和运营商网络的主要区别在于「可控性」:租户网络是 Neutron 完全可控的,基于 Neutron 网络实现模型支撑的多租户隔离多平面网络需求,租户网络的 “核心三要素” 由云管人员通过 Neutron 的 ML2 配置文件定义;而运营商网络却是 Neutron 所无法管理的运营商的物理网络在 Neutron 上的一种延伸,其 “核心三要素” 只是对运营商物理网络信息的一个记录,并无管理性质。

运营商网络的两种典型应用场景:一是打通 Neutron Network 与运营商内部的物理网络,使得两者之间的虚拟机可以互相通信;再一个是打通 Neutron Network 与 Internet,使得 Neutron Network 中的虚拟机可以访问公网。第二种应用场景也就是 Neutron 的 Floating IP 功能,是通过网络节点上 qrouter-XXX 中的 iptables NAT 实现的。

Subnet

Subnet 下属于 Network,是 Neutron 对三层子网的抽象,它作为一个具体网段(CIDR)的 IP 地址池,同时为使用接入到该子网的 VMs 提供 IP 核心网络服务,还负责保证三层网络之间的路由互通。在通常情况下,Subnet 符合人们对 “子网” 的常规理解。

  • IP VERSION

  • IPADDR

  • NETMASK

  • GATEWAY

  • ROUTE

  • DNS

  • DHCP

  • IPAM

NOTE:在某些特定的应用场景中(e.g. Multi-Segments),Subnet 被赋予了更加深厚的含义,但由于非常少见,这里我们暂且不谈。

IP 核心网络服务

IP 核心网络服务(IP CoreNetwork Services),又称 DDI(DNS、DHCP、IPAM)服务。

  • DNS — Domain Name System,域名系统

  • DHCP — Dynamic Host Configuration Protocol,动态主机设置协议

  • IPAM — IP Address Manager,IP 地址管理

DNS 和 DHCP 相信大家不会陌生,这里介绍一下 IPAM 服务。IPAM 用于发现、监视、审核和管理企业网络上使用的 IP 地址空间,IPAM 还可以对运行的 DHCP 和 DNS 服务器进行管理和监视。简而言之,IPAM 就是一种 IP 地址的管理手段,目的是让 IP 地址的分配、使用更加便利

Subnet 资源模型中与 DDI 服务相关的字段

– enable_dhcp:布尔类型,表示是否为 Subnet 启用 DHCP 服务,若启用,再会在 qdhcp-XXX namesapce 中启动 dnsmasq 服务进程。

– allocation_pools:是一个数组,表示 DHCP 服务可分配的 IP 地址池列表,每个地址池的格式为 [start IP,endIP]。若没有配置则以 Subnet 的 cidr 作为地址池。

– dns_nameservers:是一个数组,用于指定一批 DNS Server 的地址。这里仅记录地址,实际的 DNS 服务并不由 Neutron 提供。

– subnetpool_id:是 tables subnetpools 的外键,指向 SubnetPools 资源模型。

NOTE:SubnetPools 与 allocation_pools 是两个 “同类不同源” 的功能。两者均为 IP 地址的资源池,而前者是对后者的一种优化,在 Kilo 版本引入,为了更好的管理子网网络资源池(e.g. 提供访问接口)。

小结一下,IP 核心网络服务(DNS、DHCP、IPAM)是 Subnet 资源模型提供的服务,而服务的对象是使用该 Subnet 的 VMs。可见,Subnet 不仅仅是一个抽象资源接口,其具有一定的管理功能。这一点非常重要,因为我们在启动虚拟机时,时常选择的是一个 Network 而非 Subnet。e.g.

  1. $ openstack server create -h

  2. ...

  3. [--nic <net-id=net-uuid,v4-fixed-ip=ip-addr,v6-fixed-ip=ip-addr,port-id=port-uuid,auto,none>]

这会让我们产生一种错觉,虚拟机网络来自于 Network,从表面看并没有问题,也是 Neutron 有意为之(对用户隐藏复杂细节的表现)。但对于开发者而言,如果带着这种认知去阅读源码就难免会产生疑惑,IP 核心网络服务的代码逻辑处理对象实际是 Subnet 而非 Network,这一点完全契合 Subnet 的资源模型设计。所以再次强调,Network 是 NaaS 的根操作对象,表示一个二层网络;而 Subnet 下属于 Network,为 Network 中的 VMs 提供 IP 核心服务

SubnetPools 资源模型

你是否考虑过,用户真的需要关心一个 Subnet 的网段是 192.X、还是 172.X、还是 10.X 吗?用户要关心的仅仅是这个 Subnet 可以提供多少个 IP 地址而已!出于这样的需求,Network 引入了 SubnetPools 资源模型,通过 subnetpool_id 字段与 Subnet 关联。SubnetPools 和 Sunbet 的关系就相当于:前者定义了一个大的(不重复的)网段,后者从中分配了一个小的网段。e.g.

  1. $ openstack subnet create -h

  2. ...

  3. [--subnet-pool <subnet-pool> | --use-prefix-delegation USE_PREFIX_DELEGATION | --use-default-subnet-pool]

NOTE:在较新的版本(Rocky)中,配合 OpenStack Placement Project,SubnetPools 还可以被一个第三方的网络软件提供的外部 IP 资源池代替。

  1. # 记录了一个 SubnetPool 的子网网段划分规则

  2. MariaDB [neutron]> select * from subnetpoolsG;

  3. *************************** 1. row ***************************

  4. project_id: 031cec3e2df143259d302aa1993fd410

  5. id: 5bbd5cab-c6a0-4851-b2d7-1137742e6adf

  6. name: shared-default-subnetpool-v4

  7. ip_version: 4

  8. default_prefixlen: 26

  9. min_prefixlen: 8

  10. max_prefixlen: 32

  11. shared: 1

  12. default_quota: NULL

  13. hash: 27e49575-31f7-4012-b57b-55c990cb6d82

  14. address_scope_id: NULL

  15. is_default: 1

  16. standard_attr_id: 1


  17. # 记录了一个 SubnetPool 的子网网段信息

  18. MariaDB [neutron]> select * from subnetpoolprefixes;

  19. +----------------+--------------------------------------+

  20. | cidr | subnetpool_id |

  21. +----------------+--------------------------------------+

  22. | 192.168.1.0/24 | 5bbd5cab-c6a0-4851-b2d7-1137742e6adf |

  23. +----------------+--------------------------------------+

Multi-Segments

在上文中我们反复提到,Network 是一个二层网络的抽象,Subnet 是一个三层子网的抽象。这是大多数 SDN 软件设计的常规定义,创建一个 Network 就相当于获得了一个广播域,创建一个 Subnet 就相当于获得了一个三层 IP 地址池。对用户的理解非常友好。

不过在实际的生产需求中 Neutron 面临一个问题:如果一个 Network 内的 VMs/Hosts 数量太多,就会出现诸如二层广播风暴、网络内交换机 ARP 表项容量不足等情况。简单来说,这就是 Network 作为云计算平台中的大二层网络却无法支撑起 “无限” 多个 VMs 的问题。为了满足这一需求 Neutron 引入了 Multi-Segments 设计。

Multi-Segments 解决这一问题的办法就是将 Network 的定义进一步升级为 “多个二层网络的容器”,同时也将 Subnet 的定义进一步升级为 “一个二层网络以及基于此的三层子网”,Subnet 之间通过三层路由互通。

Multi-Segments 顾名思义是一个 Network 具有多个 Segments,而一个 Segment 其实是一个运营商网络,这一点可以从 Segment 资源模型看出(每条 Segment 记录都包含一个运营商网络的 “核心三要素”)。

显然,天下没有免费的午餐,Multi-Segments 的设计实际上具有非常大的局限性 —— 需要规划整个物理、虚拟网络拓扑。它是一种通过 “物理手段” 来完成的 “Network 升级”。比如:Routed Network 应用场景。

所谓 Routed Network,就是一个 Network 内的 Subnet(对应运营商的物理网络)之间使用物理路由器连通,Subnet 的 gateway_ip 指向物理路由器直连网口的 IP 地址。在现实机房中,一个机柜接入物理路由器的网口基本固定,网口的 IP 地址也不会轻易改动,这意味着 Subnet 的三层子网需要与该物理路由器网口的 IP 处于同一个网段,否则无法通信。也就是说,使用 Routed Network 要求管理员提前做好物理、虚拟网络、每个机柜的网关 IP、DHCP Server 的全盘规划。

Multi-Segments 的应用场景除了 Routed Network 还有「VTEP 位于 TOR 交换机上」这一场景,暂不作介绍。可以感受到 Multi-Segments 的应用大多需要结合实际的物理网络拓扑对机房网络进行全盘规划,虽然都并非是一种通用的方案,但 Multi-Segments 的存在也的确让 Neutron 落地物理机房多了一些更加灵活的配置选项。不过,很可惜的是,至今为止笔者依然没有碰见过在生产环境中落地的案例,有时候难免让人怀疑 Multi-Segments 存在的必要性,这是一个大家都对其 “讳莫如深” 的话题。在本章节中提出也只是为了作一个了解而已。

Routed provider networks 官方示例文档:https://docs.openstack.org/newton/networking-guide/config-routed-networks.html

NOTE:有趣的是,经过上述文档的实验发现 Multi-Segments 无法实现预期的 Segments(Subnets)之间的二层隔离,这是因为 VMs 虽然在不同 Segments(Subnets)上,但 VMs 连接到同一个(计算节点的)OvS br-int 上的 qvo-XXX 却具有相同的 Tag ID,自然就无法进行隔离了。由于 Multi-Segments 的场景实在少见,笔者也就不再深究了,只是做出提醒,了解就好。

创建 Subnet

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

创建 Subnet 可以手动输入你预期的网段,也可以应用 SubnetPools 资源模型,直接选择一个 IP 地址资源池。显然后者要来的更加简便一些,只需要通过 “网络掩码” 表单来描述你想要的 IP 地址数量即可(e.g. NETMASK=24 即 2**8 == 256 个 IP 地址)。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

创建 Subnet 时你还可以 “手动输入网络地址”,该表单对应 Subnet 资源模型的 allocationpools 属性,所以 “手动输入网络地址” 是无法和 SubnetPools 共存的,只有通过手动指定网段的方式才可以使用。“主机路由” 对应 hostroutes 属性,格式正如上文所说: [目标网络,下一跳IP 地址]。“DNS 服务器” 对应 dns_nameservers 属性,是一个数值类型,填入 DNS Server 的 IP 地址。

NOTE:同一个 Network 不可以同时具有从资源池中分配(SubnetPools)和手动输入网络地址(allocation_pools)两种类型的 Subnet — Subnets hosted on the same network must be allocated from the same subnet pool.

Network 与 Subnet 的一对多关系

Network 和 Subnet 是一对多的关系,这跟应用了 Multi-Segments 与否无关。Network 下属的 Subnets 可以有不同的 IP 网段(CIDR)且不能重叠,但不同 Networks 的 Subnets 之间可以具有相同的 CIDR。这得益于 Neutron L3 Router 应用了 qrouter-XXX network namespace,解决了 Networks 之间 CIDR 冲突的问题。对于不同 Networks 的 Subnets 之间具有相同 CIDR 时,会有以下两种情况:

  1. 若两个 Subnets 通过同一个 Router 路由,根据 Router 的配置,只有指定的一个 Subnet 可被路由。

  2. 若两个 Subnets 通过不同的 Router 路由,因为 Router 的路由表隔离,所以两个 Subnets 都可以被路由。

我们知道常规的 Network 就是二层广播域,那么你是否想过,为什么 Network 与 Subnet 的聚合关系被设计成一对多?为什么 Neutron 允许在同一个二层广播域之上可以配置多个不同的子网?其实这并非出于什么特殊的意图,只是一对多的关系使得 Neutron 的网络应用更加灵活。通常情况下,用户大概率只会在一个 Network 下创建一个 Subnet,让它们尽可能维护一个 “表面上” 的一比一关系。但总有特殊的情况,例如:一个 Subnet 的 IP 地址用完了;例如:我要启用 Multi-Segments。无论从操作层面还是从架构设计层面上看,Network 与 Subnet 的一对多关系都让 Neutron 变得更加灵活。

那么选定一个具有多个 Subnets 的 Network 来启动一个虚拟机时 Neutron 会怎么处理呢(Nova 不支持选定 Subnet 来启动虚拟机)?Neutron 会按照 Subnets 的顺序选定第一个可用的 Subnet 来给虚拟机使用,知道该 Subnet 的 IP 被分配完毕为止。由此可以感受到,如果不是有特殊需求,还是尽量让 Network 与 Subnet 维持 “表面上” 的一比一关系吧。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

NOTE:虽然 Network 下属有多个 Subnet,但为整个 Network 服务的 DHCP 仍然只有一个。e.g.

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

Port

Network 是二层网络的抽象,Subnet 是三层子网的抽象,Port 就是网卡(NIC)的抽象,是连接 Nova 虚拟机与 Neutron Subnet 的桥梁,也是 Subnet 接入 L3 Router 的桥梁。

直白的说,Port 就是一个虚拟网卡(vNIC),Port 的关键属性就是 IP 地址和 MAC 地址。虚拟机需要绑定 Port,路由器也要绑定 Port。

Port 与 Subnet 一样下属于 Network,Port 与 Subnet 的关系是水平的,为多对多。Port 的 IP 地址来源于 Subnet,也就是说一个 Port 可以具有多个 IP 地址。不过通常情况下,Port 有且只有一个 MAC 地址,对应 Port 资源模型的 mac_address 属性。

Neutron 安全组(Security Group)

Neutron 提供了 Security Group 和 FWaaS 两种安全机制,前者的作用域是单个虚拟机或 Port,后者的作用域是一个具体的网络。而 Security Group 又分为 Nova Security Group 和 Neutron Security Group,这里我们主要讨论的是 Neutron(Port)Security Group。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

当用户将一个 Port 挂载到虚拟机时,底层逻辑会在该虚拟机所处的计算节点上创建一个 Tap 设备并将 Port 的特征信息隐射到这个 Tap 设备,从而实现了为虚拟机添上一张虚拟网卡(vNIC)。我们在 Neutron 网络实现模型的章节中提到过,虚拟机的 vNIC(Tap 设备)并非是直连到 OvS br-int(综合网桥)的,之间还存在一个安全网桥(Linux Bridge qbr-XXX)层。e.g.

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

如上图,Linux Bridge qbr-XXX 就是 Neutron Security Group 的底层支撑。当用户为指定 Port 设定一系列 Security Group Rules 时,Neutron 实际上是通过 CLI 方式调用操作系统的 iptables 指令为 qbr-xxx 上的 Tap 设备配置了相应的 iptables rules。这就是所谓的 “安全层”。

那么问题来了:为什么不能直接在 OvS br-int 上为虚拟机 Port(Tap 设备)设定安全组规则?非得莫名的增加一个安全层?这是因为 OvS Bridge 本身不支持对连接到其自身的 Tap 设备使用 iptables。

直到,OvS 2.5 提出了 “基于流表” 的 Security Group 特性,它应用 Linux 内核的 conntrack(CT)模块实现了对网络连接状态识别和处理。OpenStack 则从 M 版开始应用 OvS 这一新特性,支持 openvswitch securitygroup driver,支持使用 OvS 来实现 “有状态防火墙” 功能。可以通过修改 Neutron 的 ML2 配置文件来选择 Neutron Security Group 的驱动类型。

  1. # /etc/neutron/plugins/ml2/ml2_conf.ini


  2. [securitygroup]

  3. firewall_driver = openvswitch

当然了,如果选择了 openvswitch securitygroup driver,那么 Neutron 的网络实现模型就不再需要 qbr-XXX 安全层了。相应了少了一层转发之后,网络性能也会有所提高,尤其在安全组规则数量巨大的时候。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

关于 OvS Security Group 的实现细节,这里暂不作过多讨论,感兴趣的小伙伴可以浏览《OVS实现安全组,你需要知道这些!

可用地址对(Allowed address pairs)

Neutron Security Group 不仅仅只会一味的按照安全组规则来对虚拟机进行保护,Security Group 本身的存在(启用)就已经设定了一些安全策略,例如:为了防止虚拟机被 ARP Spoofing(ARP 欺诈)、 DHCP Spoofing 的 Port IP/MAC 地址绑定安全策略。由此,默认情况下,一个 Port 的 IP 地址和 MAC 地址是一一对应且绑定,也就是说对这个 Port 的 IP 地址进行添加、修改、删除都会被 Neutron Security Group 判定为非法行为。这也是之所以在 Neutron 网络环境中无法直接使用 Keepalived 来做虚拟机高可用的原因,这是一个无处安放的 VIP 的问题。

NOTE:ARP 反欺诈有很多方案,将 IP/MAC 地址一一绑定是最直接简单的办法。

但就像上文提到的 Keepalived 例子,一个 Port 具有多个 IP 地址的情况总是存在需求的,Port 资源模型的 fixedips 属性就被设计为一个数组类型(Port 可具有多个 IP 地址,1 个 MAC 地址)。针对这样的场景一般有两个办法:关闭 Port Security(portsecurityenabled,不建议使用)或使用 Allowed address pairs(allowedaddress_pairs)机制。

每个 Port 都具有自己的 allowedaddresspairs 数组,它记录了若干对合法的 IP/MAC 地址映射,以此来支持允许多个 IP 与 Port 连通,从而满足一个 Port 具有多个 IP 地址的需求。

更多可用地址对的详情请浏览官方介绍:https://docs.openstack.org/developer/dragonflow/specs/allowedaddresspairs.html

创建一个 Port

NOTE:Port 是依托于 Network 的,所以首先需要创建一个 Network。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

上图创建了一个简单的 Port:

  • Port 的 Fixed IP 地址会从 Subnet1 的 IP 地址池中随机分配,对应 fixed_ips 属性。

  • 开启了 Port Security,现在 Port 的 IP/MAC 地址一一绑定,对应 portsecurityenabled 属性。

  • VNIC 类型为正常(normal),对应 binding:vnic_type 属性。

  • 没有指定 “设备 ID(deviceid)” 和 “设备所属者(deviceowner)”,所以现在设备的 bindingviftype 状态为 unbound。binding:viftype 除了用来标识 Port 的绑定状态(unbound,boundfailed)之外,还用于标识这个 Port 的 Mechanism 类型(e.g. ovs、bridge、macvtap)。

  • 在创建 Port 的同时可以指定这个 Port 的安全组规则

  1. [root@localhost ~]# openstack port show Port1

  2. +-------------------------+-----------------------------------------------------------------------------+

  3. | Field | Value |

  4. +-------------------------+-----------------------------------------------------------------------------+

  5. | admin_state_up | UP |

  6. | allowed_address_pairs | |

  7. | binding_host_id | |

  8. | binding_profile | |

  9. | binding_vif_details | |

  10. | binding_vif_type | unbound |

  11. | binding_vnic_type | normal |

  12. | created_at | 2019-03-08T03:17:23Z |

  13. | data_plane_status | None |

  14. | description | |

  15. | device_id | |

  16. | device_owner | |

  17. | dns_assignment | None |

  18. | dns_domain | None |

  19. | dns_name | None |

  20. | extra_dhcp_opts | |

  21. | fixed_ips | ip_address='192.168.1.27', subnet_id='96f33568-70cd-47a2-a0b5-a32a853caa11' |

  22. | id | 07995f4e-b6b2-493f-9ce5-b1d945a13807 |

  23. | location | None |

  24. | mac_address | fa:16:3e:0f:ff:74 |

  25. | name | Port1 |

  26. | network_id | e28bd712-352f-439d-88ea-35a994a4a765 |

  27. | port_security_enabled | True |

  28. | project_id | 031cec3e2df143259d302aa1993fd410 |

  29. | propagate_uplink_status | None |

  30. | qos_policy_id | None |

  31. | resource_request | None |

  32. | revision_number | 1 |

  33. | security_group_ids | 12519ba0-d1f1-46e3-a0b2-48e6639ee8ad |

  34. | status | DOWN |

  35. | tags | |

  36. | trunk_details | None |

  37. | updated_at | 2019-03-08T03:17:23Z |

  38. +-------------------------+-----------------------------------------------------------------------------+

这里强调一下 “设备 ID(deviceid)” 和 “设备所属者(deviceowner)” 两个字段,它们共同标识了 Port 的绑定实体。比如:Port 绑定到了一台虚拟机,那么 device_id=<instance_uuid>, device_owner=compute:nova。常见的 device_owner 还有:

  • network:dhcp — Neutron DHCP Agent 使用的端口,为 Network 提供 DHCP 服务

  • network:router_interface — Neutron L3 Router Agent 使用的端口,将 Subnet 接入路由器

  • network:router_gateway — Neutron L3 Router Agent 使用的接口,外部网络接入路由器的网管接口

还需要强调一下的是 Port 的类型,Neutron 支持多种类型的 Port,不同类型的 Port 底层可能由不同的 Agent 实现(e.g. ovs-agent、sriov-agent)。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇只需要提供用户预期的 IP/MAC 地址,即可为 Port 添加可用地址对。在可用地址对清单中的 IP/MAC 都可以通过自动或手动的方式应用到这个 Port 所对应的 vNIC(Tap 设备)上。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

还需要注意一点,fixe_ips 属性是一个数值类型,就是说加入一个 Network 下属具有多个 Subnet,那么这个 Port 就可以从多个 Subnets 中获取多个 IP 地址。e.g.

  1. [root@localhost ~]# openstack port create --network Net2 --fixed-ip subnet=Subnet2-1 --fixed-ip subnet=Subnet2-2 --enable-port-security Port2-1

  2. +-------------------------+--------------------------------------------------------------------------------+

  3. | Field | Value |

  4. +-------------------------+--------------------------------------------------------------------------------+

  5. | admin_state_up | UP |

  6. | allowed_address_pairs | |

  7. | binding_host_id | |

  8. | binding_profile | |

  9. | binding_vif_details | |

  10. | binding_vif_type | unbound |

  11. | binding_vnic_type | normal |

  12. | created_at | 2019-03-08T04:21:56Z |

  13. | data_plane_status | None |

  14. | description | |

  15. | device_id | |

  16. | device_owner | |

  17. | dns_assignment | None |

  18. | dns_domain | None |

  19. | dns_name | None |

  20. | extra_dhcp_opts | |

  21. | fixed_ips | ip_address='172.16.100.38', subnet_id='0f15d289-26f2-4c83-9538-fae158bf3153' |

  22. | | ip_address='192.168.100.125', subnet_id='7a2fa4b5-c8ca-48e9-94fb-c74f5e59510f' |

  23. | id | 51383a86-56b5-4907-8bd2-80801351fc1b |

  24. | location | None |

  25. | mac_address | fa:16:3e:df:03:8c |

  26. | name | Port2-1 |

  27. | network_id | 4472e95b-f2e1-4ff5-8bce-429e1997f3cf |

  28. | port_security_enabled | True |

  29. | project_id | 031cec3e2df143259d302aa1993fd410 |

  30. | propagate_uplink_status | None |

  31. | qos_policy_id | None |

  32. | resource_request | None |

  33. | revision_number | 1 |

  34. | security_group_ids | 12519ba0-d1f1-46e3-a0b2-48e6639ee8ad |

  35. | status | DOWN |

  36. | tags | |

  37. | trunk_details | None |

  38. | updated_at | 2019-03-08T04:21:57Z |

  39. +-------------------------+--------------------------------------------------------------------------------+

挂载一个 Port

使用 Port 来启动一个虚拟机

  1. openstack server create --flavor cirros256 --image cirros-0.3.4-x86_64-disk --port Port1 VM1

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

需要注意的是,即便 Port 具有多个可用地址对,但虚拟机网卡原生的 IP/MAC 依旧是 Port 的原生 fixedips/macaddress。可用地址对的含义是可以被 Port 使用的 IP/MAC,而非一定会被使用的 IP/MAC。

Port 挂载到虚拟机之后,其自身的信息也会被更新

  1. [root@localhost ~]# openstack port show Port1

  2. +-------------------------+-------------------------------------------------------------------------------------------+

  3. | Field | Value |

  4. +-------------------------+-------------------------------------------------------------------------------------------+

  5. | admin_state_up | UP |

  6. | allowed_address_pairs | ip_address='192.168.1.28', mac_address='fa:16:3e:0f:ff:28' |

  7. | | ip_address='192.168.1.29', mac_address='fa:16:3e:0f:ff:29' |

  8. | binding_host_id | localhost.localdomain |

  9. | binding_profile | |

  10. | binding_vif_details | bridge_name='br-int', datapath_type='system', ovs_hybrid_plug='False', port_filter='True' |

  11. | binding_vif_type | ovs |

  12. | binding_vnic_type | normal |

  13. | created_at | 2019-03-08T03:17:23Z |

  14. | data_plane_status | None |

  15. | description | |

  16. | device_id | 6da255cb-402a-4273-844f-5aad549d65e7 |

  17. | device_owner | compute:nova |

  18. | dns_assignment | None |

  19. | dns_domain | None |

  20. | dns_name | None |

  21. | extra_dhcp_opts | |

  22. | fixed_ips | ip_address='192.168.1.27', subnet_id='96f33568-70cd-47a2-a0b5-a32a853caa11' |

  23. | id | 07995f4e-b6b2-493f-9ce5-b1d945a13807 |

  24. | location | None |

  25. | mac_address | fa:16:3e:0f:ff:74 |

  26. | name | Port1 |

  27. | network_id | e28bd712-352f-439d-88ea-35a994a4a765 |

  28. | port_security_enabled | True |

  29. | project_id | 031cec3e2df143259d302aa1993fd410 |

  30. | propagate_uplink_status | None |

  31. | qos_policy_id | None |

  32. | resource_request | None |

  33. | revision_number | 6 |

  34. | security_group_ids | 12519ba0-d1f1-46e3-a0b2-48e6639ee8ad |

  35. | status | ACTIVE |

  36. | tags | |

  37. | trunk_details | None |

  38. | updated_at | 2019-03-08T03:51:05Z |

  39. +-------------------------+-------------------------------------------------------------------------------------------+

  • bindingviftype — 从 unbound 变成 ovs,表示底层使用的是 OvS Mechanism Driver。

  • bindinghostid — Port 对应的 Tap 设备所在的主机,也就是 VM 所在的计算节点。

  • bindingvifdetails — 记录了一些 Port 挂载后的信息,例如 Tap 设备加入的 OvS Bridge 名称,OvS Bridge 的类型。

  • deviceid & deviceowner — 指定绑定 Port 的实体对象(虚拟机)和类型(compute:nova)。

NOTE:从上述信息可以看出,Port 对应的 Tap 设备实际上实在 “绑定” 之后再创建的,Tap 设备的命名规则为 tap[port-uuid]。e.g.

  1. [root@localhost ~]# ovs-vsctl show

  2. ccb13b70-cffb-4a64-97b1-734bf9040abc

  3. Manager "ptcp:6640:127.0.0.1"

  4. is_connected: true

  5. ...

  6. Bridge br-int

  7. Controller "tcp:127.0.0.1:6633"

  8. is_connected: true

  9. fail_mode: secure

  10. ...

  11. Port "tap07995f4e-b6"

  12. tag: 5

  13. Interface "tap07995f4e-b6"

  14. ...

  15. ovs_version: "2.9.0"

使用具有多个 fixed_ips 的 Port 来启动一个虚拟机

  1. [root@localhost ~]# openstack server create --flavor cirros256 --image cirros-0.3.4-x86_64-disk --port Port2-1 VM2

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

奇怪为什么 Port 和虚拟机明明有两个 IP 地址,但 GuestOS 起来后却只看见了一个?其实虚拟机启动获取 IP 地址时是随机挑选一个的,不会把 Port 的所有 IP 都配置上去,当然你也可以手动的将两个 IP 地址配置上去。总的来说这种做法和应用可用地址对的效果差不多,如果你只是单纯的希望虚拟机具有多个 IP,还是建议你使用可用地址对。但如果你希望虚拟机可以实现跨网段中断,那么就可以使用具有多个 Subnet IP 的 Port。

Router

Router 是 Neutron 实现的路由器抽象。

需要注意的是,Router 只是 Neutron 对 Linux 服务器路由功能的抽象,而非 Neutron 实现了一个完整的 vRouter 软件。这之间有着巨大的区别。Neutron Router 对 Linux 路由功能进行了封装,并由 L3 Agent 服务进程负责处理。通常的,L3 Agent 只运行在网络节点中,所以所有的跨网段访问流量、公网访问流量都会流经网络节点。由此,网络节点成为了 Neutron 三层网络的性能瓶颈,为了解决这个问题,Neutron 提出了 DVR(分布式路由器)机制,让每个计算节点都具有三层网络功能。

简而言之,对于上层应用而言,只需要关注 Router 的 端口网关路由表 即可。

NOTE:关于 Linux 路由功能在《Linux 的路由功能》一文中已经介绍过,这里不再赘述。

外部网关

Neutron 语义环境中的 “外部网关” 有两重含义:

  • 实际的外部网关(下文称为物理外部网关),在 Neutron 的管理范畴之外。如下图的 Router_2 上的 Port2。

  • Neutron 的外部网关(下文成为 Neutron 外部网关,以作区别),在 Neutron 的管理范畴之内。如下图 Router_1 上的 Port1。

我们思考一个问题:为什么 Neutron 内部网络需要通过 Router1 再与 Router2 进行连接?而不将内部网络直连 Router_2 然后访问公网呢?首先明确一点,“Neutron 管理的内部网络” 指的是租户网络而非运营商网络。运营商网络当然可以映射到一个直连物理外部网关的物理网络,这是因为云管人员手动的为运营商网络提供了物理网络的 “核心三要素”。同理,如果租户网络希望直连到物理外部网关,那么就需要云管人员提供连接到物理外部网关的 “核心要素(e.g. 外部网关的 IP 地址)”。但是,让云管人员为每个租户网络都手动的 “填入”(实际上并非填入,而是获取) “核心要素” 显然是不明智的,再者物理路由器很可能没有足够的接口数量供租户网络使用。

出于这样的前提,Neutron 在租户网络和外部网关之间引入了一个内部路由层。每个租户都可以创建专属的内部路由层,包含若干个 L3 Router 实例对象。租户可以随意的将租户网络接入内部路由层,然后再由内部路由层统一对接物理外部网关。这样物理路由器的端口就能得到更高效的利用。

NOTE:创建多个 L3 Router 实例对象并非是说需要多个 Linux 服务器,Neutron 通过 qrouter-XXX network namespace 在网络节点上隔离出了多个 “虚拟路由器”。每创建一个 Router,运行在网络节点的 L3 Agent 就会新建一个 qrouter-XXX。由于 qrouter-XXX 具有自己独立的路由表,所以同一租户下不同的 Network 之间允许具有相同 IP 网段(CIDR)的 Subnet,只要这些 Subnet 只要不连接到同一个 Router 上就不会出现 IP 地址重叠的问题。

  1. destination next_hop out_interface

  2. 104.20.110.0/24 182.24.4.1 Port1(182.21.4.6)

这条路由表项的关键信息有三:物理外部网关 IP(182.24.4.1)、Neutron 外部网关 IP(182.21.4.6)以及隐藏信息 —— 运营商网络(外部网络)182.24.4.0/24。

可见,Neutron 内部网络要想连接公网,关键在于如何获取上述 3 个关键信息。办法很简单,只需要创建一个运营商网络(外部网络)即可,例如:182.24.4.0/24。物理外部网关 IP(182.24.4.1)就是运营商网络(外部网络)对应的 Subnet 的 gatewayip 属性,而 Neutron 外部网关 IP(182.21.4.6)就是该 Subnet 分配的一个子网 IP 地址。存放这些信息的 Router 资源模型属性就是 externalgateway_info:

  1. {

  2. "external_gateway_info": {

  3. "enable_snat": true,

  4. "external_fixed_ips": [{

  5. "ip_address": "182.24.4.6",

  6. "subnet_id": "b930d7f6-ceb7-40a0-8b81-a425dd994ccf"

  7. }],

  8. "network_id": "ae34051f-aa6c-4c75-abf5-50dc9ac99ef3"

  9. }

  10. }

  • network_id — 运营商网络(外部网络)

  • subnetid — 运营商网络(外部网络)的 Subnet(其 gatewayip 就是物理外部网关 IP 地址)

  • ip_address — Neutron 外部网关 IP 地址

  • enable_snat — Neutron 外部网关端口是否开启 SNAT 功能

如果开启了 SNAT,Neutron 就会在 qroute-XXX namespace 中添加这样的一条 iptables rule,所有从 qg-426c2bcd-f4(如上图 Port 1)出去的数据包,无论你来自哪里(源 IP 地址)或者要去哪里(目的 IP 地址),数据包的源 IP 地址都会被转换为 172.18.22.210。

  1. [root@localhost ~]# ip netns exec qrouter-a1adb970-dba9-49f0-ba4b-4294f0d07f6f iptables -nvL -t nat

  2. ...


  3. Chain neutron-l3-agent-snat (1 references)

  4. pkts bytes target prot opt in out source destination

  5. 2 142 neutron-l3-agent-float-snat all -- * * 0.0.0.0/0 0.0.0.0/0

  6. 2 142 SNAT all -- * qg-426c2bcd-f4 0.0.0.0/0 0.0.0.0/0 to:172.18.22.210

  7. 0 0 SNAT all -- * * 0.0.0.0/0 0.0.0.0/0 mark match ! 0x2/0xffff ctstate DNAT to:172.18.22.210

NOTE:添加这条 SNAT 的原因是,Linux 作为路由器时仅仅开启了内核的路由转发功能是不够的,还需要添加这么一条 SNAT。那为什么不需要添加 DNAT 呢?因为作为路由器而言,所有的数据包都只是 SNAT(送出去)而已。

新建 Router 和外部网关端口

从上文可一直,当我们希望 Neutron 内部网络连通公网时,就创建一个运营商网络(外部网络),然后使用 L3 Router 将内部网络与运营商网络(外部网络)直连起来即可。e.g.

  • 新建 Router。如果此时用户选择了 “外部网络”,那么 Neutron 会自动的创建 Router1 与 public 直连的外部网关端口。需要注意的是,只有这一种情况下 Neutron 会自动创建路由端口,否则都需要用户手动创建。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

  • 内部网络 Net1 和运营商网络(外部网络)public 通过 Router 直连

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

  • public 有一个端口连接到 Router,类型为 network:router_gateway,IP 为 172.18.22.210(Neutron 外部网关 IP)。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

  • public 的 Subnet public-subnet 具有物理外部网关 IP 地址 172.18.22.1。

  1. [root@localhost ~]# openstack subnet show public-subnet

  2. +-------------------+--------------------------------------+

  3. | Field | Value |

  4. +-------------------+--------------------------------------+

  5. | allocation_pools | 172.18.22.201-172.18.22.210 |

  6. | cidr | 172.18.22.0/24 |

  7. | created_at | 2019-02-13T03:41:09Z |

  8. | description | |

  9. | dns_nameservers | |

  10. | enable_dhcp | False |

  11. | gateway_ip | 172.18.22.1 |

  12. | host_routes | |

  13. | id | 99749410-a6b0-418b-9ebc-fd060e1a746e |

  14. | ip_version | 4 |

  15. | ipv6_address_mode | None |

  16. | ipv6_ra_mode | None |

  17. | location | None |

  18. | name | public-subnet |

  19. | network_id | 282e146e-6948-436f-992c-f2d50588e357 |

  20. | project_id | 031cec3e2df143259d302aa1993fd410 |

  21. | revision_number | 0 |

  22. | segment_id | None |

  23. | service_types | |

  24. | subnetpool_id | None |

  25. | tags | |

  26. | updated_at | 2019-02-13T03:41:09Z |

  27. +-------------------+--------------------------------------+

  • Router 具有两个端口,一个连接 Net1,IP 地址是 Net1 的网关 IP 192.168.1.1;另一个连接 public,IP 是 Neutron 外部网关 IP 172.18.22.210。

5月技术周 | 我非要捅穿这 Neutron(二)上层资源模型篇

  • Router1 的路由表和网络设备:

  1. [root@localhost ~]# ip netns exec qrouter-a1adb970-dba9-49f0-ba4b-4294f0d07f6f ifconfig

  2. lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536

  3. inet 127.0.0.1 netmask 255.0.0.0

  4. inet6 ::1 prefixlen 128 scopeid 0x10<host>

  5. loop txqueuelen 1000 (Local Loopback)

  6. RX packets 0 bytes 0 (0.0 B)

  7. RX errors 0 dropped 0 overruns 0 frame 0

  8. TX packets 0 bytes 0 (0.0 B)

  9. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


  10. qg-426c2bcd-f4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

  11. inet 172.18.22.210 netmask 255.255.255.0 broadcast 172.18.22.255

  12. inet6 fe80::f816:3eff:fe0b:c722 prefixlen 64 scopeid 0x20<link>

  13. ether fa:16:3e:0b:c7:22 txqueuelen 1000 (Ethernet)

  14. RX packets 765265 bytes 36064217 (34.3 MiB)

  15. RX errors 0 dropped 0 overruns 0 frame 0

  16. TX packets 90 bytes 5316 (5.1 KiB)

  17. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


  18. qr-cf018461-bc: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500

  19. inet 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255

  20. inet6 fe80::f816:3eff:fea5:b2bb prefixlen 64 scopeid 0x20<link>

  21. ether fa:16:3e:a5:b2:bb txqueuelen 1000 (Ethernet)

  22. RX packets 216 bytes 18796 (18.3 KiB)

  23. RX errors 0 dropped 0 overruns 0 frame 0

  24. TX packets 139 bytes 13870 (13.5 KiB)

  25. TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


  26. [root@localhost ~]# ip netns exec qrouter-a1adb970-dba9-49f0-ba4b-4294f0d07f6f route -nne

  27. Kernel IP routing table

  28. Destination Gateway Genmask Flags MSS Window irtt Iface

  29. 0.0.0.0 172.18.22.1 0.0.0.0 UG 0 0 0 qg-426c2bcd-f4

  30. 172.18.22.0 0.0.0.0 255.255.255.0 U 0 0 0 qg-426c2bcd-f4

  31. 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 qr-cf018461-bc

其中 qr-XXX 和 qg-YYY 在 qroute-XXX namespace 中用于连接 br-int 和 br-ex,从第二、三条路由表项是由链路层协议发现并创建的,分别是 Net1 和 public 子网的直连路由,由设备 qr-XXX 和 qg-YYY 转发。而第一条路由表项,则是由 Neutron 添加的默认静态路由,Neutron 从 public 的 gateway_ip 获取到物理外部网关 IP 地址,所有非直连路由的子网访问流量,都会使用默认静态路由进行转发。

Router 的路由表

我们知道路由器的路由表项分配静态路由和动态路由,Neutron 中所有的路由表项均为静态路由(不遵循动态路由协议),又细分为:

  • 静态路由

  • 静态默认路由

  • 直连路由

其中只有 “静态路由” 一种类型会被 Neutron 记录在 Router 资源模型的 routes(数值类型)属性中。

  1. MariaDB [neutron]> desc routerroutes;

  2. +-------------+-------------+------+-----+---------+-------+

  3. | Field | Type | Null | Key | Default | Extra |

  4. +-------------+-------------+------+-----+---------+-------+

  5. | destination | varchar(64) | NO | PRI | NULL | |

  6. | nexthop | varchar(64) | NO | PRI | NULL | | # 目的网段( CIDR)

  7. | router_id | varchar(36) | NO | PRI | NULL | | # 下 一 跳 IP(下一个路由器的端口 IP)