SONiC系统由两部分组成:
1.彼此交互的模块
2.用于交互的基础设施(集中式,可扩展)
其中用于交互的基础设施主要是一个非关系型数据库Redis引擎:
1.提供了一个无视语言的接口
2.是一种数据保持,复制和多进程交互的手段
每个模块只订阅自己关注的数据
每个模块都存在于各自的Docker容器里形成独立的组件,每个组件都与平台细节完全解耦
SONiC由一下几个容器组成:
下图描绘出了每个模块中包含的功能,以及它们之间的交互。
不是所有的功能都与Redis服务器交互,其中一些功能与外部实体(netlink,文件系统等)产生交互。
图中蓝色箭头表示与Redis数据库的交互,黑色交投表示与外部实体的交互
不是所有的功能都位于某个容器中,比如CLI和sonic配置模块,就是位于Linux主机上的
可以运行Quagga或FRR的路由协议栈
此容器可以进一步分为以下几个部分:
SWitch State Service是一组工具套装,它能有效促使SONiC各个模块之间的交流
它提供了一个机制去促成多方的交流和仲裁
同时,SWSS的几个进程会负责与SONiC应用层的北向交互
其中有三个进程是运行在其他容器里的,包括Fpmsyncd,Teamsyncd和Lldp_syncd
但是无论它们运行在哪个容器里,都有着一个共同的目标:
【提供了 能够使 SONiC应用 和 SONiC的集中式消息基础设施(Redis引擎) 保持连接的途径】
【provide the means to allow connectivity between SONiC applications and SONiC’s centralized message infrastructure (redis-engine).】
这些进程 约定俗成地 命名为 *syncd。下面介绍各种syncd:
以上进程都是发布者,根据 发布者/订阅者 模型,SWSS还需要订阅者的角色来完成对接收到的消息的消耗和转移,下面的几个进程就是这样的角色:
Syncd 的主要目标就是提供一种 能让交换机的网络状态信息 和 交换机硬件/ASIC上的实际状态 保持同步的一种机制。这种机制主要包括初始化,配置以及收集交换机ASIC当前的状态。
它包含了几个主要的逻辑模块:
SONiC中负责提供命令行和系统配置的功能模块。
CLI组件重度依赖Python的Click库,该库为用户提供了一种灵活的客制化的方式去构建一个命令行工具。
Sonic-cfggen组件被SONIC的CLI调用,来完成 对配置修改 和 任何与SONiC模块交互的配置相关的动作。
在这一部分,我们来看一下在收到一个eBGP路由更新时SONiC的处理流程。我们假设会话已经建立起来了,而且学到的新路由以它的直连接口作为下一跳。
下图展示处理流程,有些不必要的步骤已经被省略:
(0) 在BGP容器初始化时,zebra通过一个常规的TCP套接字连接到fpmsyncd。在稳定状态下,zebra所持有的路由表,Linux内核,APPL_DB和ASIC_DB需要保持高度一致。
(1) 一个新的TCP数据包到达位于内核空间的BGP位。内核的网络栈最终将携带的载荷递送至bgpd进程。
(2) Bgpd解析这个新的数据包,处理这个bgp更新,并且通知zebra这个新前缀的存在和与该协议相关的下一跳。
(3) 根据zebra的可达性判断,zebra生成一个route-netlink状态信息并将其注入到内核。
(4) Zebra 利用 FPM接口 发送这个netlink-route消息至fpmsyncd.
(5) Fpmsyncd处理该netlink消息然后推送该消息至APPL_DB.
(6) 作为订阅APPL_DB的订阅者,orchagentd将接收之前被推送至APPL_DB的信息内容。
(7) 完成对接收信息的处理后,orchagentd将引用sairedis APIs完成对ASIC_DB的路由信息注入。
(8) 作为订阅ASIC_DB的订阅者,syncd将接收 产生于orchagentd的 新状态信息。
(9)Syncd将会处理信息,然后引用SAI APIs,将这个状态信息注入到相应的asic驱动器中。
(10) 最终,新路由信息被推送到硬件。