前言
- 对于openstack neutron,曾花费很多的时间去看它的源码,结果啥都没有看出来。
- openstack代码风格是,为了实现plugin的可插拔,运用了很多设计模式,设计思想也非常哲学。这样的好处是,开发者可以专注于自己需要开发的功能而不必关心底层细节,但对于新手,完全是一头雾水。
- 我个人的经验是,一定要多问,从代码结构到实现方式,一旦有人告诉你它的分层结构,豁然开朗。
- 当然你可以上网去搜,但据我所知,网上关于openstack的文档太过浅显,深入源码的分析又看不懂,仅仅说个架构也不见得有多大的帮助。
- 本文主要还是作为笔者对最近neutron开发工作一个简单的总结分析吧,结合我对neutron理解。后续随着本人学习的深入,逐步会出neutron系列的文章。
neutron的开发流程
neutron无须理会实现细节,只要专注于自己开发的功能就好。开发一个plugin,无非就是定义API,设计model,开发db层以及具体实现。
- neutron仅有一个主要服务进程neutron-server,对外提供API,通过它写db,调用plugin进行处理,最终通过消息队列实现RPC发送给agent端处理。
- 无须理解api机制是如何实现的,api分为两类:core api及extension api:core 实现network、subnet以及port的二层功能,extensions主要实现router、lb、qos等三层功能及各类增强实现。各大厂商可以通过实现extensions plugin增加自己的功能。
- neutron_lib/api/definitions 定义了各类extensions api,neutron/extensions下可以实现extensions api的二次扩展或定义自己的extensions api。
- neutron/db/models中实现新功能的db设计
- neutron/db实现db层的增删改查接口,例如l3_db.py,一般可以在这里实现函数,引用ext api中定义的抽象类,重载定义的方法,并调用db.models实现去完成增删改查,同时发送rpc消息让agent端处理
- 此时要让neutron-server在启动时能够加载我们定义的plugin,一般在neutron/services下实现,例如neutron/services/l3_router/l3_router_plugin.py
neutron db升级
- neutron有个db升级工具
neutron-db-manage
,可以生成db升级文件,但无法降级。降级操作需要手动操作数据库。
# 生成数据库升级文件
neutron-db-manage --subproject neutron revision -m test
- 以R版为例,neutron/db/migration/alembic_migrations/version/rocky下会生成相应的文件,命名格式为test_xxxx.py,xxxx是版本编号。
- neutron/db/migration/alembic_migrations/ 路径下存在两个文件,
EXPAND_HEAD
和CONTRACT_HEAD
,neutron项目的两个版本分支,这两个文件分别记录了当前最新的版本编号。 - 两个分支都是独立的,neutron数据库表alembic_version中记录着当前的版本分支,每次升级都会更改。
- 如果需要执行降级操作,则要将alembic_version中的版本编号还原,否则版本时间线会出现差异,导致后续版本操作出现不可知的影响。
# 数据库升级文件中存在如下记录
# revision代表当前升级文件的版本编号
revision = '867d39095bf4'
# down_revision记录了上一个版本升级版本
down_revision = '61663558142c'
# 执行neutron-db-manage,如果指定neutron子项目,则会生成expand和contract两个分支的文件
# 如果没有指定子项目,则会生成包括neutron、fwaas、lbaasv2等全部项目的双分支的升级文件
# 实际上只需要单独编写一个分支执行升级就好,多余的文件实属冗余
neutron-db-manage upgrade --expand # 升级expand分支
neutron-db-manage upgrade --contract # 升级contract分支
- 通过这种方式,neutron维护了一套版本滚动升级的方式,版本时间线衔接向前,无论是升级还是回滚都有迹可循。