作者:中国移动云能力中心——罗川
概要:上一篇讲了如何部署KubeEdge,并成功模拟部署了一个可用的边缘节点。本篇我们来运行一个简单的示例,来体验一下,然后,我会基于源码跟你说明其背后的流程。虽然这是一个非常简单的Demo,但对了解KubeEdge的整体工作流程是非常有帮助的,通过这篇文章,你可以看到KubeEdge这个产品是如何去做云边协同,云端是如何实时获取边缘信息的。
边缘计算底座KubeEdge(二):实战体验好,上一篇讲了如何部署KubeEdge,并成功模拟部署了一个可用的边缘节点
接下来,我们来运行一个简单的示例,来体验一下,然后,我们看看其背后的流程
让我们开始吧!
示例选取
因为我们并没有IoT的设备环境,所以选取的是官网最简单的示例:KubeEdge Counter Demo
它由这么几部分组成:
- 云端部署的是一个web页面,可以下发三个简单的命令
- 边端部署的是一个名叫Counter的进程,它可以跟模拟的设备交互,并反馈消息给云端
- 边缘部署的进程里含有一个模拟的假设备,可以看做是一个端设备,其功能可以理解为数秒
云端下发的三个简单的命令分别是:
- ON(打开):打开端设备,端设备开始计数,每秒加1
- OFF(重置):关闭端设备,端设备重置计数
- STATUS(获取状态):获取打印的计数数值
形象化的理解流程可以参考官方图:
流程图
前置条件
- 运行状态的KubeEdge集群,版本1.5+
- MQTT Broker在边端运行
- /etc/kubernetes/manifests/kube-apiserver.yaml文件加入配置--insecure-port=8080 and --insecure-bind-address=0.0.0.0
一般来说,只有第三点要注意,开放不需要认证的HTTP端口。我们可以只管加入配置就好,api-server会动态加载配置。
开始实战
clone代码
第一步先把代码download下来,因为我们需要手动来编译并制作镜像
git clone git@github.com:kubeedge/examples.git
定义CRD
为了跟设备交互,KubeEdge需要将端设备描述成Kubernetes能够看懂的资源,一种设备需要定义两个CRD,分别是设备模板(model)和具体设备(instance),可以理解为Java中的class和对象。本示例中的设备名为counter,我们分别创建出来。
kubectl create -f crds/kubeedge-counter-model.yaml
# replace "" with your edge node name
sed -i "s#edge-node##" crds/kubeedge-counter-instance.yaml
kubectl create -f crds/kubeedge-counter-instance.yaml
这里注意要修改instance的内容,里面定义了一个nodeSelector,将edge-node替换成你的边缘节点名称
注意,只能修改节点名称,而不能修改nodeSelector的结构,我把nodeSelector改成通过标签的方式定位,下发命令时,cloudcore直接因为数组越界崩溃了...
因为cloudcore会去按照yaml文件的结构去解析节点名称,用来定义mqtt topic名字
downstream.go 632
resource, err := messagelayer.BuildResource(device.Spec.NodeSelector.NodeSelectorTerms[0].Matchexpressions[0].Values[0], "device/"+device.Name+"/twin/cloud_updated", "")
制作镜像并启动
我们需要分别制作云端web程序和边端应用程序两个镜像
插曲:本来想偷懒直接去用别人打好的镜像,搜了一下DockHub,还真有。经过自己查看提供镜像的tag,试了几个,不是起不来就是因为go build cpu架构版本有出入,最后一个倒是跑起来了,不过报错:the server could not find the requested resource (patch devices.devices.kubeedge.io counter)... Github上倒还真有一个PR解决了这个问题
所以,没办法,只能自己根据最新的代码,来做镜像了,其实非常简单
首先 web程序,进入web-controller-app目录,然后
$ make $ make docker
这样镜像就打好了,因为我们要让它在master上运行,所以直接启动就好了,这个Pod配置了相对应容忍,是可以在master运行的
注意:web启动后默认占用80端口,如果机器上的端口已经被占用了,修改一下代码中的端口即可
$ kubectl create -f crds/kubeedge-pi-counter-app.yaml
接下来是边端程序,进入counter-mapper
这里要注意GOARCH环境变量,如果你编译打包的环境和最终运行环境的CPU架构不一样,就要指定区分一下,比如你在ubuntu上编译打包,边缘节点是一个树莓派,就要修改GOARCH为arm64
因为我们的两个环境架构一致,就不用考虑这个问题了。直接build一下
$ make $ make docker
镜像打好了,但是为了让边缘节点能够拉取到镜像,我们把它push到私服里,边缘节点到私服网络也是通的
然后修改一下yaml文件中的image名称,启动
$ kubectl create -f kubeedge-pi-counter-app.yaml
值得一提的是,这个deployment指定了hostNetwork为true,应该是为了访问主机节点上的MQTT
好了,因为deployment中指定了nodeSelector为边缘节点的标签,所以这个Pod会指定跑在边缘设备上
实际效果验证
访问Web页面,可以看到这样的窗口
Web 页面
进入K8s Dashboard,可以看到pod已经在边缘节点运行
K8s Dashboard
这里注意,我们暂时不能在Dashboard里像普通Pod一样直接进入后台或者查看日志,需要特殊配置
我们ssh登陆到边缘节点后台,docker ps查看一下
边缘节点容器云心情况
可以看到容器已经在运行了,现阶段,我们可以通过docker命令来查看容器的日志,效果是一样的
我们现在选择ON来运行一下
Turn On counter
通过容器的日志,可以看到边缘节点已经收到了消息,开始计数了
边缘容器的日志
在浏览器里面,选择STATUS,运行一下
可以获取当前的计数值
获取当前状态
最后选择OFF,运行
Turn Off counter
边缘节点上容器停止计数
边缘容器的日志
以上,就是整个例子的过程演示
最后,我们来分析一下其中的内部流程吧
内部探索
下图是我理解的这个Demo的交互时序图。其中,因为我们现在对KubeEdge内部的功能模块还不熟悉,暂定它为一个整体。
交互时序图
1)当我们选择ON运行时,WEB会通过K8s API更新之前定义的CRD(device instance)的一个属性
2)KubeEdge云端的模块会一直Watch这类事件,然后会发现到这个更改
3)然后云端的模块会将这个更改封装成内部消息,一直传送到提前约定好的边缘端MQTT的某个topic中
4)我们前面启动的边缘端应用会订阅MQTT中的特定topic
5)根据收到的消息,做出相应的动作,当消息是ON时,就开始计数,当消息是OFF时,就重置并停止计数
6)每当计数变化,都会返回一个消息给MQTT中的另一个topic,无论是正常计数还是重置
7)KubeEdge边缘端的模块订阅了MQTT的这个topic,会收到这个返回消息
8)然后边端的模块会将这个消息封装好,一直传送到云端模块
9)云端模块通过K8s API相应的更新CRD(device instance)的属性
10)如果这时候你选择STATUS并运行,Web就会通过K8s API 去获取这个CRD(device instance)的属性,打印至页面
这就是内部的整个流程
云边如何协同,云端怎么实时获取边缘信息的过程
在这个的Demo中,其实是没有实际Device的存在,边缘应用内部通过go channel模拟了跟Device的交互过程
在真实环境中,是需要根据端设备的具体协议去做这个交互的
好了,以上就是本篇博文的全部内容,后续会对KubeEdge内部的一些模块进行探索
既然看到了最后,不妨来个三连吧 : )
版权声明 (原创):本文内容由移动云用户自发贡献,版权归原作者所有,移动云开发者社区不拥有其著作权,亦不承担相应法律责任。如果您发现本社区有涉嫌抄袭的内容,可填写举报信息,一经查实,本社区将立刻删除涉嫌侵权内容。



