主要流程

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

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

这是 DeviceLink的示例:

  1. apiVersion: edge.cattle.io/v1alpha1
  2. kind: DeviceLink
  3. metadata:
  4. name: example
  5. namespace: octopus-test
  6. spec:
  7. adaptor:
  8. node: edge-worker
  9. name: adaptors.edge.cattle.io/dummy
  10. model:
  11. apiVersion: "devices.edge.cattle.io/v1alpha1"
  12. kind: "DummyDevice"
  13. template:
  14. metadata:
  15. labels:
  16. device: example
  17. spec:
  18. gear: slow
  19. "on": true

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

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

  1. ┌─────────────────────┐ 节点是否可用?
  2. NodeExisted │───────────────┐
  3. └─────────────────────┘
  4. .
  5. ( ) brain
  6. '

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

  1. ┌─────────────────────┐ 节点是否可用?
  2. NodeExisted │───────────────┐
  3. └─────────────────────┘
  4. 节点可用 .
  5. ┌─────────────────────────( ) brain
  6. '
  7. ┌─────────────────────┐ 设备模型是否存在?
  8. │ ModelExisted │───────────────┐
  9. └─────────────────────┘ │
  10. .
  11. ( ) brain
  12. '

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

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

  1. ┌─────────────────────┐ 设备模型是否存在?
  2. ModelExisted │───────────────┐
  3. └─────────────────────┘
  4. 设备模型存在 .
  5. ┌─────────────────────────( ) brain
  6. '
  7. ┌─────────────────────┐ 适配器(Adaptor)是否可用?
  8. │ AdaptorExisted │───────────────┐
  9. └─────────────────────┘ │
  10. .
  11. ( ) limb
  12. '

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

  1. ┌─────────────────────┐ 适配器(Adaptor)是否可用?
  2. AdaptorExisted │───────────────┐
  3. └─────────────────────┘
  4. yes .
  5. ┌─────────────────────────( ) limb
  6. '
  7. ┌─────────────────────┐ 基于设备模型创建设备实例
  8. │ DeviceCreated │───────────────┐
  9. └─────────────────────┘ │
  10. .
  11. ( ) limb
  12. '

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

  1. ┌─────────────────────┐ 创建设备实例
  2. DeviceCreated │───────────────┐
  3. └─────────────────────┘
  4. 创建成功 .
  5. ┌─────────────────────────( ) limb
  6. '
  7. ┌─────────────────────┐ 连接到真实设备
  8. │ DeviceConnected │───────────────┐
  9. └─────────────────────┘ │
  10. .
  11. ( ) limb
  12. '

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

  1. ┌─────────────────────┐ 节点是否可用?
  2. NodeExisted │───────────────┐
  3. └─────────────────────┘
  4. 节点可用 .
  5. ┌─────────────────────────( ) brain
  6. '
  7. ┌─────────────────────┐ 设备模型是否存在?
  8. │ ModelExisted │───────────────┐
  9. └─────────────────────┘ │
  10. 存在设备模型 .
  11. ┌─────────────────────────( ) brain
  12. │ '
  13. ┌─────────────────────┐ 适配器(Adaptor)是否可用?
  14. AdaptorExisted │───────────────┐
  15. └─────────────────────┘
  16. 适配器可用 .
  17. ┌─────────────────────────( ) limb
  18. '
  19. ┌─────────────────────┐ 创建设备实例
  20. │ DeviceCreated │───────────────┐
  21. └─────────────────────┘ │
  22. 创建成功 .
  23. ┌─────────────────────────( ) limb
  24. │ '
  25. ┌─────────────────────┐ 连接到真实设备
  26. DeviceConnected │───────────────┐
  27. └─────────────────────┘
  28. healthy .
  29. └─────────────────────────( ) limb ─────────┐
  30. ' │
  31. ▲ ▼
  32. │ .
  33. └───────────────( ) adaptor
  34. '

:::note 说明 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),如下图所示:

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

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

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

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

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