SONiC Warm Reboot

原文:https://github.com/jipanyang/SONiC/blob/69d76c5fd2d870e2c53cbe367fd09927bb4836ba/doc/warm-reboot/SONiC_Warmboot.md

 

       

 

Overview

        SONiC热重启的目标是能够在不影响数据平面的情况下重启和升级SONiC软件。每个进程/docker的热重启也是目标的一部分。除了syncd和database docker之外,所有其他网络应用程序和docker都需要支持非计划的热重启。
       对于重启处理,SONiC可大致分为三层:

网络应用程序和Orchagent:每个应用程序将经历相似的处理流程。应用程序和相应的orchagent子模块需要协同工作,以恢复原始数据并填充热启动的增量。以路由为例,重启操作后,网络应用程序BGP优雅地重启,通过与对等方的对话与最新的路由状态同步,fpmsyncd利用BGP的输入编写appDB程序,并对除这些路由外的所有旧路由/新路由进行处理,不作任何更改。RouteOrch响应来自fpmsyncd的操作请求,并将任何更改向下传播到syncd。

Syncd:Syncd应该在重启前转储ASICDB,并恢复到与重启前相同的状态。恢复SONiC syncd本身不应干扰ASIC的状态。它从Orchagent获取更改,并在必要的转换之后将其传递给LibSAI/ASIC。
LibSAI/ASIC:ASIC供应商需要确保ASIC和LibSAI的状态恢复到与重启前相同的状态。

SONiC Warm Reboot

 

用例

In-Service restart

在不影响服务的情况下重新启动组件的机制。这假设组件的软件版本在重新启动后没有更改。在重新启动窗口期间,可能会有数据更改,如新/旧路由、端口状态更改、fdb更改。
这里的组件可以是整个SONiC系统,也可以是运行SONiC的一个或多个dockers。

Un-Planned restart

所有网络应用程序和orchagent都希望能够处理计划外重启,并正常恢复。由于对ASIC处理的依赖性,对syncd和ASIC/LibSAI,这不是必要条件。

BGP docker restart

BGP docker重启后,可以从BGP对等方处学习新路由,一些已被推下至APPDB和ASIC的路由可能已不存在。系统应能清除从APPDB到ASIC的陈旧路由,并对新的路由进行编程。

SWSS docker restart

swss docker重启后,所有端口/LAG、vlan、接口、arp和route data都应该从configDB、APPDB、Linux内核和其他可靠来源恢复。在重新启动窗口期间可能会有端口状态、ARP、FDB更改,应执行正确的同步处理。

Syncd docker restart

重新启动syncd docker应保持数据平面完好无损。重启后,syncd恢复对ASIC/LibSAI的控制和与swss docker的通信。在syncd docker中运行的所有其他函数也应该像flexcounter处理一样恢复。

Teamd docker restart

重新启动teamd docker不应导致link 抖动或任何流量损失。数据平面上的所有滞后应保持不变。

In-Service upgrade

在不影响服务的情况下将组件升级到较新版本的机制。
这里的组件可以是整个SONiC系统,也可以是运行SONiC的一个或多个dockers。

Case 1: without SAI api call change

BGP、neighsyncd、portsyncd甚至orchagent等网络应用程序中都有软件更改,但这些更改不会影响到与syncd的接口以及现有数据(元数据和依赖关系图)的组织。在重新启动窗口期间,可能会有数据更改,如新/旧路由、端口状态更改、fdb更改。
服务内重启的所有处理也适用于此。

Case 2: with SAI api call change

Case 2.1 attribute change with SET

新版本的orchagent可能会导致SET api对某些属性使用与以前版本不同的值。或者将调用一个新的属性集。

Case 2.2 Object change with REMOVE

在新的软件版本中,默认情况下可以删除以前版本中存在的对象。

Case 2.3 Object change with CREATE

两种情况:

case 2.3.1 New SAI object

这是在SAI层定义的新对象,在新版软件的orchagent处触发CREATE调用。

case 2.3.2 Old object in previous version to be replaced with new object in new software version

例如,对象将被创建为具有更多或更少的属性或不同的属性值,或者多个实例对象将被替换为聚合对象。这是最复杂的场景,如果旧对象不是叶对象,那么所有其他依赖于旧对象的对象都应该被正确清理。

Cold restart fallback(冷重启回退)

应提供通过SWSS、syncd和teamd dockers配置进行冷重启或热重启的选项。如果热重启失败,应提供冷重启的回退机制。

Proposal 1: Reconciliation at Orchagent

Key steps

Restore to original state

a、 LibSAI/ASIC能够在不中断上层的情况下恢复到重启前的状态。

b、 Syncd能够在不中断ASIC和上层的情况下恢复到重启前的状态。

c、 Syncd状态由Orchagent驱动(FDB除外),一旦恢复,就不需要自己进行调解。

Remove stale date and perform new update

a、 根据每个网络应用程序的具体行为,它要么从configDB读取数据,要么从Linux内核(例如,for port、ARP)和BGP协议等其他源获取数据,然后再次对APPDB进行编程。它跟踪任何过时的数据以便删除。Orchagent使用来自APPDB的请求。
b、 Orchagent从APPDB中恢复在其他docker(如BGP和teamd)中运行的应用程序的数据,以便能够处理仅重启swss的情况,并从configDB恢复ACL数据。Orchagent确保LibSaiRedis接口上的idempotent 操作,不传递以前对对象执行的任何create/remove/set操作。
请注意,为了减少orchagent中的依赖等待时间,松散顺序控制是很有帮助的。路由的恢复可以在端口、lag、接口和ARP数据(主要)处理之后进行。
每个应用程序负责在重启前后收集任何增量,并对增量数据执行创建(新对象)、设置或删除(过时对象)操作。
c、 Syncd处理来自Orchagent的请求,就像正常引导一样。

States of ASIC/LibSAI, syncd, orchagent and applications become consistent and up to date.

(ASIC/LibSAI、syncd、orchagent和应用程序的状态变得一致和最新)

Questions

How syncd restores to the state of pre-shutdown

在这种方法中,syncd只需要保存和恢复对象RID和VID之间的映射。

How Orchagent manages data dependencies during state restore

(Orchagent如何在状态恢复期间管理数据依赖关系)

每个orchagent子例程的构造函数可以正常启动。

每个应用程序从读取configDB数据或Linux内核恢复数据,或者在重新启动时通过网络协议重新填充数据,并相应地对appDB进行编程。每个网络应用程序和orchagent子例程相应地处理依赖关系,这意味着某些操作可能会被延迟,直到所有必需的对象都准备好。依赖性检查已经成为orchagent中现有实现的一部分,但是这个新场景可能会出现新的问题。
为了能够处理只有swss重启的情况,orchagent除了订阅APPDB consumer channel外,还直接从APPDB恢复route(对于BGP docker)和portchannel数据(对于teamd docker)。数据恢复的松散顺序控制有助于加快处理速度。

What is missing in Orchagent for it to restore to the state of pre-shutdown

(Orchagent中缺少什么,以便它恢复到停机前的状态)

Orchagent和application可以在正常启动时从configDB和APPDB获取数据,但是为了能够与syncd同步和通信,还需要为每个键类型为sai_object_id_t的对象提供OID。

typedef struct _sai_object_key_t
{
    union _object_key {
        sai_object_id_t           object_id;
        sai_fdb_entry_t           fdb_entry;
        sai_neighbor_entry_t      neighbor_entry;
        sai_route_entry_t         route_entry;
        sai_mcast_fdb_entry_t     mcast_fdb_entry;
        sai_l2mc_entry_t          l2mc_entry;
        sai_ipmc_entry_t          ipmc_entry;
        sai_inseg_entry_t         inseg_entry;
    } key;
} sai_object_key_t;

How Orchagent gets the OID information

对于对象键类型为sai_object_id_t的对象的SAI redis create操作,Orchagent必须能够使用与关机前完全相同的OID,否则它将与syncd不同步。但目前的Orchagent实现只在运行时数据结构中保存OID。
对于以前通过sai redis get操作获取的对象ID,同样的方法仍然有效。
一个可能的解决方案是在redis_generic_create()保存OID和attr_list之间的映射。这假设在还原期间,对象创建将使用完全相同的 attr_list列表,因此可以找到并返回相同的OID。

当属性第一次发生更改时,原始的默认映射可以保存在DEFAULT_ATTR2OID_ and DEFAULT_OID2ATTR_ tables表中。这是因为在还原过程中,object create可能使用默认属性而不是当前属性。
所有新的更改都将应用于常规ATTR2OID_ and OID2ATTR_ mapping表。
对于为同一组属性创建多个对象的情况,可以为从属性到OID的映射分配一个额外的所有者标识符,因此每个对象基于所有者上下文是唯一可识别的。一个突出的例子是使用lag_alias作为lag所有者,因此每个lag可以在重启期间检索相同的OID,尽管为lag create提供了NULL属性。

+    SET_OBJ_OWNER(lag_alias);
     sai_status_t status = sai_lag_api->create_lag(&lag_id, gSwitchId, 0, NULL);
+    UNSET_OBJ_OWNER();

此解决方案中不需要虚拟OID。但如果保留虚拟OID层,也不会有什么坏处。
LibSaiRedis接口需要Idempotency 。

How to handle the cases of SAI api call change during restore phase.

(如何处理SAI-api调用在恢复阶段发生变化的情况)

案例2.1属性随集更改:在sai_redis_generic_set层,基于object键,比较属性值,并将更改直接应用到syncd/libsai/ASIC。

案例2.2Object change with REMOVE::在 sai_redis_gereric_remove 层,如果在restoreDB中找到了对象键,则直接向syncd/libsai/ASIC应用REMOVE sai api调用。在orchagent已经保证了依赖性。
案例2.3使用CREATE更改对象:
案例2.3.1新SAI对象:只需将SAIAPI创建操作向下应用到syncd/libsai/ASIC。在orchagent已经保证了依赖性。但如果它不是一个叶子对象,那么在创建时对依赖它的其他对象会产生级联效应,这将在下一个用例场景中处理。如果新的SAI对象仅用作其他对象的SET调用中的一个属性,则可以在案例2.1属性随SET更改时处理它。
案例2.3.2用新软件版本中的新对象替换以前版本中的旧对象:如果这是一个叶子对象,如路由条目、邻居条目或fdb条目,只需添加特定于版本的逻辑即可将其删除并创建新的。否则,如果有其他对象必须在create调用期间将此对象用作属性之一,则应先删除这些对象,然后再删除此旧对象。这里需要特定于版本的逻辑。

How to deal with the missing notification during the reboot/restart window

端口/fdb在重新启动窗口期间可能有新的状态通知?可能相应的orchagent子例程应该对对象执行get操作?

Requirements on LibSAI and ASIC

LibSAI和ASIC应该能够保存所有必要的状态关闭请求与热重启选项。在create_switch()请求时,LibSAI/ASIC应恢复到预关闭的确切状态。在整个恢复过程中不应影响数据平面。一旦恢复完成,LibSAI/ASIC工作在正常的操作状态,它们不知道上层发生的任何热重启处理。希望在LibSAI中支持create/remove/set的idempotency ,但对于热重启解决方案可能不是绝对必要的。

Requirements on syncd

Syncd应该能够保存所有必要的状态关闭请求与热重启选项。重新启动时,syncd应恢复到预关机的确切状态。一旦恢复完成,syncd工作在正常的操作状态,它是不可知的,任何热重启处理发生在上层。

Requirement on network applications and orch data

General requirements

每个应用程序都应该能够恢复到关机前的状态。
Orchagent必须能够保存和恢复Orchagent创建的对象的OID,并且对象key 类型为sai_object_id_t.。其他未由Orchagent创建的对象可以通过libsaireis接口的get操作还原OID。
每个应用程序的orchagent子例程可以使用现有的正常构造函数和producerstate/consumerstate处理流,以确保依赖性并填充内部数据结构。
如果docker仅重新启动swss,则它应该能够直接从appDB恢复路由和延迟数据,因为bgp docker和TeamDocker在此场景中不会将整组数据再次提供给appDB。
状态恢复后,每个应用程序都应该能够删除任何过时的对象/状态,并执行任何需要的创建/设置,或者以正常方式处理请求。

Port

Lag/teamd

Interface

Fdb

Arp

Route

Acl

Buffer

Qos

Summary

Layer Restore Reconciliation Idempotency Dependency management
Application/Orchagent Y Y Y for LibSaiRedis interface Y
Syncd Y N Good to have Good to have
LibSAI/ASIC Y N Good to have Good to have

Approach evaluation(方法评估)

Advantages(优势)

  • 简单明了的逻辑,对于大多数升级/重启案例来说易于实现。
  • 层/应用程序解耦,易于分而治之。
  • 每个docker都是独立的,为swss进程和其他网络应用程序的意外热重启做好准备。

Concerns/Issues with this approach(此方法的关注点/问题)

  • Orchagent软件升级可能很方便,特别是对于SAI对象替换的情况,这需要Orchagent使用一次代码来处理它们以进行服务内升级。

Proposal 2: Reconciliation at syncd

The existing syncd INIT/APPLY view framework

基本上有两个视图是为热重启创建的。当前视图表示关闭前的ASIC状态,临时视图表示重新启动后新的预期ASIC状态。基于SAI对象数据模型,每个视图都是一个有向无环图,all(?)对象链接在一起。

Invariants for view comparison(视图比较的不变量)

Switch internal objects discovered vis SAI get operation.

它们包括 SAI_OBJECT_TYPE_PORT, SAI_OBJECT_TYPE_QUEUE, SAI_OBJECT_TYPE_SCHEDULER_GROUP, SAI_OBJECT_TYPE_SCHEDULER_GROUP 等。假设这些对象的RID/VID保持不变。问题1:如果版本更改后发现的对象发生更改,会怎样?

Question 2: what if some of the discovered objects got changed? Like dynamic port breakout case.

Configured attribute values like VLAN id, interface IP and etc.

There could be change to the configured value, those not being changed may work as invariants. Question 3: could some virtual OIDs for created objects in tmp view coincidently match with object in current view, but the objects are different? matchOids().

View comparison logic

视图比较逻辑
利用对象的元数据,以这些不变量作为锚定点,对temp视图中的每个对象,从树的根开始,向下到子节点的所有层,直到叶子找到最佳匹配。如果未找到匹配项,则应在临时视图中创建对象,这是对象创建操作。如果找到了最佳匹配,但临时视图中的对象和当前视图中的对象的属性不同,则应执行设置操作。精确匹配产生Temp VID到当前VID的转换,这也为上层比较铺平了道路。应删除当前视图中末尾引用计数为0的所有对象,请执行“删除”操作。

Question 4: how to handle two objects with exactly same attributes? Example: overlay loopback RIF and underlay loopback RIF. VRF and possibly some other object in same situation?

Question 5: New version of software call create() API with one extra attribute, how will that be handled? Old way of create() plus set() for the extra attribute, or delete the existing object then create a brand new one?

Question 6: findCurrentBestMatchForGenericObject(), the method looks dynamic. What we need is deterministic processing which matches exactly what orchagent will do (if same operation is to be done there instead), no new unnecessary REMOVE/SET/CREATE, how to guarantee that?

问题4:如何处理两个属性完全相同的对象?示例:覆盖环回RIF和参考底图环回RIF。VRF和其他物体在同一情况下?
问题5:新版本的软件调用create()API,它有一个额外的属性,如何处理?“为附加属性创建()加set()的旧方法,还是删除现有对象,然后创建一个全新的对象?”?
问题6:FindCurrentBestMatchForgericObject(),方法看起来是动态的。我们需要的是确定性处理,它与orchagent将要做的事情完全匹配(如果要在那里执行相同的操作),没有新的不必要的移除/设置/创建,如何保证?

Orchagent and network application layer processing

除了libsaireis接口上create/set/remove操作的idempotency 支持外,本方案需要与方案1中相同的处理,如原始数据恢复和每个应用程序根据需要删除appDB陈旧数据。
一种可能但却是一种极端的解决方案是:在应用程序重新启动时,始终刷新所有相关的appDB表,甚至整个appDB,并让每个应用程序从头重新填充新数据。然后,将新数据集向下推到syncd。syncd执行旧数据和新数据之间的比较逻辑。

Approach evaluation

Advantages

  • 基于SAI对象模型的泛型处理。
  • 不需要更改libsairedis库的实现,也不需要在orchagent层恢复OID。

Concerns/Issues with this approach

  • syncd中的高度复杂逻辑
  • 与syncd紧密结合的上层应用程序的热重启。
  • 必须处理来自SAI对象模型的各种转角情况以及SAI对象模型本身的更改。

Open issues(未决问题)

如何在docker级别进行软件升级的版本控制?

Show version命令能够检索每个docker的版本数据。进一步的扩展可能就是基于此。

root@PSW-A2-16-A02.NA62:/home/admin# show version
SONiC Software Version: SONiC.130-14f14a1
Distribution: Debian 8.1
Kernel: 3.16.0-4-amd64
Build commit: 14f14a1
Build date: Wed May 23 09:12:22 UTC 2018
Built by: jipan@ubuntu01

Docker images:
REPOSITORY                 TAG                 IMAGE ID            SIZE
docker-fpm-quagga          latest              0f631e0fb8d0        390.4 MB
docker-syncd-brcm          130-14f14a1         4941b40cc8e7        444.4 MB
docker-syncd-brcm          latest              4941b40cc8e7        444.4 MB
docker-orchagent-brcm      130-14f14a1         40d4a1c08480        386.6 MB
docker-orchagent-brcm      latest              40d4a1c08480        386.6 MB
docker-lldp-sv2            130-14f14a1         f32d15dd4b77        382.7 MB
docker-lldp-sv2            latest              f32d15dd4b77        382.7 MB
docker-dhcp-relay          130-14f14a1         df7afef22fa0        378.2 MB
docker-dhcp-relay          latest              df7afef22fa0        378.2 MB
docker-database            130-14f14a1         a4a6ba6874c7        377.7 MB
docker-database            latest              a4a6ba6874c7        377.7 MB
docker-snmp-sv2            130-14f14a1         89d249faf6c4        444 MB
docker-snmp-sv2            latest              89d249faf6c4        444 MB
docker-teamd               130-14f14a1         b127b2dd582d        382.8 MB
docker-teamd               latest              b127b2dd582d        382.8 MB
docker-sonic-telemetry     130-14f14a1         89f4e1bb1ede        396.1 MB
docker-sonic-telemetry     latest              89f4e1bb1ede        396.1 MB
docker-router-advertiser   130-14f14a1         6c90b2951c2c        375.4 MB
docker-router-advertiser   latest              6c90b2951c2c        375.4 MB
docker-platform-monitor    130-14f14a1         29ef746feb5a        397 MB
docker-platform-monitor    latest              29ef746feb5a        397 MB
docker-fpm-quagga          130-14f14a1         5e87d0ae9190        389.4 MB

SONiC中的回滚支持

这是一个一般要求,不限于热重启。可能应该为这个主题准备一个单独的设计文档。

对控制平面停机时间有什么要求?

目前,在热重启期间,对控制平面的停机时间没有硬性要求。应商定适当的数目。

支持热重启的升级路径

No clear requirement available yet. The general idea is to support warm reboot between consecutive SONiC releases.

目前还没有明确的要求。总体思路是在连续的SONiC版本之间支持热重启。

LibSAI/SDK热重启延迟要求

这一层还没有严格的要求。大概是几秒钟,比如说10秒钟?

SAI/LibSAI/SDK的向后兼容性要求?

是的,对于热重启支持,向后兼容性是必需的。

对于热重启期间的数据平面流量,LibSAI/SDK有什么要求?FDB可以flushed吗? 

现有数据流在数据平面上没有丢包。通常,FDB flush应该由LibSAI/SDK的NOS instread触发。

SONiC支持热重启的原则是什么?

其中一个原则就是在每一层/模块/docker上都有热重启支持,每一层/模块/docker都是独立的。

 

 

 

 

 

上一篇:linux – 在crontab中运行脚本 – 找不到reboot:command


下一篇:Android:通过手机重启持续通知