EdgeX Foundry 作为一个开源的边缘计算框架,为开发者提供了一个灵活、可扩展的平台,用于构建和管理边缘设备及服务。然而,对于初次接触 EdgeX 的用户来说,从零开始安装并运行其相关组件(如 device-sdk-c 示例)可能会面临不少挑战。
无论是环境的配置、依赖的安装,还是编译与调试的过程,每一步都需要细致的操作和清晰的思路。本文将以 Ubuntu 22.04 为基础平台,详细记录如何从克隆 EdgeX 源码到成功运行 device-sdk-c 的 sample 示例的全过程。希望通过这篇博客,不仅能为新手提供一份实用的操作指南,也能让有经验的开发者在遇到问题时找到解决思路。
在开始安装 EdgeX 之前,我们需要先获取其源码,而 GitHub 是获取最新版本的最佳途径。为了让后续操作更加有条理,我们首先在用户主目录下创建一个专属的工作目录,用于存放 EdgeX 相关的文件。以下是具体操作:
打开终端,输入以下命令创建一个名为 edgex
的文件夹,并进入该目录:
mkdir edgex && cd edgex
接下来,我们需要从 GitHub 上克隆 EdgeX 的 Compose 文件仓库,这是运行 EdgeX 服务的核心配置文件集合。执行以下命令:
git clone https://github.com/edgexfoundry/edgex-compose.git
cd edgex-compose
结果显示如下:
root@ubuntu:/home/ubuntu# mkdir edgex && cd edgex
root@ubuntu:/home/ubuntu/edgex# git clone https://github.com/edgexfoundry/edgex-compose.git
Cloning into 'edgex-compose'...
remote: Enumerating objects: 5826, done.
remote: Counting objects: 100% (3563/3563), done.
remote: Compressing objects: 100% (319/319), done.
remote: Total 5826 (delta 3504), reused 3250 (delta 3244), pack-reused 2263 (from 3)
Receiving objects: 100% (5826/5826), 1.59 MiB | 1.76 MiB/s, done.
Resolving deltas: 100% (4949/4949), done.
root@ubuntu:/home/ubuntu/edgex# ls
edgex-compose
输出信息显示了克隆进度,最终 ls 命令确认目录中已存在 edgex-compose 文件夹,说明这一步成功完成。
EdgeX 的部署离不开 Docker,因为它通过容器化技术简化了服务的管理和运行。因此,我们需要先在 Ubuntu 系统中安装 Docker。以下是详细的安装步骤:
使用官方脚本安装 Docker,并指定阿里云镜像源以加速下载:
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh --mirror Aliyun
docker -v
第一条命令通过 curl
下载安装脚本并保存为 get-docker.sh
文件;第二条命令执行脚本,--mirror Aliyun
参数指定使用阿里云镜像源,避免默认源下载缓慢;最后通过 docker -v
检查版本,确保安装成功。安装过程的输出类似:
root@ubuntu:/home/ubuntu# curl -fsSL https://get.docker.com -o get-docker.sh
root@ubuntu:/home/ubuntu# sh get-docker.sh --mirror Aliyun
# Executing docker install script, commit: 4c94a56999e10efcf48c5b8e3f6afea464f9108e
...
Client: Docker Engine - Community
Version: 28.0.1
API version: 1.48
...
root@ubuntu:/home/ubuntu# docker -v
Docker version 28.0.1, build 068a01e
如果下载速度过慢,可能是镜像源的问题。这时可以调整 Ubuntu 的软件源以提高效率。首先检查系统版本:
root@ubuntu:/home/ubuntu# more /etc/os-release
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-poli
cy"
UBUNTU_CODENAME=jammy
# vim /etc/apt/sources.list
deb https://mirror.nju.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirror.nju.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirror.nju.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
启动 docker 并查看状态:
root@ubuntu:/home/ubuntu# systemctl restart docker
root@ubuntu:/home/ubuntu# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset>
Active: active (running) since Thu 2025-03-13 12:21:05 CST; 6s ago
TriggeredBy: ● docker.socket
Docs: https://docs.docker.com
Main PID: 28525 (dockerd)
Tasks: 10
Memory: 22.1M
CPU: 1.228s
CGroup: /system.slice/docker.service
└─28525 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/con>
Active: active (running)
表示 Docker 已正常运行,为后续 EdgeX 部署奠定了基础。
有了 Docker 支持后,我们可以开始部署 EdgeX 服务。EdgeX 使用 Docker Compose 管理多个容器,因此需要进入 compose-builder 目录执行构建和运行命令:
进入目录并运行无安全模式的 EdgeX:
root@ubuntu:/home/ubuntu# cd /home/ubuntu/edgex/edgex-compose/compose-builder/
root@ubuntu:/home/ubuntu/edgex/edgex-compose/compose-builder# make run no-secty
echo MQTT_VERBOSE=
MQTT_VERBOSE=
docker compose -p edgex -f docker-compose-base.yml -f add-postgres.yml -f add-mqtt-messagebus.yml -f add-mqtt-broker-mosquitto.yml convert --output docker-compose.yml.gen
if [ "0" = "0" ]; then rm -rf ./gen_ext_compose; fi
echo "# Generated with: Docker Compose version v2.33.1" > docker-compose.yml
cat docker-compose.yml.gen >> docker-compose.yml
rm docker-compose.yml.gen
docker compose -p edgex up -d
[+] Running 12/12
✔ Container edgex-ui-go Running 0.0s
✔ Container edgex-postgres Running 0.0s
✔ Container edgex-mqtt-broker Running 0.0s
✔ Container edgex-core-keeper Running 0.0s
✔ Container edgex-core-metadata Running 0.0s
✔ Container edgex-core-common-config-bootstrapper Running 0.0s
✔ Container edgex-app-rules-engine Running 0.0s
✔ Container edgex-support-scheduler Running 0.0s
✔ Container edgex-core-data Running 0.0s
✔ Container edgex-kuiper Running 0.0s
✔ Container edgex-support-notifications Running 0.0s
✔ Container edgex-core-command Started 0.4s
这表明所有容器已启动,包括 UI、数据库和核心服务等。
查看容器运行状态,显示如下,每个容器显示 Up
状态,说明 EdgeX 已成功运行:
root@ubuntu:/home/ubuntu/edgex/edgex-compose/compose-builder# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
edgex-app-rules-engine nexus3.edgexfoundry.org:10004/app-service-configurable:latest "/app-service-config…" app-rules-engine 7 minutes ago Up 7 minutes 48095/tcp, 127.0.0.1:59701->59701/tcp
edgex-core-command nexus3.edgexfoundry.org:10004/core-command:latest "/core-command --reg…" core-command 7 minutes ago Up 5 minutes 127.0.0.1:59882->59882/tcp
edgex-core-common-config-bootstrapper nexus3.edgexfoundry.org:10004/core-common-config-bootstrapper:latest "entrypoint.sh /core…" core-common-config-bootstrapper 7 minutes ago Up 7 minutes
edgex-core-data nexus3.edgexfoundry.org:10004/core-data:latest "/core-data --regist…" core-data 7 minutes ago Up 7 minutes 127.0.0.1:59880->59880/tcp
edgex-core-keeper nexus3.edgexfoundry.org:10004/core-keeper:latest "/core-keeper" core-keeper 7 minutes ago Up 7 minutes 127.0.0.1:59890->59890/tcp
edgex-core-metadata nexus3.edgexfoundry.org:10004/core-metadata:latest "/core-metadata ...
为了运行 device-sdk-c 的示例,我们还需要获取其源码。device-sdk-c 包含了丰富的 C 语言示例,是开发自定义设备服务的好起点:
在 /edgex
目录下克隆仓库:
root@ubuntu:/home/ubuntu/edgex/edgex-compose/compose-builder# cd ../..
root@ubuntu:/home/ubuntu/edgex# ls
edgex-compose
root@ubuntu:/home/ubuntu/edgex# git clone https://github.com/edgexfoundry/device-sdk-c.git
Cloning into 'device-sdk-c'...
remote: Enumerating objects: 5641, done.
remote: Counting objects: 100% (527/527), done.
remote: Compressing objects: 100% (213/213), done.
remote: Total 5641 (delta 419), reused 337 (delta 307), pack-reused 5114 (from 4)
Receiving objects: 100% (5641/5641), 1.93 MiB | 1.70 MiB/s, done.
Resolving deltas: 100% (3210/3210), done.
编译 device-sdk-c 需要一系列依赖库,参考官方 README(https://github.com/edgexfoundry/device-sdk-c/blob/main/README.md)
apt-get install libcurl4-openssl-dev libmicrohttpd-dev libyaml-dev libcbor-dev libpaho-mqtt-dev
apt-get install lsb-release apt-transport-https curl gnupg
curl -fsSL https://iotech.jfrog.io/artifactory/api/gpg/key/public | gpg --dearmor -o /usr/share/keyrings/iotech.gpg
echo "deb [signed-by=/usr/share/keyrings/iotech.gpg] https://iotech.jfrog.io/iotech/debian-release $(lsb_release -cs) main" | tee -a /etc/apt/sources.list.d/iotech.list
apt-get update
apt-get install iotech-iot-1.5-dev
apt install uuid-dev
在C SDK 顶层目录下, 运行 make,最终结果显示如下:
root@ubuntu:/home/ubuntu/edgex/device-sdk-c# make
...
[100%] Built target device-file
将编译好的可执行文件 device-random 复制到以下源文件目录,因为源文件目录提供了/res
里面包含预设的配置文件:
cp device-sdk-c/build/release/c/examples/random/device-random device-sdk-c/src/c/examples/random/
cd /home/ubuntu/edgex/device-sdk-c/src/c/examples/random/
执行以下命令:-o 表示覆盖默认配置,-cp 指定配置提供者
./device-random -o -cp=keeper.http://localhost:59890
如果遇到报错,按以下方法解决:
安全 Token 报错:设置环境变量禁用安全服务:
root@ubuntu:/home/ubuntu/edgex/device-sdk-c/src/c/examples/random# ./device-random -o -cp=keeper.http://localhost:59890
level=INFO ts=2025-03-13T06:44:41Z app=device-random msg="iot_threadpool_alloc (threads: 8 max_jobs: 0 default_priority: -1 affinity: -1)"
level=INFO ts=2025-03-13T06:44:41Z app=device-random msg="iot_scheduler_alloc (priority: -1 affinity: -1)"
level=ERROR ts=2025-03-13T06:44:41Z app=device-random msg="vault: Token file /tmp/edgex/secrets/device-random/secrets-token.json doesn't parse as JSON"
Error: 4: Configuration is invalid
解决:需要关闭Edges安全服务:
参考https://docs.edgexfoundry.org/4.0/microservices/configuration/CommonEnvironmentVariables/#edgex_security_secret_store
export EDGEX_SECURITY_SECRET_STORE="false"
Curl 解析失败:编辑 /etc/hosts:
level=DEBUG ts=2025-03-13T06:45:41Z app=device-random msg="mqtt: subscribing to edgex/configs/edgex/v4/core-common-config-bootstrapper/all-services/#"
level=DEBUG ts=2025-03-13T06:45:41Z app=device-random msg="mqtt: subscribing to edgex/configs/edgex/v4/core-common-config-bootstrapper/device-services/#"
level=ERROR ts=2025-03-13T06:45:42Z app=device-random msg="Curl failed with code 6 (Couldn't resolve host name)"
level=ERROR ts=2025-03-13T06:45:43Z app=device-random msg="Curl failed with code 6 (Couldn't resolve host name)"
level=ERROR ts=2025-03-13T06:45:44Z app=device-random msg="Curl failed with code 6 (Couldn't resolve host name)"
level=ERROR ts=2025-03-13T06:45:45Z app=device-random msg="Curl failed with code 6 (Couldn't resolve host name)"
level=ERROR ts=2025-03-13T06:45:46Z app=device-random msg="Curl failed with code 6 (Couldn't resolve host name)"
level=ERROR ts=2025-03-13T06:45:47Z app=device-random msg="Curl failed with code 6 (Couldn't resolve host name)"
解决:在/etc/hosts
中添加127.0.0.1 edgex-core-metadata
:
/etc/hosts
127.0.0.1 localhost
127.0.0.1 edgex-core-metadata
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
健康检查间隔缺失:修改 res/configuration.yml:
level=DEBUG ts=2025-03-13T06:50:39Z app=device-random msg="HTTP response: 404"
level=DEBUG ts=2025-03-13T06:50:39Z app=device-random msg="HTTP response: 400"
level=ERROR ts=2025-03-13T06:50:39Z app=device-random msg="Register service failed: {"apiVersion":"v3","message":"AddRegistrationRequest.Registration.HealthCheck.Interval field is required","statusCode":400}
"
level=ERROR ts=2025-03-13T06:50:39Z app=device-random msg="Unable to register service in registry"
Error: 21: HTTP request failed
level=DEBUG ts=2025-03-13T06:50:39Z app=device-random msg="Scheduler thread stopping"
解决:在res/configration.yml
中添加 HealthCheckInterval: 10s
:
Writable:
LogLevel: DEBUG
Service:
Host: localhost
Port: 59999
StartupMsg: Example random device service started
HealthCheckInterval: 10s
如果程序运行成功,将显示如下:
...
level=INFO ts=2025-03-13T07:36:45Z app=device-random correlation-id=c26ef1f7-755c-4952-8091-5c7c436e039b msg="AutoEvent: RandomDevice1/SensorOne"
level=INFO ts=2025-03-13T07:36:50Z app=device-random correlation-id=dc222997-3113-465b-9c5c-26829ce24901 msg="AutoEvent: RandomDevice1/SensorTwo"
level=INFO ts=2025-03-13T07:36:55Z app=device-random correlation-id=049d560d-896a-4e5a-8101-f3364c2767f1 msg="AutoEvent: RandomDevice1/SensorOne"
打开浏览器进入:localhost:4000
可以看见一个设备服务,并能成功读取随机数,如下所示:
通过以上步骤,我们成功地在 Ubuntu 22.04 上完成了 EdgeX 的安装,并运行了 device-sdk-c 的 random 设备服务示例。从源码的克隆到 Docker 环境的搭建,再到依赖库的安装和配置文件的调整,每一个环节都环环相扣,考验着我们的耐心和解决问题的能力。
过程中可能遇到的报错,如安全性 token 问题、Curl 解析失败或健康检查间隔配置缺失,也提醒我们在操作复杂系统时,细节的重要性不容忽视。
最终,当我们在浏览器中看到 localhost:4000 界面上显示的设备服务和随机数据时,那份成就感无疑是对所有努力的最好回报。这不仅是一个技术实现的过程,更是一次对 EdgeX 架构和边缘计算理念的深入学习之旅。未来,我们还可以基于此基础,进一步扩展功能、优化性能,让边缘计算的潜力在更多场景中得以释放!