前置条件

已有 k3s 集群或 Kubernetes 集群。

使用步骤

在本演练中,我们将部署 Octopus 并通过其管理一类虚拟设备并执行以下任务:

  1. 使用 k3d 搭建 k3s 集群
  2. 部署 Octopus
  3. 部署设备模型和设备控制器
  4. 创建 DeviceLink
  5. 管理设备

1. 使用 k3d 搭建 k3s 集群(可选)

k3d是快速搭建容器化 k3s 集群的工具。 您可以使用 Docker 在单台计算机上启动多节点 k3s 集群。如果您已有 k3 集群或 Kubernetes 集群,请跳过此步骤。

  1. 运行以下指令,启动具有 3 个 worker 节点的本地 k3s 集群。

    1. curl -fL https://octopus-assets.oss-cn-beijing.aliyuncs.com/k3d/cluster-k3s-spinup.sh | bash -

    :::note 说明 如果安装成功,则应该看到以下日志,请使用CTRL+C键以停止本地集群。 :::

    1. [INFO] [0604 17:09:41] creating edge cluster with v1.17.2
    2. INFO[0000] Created cluster network with ID d5fcd8f2a5951d9ef4dba873f57dd7984f25cf81ab51776c8bac88c559c2d363
    3. INFO[0000] Created docker volume k3d-edge-images
    4. INFO[0000] Creating cluster [edge]
    5. INFO[0000] Creating server using docker.io/rancher/k3s:v1.17.2-k3s1...
    6. INFO[0008] SUCCESS: created cluster [edge]
    7. INFO[0008] You can now use the cluster with:
    8. export KUBECONFIG="$(k3d get-kubeconfig --name='edge')"
    9. kubectl cluster-info
    10. [WARN] [0604 17:09:50] default kubeconfig has been backup in /Users/guangbochen/.kube/rancher-k3s.yaml_k3d_bak
    11. [INFO] [0604 17:09:50] edge cluster's kubeconfig wrote in /Users/guangbochen/.kube/rancher-k3s.yaml now
    12. [INFO] [0604 17:09:50] waiting node edge-control-plane for ready
    13. INFO[0000] Adding 1 agent-nodes to k3d cluster edge...
    14. INFO[0000] Created agent-node with ID 3197e431b1a060fbb591b4c315c4949f1b472213312ff8e04c898e3353e05bdc
    15. [INFO] [0604 17:10:01] waiting node edge-worker for ready
    16. INFO[0000] Adding 1 agent-nodes to k3d cluster edge...
    17. INFO[0000] Created agent-node with ID d9bb3e589e745797f3b189962d14de77cfc6afe86d1b6af93a43d808a9c72b5c
    18. [INFO] [0604 17:10:13] waiting node edge-worker1 for ready
    19. INFO[0000] Adding 1 agent-nodes to k3d cluster edge...
    20. INFO[0000] Created agent-node with ID bc69aa9867aa2081df0cf425661ae002142bd667d3d618bc5a5b34bc092d7562
    21. [INFO] [0604 17:10:25] waiting node edge-worker2 for ready
    22. [WARN] [0604 17:10:37] please input CTRL+C to stop the local cluster
  2. 打开一个新终端,并配置KUBECONFIG以访问本地 k3s 集群。

    1. export KUBECONFIG="$(k3d get-kubeconfig --name='edge')"
  3. 运行kubectl get node命令, 检查本地 k3s 集群的节点是否正常。

    1. kubectl get node
    2. NAME STATUS ROLES AGE VERSION
    3. edge-control-plane Ready master 3m46s v1.17.2+k3s1
    4. edge-worker2 Ready <none> 3m8s v1.17.2+k3s1
    5. edge-worker Ready <none> 3m33s v1.17.2+k3s1
    6. edge-worker1 Ready <none> 3m21s v1.17.2+k3s1

2. 部署 Octopus

两种部署 Octopus 的方法,为方便起见,我们将通过一份 all-in-one的 YAML 文件来部署。 安装程序 YAML 文件位于 Github 上的deploy/e2e目录下:

  1. kubectl apply -f https://raw.githubusercontent.com/cnrancher/octopus/master/deploy/e2e/all_in_one.yaml

预期结果:

  1. namespace/octopus-system created
  2. customresourcedefinition.apiextensions.k8s.io/devicelinks.edge.cattle.io created
  3. role.rbac.authorization.k8s.io/octopus-leader-election-role created
  4. clusterrole.rbac.authorization.k8s.io/octopus-manager-role created
  5. rolebinding.rbac.authorization.k8s.io/octopus-leader-election-rolebinding created
  6. clusterrolebinding.rbac.authorization.k8s.io/octopus-manager-rolebinding created
  7. service/octopus-brain created
  8. service/octopus-limb created
  9. deployment.apps/octopus-brain created
  10. daemonset.apps/octopus-limb created

安装后,我们可以验证 Octopus 的状态,如下所示:

  1. kubectl get all -n octopus-system
  2. NAME READY STATUS RESTARTS AGE
  3. pod/octopus-limb-w8vcf 1/1 Running 0 14s
  4. pod/octopus-limb-862kh 1/1 Running 0 14s
  5. pod/octopus-limb-797d8 1/1 Running 0 14s
  6. pod/octopus-limb-8w462 1/1 Running 0 14s
  7. pod/octopus-brain-65fdb4ff99-zvw62 1/1 Running 0 14s
  8. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  9. service/octopus-brain ClusterIP 10.43.92.81 <none> 8080/TCP 14s
  10. service/octopus-limb ClusterIP 10.43.143.49 <none> 8080/TCP 14s
  11. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
  12. daemonset.apps/octopus-limb 4 4 4 4 4 <none> 14s
  13. NAME READY UP-TO-DATE AVAILABLE AGE
  14. deployment.apps/octopus-brain 1/1 1 1 14s
  15. NAME DESIRED CURRENT READY AGE
  16. replicaset.apps/octopus-brain-65fdb4ff99 1 1 1 14s

3. 部署设备模型和设备控制器

接下来我们会使用设备模拟器进行测试(不需要将其连接到真实的物理设备)。

首先,我们需要将设备描述为 Kubernetes 中的一种资源。 此描述过程即为对设备进行建模。 在 Kubernetes 中,描述资源的最佳方法是使用CustomResourceDefinitions,因此定义 Octopus 的设备模型实际上是在定义 CustomResourceDefinition, 可快速浏览一下下列的DummySpecialDevice模型(假设这是一个智能风扇):

:::note 说明 下列 YAML 可通过code-generator动态生成,无需手动编辑。 :::

  1. apiVersion: apiextensions.k8s.io/v1
  2. kind: CustomResourceDefinition
  3. metadata:
  4. annotations:
  5. controller-gen.kubebuilder.io/version: v0.2.5
  6. devices.edge.cattle.io/description: dummy device description
  7. devices.edge.cattle.io/device-property: ""
  8. devices.edge.cattle.io/enable: "true"
  9. devices.edge.cattle.io/icon: ""
  10. labels:
  11. app.kubernetes.io/name: octopus-adaptor-dummy
  12. app.kubernetes.io/version: master
  13. name: dummyspecialdevices.devices.edge.cattle.io
  14. spec:
  15. group: devices.edge.cattle.io
  16. names:
  17. kind: DummySpecialDevice
  18. listKind: DummySpecialDeviceList
  19. plural: dummyspecialdevices
  20. singular: dummyspecialdevice
  21. scope: Namespaced
  22. versions:
  23. - name: v1alpha1
  24. schema:
  25. openAPIV3Schema:
  26. description: DummySpecialDevice is the Schema for the dummy special device
  27. API.
  28. properties:
  29. ...
  30. spec:
  31. description: DummySpecialDeviceSpec defines the desired state of DummySpecialDevice.
  32. properties:
  33. gear:
  34. description: Specifies how fast the dummy special device should be.
  35. enum:
  36. - slow
  37. - middle
  38. - fast
  39. type: string
  40. "on":
  41. description: Turn on the dummy special device.
  42. type: boolean
  43. protocol:
  44. description: Protocol for accessing the dummy special device.
  45. properties:
  46. location:
  47. type: string
  48. required:
  49. - location
  50. type: object
  51. required:
  52. - "on"
  53. - protocol
  54. type: object
  55. status:
  56. description: DummySpecialDeviceStatus defines the observed state of DummySpecialDevice.
  57. properties:
  58. gear:
  59. description: Reports the current gear of dummy special device.
  60. enum:
  61. - slow
  62. - middle
  63. - fast
  64. type: string
  65. rotatingSpeed:
  66. description: Reports the detail number of speed of dummy special device.
  67. format: int32
  68. type: integer
  69. type: object
  70. type: object
  71. ...
  72. status:
  73. ...

虚拟设备适配器(Dummy Adaptor)的安装 YAML 文件位于adaptors/dummy/deploy/e2e目录下,即 all_in_one.yaml, 它包含了设备模型和设备适配器,我们可以通过以下指令将其直接部署到 k3s 集群中:

  1. kubectl apply -f https://raw.githubusercontent.com/cnrancher/octopus/master/adaptors/dummy/deploy/e2e/all_in_one.yaml

预期结果:

  1. customresourcedefinition.apiextensions.k8s.io/dummyspecialdevices.devices.edge.cattle.io created
  2. customresourcedefinition.apiextensions.k8s.io/dummyprotocoldevices.devices.edge.cattle.io created
  3. clusterrole.rbac.authorization.k8s.io/octopus-adaptor-dummy-manager-role created
  4. clusterrolebinding.rbac.authorization.k8s.io/octopus-adaptor-dummy-manager-rolebinding created
  5. daemonset.apps/octopus-adaptor-dummy-adaptor created
  6. kubectl get all -n octopus-system
  7. NAME READY STATUS RESTARTS AGE
  8. pod/octopus-limb-w8vcf 1/1 Running 0 2m27s
  9. pod/octopus-limb-862kh 1/1 Running 0 2m27s
  10. pod/octopus-limb-797d8 1/1 Running 0 2m27s
  11. pod/octopus-limb-8w462 1/1 Running 0 2m27s
  12. pod/octopus-brain-65fdb4ff99-zvw62 1/1 Running 0 2m27s
  13. pod/octopus-adaptor-dummy-adaptor-6xcdz 1/1 Running 0 21s
  14. pod/octopus-adaptor-dummy-adaptor-mmk5l 1/1 Running 0 21s
  15. pod/octopus-adaptor-dummy-adaptor-xnjrf 1/1 Running 0 21s
  16. pod/octopus-adaptor-dummy-adaptor-srsjz 1/1 Running 0 21s
  17. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  18. service/octopus-brain ClusterIP 10.43.92.81 <none> 8080/TCP 2m27s
  19. service/octopus-limb ClusterIP 10.43.143.49 <none> 8080/TCP 2m27s
  20. NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
  21. daemonset.apps/octopus-limb 4 4 4 4 4 <none> 2m27s
  22. daemonset.apps/octopus-adaptor-dummy-adaptor 4 4 4 4 4 <none> 21s
  23. NAME READY UP-TO-DATE AVAILABLE AGE
  24. deployment.apps/octopus-brain 1/1 1 1 2m27s
  25. NAME DESIRED CURRENT READY AGE
  26. replicaset.apps/octopus-brain-65fdb4ff99 1 1 1 2m27s

请注意,还需要授予 Octopus 管理 DummySpecialDevice/DummyProtocolDevice的权限:

  1. $ kubectl get clusterrolebinding | grep octopus
  2. octopus-manager-rolebinding 2m49s
  3. octopus-adaptor-dummy-manager-rolebinding 43s

4. 创建 DeviceLink

前面我们提到过 DeviceLink 是 Octopus 自定义的一个 k8s 资源对象(简称 dl),用户可通过编辑 DeviceLink 的 YAML 文件来进行配置与和管理设备连接。

接下来,我们将通过 DeviceLink YAML 来连接一个虚拟设备。 DeviceLink 由 3 部分组成:Adaptor、Model 和 Device spec。

  • Adaptor - 适配器定义了要使用的适配器(即协议)以及实际设备应连接的节点。
  • Model - 模型描述了设备的模型,它是设备模型的TypeMeta CRD。
  • Device Spec - 设备参数描述了如何连接到设备及其所需的设备属性或状态,这些参数由设备模型的 CRD 来定义。

假设有一个名为 living-room-fan 的设备可以通过 edge-worker 节点连接,我们可以使用以下 YAML 来测试其工作方式。

  1. cat <<EOF | kubectl apply -f -
  2. apiVersion: edge.cattle.io/v1alpha1
  3. kind: DeviceLink
  4. metadata:
  5. name: living-room-fan
  6. namespace: default
  7. spec:
  8. adaptor:
  9. node: edge-worker # select the node that the device will be connect to
  10. name: adaptors.edge.cattle.io/dummy
  11. model:
  12. apiVersion: "devices.edge.cattle.io/v1alpha1"
  13. kind: "DummySpecialDevice"
  14. template:
  15. metadata:
  16. labels:
  17. device: living-room-fan
  18. spec: # specify device specs
  19. protocol:
  20. location: "living_room"
  21. gear: slow
  22. "on": true
  23. EOF

DeviceLink 包含了几种状态,如果我们发现其PHASEDeviceConnectedSTATUSHealthy的状态下,我们就可以使用设备模型的 CRD 对象来查询其状态(即此处的 dummyspecialdevice):

  1. kubectl get devicelink living-room-fan -n default
  2. NAME KIND NODE ADAPTOR PHASE STATUS AGE
  3. living-room-fan DummySpecialDevice edge-worker adaptors.edge.cattle.io/dummy DeviceConnected Healthy 10s

查看虚拟设备上报的状态或信息:

  1. kubectl get dummyspecialdevice living-room-fan -n default -w
  2. NAME GEAR SPEED AGE
  3. living-room-fan slow 10 32s
  4. living-room-fan slow 11 33s
  5. living-room-fan slow 12 36s

5. 管理设备

用户可以使用修改设备属性来管理其设备,例如,假设我们要关闭风扇,可以将其on(开关属性)配置设置为 "on":false

  1. kubectl patch devicelink living-room-fan -n default --type merge --patch '{"spec":{"template":{"spec":{"on":false}}}}'

日志显示 devicelink.edge.cattle.io/living-room-fan is patched,查询其状态,GEARSPEED值均显示为空值(表示已关闭)。

  1. kubectl get devicelink living-room-fan -n default
  2. NAME KIND NODE ADAPTOR PHASE STATUS AGE
  3. living-room-fan DummySpecialDevice edge-worker adaptors.edge.cattle.io/dummy DeviceConnected Healthy 89s
  4. kubectl get dummyspecialdevice living-room-fan -n default
  5. NAME GEAR SPEED AGE
  6. living-room-fan 117s