sonic 架构学习

射人先射马,擒贼先擒王
在我们学习sonic的过程中,无疑了解sonic的架构是非常重要的,然后再去了解各个模块的细节,总分学习模式。下面是我自我学习并翻译的链接https://github.com/Azure/SONiC/wiki/Architecture?spm=a2c6h.12873639.0.0.980036b0oeCGJJ

参考文档

#Document Title Document Identifier & Link
1 SONiC official wiki https://github.com/Azure/SONiC/wiki
2 SONiC architecture https://github.com/Azure/SONiC/wiki/Architecture
3 SAI API https://github.com/opencomputeproject/SAI
4 Redis documentation https://redis.io/documentation
5 Click module http://click.pocoo.org/5/
6 JSON introduction https://www.json.org/
7 SONiC supported platforms https://github.com/Azure/SONiC/wiki/Supported-Devices-and-Platforms
8 SONiC Software Architecture 2018 Workshop Videos Slides

SONIC 系统架构

SONiC系统的体系结构包含各种模块,这些模块通过集中式和可扩展的基础结构相互交互。该基础架构依赖于redis数据库引擎的使用:一个提供独立于语言的接口的键值数据库,一种用于所有SONiC子系统之间的数据持久性,复制和多进程通信的方法。

通过依赖redis引擎基础结构提供的发布者/订阅者消息传递范例,应用程序只能订阅他们所需的数据视图,并避免与功能无关的实现细节。

SONiC将每个模块放置在独立的docker容器中,以在语义仿射组件之间保持较高的内聚性,同时减少相互分离的组件之间的耦合。这些组件中的每一个都完全独立于与较低层抽象交互所需的特定于平台的细节而编写。
截至今天,SONiC将其主要功能组件分为以下docker containers:
Dhcp-relay

Pmon

Snmp

Lldp

Bgp

Teamd

Database

Swss

Syncd

下图显示了每个Docker容器中包含的功能的高级视图,以及这些容器之间的交互方式。请注意,并非所有SONiC应用程序都与其他SONiC组件进行交互,因为其中一些组件是从外部实体收集其状态的。我们使用蓝色箭头来表示与集中式redis引擎的交互,而使用黑色箭头来表示其他所有(网络链接,/ sys文件系统等)。

即使SONiC的大多数主要组件都保存在docker容器中,但在Linux主机系统本身中仍存在一些关键模块。 SONiC的配置模块(sonic-cfggen)和SONiC的CLI就是这种情况。

本文档的后续部分将介绍所有可能的组件交互作用以及正在转移的关联状态的更完整描述

在这里插入图片描述

SONIC 子系统介绍

本部分旨在提供每个docker容器中包含的功能的描述,以及从linux-host系统运行的主要SONiC组件。目的是为读者提供高层次的介绍。在后续部分中,将采用一种更加图形化(希望如此)的直观方法。

teamed 容器:在SONiC设备中运行链接聚合功能(LAG)。 “ teamed”是基于Linux的LAG协议的开源实现。 “团队同步”过程允许“团队”子系统和南向子系统之间进行交互。

Pmon容器:负责运行“ sensored”的守护程序,该守护程序用于定期记录硬件组件中的传感器读数并在发出警报时发出警报。 Pmon容器还托管“ fancontrol”进程,以从相应的平台驱动程序收集与风扇相关的状态。

Snmp容器:托管snmp功能。此容器中有两个相关过程:
------Snmpd:负责处理来自外部网络元素的传入snmp轮询的实际snmp服务器。
-------Snmp代理(sonic_ax_impl):这是SONiC的AgentX snmp子代理的实现。该子代理向主代理(snmpd)提供从集中式Redis引擎中SONiC数据库收集的信息。

Dhcp中继容器:dhcp中继代理可将DHCP请求从没有DHCP服务器的子网中继到其他子网上的一台或多台DHCP服务器。

Lldp容器:顾名思义,此容器承载lldp功能。这些是在此容器中运行的相关进程:
-----Lldp:具有lldp功能的实际lldp守护程序。这是与外部对等方建立lldp连接以通告/接收系统功能的过程。
-----Lldp_syncd:负责将lldp的发现状态上载到集中式系统的消息基础结构(重新分发引擎)的过程。这样,lldp状态将传递给对使用此信息感兴趣的应用程序(例如snmp)。
-------Lldpmgr:进程为lldp守护程序提供增量配置功能;它通过在redis引擎内订阅STATE_DB来实现。有关此主题的详细信息,请参见下文。

Bgp容器:运行支持的路由堆栈之一:Quagga或FRR。即使容器是根据使用的路由协议(bgp)命名的,实际上,这些路由堆栈也可以运行其他各种协议(例如ospf,isis,ldp等)。

BGP容器功能细分如下:
----bgpd:常规的bgp实现。来自外部各方的路由状态通过常规的tcp / udp套接字接收,并通过zebra / fpmsyncd接口下推到转发平面。

----zebra:充当传统的IP路由管理器;也就是说,它提供了跨不同协议的内核路由表更新,接口查找和路由重新分配服务。 Zebra还负责将计算出的FIB下推到内核(通过netlink接口)和转发过程中涉及的南向组件(通过Forwarding-Plane-Manager接口–FPM–)。

----fpmsyncd:小型守护程序,负责收集由zebra生成的FIB状态并将其内容转储到redis引擎中的Application-DB表(APPL_DB)中。

数据库容器:托管redis数据库引擎。 SONiC应用程序可以通过redis-daemon为此目的公开的UNIX套接字访问SONiC应用程序中的数据库。这些是redis引擎托管的主要数据库:

----APPL_DB:存储由所有应用程序容器生成的状态-路由,下一跳,邻居等。这是所有希望与其他SONiC子系统进行交互的应用程序的南向入口点。

----CONFIG_DB:存储SONiC应用程序创建的配置状态-端口配置,接口,VLAN等。

----STATE_DB:存储系统中配置的实体的“键”操作状态。此状态用于解决不同SONiC子系统之间的依赖性。例如,LAG端口通道(由组合子模块定义)可以潜在地指代系统中可能存在或可能不存在的物理端口。另一个示例是VLAN的定义(通过vlanmgrd组件),它可以引用系统中不确定其存在的端口成员。本质上,此数据库存储所有被认为是解决交叉模块依赖性所必需的状态。

----ASIC_DB:存储必要的状态以驱动asic的配置和操作-此处的状态保持为asic友好格式,以简化已同步(请参见下面的详细信息)和asic SDK之间的交互。

----COUNTERS_DB:存储与系统中每个端口关联的计数器/统计信息。此状态可用于满足CLI本地请求,或用于遥测通道。

Swss容器:交换状态服务(SwSS)容器包含一组工具,以允许所有SONiC模块之间进行有效通信。如果数据库容器擅长提供存储功能,则Swss主要致力于提供机制来促进所有不同方之间的通信和仲裁。

Swss还托管负责与SONiC应用程序层进行北向交互的进程。如前所述,fpmsyncd,teamsyncd和lldp_syncd进程是一个例外,它们分别在bgp,teamd和lldp容器的上下文中运行。无论这些过程在swss容器内部还是外部运行的环境如何,它们都有相同的目标:提供允许SONiC应用程序与SONiC集中式消息基础结构(重新设计引擎)之间连接的方法。这些守护程序通常由所使用的命名约定标识:* syncd。
----Portsyncd:侦听与端口相关的netlink事件。在启动过程中,portsyncd通过解析系统的硬件配置文件配置文件来获取物理端口信息。在所有这些情况下,portsyncd最终会将所有收集的状态推送到APPL_DB中。通过该通道传输端口速度,通道和mtu等属性。 Portsyncd还将状态注入STATE_DB。有关更多详细信息,请参阅下一部分。

----Intfsyncd:侦听与接口相关的netlink事件,并将收集的状态推送到APPL_DB中。与该接口相关联的属性(例如新/更改的ip地址)由该过程处理。

----Neighsyncd:侦听由于ARP处理而由新发现的邻居触发的邻居相关的网络链接事件。该守护程序处理诸如mac-address和邻居的address-family之类的属性。该状态最终将用于构建数据平面中出于L2重写目的所需的邻接表。再一次,所有收集的状态最终都将转移到APPL_DB。

----Teamsyncd:先前讨论过-在成组的docker容器中运行。与前面的情况一样,将获得的状态推送到APPL_DB中。

----Fpmsyncd:先前讨论过-在bgp docker容器中运行同样,将收集的状态注入到APPL_DB中。

----Lldp_syncd:前面也讨论过-在lldp docker容器中运行。

当将信息注入redis引擎所代表的发布者-订阅者管道时,上述过程显然充当了状态产生者的角色。但是显然,必须有另一组进程充当订阅者,他们愿意消费和重新分配所有此传入状态。以下守护程序就是这种情况:
----Orchagent:Swss子系统中最关键的组件。 Orchagent包含的逻辑可提取* syncd守护程序注入的所有相关状态,并相应地处理和发送此信息,最后将其推向其南向接口。这个向南的接口又是redis引擎(ASIC_DB)中的另一个数据库,因此,我们可以看到,Orchagent既作为使用者(例如来自APPL_DB的状态)运行,又作为生产者(对于状态为推送到ASIC_DB中)。

----IntfMgrd:对从APPL_DB,CONFIG_DB和STATE_DB到达的状态做出反应,以配置Linux内核中的接口。仅当所监视的任何数据库中没有冲突或不一致的状态时,才完成此步骤。请参阅上面的数据库容器部分,以获取这种不良行为的示例。

----VlanMgrd:对从APPL_DB,CONFIG_DB和STATE_DB到达的状态做出反应,以在Linux内核中配置vlan接口。与IntfMgrd的情况一样,只有在没有任何未满足的依赖状态/条件被满足时,才会尝试执行此步骤。

Syncd container:简而言之,同步容器的目标是提供一种机制,以允许将交换机的网络状态与交换机的实际硬件/ ASIC进行同步。这包括开关的ASIC当前状态的初始化,配置和收集。
这些是同步容器中存在的主要逻辑组件:
----Syncd:负责执行上述同步逻辑的过程。在编译时,与硬件供应商提供的ASIC SDK库进行同步链接,并通过调用为此提供的接口将状态注入ASIC。 Syncd订阅ASIC_DB以从SWSS actor接收状态,同时注册为发布者以推送来自硬件的状态

----SAI API:交换机抽象接口(SAI)定义了API,以统一方式提供了独立于供应商的方式来控制转发元素,例如交换ASIC,NPU或软件交换机。有关SAI API的更多详细信息,请参见[3]。

----ASIC SDK:硬件供应商应提供驱动其ASIC所需的SDK的SAI友好实现。通常以动态链接库的形式提供此实现,该库链接到负责驱动其执行的驱动过程(在这种情况下是同步的)。

CLI / sonic-cfggen:SONiC模块,负责提供CLI功能和系统配置功能。
CLI组件在很大程度上依赖于Python的Click库[5]为用户提供一种灵活且可自定义的构建命令行工具的方法。
Sonic-cfggen组件由SONiC的CLI调用以执行配置更改或需要与SONiC模块进行与配置相关的交互的任何操作。 [] {。underline}

SONIC 子系统交互

本节预告为读者提供对各种SONiC组件之间发生的相互关联作用的详细了解。正在交换的特定状态。

LLDP-state 交互

下图描述了在LLDP状态转移事件期间观察到的一组相互作用。在此特定示例中,我们遍历在携带状态更改的LLDP消息到达时发生的一系列步骤。

在这里插入图片描述
(1)在LLDP容器初始化期间,lldpmgrd订阅STATE_DB以获得系统中物理端口状态的实时提要-lldpmgrd的轮询周期每5秒运行一次。基于此信息,Lldpd(及其网络对等方)将随时了解系统端口状态的变化以及影响其运行的任何配置变化。

(2)在某个时刻,新的LLDP数据包到达内核空间中lldp的套接字。内核的网络堆栈最终将关联的有效负载交付给lldp进程。

(3)Lldp解析并消化此新状态,该状态最终由lldp_syncd在执行lldpctl cli命令的过程中匹配-通常每10秒运行一次。

(4)Lldp_syncd将此新状态推送到APPL_DB中,具体到表LLDP_ENTRY_TABLE。

(5)从这一刻起,所有订阅此表的实体都应收到新状态的副本(当前,snmp是唯一感兴趣的侦听器)。

SNMP-state 交互

如前所述,snmp容器既托管snmp主代理(snmpd),也托管SONiC特定的agentX进程(snmp_subagent)。该子代理与所有提供可从中导出MIB状态的信息的redis数据库/表进行交互。具体而言,snmp-agent订阅以下数据库/表:
APPL_DB: PORT_TABLE, LAG_TABLE, LAG_MEMBER_TABLE, LLDP_ENTRY_TABLE

STATE_DB: *

COUNTERS_DB: *

ASIC_DB: ASIC_STATE:SAI_OBJECT_TYPE_FDB*
下图描述了系统处理传入的snmp查询期间各种SONiC组件之间的典型交互。
在这里插入图片描述

(0)在对snmp-subagent进程中支持的不同MIB子组件进行初始化的过程中,该组件建立与上述各种DB的连接。从此刻开始,将从所有这些DB获得的状态本地缓存在snmp-subagent中。每隔几秒钟(<60)刷新一次此信息,以确保DB和snmp-subagent完全同步。

(1)snmp查询到达内核空间中snmp的套接字。内核的网络堆栈将数据包交付给snmpd进程。

(2)解析snmp消息,并将关联的请求发送到SONiC的agentX子代理(即sonic_ax_impl)。

(3)Snmp-subagent为查询提供服务,该查询超出了其本地数据结构中缓存的状态,并将信息发送回snmpd进程。

(4)Snmpd最终通过通常的套接字接口将回复发送回发起者。

Routing-state 交互

在本节中,我们将遍历SONiC中处理从eBGP对等方接收到的新路由的一系列步骤。我们将假定已经建立了该会话,并且正在学习一条将直接连接的对等方用作下一跳的新路由。

下图显示了此过程涉及的元素。请注意,我故意删除了与此SONiC架构描述无关的细节。
在这里插入图片描述
(0)在BGP容器初始化期间,zebra通过常规TCP套接字连接到fpmsyncd。在稳定/非瞬态条件下,确认zebra,Linux内核,APPL_DB和ASIC_DB中保存的路由表是完全一致/等效的。

(1)一个新的TCP数据包到达内核空间中bgp的套接字。内核的网络堆栈最终将相关的有效负载交付给bgpd进程。

(2)Bgpd解析新数据包,处理bgp-update并通知zebra该新前缀及其相关协议的下一跳的存在。

(3)在zebra确定该前缀的可行性/可及性之后(例如,现有的转发nh),zebra生成了一个路由网络链接消息,以将该新状态注入内核。

(4)Zebra利用FPM接口将该网络链接路由消息传递给fpmsyncd。

(5)Fpmsyncd处理netlink消息并将此状态推入APPL_DB。

(6)被安排为APPL_DB订户时,它将接收先前推送到APPL_DB的信息的内容。

(7)处理收到的信息后,orchagentd将调用sairedis API,以将路由信息注入ASIC_DB。

(8)正在同步ASIC_DB订户,它将接收orchagentd生成的新状态。

(9)Syncd将处理该信息并调用SAI API将此状态注入到相应的asic驱动程序中。

(10)新路线最终被推向硬件。

Port-state 交互

本节描述了与端口相关的信息传输期间发生的系统交互。考虑到portsyncd发挥的关键作用以及它在其他SONiC子系统中施加的依赖关系,我们通过覆盖其初始化过程来开始本节。

此练习的目标是双重的。首先,我们在系统中公开了对产生或使用端口相关信息感兴趣的多个组件。其次,我们通过一个图形化的示例向读者介绍STATE_DB在系统中的使用方式,以及不同的应用程序如何依靠其信息进行内部操作。
在这里插入图片描述
(0)在初始化期间,portsyncd与redis引擎中的主数据库建立通信通道。 Portsyncd声明打算充当APPL_DB和STATE_DB的发布者,以及CONFIG_DB的订阅者。同样,portsyncd也订阅系统的netlink通道,该通道负责传送端口/链接状态信息。

(1)Portsyncd通过解析与系统中正在使用的硬件配置文件/ sku相关联的端口配置文件(port_config.ini)开始(更多信息,请参阅配置部分)。与通道相关的信息(例如通道,接口名称,接口别名,速度等)将通过此通道传输到APPL_DB。

(2)Orchagent听到了所有这些新状态,但是将推迟对其执行操作,直到portsyncd通知它已完全完成解析port_config.ini信息为止。一旦发生这种情况,orchagent将继续进行硬件/内核中相应端口接口的初始化。 Orchagent调用sairedis API来传递此请求,以通过常规ASIC_DB接口进行同步。

(3)Syncd通过ASIC_DB接收此新请求,并准备调用满足Orchagent的请求所需的SAI API。

(4)Syncd利用SAI API + ASIC SDK创建与正在初始化的物理端口相关的内核主机接口。

(5)上一步将生成一个netlink消息,该消息将被portsyncd接收。与先前从port_config.ini解析的所有端口相关的消息到达portsyncd后(在步骤1),portsyncd将继续声明“初始化”过程已完成。

(6)作为上一步的一部分,portsyncd将记录条目写入与成功初始化的每个端口相对应的STATE_DB中。

(7)从现在开始,以前订阅STATE_DB内容的应用程序将收到通知,以允许这些应用程序开始使用它们所依赖的端口。换句话说,如果在STATE_DB中找不到用于特定端口的有效条目,则任何应用程序都无法使用它。
注意:截止到今天,这些都是活跃的应用程序
监听STATE_DB中的更改:teamsyncd,intfmgrd,vlanmgrd
和lldpmgr。我们将在后续内容中介绍所有这些组件
部分-lldpmgr已在上面解决

现在,让我们遍历物理端口发生故障时发生的步骤顺序:
在这里插入图片描述
(0)如概述部分所述,syncd在ASIC_DB上下文中既充当发布者又充当订阅者。 “订阅者”模式显然是需要同步以接收来自北向应用程序的状态的,这是迄今为止所有模块交互的情况。需要使用“发布者”模式来允许同步,以将硬件衍生事件的到达通知给更高级别的组件。

(1)在相应的ASIC的光模块检测到载波丢失后,将向相关的驱动程序发送通知,该驱动程序又将此信息传递给已同步。

(2)Syncd调用适当的通知处理程序,并将port-down事件发送到ASIC_DB。

(3)Orchagent利用其通知线程(专用于此任务)从ASIC_DB收集新状态,并执行“端口状态更改”处理程序以:
----a.生成APPL \ _DB的更新以警告依赖于的应用程序
操作状态(e.g. CLI – “show interface
status”).

----b.调用sairedis API,以提醒同步更新
与端口的主机接口关联的内核状态
拿下来。再次,orchagent传递此请求以进行同步
通过常规的ASIC \ _DB接口。

(4)Syncd通过ASIC_DB接收此新请求,并准备调用满足Orchagent的请求所需的SAI API。

(5)Syncd使用SAI API + ASIC SDK来用受影响的主机接口的最新操作状态(DOWN)更新内核。

(6)在portsyncd处接收到与上一步关联的netlink消息,由于所有SONiC组件现在都已完全意识到port-down事件,因此该消息被静默丢弃。

接口状态交互。
待定

邻居状态交互。
待定

LAG接口状态交互。
待定

配置状态交互。
待定

有关向用户公开的不同CLI命令以及系统配置文件的更多详细信息,将在本文档的后续部分中介绍。

猜你喜欢

转载自blog.csdn.net/weixin_39094034/article/details/115189718