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

news2024/11/26 22:18:12

作者:
涂家英,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 可以解决边缘场景下发现和使用设备的问题,这样用户就能将更多的精力专注在数据处理的应用上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/27339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

指数函数及其导函数

目录前言指数函数的导函数指数函数导函数动图绘制参考文献前言 前面我们介绍了指数函数及其基本性质以及如何在笛卡尔直角坐标系下绘制静态的指数函数图像&#xff0c;这一节&#xff0c;我们将重点讨论一下指数函数的导函数以及导函数的动态表示&#xff0c;为方便起见&#…

大数据(9f)Flink富函数RichFunction

文章目录1、概述2、示例2.1、普通函数2.2、富函数2.2.1、获取富函数的运行时上下文3、源码截取3.1、RichFunction3.2、RuntimeContext1、概述 Rich Function&#xff0c;译名富函数&#xff0c;和普通函数相比&#xff0c;多了&#xff1a;生命周期&#xff08;open和close方法…

DGL学习笔记——第二章 消息传递范式

提示&#xff1a;DGL用户指南学习中 文章目录一、内置函数和消息传递API二、编写高效的消息传递代码总结消息传递是实现GNN的一种通用框架和编程范式。它从聚合与更新的角度归纳总结了多种GNN模型的实现。 假设节点 &#x1d463; 上的的特征为 &#x1d465;&#x1d463;∈ℝ…

Java(八)----多线程

1. 线程的基本概念 1.1 进程 任何的软件存储在磁盘&#xff08;硬盘&#xff09;中,运行软件的时候,OS&#xff08;操作系统&#xff09;使用IO技术,将磁盘中的软件的文件加载到内存,程序才能运行。 &#xff08;进程是从硬盘到内存&#xff09; 进程的概念 &#xff1a; 应…

Marked.js让您的文档编辑更加轻松自如!

低代码应用平台——kintone既可以保留更改记录&#xff0c;也有流程管理的功能&#xff0c;在公司内部分享会议记录啊、wiki等文档或学习资料等时非常的便利。 kintone还有丰富的文本编辑框&#xff0c;可以对内容进行编辑提高易读性。但是还是有不少人觉得如果能够使用Markdo…

19.[Python GUI] PyQt5中的模型与视图框架-基本原理

PyQt中的模型与视图框架 一、Qt中模型与视图相关的类 二、模型与视图的基本原理 MVC把图形界面分为三个部分&#xff1a;模型&#xff08;Model&#xff09;&#xff0c;视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09;&#xff0c; 模型&#x…

Git大型文件存储

什么是 Git LFS&#xff1f; Git 是跟踪代码库演变和与同行高效协作的绝佳选择。但是&#xff0c;当您要跟踪的存储库非常大时会发生什么&#xff1f; 如果您考虑一下&#xff0c;存储库变得庞大的主要原因大致有两个&#xff1a; 他们积累了非常非常长的历史&#xff08;项目…

【C】文件操作fopen与fclose

目录 函数 1.fopen 2.fclose 3.freopen 函数 头文件 #include<stdio.h> 1.fopen FILE *fopen(const char *restrict dilename,const char* restrict mode); 作用&#xff1a;打开文件参数&#xff1a; 第一个是含有要打开文件名的字符串&#xff08;"文件名…

肝了一周的八万字Redis实战篇

Redis实战篇 文章目录Redis实战篇开篇导读1. 短信登录2. 商户查询缓存3. 优惠卷秒杀4. 附近的商户5. UV统计6. 用户签到7. 好友关注8. 达人探店一、短信登录1. 导入黑马点评项目1.1 导入SQL1.2 有关当前模型1.3 导入后端项目1.4 导入前端工程1.5 运行前端项目2. 基于Session实现…

【杂谈】快来看看如何使用LGMT这样的蜜汁缩写来进行CodeReview吧!

文章目录一、先从一个梗开始说起吧&#xff01;二、什么是LGTM&#xff1f;2.1 LGTM 是什么意思&#xff1f;2.2 蹭梗品牌故事2.3 虚假的CodeReview三、Code Review中的蜜汁缩写四、参考链接一、先从一个梗开始说起吧&#xff01; 公司最近在如火如荼的开展CodeReview活动&…

Reinforcement learning from demonstration through shaping(Wiewiora 2003)

摘要 强化学习中的一个重要问题是如何以有原则的方式整合专家知识&#xff0c;尤其是当我们扩展到现实世界的任务时。在本文中&#xff0c;我们提出了一种在不改变最优策略的情况下将任意建议纳入强化学习agent的奖励结构的方法。 该方法将 Ng 等人 (1999) 提出的基于势能的塑…

1530_AURIX_TriCore内核架构_通用寄存器以及系统寄存器

全部学习汇总&#xff1a; GreyZhang/g_tricore_architecture: some learning note about tricore architecture. (github.com) 继续看一下内核手册&#xff0c;这次了解一下通用寄存器以及系统寄存器。最近一段时间最复位以及trap困扰了许久&#xff0c;看看这里面是否能够获取…

黄河水稻山东智慧 国稻种芯·中国水稻节:济南泉城米袋子

黄河水稻山东智慧 国稻种芯中国水稻节&#xff1a;济南泉城米袋子 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯中国水稻节 中国三农智库网-功能性农业农业大健康大会报道&#xff1a;又是一年春天。济南黄河流域吴家堡水稻田旁的…

数据挖掘与机器学习:数据挖掘算法原理与实践:数据预处理

目录 第一关&#xff1a;标准化 任务描述&#xff1a; 相关知识&#xff1a; 一、为什么要进行标准化 二、Z-score标准化 三、Min-max标准化 四、MaxAbs标准化 编程要求&#xff1a; 测试说明&#xff1a; 第二关&#xff1a;非线性转换 任务描述&#xff1a; 相关知…

【LeetCode】878. 第 N 个神奇数字

题目描述 一个正整数如果能被 a 或 b 整除&#xff0c;那么它是神奇的。 给定三个整数 n , a , b &#xff0c;返回第 n 个神奇的数字。因为答案可能很大&#xff0c;所以返回答案 对 109 7 取模 后的值。 示例 1&#xff1a; 输入&#xff1a;n 1, a 2, b 3 输出&#xff…

stm32cubemx hal学习记录:FreeRTOS互斥量

一、互斥量 1、互斥量用于互锁&#xff0c;可以充当资源保护的令牌&#xff0c;当一个任务希望访问某个资源时&#xff0c;它必须先获取令牌&#xff0c;当任务使用完资源后&#xff0c;必须返还令牌&#xff0c;以便其他任务可以访问该资源。 2、互斥量一般用于临界资源保护…

[附源码]计算机毕业设计JAVA教师档案管理系统

[附源码]计算机毕业设计JAVA教师档案管理系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybati…

LabVIEW通信-CAN

文章目录CANcan总线特点位定位与同步标识符检验滤波报文传输类型CAN CAN属于OSI的物理层与数据链路层 can总线特点 网络各节点之间的数据通信实时性强 开发周期短 结构简单&#xff08;只有两根线与外部相连&#xff0c;内部继承了错误探测和管理模块&#xff09; 数据通信没…

Spring IOC

一、为什么要使用Spring&#xff1f; Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用&#xff0c;但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发&#xff0c;并通过POJO为基础的编程模型促进良好的编程习惯。 为…

RPA案例|云扩助力保险行业开启超自动化运营新阶段

近五年&#xff0c;全球平均保险深度总体呈小幅平稳下降趋势&#xff0c;2021年中国保险深度为4.15%&#xff0c;全球平均保险深度为5.96%&#xff0c;而美国、英国等发达国家的保险深度则保持在10%以上&#xff0c;中国保险深度仍然具有很大的上升空间。 为进一步拓展增量空间…