您现在的位置是:首页 > 文章详情

云原生边缘设备解决方案Akri on k3s初体验

日期:2022-11-22点击:260

作者:

涂家英,SUSE 资深架构师,专注 Cloud-Native 相关产品和解决方案设计,在企业级云原生平台建设领域拥有丰富的经验。

写在前面

k3s 是 SUSE 推出的为物联网和边缘计算构建的经过认证的 Kubernetes 发行版,它可以帮助用户在资源受限的场景下使用 kubernetes,并结合 SUSE Rancher 实现云边协同。

将 k3s 与微软开源的 kubernetes 边缘项目 Akri 结合使用,用户就拥有了在边缘环境发现和使用各种 IOT 设备的能力。

架构

Akri 目前是 CNCF 的一个开源项目,其功能简单地说就是可以根据配置自动地寻找到相应的 iot 设备,为其创建关联的工作负载,并且通过不断地检测实现工作负载的动态变化。引用一句官方的描述为:You name it, Akri finds it, you use it.

架构如下:

包含了 Controller 服务、Agent 服务和 Discovery Handlers 服务以及两个 CRD 资源。

具体的组件解析可以查看官方文档:https://docs.akri.sh/architecture/architecture-overview

下面我们通过一个示例来更好地理解 Akri 的工作方式。

体验

示例使用了官方提供的一个 OPC UA 温度计 Demo,OPC UA 是现在使用比较广泛的工业自动化通信协议,我们可以通过 Akri 自动发现使用 OPU CA 协议的温度计设备,并为其创建工作负载,采集和使用其产生的温度数据。

示例中体现的大致工作流程如下:

首先需要模拟出两台 OPC UA 的服务设备,然后在 k3s 集群上部署 Akri 服务,基础工作完成后:

  1. 向集群配置用于发现 OPC UA 设备的 CRD(Configuration)
  2. CRD 下发后,Akri 的相应 Discovery 服务会按照规则寻找 OPC UA 设备
  3. 在找到 OPC UA 设备后,Agent 服务会生成设备对应的 CRD(Instance),Controller 服务查看到 Instance CRD 资源后,将创建对应的工作负载

OPC UA 设备模拟

使用了一个.NET 类型的开源项目模拟实现 OPU CA 设备,项目地址为:https://gitee.com/leotuss/opcua-donet

克隆到本地后,需要修改以下文件:

# /opcua-dotnet/Applications/ConsoleReferenceServer/Quickstarts.ReferenceServer.Config.xml文件第76、77行 将<node-ip style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">替换为节点地址 #/opcua-dotnet/Applications/ReferenceServer/Quickstarts.ReferenceServer.Config.xml文件第77、78行 将<node-ip style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">替换为节点地址</node-ip></node-ip>` 

Linux 要运行这个程序,需要安装.NET core 的 SDK 和 runtime

可以使用以下命令运行此程序:

dotnet run --project /opcua-dotnet/Applications/ConsoleReferenceServer/NetCoreReferenceServer.csproj 

运行后,可以看到如下提示:

root@edge-iot1:~/opcua-dotnet/Applications/ConsoleReferenceServer# dotnet run --project NetCoreReferenceServer.csproj .Net Core OPC UA Reference Server opc.tcp://192.168.6.151:62541/Quickstarts/ReferenceServer https://192.168.6.151:62540/Quickstarts/ReferenceServer/ Server started. Press Ctrl-C to exit... 

至此程序运行成功,应用可以通过订阅opc.tcp://:62541/Quickstarts/ReferenceServer获得数据

安装 Akri

可以通过 Helm 安装 Akri:

# 添加Akri repo helm repo add akri-helm-charts https://project-akri.github.io/akri/ # 部署Akri helm install akri akri-helm-charts/akri\     --set kubernetesDistro=k3s \     --set opcua.discovery.enabled=true 

关于 kubernetesDistro 配置,Akri 依赖 crictl 跟踪 pod 信息,所以必须知道容器运行时 socket 的位置。目前 Akri 支持四种类型:

  • 标准 kuberentes,对应配置为:--set kubernetesDistro=k8s
  • k3s,对应配置为:--set kubernetesDistro=k3s
  • microk8s,对应配置为:--set kubernetesDistro=microk8s
  • 其它,对应配置为:--set agent.host.containerRuntimeSocket=/container/runtime.sock

关于 xxx.discovery.enabled 配置,Akri 目前支持三种设备发现:

  • onvif:IP Cameras 的主流协议
  • opc ua:工业自动化通信协议
  • udev:linux 设备管理器

如我们需要 Akri 发现 onvif 设备,就可以配置 --set onvif.discovery.enabled=true,配置后 Akri 会在集群中部署相应的 Discovery 服务,以 Daemonset 的方式运行,支持叠加部署,如需要发现上述三种类型设备,部署命令可以修改为:

helm install akri akri-helm-charts/akri\     --set kubernetesDistro=k3s \     --set opcua.discovery.enabled=true \     --set onvif.discovery.enabled=true \     --set udev.discovery.enabled=true 

部署完成后查看集群 Pods 可以看到:

root@edge-k3s:~# kubectl get pods NAME                                         READY   STATUS    RESTARTS       AGE akri-controller-deployment-d4f7847b6-rlgrr   1/1     Running   11 (25h ago)   4d2h akri-agent-daemonset-9s9m9                   1/1     Running   10 (25h ago)   3d23h akri-opcua-discovery-daemonset-tv84d         1/1     Running   8 (25h ago)    3d17h 

部署 CRD

使用 Akri 发现设备需要部署类型为 Configuration 的 CRD:

apiVersion: akri.sh/v0 kind: Configuration metadata:  name: akri-opcua-monitoring  namespace: default spec:  brokerProperties:    IDENTIFIER: Thermometer_Temperature    NAMESPACE_INDEX: "2"  brokerSpec:    brokerPodSpec:      containers:      - image: ghcr.io/project-akri/akri/opcua-monitoring-broker:latest        name: akri-opcua-monitoring-broker        resources:          limits:            '{{PLACEHOLDER}}': "1"            cpu: 30m            memory: 200Mi          requests:            '{{PLACEHOLDER}}': "1"            cpu: 9m            memory: 76Mi  capacity: 1  configurationServiceSpec:    ports:    - name: grpc      port: 80      protocol: TCP      targetPort: 8083    type: ClusterIP  discoveryHandler:    name: opcua    discoveryDetails: |+      opcuaDiscoveryMethod:        standard:          discoveryUrls:          - opc.tcp://192.168.6.151:62541/Quickstarts/ReferenceServer/          - opc.tcp://192.168.6.152:62541/Quickstarts/ReferenceServer/      applicationNames:        action: Exclude        items: []    name: opcua  instanceServiceSpec:    ports:    - name: grpc      port: 80      protocol: TCP      targetPort: 8083    type: ClusterIP 

需要关注的配置:

  • spec.brokerProperties: 用于定义需要采集数据的 ID 信息,本演示中 opcua 程序中添加了 IDENTIFIER:为Thermometer_TemperatureNAMESPACE_INDEX: "2"的数据输出,数据输出内容为 70-80 的随机数,并且在随机到 75 时,将 75 替换为 120
  • spec.brokerSpec.brokerPodSpec.containers.image: 设备对应工作负载的镜像,演示使用的是官方提供的镜像,作用是订阅 opcua 所产生的相应数据,此镜像是可以自定义的,实现更多可能
  • spec.capacity:针对设备的工作负载副本数量,用于实现工作负载高可用
  • spec.discoveryHandler: 这部分主要定义了发现 opuca 设备的规则,支持一些过滤规则
  • spec.configurationServiceSpec:Akri Controller 服务会为所有设备的工作负载创建一个总 svc,这段用于定义相应的 svc 的配置
  • spec.instanceServiceSpec: Akri Controller 服务会为每一个工作负载创建 svc,这段用于定义相应 svc 的配置

示例中可以看到 opuca 的发现规则是具体的服务地址,如果要支持批量的 opuca 设备发现,可以使用 Local discovery server(LDS),将 opcua 的设备注册到 LDS 中,然后在 discoveryUrls 配置中使用 LDS 的地址。采用 LDS 方式的话,可以实现过滤能力,如排除掉哪些 opcua 服务或者包含哪些 opcua 服务,示例如下:

# 发现LDS中的所有opcua设备,除了<someserver style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">以外</someserver> discoveryDetails: |+  opcuaDiscoveryMethod:    standard:      discoveryUrls:      - opc.tcp://<lds服务器地址 style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">:4840</lds服务器地址>  applicationNames:    action: Exclude    items:    - 

将 akri-opcua-monitoring 的 crd 部署到集群后,可以通过 kubectl get akric 查看:

root@edge-k3s:~/akric-crd# kubectl get akric NAME                    CAPACITY   AGE akri-opcua-monitoring   1          2m13s 

查看 Discovery 的服务日志可以看到,两个 opcua 设备已经被发现:

[2022-11-10T08:26:26Z TRACE akri_opcua::discovery_impl] get_discovery_url_from_application - found server : Quickstart Reference Server [2022-11-10T08:26:26Z TRACE akri_opcua::discovery_impl] get_discovery_url_from_application - server has [UAString { value: Some("https://192.168.6.151:62540/Quickstarts/ReferenceServer/discovery") }, UAString { value: Some("opc.tcp://192.168.6.151:62541/Quickstarts/ReferenceServer") }] DiscoveryUrls [2022-11-10T08:26:26Z TRACE akri_opcua::discovery_impl] get_discovery_urls - Server at opc.tcp://192.168.6.152:62541/Quickstarts/ReferenceServer/ responded with 1 Applications [2022-11-10T08:26:26Z TRACE akri_opcua::discovery_impl] get_discovery_url_from_application - found server : Quickstart Reference Server [2022-11-10T08:26:26Z TRACE akri_opcua::discovery_impl] get_discovery_url_from_application - server has [UAString { value: Some("https://192.168.6.152:62540/Quickstarts/ReferenceServer/discovery") }, UAString { value: Some("opc.tcp://192.168.6.152:62541/Quickstarts/ReferenceServer") }] DiscoveryUrls [2022-11-10T08:26:26Z TRACE akri_opcua::discovery_handler] discover - found OPC UA server at DiscoveryURL opc.tcp://192.168.6.151:62541/Quickstarts/ReferenceServer [2022-11-10T08:26:26Z TRACE akri_opcua::discovery_handler] discover - found OPC UA server at DiscoveryURL opc.tcp://192.168.6.152:62541/Quickstarts/ReferenceServer 

可以通过 kubectl get akrii 查看由 Agent 自动生成的 opcua 的 instance crd 资源:

root@edge-k3s:~/akric-crd# kubectl get akrii NAME                           CONFIG                  SHARED   NODES          AGE akri-opcua-monitoring-7aa6fb   akri-opcua-monitoring   true     ["edge-k3s"]   5m10s akri-opcua-monitoring-20f7e0   akri-opcua-monitoring   true     ["edge-k3s"]   5m9s` 

于此同时,使用 kubectl get pods 可以查看到为设备自动创建的工作负载:

NAME                                         READY   STATUS    RESTARTS       AGE akri-controller-deployment-d4f7847b6-rlgrr   1/1     Running   11 (27h ago)   4d4h akri-agent-daemonset-9s9m9                   1/1     Running   10 (27h ago)   4d1h akri-opcua-discovery-daemonset-tv84d         1/1     Running   8 (27h ago)    3d19h edge-k3s-akri-opcua-monitoring-7aa6fb-pod    1/1     Running   0              6m44s  <--- edge-k3s-akri-opcua-monitoring-20f7e0-pod    1/1     Running   0              6m43s  <--- 

部署数据展示服务

部署数据展示服务查看效果:

kubectl apply -f https://raw.githubusercontent.com/project-akri/akri/main/deployment/samples/akri-anomaly-detection-app.yaml 

部署完成后,查看一下展示服务 SVC 的 NodePort 端口:

root@edge-k3s:~# kubectl get svc NAME                               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE kubernetes                         ClusterIP   10.43.0.1       <none>        443/TCP        5d6h akri-opcua-monitoring-7aa6fb-svc   ClusterIP   10.43.152.214   <none>        80/TCP         13m akri-opcua-monitoring-svc          ClusterIP   10.43.242.118   <none>        80/TCP         13m akri-opcua-monitoring-20f7e0-svc   ClusterIP   10.43.22.196    <none>        80/TCP         13m akri-anomaly-detection-app         NodePort    10.43.248.164   <none>        80:32007/TCP   7s <--- 

访问 NodePort 端口,查看效果:

这个展示服务原理是通过连接工作负载的 SVC 获取工作负载采集到的设备数据,当值为 70-80 中任意数值时表示正常,用黑体展示;当值为 120 时表示异常,用红体展示

当设备下线时,Akri 会自动删除设备对应的工作负载,删除的时间大约为 5 分钟,以便应对可能出现的临时网络故障。

总 结

Akri 其实可以理解为是一种设备自动发现的框架,它可以通过云原生的方式帮助我们发现并使用 IOT 设备,目前支持 onvif、udev、opcua 三种类型。其它包括 Bluetooth、CoAP、IP、LoRaWAN、Zeroconf、acpid、MQTT 也正在开发中。

使用 k3s 可以帮助用户实现在边缘侧使用 kubernetes 的能力,通过 Akri 可以解决边缘场景下发现和使用设备的问题,这样用户就能将更多的精力专注在数据处理的应用上。

原文链接:https://my.oschina.net/rancher/blog/5597234
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章