边缘节点OpenAPI
功能概述
边缘节点开放OpenAPI,开发者可以调用OpenAPI获取边缘节点信息、边缘应用信息等。
目前边缘OpenAPI不支持更新操作,只支持查询操作。
边缘节点OpenAPI清单:
-
节点影子:
- 宿主机调用:
https://localhost:30050/node/properties
- K8s服务间调用:
https://baetyl-core.baetyl-edge-system/node/properties
- 宿主机调用:
-
节点状态:
- 宿主机调用:
https://localhost:30050/node/stats
- K8s服务间调用:
https://baetyl-core.baetyl-edge-system/node/stats
- 宿主机调用:
说明:节点信息相关的api通过baetyl-core应用暴露,容器内端口443,宿主机端口30050。
节点影子
节点影子可以看做边缘设备数据在云端的映射。通过节点影子,可以利用端云同步通道,将云端节点数据或属性同步至边缘设设备。边缘设备上的应用可以通过相关接口获取来自云端的数据,同时也可以利用接口对数据进行更新,然后同步至云端。简而言之,节点影子可以作为云边数据双向同步的一种方式。
同步的数据格式为键值对Json,且数据类型均为字符串,数据内容不限。例如当需要同步配置文件,可以指定属性名称为配置文件名,期望值为文件内容。设备端即可以接收来自云端同步的配置文件,使用配置文件对应用进行热更新。具体使用方式如下:
- 在云端节点页面点击节点影子标签,显示该节点现有属性为空,
-
边缘侧获取云端影子desire信息,主要有两种方式:
- 在边缘侧订阅baetyl-broker的
$baetyl/node/props
主题消息,获取云端影子desire信息 - 在边缘侧调用节点OpenAPI,获取云端影子desire信息
- 在边缘侧订阅baetyl-broker的
- 边缘侧修改report信息:在边缘侧获取到云端desire消息以后,边缘侧需要做出响应,调用OpenAPI反馈report值。只有到边缘report的值与云端desire的值相同时,云端才停止想边缘侧发送影子desire消息。否则在边缘侧可以一直订阅到云端desire值。
接收节点影子数据增量更新消息
为模拟应用订阅系统 MQTT broker,先将系统broker配置进行调整。注意,这里仅仅是为了便于操作,实际应用订阅主题推荐使用TLS连接系统 MQTT broker,下文会有介绍。
点击编辑,添加属性,如下图所示:
- 属性名称:conf.yml
- 期望值:value
确定后,即可在属性列表查看相关属性。
而后会通过端云协同将所有属性同步至边缘设备,且以增量更新的方式通知。具体为通过MQTT订阅相关主题,接收事件消息,消息内容即为需要更新的属性键值对。
说明:云端会一直下发期望值,边缘侧会一直收到消息,直到边缘侧上报值和云端期望值一样,云端才会停止发送消息。
通常是边缘运行应用订阅系统MQTT broker,在这里对节点系统broker应用配置进行修改,便于订阅主题。
点击节点应用部署,并进入系统broker应用(名称中有broker)进行配置修改,点击应用配置。
添加端口配置,配置1883->1883端口映射,并点击确定。
然后,切换到数据卷标签,并进入conf配置卷(名称中有conf)进行配置修改。
点击编辑,添加listeners。
内容为
1listeners:
2 - address: 'tcp://0.0.0.0:1883'
3session:
4 sysTopics:
5 - $link
6 - $baetyl
7logger:
8 level: debug
9 encoding: console
改好后点击保存,并确定。
打开MQTT.Box,配置设备host。
确认已连接至设备MQTT broker,并订阅 $baetyl/node/props 主题
、
之后会接收到来自该主题的消息,内容为云端节点属性。
说明:
- 边缘应用订阅系统MQTT broker时通常是使用证书认证,实现免密码配置
- 边缘应用可以使用在/var/lib/baetyl/system/certs下证书连接baetyl-broker,连接的服务地址为:ssl://baetyl-broker.baetyl-edge-system:50010
- 此处为了便于演示,所以单独配置了用户名密码连接baetyl-broker
通过OpenAPI获取节点影子属性
边缘应用服务调用需要基于应用证书校验。应用证书的获取方式参考:证书管理。
且由于baetyl-core应用配置了端口映射30050->443
,使用如下命令获取节点影子:
1# version<2.3.4
2curl -k https://localhost:30050/node/properties
3# version>=2.3.4
4curl --cacert ca.pem --cert crt.pem --key key.pem https://localhost:30050/node/properties
上述desire为云端期望数据。report为空,表示没有上报数据。
通过OpenAPI更新节点影子属性
类似于获取节点影子属性,使用证书以HTTPS协议可以对节点影子数据进行更新,接口同样为 https://baetyl-core.baetyl-edge-system/node/properties
同样以模拟方式,跳过对服务端证书校验,执行如下命令:
1# version<2.3.4
2curl -k -X PUT https://localhost:30050/node/properties -d '{"conf.yml":"value"}'
3# version>=2.3.4
4curl --cacert ca.pem --cert crt.pem --key key.pem -X PUT https://localhost:30050/node/properties -d '{"conf.yml":"value"}'
指定需要更新的属性,接口会返回当前节点影子所有属性。也可以再次调用获取节点影子属性的api查看。
1# version<2.3.4
2curl -k https://localhost:30050/node/properties
3# version>=2.3.4
4curl --cacert ca.pem --cert crt.pem --key key.pem https://localhost:30050/node/properties
同时,在云端的节点影子可以看到边缘设备对属性的更新。
注意事项 节点影子功能依赖于系统应用baetyl-broker,如对系统应用baetyl-broker的配置更改影响了baetyl-broker服务的正常运行,将可能导致节点影子功能不可用。
节点状态
- 在边缘侧调用节点状态接口
1# version<2.3.4
2curl -k https://localhost:30050/node/stats
3# version>=2.3.4
4curl --cacert ca.pem --cert crt.pem --key key.pem https://localhost:30050/node/stats
- 节点状态返回样例
1{
2 "name":"node-v234",
3 "createTime":"2022-06-22T08:28:55.260431395Z",
4 "report":{
5 "time":"2022-06-22T09:21:47.572487627Z",
6 "sysapps":[
7 {
8 "name":"baetyl-init-zblt9lxq3",
9 "version":"1655885684uxsem4"
10 },
11 {
12 "name":"baetyl-core-wlnwutiv6",
13 "version":"1655885684bstpt7"
14 },
15 {
16 "name":"baetyl-broker-j2sqaze3v",
17 "version":"1655889584ewsaqs"
18 },
19 {
20 "name":"baetyl-agent-xgaiskczn",
21 "version":"1655885685hgzz7s"
22 }
23 ],
24 "core":{
25 "goVersion":"go1.13.5",
26 "binVersion":"v2.3.4",
27 "gitRevision":"git-2524dce"
28 },
29 "sysappstats":[
30 {
31 "name":"baetyl-init-zblt9lxq3",
32 "version":"1655885684uxsem4",
33 "deployType":"deployment",
34 "status":"Running",
35 "instances":{
36 "baetyl-init-7f55445ff4-tnp7j":{
37 "name":"baetyl-init-7f55445ff4-tnp7j",
38 "appName":"baetyl-init-zblt9lxq3",
39 "usage":{
40 "cpu":"0.003",
41 "memory":"10612736"
42 },
43 "status":"Running",
44 "ip":"10.42.0.76",
45 "nodeName":"pd-vm",
46 "createTime":"2022-06-22T08:28:40Z",
47 "containers":[
48 {
49 "name":"baetyl-init",
50 "usage":{
51 "cpu":"2835088n",
52 "memory":"10364Ki"
53 },
54 "state":"Running"
55 }
56 ]
57 }
58 }
59 },
60 {
61 "name":"baetyl-core-wlnwutiv6",
62 "version":"1655885684bstpt7",
63 "deployType":"deployment",
64 "status":"Running",
65 "instances":{
66 "baetyl-core-wlnwutiv6-798fcd98fc-72ksp":{
67 "name":"baetyl-core-wlnwutiv6-798fcd98fc-72ksp",
68 "appName":"baetyl-core-wlnwutiv6",
69 "usage":{
70 "cpu":"0.005",
71 "memory":"11939840"
72 },
73 "status":"Running",
74 "ip":"10.42.0.77",
75 "nodeName":"pd-vm",
76 "createTime":"2022-06-22T08:28:52Z",
77 "containers":[
78 {
79 "name":"baetyl-core",
80 "usage":{
81 "cpu":"4073131n",
82 "memory":"11660Ki"
83 },
84 "state":"Running"
85 }
86 ]
87 }
88 }
89 },
90 {
91 "name":"baetyl-broker-j2sqaze3v",
92 "version":"1655889584ewsaqs",
93 "deployType":"deployment",
94 "status":"Running",
95 "instances":{
96 "baetyl-broker-j2sqaze3v-b4c4f8fc8-kblfw":{
97 "name":"baetyl-broker-j2sqaze3v-b4c4f8fc8-kblfw",
98 "appName":"baetyl-broker-j2sqaze3v",
99 "usage":{
100 "cpu":"0.001",
101 "memory":"3088384"
102 },
103 "status":"Running",
104 "ip":"10.42.0.80",
105 "nodeName":"pd-vm",
106 "createTime":"2022-06-22T09:19:56Z",
107 "containers":[
108 {
109 "name":"baetyl-broker",
110 "usage":{
111 "cpu":"366602n",
112 "memory":"3016Ki"
113 },
114 "state":"Running"
115 }
116 ]
117 }
118 }
119 },
120 {
121 "name":"baetyl-agent-xgaiskczn",
122 "version":"1655885685hgzz7s",
123 "deployType":"daemonset",
124 "status":"Running",
125 "instances":{
126 "baetyl-agent-xgaiskczn-75mdk":{
127 "name":"baetyl-agent-xgaiskczn-75mdk",
128 "appName":"baetyl-agent-xgaiskczn",
129 "usage":{
130 "cpu":"0.002",
131 "memory":"4612096"
132 },
133 "status":"Running",
134 "ip":"10.211.55.5",
135 "nodeName":"pd-vm",
136 "createTime":"2022-06-22T08:29:08Z",
137 "containers":[
138 {
139 "name":"baetyl-agent",
140 "usage":{
141 "cpu":"1300406n",
142 "memory":"4504Ki"
143 },
144 "state":"Running"
145 }
146 ]
147 }
148 }
149 }
150 ],
151 "node":{
152 "pd-vm":{
153 "hostname":"pd-vm",
154 "address":"10.211.55.5",
155 "arch":"arm64",
156 "kernelVer":"5.13.0-37-generic",
157 "os":"linux",
158 "containerRuntime":"docker://20.10.13",
159 "machineID":"3787c48ab74047b28638ef2ddc97be6c",
160 "bootID":"2e058c7a-072f-4d6c-baf1-ed81a948f15c",
161 "systemUUID":"c4be2e07-1110-4801-a2af-e5f9a9aed71b",
162 "osImage":"Ubuntu 20.04.4 LTS",
163 "role":"master",
164 "labels":{
165 "baetyl-node":"true",
166 "beta.kubernetes.io/arch":"arm64",
167 "beta.kubernetes.io/instance-type":"k3s",
168 "beta.kubernetes.io/os":"linux",
169 "kubernetes.io/arch":"arm64",
170 "kubernetes.io/hostname":"pd-vm",
171 "kubernetes.io/os":"linux",
172 "node-role.kubernetes.io/control-plane":"true",
173 "node-role.kubernetes.io/master":"true",
174 "node.kubernetes.io/instance-type":"k3s"
175 }
176 }
177 },
178 "nodestats":{
179 "pd-vm":{
180 "ready":true,
181 "usage":{
182 "cpu":"0.211",
183 "disk":"28374298624",
184 "memory":"1637335040"
185 },
186 "capacity":{
187 "cpu":"2",
188 "disk":"66842079232",
189 "memory":"4104314880"
190 },
191 "percent":{
192 "cpu":"0.1055",
193 "disk":"0.42449754630637043",
194 "memory":"0.39893017175134476"
195 },
196 "netio":{
197 "netBytesRecv":"1470",
198 "netBytesSent":"1362",
199 "netPacketsRecv":"19",
200 "netPacketsSent":"17"
201 },
202 "extension":{
203 "diskPercent":0.42449754630637043,
204 "diskTotal":66842079232,
205 "diskUsed":28374298624,
206 "netBytesRecv":1470,
207 "netBytesSent":1362,
208 "netPacketsRecv":19,
209 "netPacketsSent":17
210 }
211 }
212 },
213 "nodeinsnum":{
214 "pd-vm":4
215 },
216 "modeinfo":"v1.22.5+k3s1"
217 },
218 "appMode":"kube",
219 "desire":{
220 "nodeprops":{
221 "conf.yml":"value"
222 }
223 },
224 "cluster":false,
225 "ready":1,
226 "mode":""
227}