云原生管理端设备

本文档主要讲述如何在已有的OpenYurt集群上使用PlatformAdmin部署EdgeX系统和YurtIoTDock组件。 在 OpenYurt v1.4 版本中,我们升级了原来的 yurt-edgex-manager 和 yurt-device-controller 组件。前者已经内置于 yurt-manager 中,用户可以通过编写 Yaml 文件来创建 PlatformAdmin 资源,简单几行配置就可以往节点池内构建一套完整的 EdgeX 系统;后者更名为 yurt-iot-dock ,会在 PlatformAdmin 创建时自动下发到边缘侧,实现帮助用户一键实现端设备托管的能力。

如果你还没有OpenYurt集群,你可以使用yurtadm工具来初始化一个OpenYurt集群或将一个Kubernetes集群转换为OpenYurt集群。

环境要求

  • OpenYurt v1.4.0+

  • 安装了yurt-manager组件

  • 与master不在同一局域网下的节点都需要部署coreDNS pod

  • 将访问coreDNS service的流量改为节点池内闭环,参考教程

安装YurtIoTDock环境

如果想要使用PlatformAdmin来部署yurt-iot-dock,需要先将yurt-iot-dock相关的helm包安装到集群中。

  1. helm install yurt-iot-dock ./charts/yurt-iot-dock

端设备平台管理

1. 创建节点池

首先创建两个节点池,一个是名为beijing的云端节点池,一个是名为hangzhou的边缘节点池。

  1. # 创建beijing节点池
  2. cat << EOF | kubectl apply -f -
  3. apiVersion: apps.openyurt.io/v1beta1
  4. kind: NodePool
  5. metadata:
  6. name: beijing
  7. spec:
  8. type: Cloud
  9. EOF
  10. # 创建hangzhou节点池
  11. cat << EOF | kubectl apply -f -
  12. apiVersion: apps.openyurt.io/v1beta1
  13. kind: NodePool
  14. metadata:
  15. name: hangzhou
  16. spec:
  17. type: Edge
  18. EOF

然后将指定的节点加入节点池,标记openyurt-worker节点为云端节点,标记openyurt-worker2节点为边缘节点

  1. # 将openyurt-worker标记为云端节点
  2. kubectl label node openyurt-worker apps.openyurt.io/nodepool=beijing
  3. # 将openyurt-worker2标记为边缘节点
  4. kubectl label node openyurt-worker2 apps.openyurt.io/nodepool=hangzhou

最后检查节点池状态,确保节点池状态正常

  1. # 检查节点池状态
  2. kubectl get np
  3. NAME TYPE READYNODES NOTREADYNODES AGE
  4. beijing Cloud 1 0 4d18h
  5. hangzhou Edge 1 0 4d18h

2. 在节点池内创建IoT系统PlatformAdmin

配置好使用EdgeX版本,选择在hangzhou节点池中创建

  1. # 在节点池hangzhou中创建minnesota版本的EdgeX
  2. cat <<EOF | kubectl apply -f -
  3. apiVersion: iot.openyurt.io/v1alpha2
  4. kind: PlatformAdmin
  5. metadata:
  6. name: edgex-sample
  7. spec:
  8. version: minnesota
  9. poolName: hangzhou
  10. EOF
  11. # 检查部署情况
  12. kubectl get po
  13. NAME READY STATUS RESTARTS AGE
  14. edgex-core-command-hangzhou-4j6pz-8668ff94d7-hqw2r 1/1 Running 0 61s
  15. edgex-core-common-config-bootstrapper-hangzhou-jnw2q-57bd99xr9p 1/1 Running 0 61s
  16. edgex-core-consul-hangzhou-6p9tj-798489c647-6xz4m 1/1 Running 0 61s
  17. edgex-core-metadata-hangzhou-6l7v5-6f964fc4f-67f9p 1/1 Running 0 61s
  18. edgex-redis-hangzhou-cwgsw-5c7d7fc478-fsgp9 1/1 Running 0 61s

3. 部署可选组件

目前v1.4.0的PlatformAdmin支持通过components字段一键部署可选组件,下面是通过components字段部署yurt-iot-dock、edgex-device-virtual、edgex-device-rest的例子

可选组件的组件名参考Component文档

  1. # 在刚才部署的PlatformAdmin之上增加components字段
  2. cat <<EOF | kubectl apply -f -
  3. apiVersion: iot.openyurt.io/v1alpha2
  4. kind: PlatformAdmin
  5. metadata:
  6. name: edgex-sample
  7. spec:
  8. version: minnesota
  9. poolName: hangzhou
  10. components:
  11. - name: yurt-iot-dock
  12. - name: edgex-device-virtual
  13. - name: edgex-device-rest
  14. EOF
  15. # 可以看到可选的components已经部署起来了
  16. kubectl get po
  17. NAME READY STATUS RESTARTS AGE
  18. edgex-core-command-hangzhou-cwgs2-77bb5d9cdd-zp89r 1/1 Running 0 20m
  19. edgex-core-common-config-bootstrapper-hangzhou-bqhnb-57bd9c4q5q 1/1 Running 0 20m
  20. edgex-core-consul-hangzhou-5rl7c-66dbc9c7d7-dqvm8 1/1 Running 0 20m
  21. edgex-core-metadata-hangzhou-srpff-dd6c6f9cb-2cj9k 1/1 Running 0 20m
  22. edgex-device-rest-hangzhou-v7p99-7b8bb4f5d4-kz8sq 1/1 Running 0 7m49s
  23. edgex-device-virtual-hangzhou-ssz59-796f948c69-5k4tc 1/1 Running 0 7m49s
  24. edgex-redis-hangzhou-bk5g5-5fbdf6fffb-cmf6d 1/1 Running 0 20m
  25. yurt-iot-dock-hangzhou-56f98-8549f848f5-v2pjn 1/1 Running 0 7m49s

4. 修改组件配置

PlatfromAdmin给高阶用户提供了自定义配置的入口,所有PlatformAdmin的配置都通过一个名为platformadmin-framework的configmap控制,通过修改这个configmap的值用户可以修改每个组件的配置,下面是platformadmin-framework的一个例子

  1. apiVersion: v1
  2. data:
  3. framework: |
  4. components:
  5. - deployment:
  6. selector:
  7. matchLabels:
  8. app: edgex-core-command
  9. strategy: {}
  10. template:
  11. metadata:
  12. creationTimestamp: null
  13. labels:
  14. app: edgex-core-command
  15. spec:
  16. containers:
  17. - env:
  18. - name: SERVICE_HOST
  19. value: edgex-core-command
  20. - name: EXTERNALMQTT_URL
  21. value: tcp://edgex-mqtt-broker:1883
  22. envFrom:
  23. - configMapRef:
  24. name: common-variables
  25. image: openyurt/core-command:3.0.0
  26. imagePullPolicy: IfNotPresent
  27. name: edgex-core-command
  28. ports:
  29. - containerPort: 59882
  30. name: tcp-59882
  31. protocol: TCP
  32. resources: {}
  33. hostname: edgex-core-command
  34. name: edgex-core-command
  35. service:
  36. ports:
  37. - name: tcp-59882
  38. port: 59882
  39. protocol: TCP
  40. targetPort: 59882
  41. selector:
  42. app: edgex-core-command
  43. ...

5. 手动添加组件

考虑到某些用户可能需要新增一些自己编写或修改的组件,PlatformAdmin的component机制也支持用户新增组件。新增组件需要遵守如下步骤:

配置PlatformAdmin

在PlatformAdmin的components字段中加入需要新增的组件的名字,比如我们想要增加一个名为nginx-demo的组件

  1. # 在components字段中增加nginx-demo
  2. cat <<EOF | kubectl apply -f -
  3. apiVersion: iot.openyurt.io/v1alpha2
  4. kind: PlatformAdmin
  5. metadata:
  6. name: edgex-sample
  7. spec:
  8. version: minnesota
  9. poolName: hangzhou
  10. components:
  11. - name: yurt-iot-dock
  12. - name: edgex-device-virtual
  13. - name: edgex-device-rest
  14. - name: nginx-demo
  15. EOF

填写PlatformAdminFramework

由于AutoCollector收集的标准配置文件并不存在nginx-demo这个组件,所以platformadmin-framework中并没有对应的配置,这时用户可以手动增加这个组件

  1. # 使用kubectl edit修改configmap中的内容
  2. kubectl edit cm platformadmin-framework
  3. # 新增nginx-demo配套的deployment和service
  4. apiVersion: v1
  5. data:
  6. framework: |
  7. components:
  8. - deployment:
  9. selector:
  10. matchLabels:
  11. app: nginx-demo
  12. strategy: {}
  13. template:
  14. metadata:
  15. creationTimestamp: null
  16. labels:
  17. app: nginx-demo
  18. spec:
  19. containers:
  20. - image: nginx
  21. imagePullPolicy: IfNotPresent
  22. name: nginx-demo
  23. ports:
  24. - containerPort: 80
  25. name: nginx
  26. protocol: TCP
  27. resources: {}
  28. hostname: nginx-demo
  29. name: nginx-demo
  30. service:
  31. ports:
  32. - name: nginx
  33. port: 80
  34. protocol: TCP
  35. targetPort: 80
  36. selector:
  37. app: nginx-demo
  38. ...

保存退出后可以看到nginx-demo这个组件已经被部署起来了

  1. # deployment成功创建,pod已经成功部署
  2. kubectl get po
  3. NAME READY STATUS RESTARTS AGE
  4. edgex-core-command-hangzhou-2mvhc-77bb5d9cdd-7xtgp 1/1 Running 0 4m17s
  5. edgex-core-common-config-bootstrapper-hangzhou-tp2qc-57bd9cpj8p 1/1 Running 0 4m17s
  6. edgex-core-consul-hangzhou-hhnvv-66dbc9c7d7-cp5c9 1/1 Running 0 4m17s
  7. edgex-core-metadata-hangzhou-pd9b2-dd6c6f9cb-xzx45 1/1 Running 0 4m17s
  8. edgex-device-rest-hangzhou-l55qd-7b8bb4f5d4-s7pw6 1/1 Running 0 4m17s
  9. edgex-device-virtual-hangzhou-ftrg9-796f948c69-rfpnk 1/1 Running 0 4m17s
  10. edgex-redis-hangzhou-9hnpn-5fbdf6fffb-vzh5k 1/1 Running 0 4m17s
  11. nginx-demo-hangzhou-p5p2k-5cd7c897d6-49ss9 1/1 Running 0 108s
  12. yurt-iot-dock-hangzhou-gg85j-8549f848f5-sbhmk 1/1 Running 0 4m17s
  13. # 对应的service也成功创建
  14. kubectl get svc
  15. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  16. edgex-core-command ClusterIP 10.96.146.121 <none> 59882/TCP 4m54s
  17. edgex-core-consul ClusterIP 10.96.39.123 <none> 8500/TCP 4m54s
  18. edgex-core-metadata ClusterIP 10.96.58.12 <none> 59881/TCP 4m54s
  19. edgex-device-rest ClusterIP 10.96.39.152 <none> 59986/TCP 4m54s
  20. edgex-device-virtual ClusterIP 10.96.165.130 <none> 59900/TCP 4m54s
  21. edgex-redis ClusterIP 10.96.159.68 <none> 6379/TCP 4m54s
  22. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
  23. nginx-demo ClusterIP 10.96.40.228 <none> 80/TCP 2m25s

如果想要一键移除这个组件的话,只需要在components字段中去掉对应的name就行,PlatformAdmin会自动回收对应名字的组件

  1. # 在components字段中删除nginx-demo
  2. cat <<EOF | kubectl apply -f -
  3. apiVersion: iot.openyurt.io/v1alpha2
  4. kind: PlatformAdmin
  5. metadata:
  6. name: edgex-sample
  7. spec:
  8. version: minnesota
  9. poolName: hangzhou
  10. components:
  11. - name: yurt-iot-dock
  12. - name: edgex-device-virtual
  13. - name: edgex-device-rest
  14. # - name: nginx-demo
  15. EOF
  16. # 可以看到对应的deployment和service都回收了
  17. kubectl get deploy
  18. NAME READY UP-TO-DATE AVAILABLE AGE
  19. edgex-core-command-hangzhou-2mvhc 1/1 1 1 7m50s
  20. edgex-core-common-config-bootstrapper-hangzhou-tp2qc 1/1 1 1 7m50s
  21. edgex-core-consul-hangzhou-hhnvv 1/1 1 1 7m50s
  22. edgex-core-metadata-hangzhou-pd9b2 1/1 1 1 7m50s
  23. edgex-device-rest-hangzhou-l55qd 1/1 1 1 7m50s
  24. edgex-device-virtual-hangzhou-ftrg9 1/1 1 1 7m50s
  25. edgex-redis-hangzhou-9hnpn 1/1 1 1 7m50s
  26. yurt-iot-dock-hangzhou-gg85j 1/1 1 1 7m50s
  27. kubectl get svc
  28. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  29. edgex-core-command ClusterIP 10.96.146.121 <none> 59882/TCP 8m1s
  30. edgex-core-consul ClusterIP 10.96.39.123 <none> 8500/TCP 8m1s
  31. edgex-core-metadata ClusterIP 10.96.58.12 <none> 59881/TCP 8m1s
  32. edgex-device-rest ClusterIP 10.96.39.152 <none> 59986/TCP 8m1s
  33. edgex-device-virtual ClusterIP 10.96.165.130 <none> 59900/TCP 8m1s
  34. edgex-redis ClusterIP 10.96.159.68 <none> 6379/TCP 8m1s
  35. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d

注:不建议在platformadmin-framework中直接修改组件名,这会导致组件脱离platformadmin管控!

端设备管理

接下来,我们将以虚拟设备为例,介绍 yurt-iot-dock 在端设备管理功能。

1. 手动添加 device-virtual 组件

为了方便起见,我们只需部署一个虚拟设备驱动程序 device-virtual-go。 它可以模拟不同类型的设备,生成设备数据,用户可以发送命令,从设备获得响应或对设备执行控制指令。

首先,我们需要确保在 PlatformAdmin 框架的 configmap 中存在 edgex-device-virtual:

  1. # 使用 kubectl edit 获取 configmap 中的内容
  2. kubectl get cm platformadmin-framework -o yaml
  3. apiVersion: v1
  4. data:
  5. framework: |
  6. components:
  7. - deployment:
  8. selector:
  9. matchLabels:
  10. app: edgex-device-virtual
  11. strategy: {}
  12. template:
  13. metadata:
  14. creationTimestamp: null
  15. labels:
  16. app: edgex-device-virtual
  17. spec:
  18. containers:
  19. - env:
  20. - name: SERVICE_HOST
  21. value: edgex-device-virtual
  22. envFrom:
  23. - configMapRef:
  24. name: common-variables
  25. image: openyurt/device-virtual:3.0.0
  26. imagePullPolicy: IfNotPresent
  27. name: edgex-device-virtual
  28. ports:
  29. - containerPort: 59900
  30. name: tcp-59900
  31. protocol: TCP
  32. resources: {}
  33. hostname: edgex-device-virtual
  34. name: edgex-device-virtual
  35. service:
  36. ports:
  37. - name: tcp-59900
  38. port: 59900
  39. protocol: TCP
  40. targetPort: 59900
  41. selector:
  42. app: edgex-device-virtual
  43. ...

device-virtual-go 组件会在启动时自动创建并注册 deviceservice、5 种不同类型的 device 及其 deviceprofiles,而 yurt-iot-dock 组件会将它们都同步到 OpenYurt中。因此,你可以用 kubectl 进行检查:

  1. $ kubectl get deviceservice
  2. NAME NODEPOOL SYNCED AGE
  3. hangzhou-device-virtual hangzhou true 2d1h
  4. $ kubectl get device
  5. NAME NODEPOOL SYNCED AGE
  6. hangzhou-random-binary-device hangzhou true 2d1h
  7. hangzhou-random-boolean-device hangzhou true 2d1h
  8. hangzhou-random-float-device hangzhou true 2d1h
  9. hangzhou-random-integer-device hangzhou true 2d1h
  10. hangzhou-random-unsignedinteger-device hangzhou true 2d1h
  11. $ kubectl get deviceprofile
  12. NAME NODEPOOL SYNCED AGE
  13. hangzhou-random-binary-device hangzhou true 2d1h
  14. hangzhou-random-boolean-device hangzhou true 2d1h
  15. hangzhou-random-float-device hangzhou true 2d1h
  16. hangzhou-random-integer-device hangzhou true 2d1h
  17. hangzhou-random-unsignedinteger-device hangzhou true 2d1h

2. 创建 Device, DeviceProfile

除了通过预配置在 edgex 中同步设备、设备配置文件和设备服务外,Openyurt 侧还提供了一种更通用的方法来创建设备和设备配置文件。

  1. 创建 DeviceProfile
  1. apiVersion: iot.openyurt.io/v1alpha1
  2. kind: DeviceProfile
  3. metadata:
  4. name: openyurt-created-random-boolean-deviceprofile
  5. spec:
  6. description: Example of Device-Virtual Created By OpenYurt
  7. deviceCommands:
  8. - isHidden: false
  9. name: WriteBoolValue
  10. readWrite: W
  11. resourceOperations:
  12. - defaultValue: ""
  13. deviceResource: Bool
  14. - defaultValue: "false"
  15. deviceResource: EnableRandomization_Bool
  16. - isHidden: false
  17. name: WriteBoolArrayValue
  18. readWrite: W
  19. resourceOperations:
  20. - defaultValue: ""
  21. deviceResource: BoolArray
  22. - defaultValue: "false"
  23. deviceResource: EnableRandomization_BoolArray
  24. deviceResources:
  25. - description: used to decide whether to re-generate a random value
  26. isHidden: true
  27. name: EnableRandomization_Bool
  28. properties:
  29. defaultValue: "true"
  30. readWrite: W
  31. valueType: Bool
  32. - description: Generate random boolean value
  33. isHidden: false
  34. name: Bool
  35. properties:
  36. defaultValue: "true"
  37. readWrite: RW
  38. valueType: Bool
  39. - description: used to decide whether to re-generate a random value
  40. isHidden: true
  41. name: EnableRandomization_BoolArray
  42. properties:
  43. defaultValue: "true"
  44. readWrite: W
  45. valueType: Bool
  46. - description: Generate random boolean array value
  47. isHidden: false
  48. name: BoolArray
  49. properties:
  50. defaultValue: '[true]'
  51. readWrite: RW
  52. valueType: BoolArray
  53. labels:
  54. - openyurt-created-device-virtual-example
  55. manufacturer: OpenYurt Community
  56. model: OpenYurt-Device-Virtual-01
  57. nodePool: hangzhou

此 DeviceProfile 只是 device-virtual-go 为演示目的而创建的 random-boolean DeviceProfile 的副本。

  1. 创建 Device

可以使用预先同步的 DeviceService 和上面创建的 DeviceProfile 创建一个虚拟的bool Device:

  1. apiVersion: iot.openyurt.io/v1alpha1
  2. kind: Device
  3. metadata:
  4. name: openyurt-created-random-boolean-device
  5. spec:
  6. adminState: UNLOCKED
  7. description: Example of Device Virtual
  8. labels:
  9. - openyurt-created-device-virtual-example
  10. managed: true
  11. nodePool: hangzhou
  12. notify: true
  13. operatingState: UP
  14. profileName: openyurt-created-random-boolean-deviceprofile
  15. protocols:
  16. other:
  17. Address: openyurt-created-device-virtual-bool-01
  18. Port: "300"
  19. serviceName: device-virtual

然后,我们可以通过 kubectl 查看 OpenYurt 中的资源对象,如下所示:

  1. $ kubectl get deviceprofile openyurt-created-random-boolean-deviceprofile
  2. NAME NODEPOOL SYNCED AGE
  3. openyurt-created-random-boolean-deviceprofile hangzhou true 15h
  4. $ kubectl get device openyurt-created-random-boolean-device
  5. NAME NODEPOOL SYNCED AGE
  6. openyurt-created-random-boolean-device hangzhou true 14h

4. 读取设备生成的数据

我们已经建立了环境并模拟了一个虚拟的布尔设备。

在 OpenYurt 中,我们只需像这样检查设备资源对象的状态子资源,就能轻松获取设备生成的最新数据:

  1. $ kubectl get device openyurt-created-random-boolean-device -o yaml
  2. apiVersion: iot.openyurt.io/v1alpha1
  3. kind: Device
  4. metadata:
  5. annotations:
  6. kubectl.kubernetes.io/last-applied-configuration: |
  7. {"apiVersion":"iot.openyurt.io/v1alpha1","kind":"Device","metadata":{"annotations":{},"name":"openyurt-boolean-device","namespace":"default"},"spec":{"adminState":"UNLOCKED","description":"Example of Device Virtual","labels":["openyurt-device-boolean-virtual"],"managed":true,"nodePool":"hangzhou","notify":true,"operatingState":"UP","profileName":"Random-Boolean-Device","protocols":{"other":{"Address":"openyurt-device-boolean-virtual-01","Port":"301"}},"serviceName":"openyurt-boolean-device"}}
  8. creationTimestamp: "2023-09-14T06:25:10Z"
  9. finalizers:
  10. - iot.openyurt.io/device
  11. generation: 2
  12. name: openyurt-boolean-device
  13. namespace: default
  14. resourceVersion: "1717015"
  15. uid: 6677eb4a-b644-4d5d-970a-1446f141a353
  16. spec:
  17. adminState: UNLOCKED
  18. description: Example of Device Virtual
  19. deviceProperties:
  20. Bool:
  21. desiredValue: "true"
  22. name: Bool
  23. labels:
  24. - openyurt-created-device-virtual-example
  25. managed: false
  26. nodePool: hangzhou
  27. notify: true
  28. operatingState: UP
  29. profileName: openyurt-created-random-boolean-deviceprofile
  30. protocols:
  31. other:
  32. Address: openyurt-created-device-virtual-bool-01
  33. Port: "300"
  34. serviceName: device-virtual
  35. status:
  36. adminState: UNLOCKED
  37. deviceProperties:
  38. Bool:
  39. actualValue: "true"
  40. getURL: http://edgex-core-command:59882/api/v3/device/name/openyurt-boolean-device/Bool
  41. name: Bool
  42. BoolArray:
  43. actualValue: '[true, true, true, false, false]'
  44. getURL: http://edgex-core-command:59882/api/v3/device/name/openyurt-boolean-device/BoolArray
  45. name: BoolArray
  46. edgeId: 5e63effd-deeb-4505-890e-17ec32f02511
  47. operatingState: UP
  48. synced: true

deviceProperties 显示该设备的所有属性。

例如,Bool 属性的最新值是 false,该值是从 EdgeX rest api http://edgex-core-command:59882/api/v2/device/name/openyurt-created-random-boolean-device/Bool 获取的。

5. 更新设备属性

如果要通过更新设备的可写属性来控制该设备,应首先将 Device.Spec.Managed 字段设置为 true,以表示 yurt-iot-dock 接管设备,否则所有更新操作都将被忽略。

  1. 将设备的 managed 字段设置为 true
  1. kubectl patch device openyurt-created-random-boolean-device -p '{"spec":{"managed":true}}' --type=merge
  1. 更改设备的管理状态

管理状态(又称 admin 状态)可由人工或其他系统控制设备服务。它可以设置为 “锁定”(LOCKED)或 “解锁”(UNLOCKED)。当设备服务被设置为锁定状态时,它不能响应任何命令请求,也不能从设备发送数据。

  1. kubectl patch device openyurt-created-random-boolean-device -p '{"spec":{"adminState":"UNLOCKED"}}' --type=merge

设置设备属性以控制/更新设备

  1. kubectl patch device openyurt-created-random-boolean-device --type=merge -p '{"spec":{"managed":true,"deviceProperties":{"Bool": {"name":"Bool", "desiredValue":"false"}}}}'

在命令中,我们将 Bool DeviceProperty 值设置为 false,yurt-iot-dock 就会触发 EdgeX 命令并更改设备属性。我们可以多次观察设备的状态来检查这一点,你会发现该值始终为 false,除非你再次将该属性改为 true。

  1. watch "kubectl get device openyurt-created-random-boolean-device -o json | jq '.status.deviceProperties.Bool.actualValue'"
  2. # output
  3. Every 2.0s: kubectl get device openyurt-boolean-device -o json | jq '.status.deviceProperties.Bool.actualValue' VM-16-6-ubuntu: Sat Sep 16 16:39:58 2023
  4. "false"