DeviceLink 的状态

主要流程

DeviceLink的状态中,有下列几种条件可用于跟踪其链接的状态:

  • NodeExisted:节点是否可用
  • ModelExisted:设备模型是否存在
  • AdaptorExisted:适配器是否可用
  • DeviceCreated:是否已创建设备
  • DeviceConnected:是否已连接设备

这是 DeviceLink的示例:

apiVersion: edge.cattle.io/v1alpha1
kind: DeviceLink
metadata:
name: example
namespace: octopus-test
spec:
adaptor:
node: edge-worker
name: adaptors.edge.cattle.io/dummy
model:
apiVersion: "devices.edge.cattle.io/v1alpha1"
kind: "DummyDevice"
template:
metadata:
labels:
device: example
spec:
gear: slow
"on": true

当我们将上述DeviceLink部署到集群中时,brain负载校验NodeExistedModelExistedlimb负载校验AdaptorExistedDeviceCreatedDeviceConnected

首先,brain会验证spec.adaptor.node中指定的节点是否可用:

┌─────────────────────┐ 节点是否可用?
│ NodeExisted │───────────────┐
└─────────────────────┘ │
.
( ) brain
'

如果该节点可用,brain会验证CRD对应的spec.model(设备模型)是否存在:

┌─────────────────────┐ 节点是否可用?
│ NodeExisted │───────────────┐
└─────────────────────┘ │
节点可用 .
┌─────────────────────────( ) brain
│ '
┌─────────────────────┐ 设备模型是否存在?
│ ModelExisted │───────────────┐
└─────────────────────┘ │
.
( ) brain
'
说明

用作设备模型的CRD需要包含注释:devices.edge.cattle.io/enable:true

如果CRD(设备模型)验证通过,则limb将验证适配器(Adaptor)对应的spec.adaptor.name是否可用:

┌─────────────────────┐ 设备模型是否存在?
│ ModelExisted │───────────────┐
└─────────────────────┘ │
设备模型存在 .
┌─────────────────────────( ) brain
│ '
┌─────────────────────┐ 适配器(Adaptor)是否可用?
│ AdaptorExisted │───────────────┐
└─────────────────────┘ │
.
( ) limb
'

您可以检查Adaptor的设计来了解limb如何检测适配器。 如果适配器可用,那么limb将尝试创建与spec.model相关的设备实例:

┌─────────────────────┐ 适配器(Adaptor)是否可用?
│ AdaptorExisted │───────────────┐
└─────────────────────┘ │
yes .
┌─────────────────────────( ) limb
│ '
┌─────────────────────┐ 基于设备模型创建设备实例
│ DeviceCreated │───────────────┐
└─────────────────────┘ │
.
( ) limb
'

成功创建设备实例后,limb将使用spec.template.spec通过适配器(Adaptor)连接该实际设备:

┌─────────────────────┐ 创建设备实例
│ DeviceCreated │───────────────┐
└─────────────────────┘ │
创建成功 .
┌─────────────────────────( ) limb
│ '
┌─────────────────────┐ 连接到真实设备
│ DeviceConnected │───────────────┐
└─────────────────────┘ │
.
( ) limb
'

如果连接状态是healthy,则相应的设备实例将从实际物理设备同步其状态。 以下是所有状态的完整过程:

┌─────────────────────┐ 节点是否可用?
│ NodeExisted │───────────────┐
└─────────────────────┘ │
节点可用 .
┌─────────────────────────( ) brain
│ '
┌─────────────────────┐ 设备模型是否存在?
│ ModelExisted │───────────────┐
└─────────────────────┘ │
存在设备模型 .
┌─────────────────────────( ) brain
│ '
┌─────────────────────┐ 适配器(Adaptor)是否可用?
│ AdaptorExisted │───────────────┐
└─────────────────────┘ │
适配器可用 .
┌─────────────────────────( ) limb
│ '
┌─────────────────────┐ 创建设备实例
│ DeviceCreated │───────────────┐
└─────────────────────┘ │
创建成功 .
┌─────────────────────────( ) limb
│ '
┌─────────────────────┐ 连接到真实设备
│ DeviceConnected │───────────────┐
└─────────────────────┘ │
▲ ▼
│ healthy .
└─────────────────────────( ) limb ─────────┐
' │
▲ ▼
│ .
└───────────────( ) adaptor
'
说明

DeviceLink的状态流是有序执行的,如果前一个状态未准备就绪(不成功或错误),则不会进入到下一个状态。

流程与行为

主要流程并不一定总是向前发展,某些检测逻辑可以对其进行调整以显示当前状态,我们称它们为更正。 有些更正是自动的,但有些需要手动干预。

状态控制器逻辑描述
NodeExistedbrain如果该节点已被删除、驱逐或束缚,则Octopus的brain会将主流重新调整为NodeExisted,并将其标记为不可用。 当节点再次可用时,brain将触发主流重新开始。
ModelExistedbrain如果CRD(设备模型)已被删除或禁用,则brain会将主流调整回ModelExisted并标记为不可用。当CRD再次可用时,brain将触发主要流程,从模型检测开始。
AdaptorExistedlimb如果已删除适配器,则limbs会将主流调整回AdaptorExisted并标记为不可用。当适配器再次可用时,limb将触发主要流程,从适配器检测开始。
DeviceConnectedlimblimbs不会立即察觉到设备实例的意外删除,因为limbs通过适配器控制设备,无法监视到这些真实设备的实例。如果删除处于已经连接状态(DeviceConnected: healthy)的设备,并且适配器的实现是实时或定时地同步实际设备的状态,则它可能有机会由limb重新创建。 limb将触发主要流程再次从设备创建开始。否则,该链接需要手动修改或重新创建该设备。

设备连接状态

在谈论DeviceConnected之前,需要知道Octopus的设备连接管理分为两部分,一个是limb与适配器之间的连接(c1),另一个是适配器与真实设备之间的连接(c2),如下图所示:

┌──────────┐ c1 ┌─────────┐ c2 .
│ limb │◀──────▶│ adaptor │◀──────▶( ) real device
└──────────┘ └─────────┘ '

c1基于gRPC,而c2由适配器确定。 当c1和c2都健康时,limb会将DeviceConnected状态设置为healthy

limb可以观察到c1的变化,如果c1意外关闭,则limb会触发主流从设备连接重新开始。

但是,limb 无法感知 c2是否意外关闭,因此适配器需要负责通知其状态,通常,适配器需要向limb发送ERROR状态的消息。 然后,limb会将 DeviceConnected状态设置为unhealthy

如果中断的c2没有重新连接,则链接将保持unhealthy的状态。