在 ubuntu22.04 中 安装 EdgeX 并运行 device-sdk-c sample

EdgeX Foundry 作为一个开源的边缘计算框架,为开发者提供了一个灵活、可扩展的平台,用于构建和管理边缘设备及服务。然而,对于初次接触 EdgeX 的用户来说,从零开始安装并运行其相关组件(如 device-sdk-c 示例)可能会面临不少挑战。

无论是环境的配置、依赖的安装,还是编译与调试的过程,每一步都需要细致的操作和清晰的思路。本文将以 Ubuntu 22.04 为基础平台,详细记录如何从克隆 EdgeX 源码到成功运行 device-sdk-c 的 sample 示例的全过程。希望通过这篇博客,不仅能为新手提供一份实用的操作指南,也能让有经验的开发者在遇到问题时找到解决思路。

1.克隆源码-EdgeX

在开始安装 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 文件夹,说明这一步成功完成。

2.安装工具

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

    确认版本为 jammy 后,访问南京大学镜像站(https://mirror.nju.edu.cn/mirrorz-help/ubuntu/), 获取对应源配置并编辑 /etc/apt/sources.list

    # 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 部署奠定了基础。

3.编译运行-EdgeX

有了 Docker 支持后,我们可以开始部署 EdgeX 服务。EdgeX 使用 Docker Compose 管理多个容器,因此需要进入 compose-builder 目录执行构建和运行命令:

  • 进入目录并运行无安全模式的 EdgeX:

    cd /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 已成功运行:

    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 ...

4.克隆源码-SDK-C

为了运行 device-sdk-c 的示例,我们还需要获取其源码。device-sdk-c 包含了丰富的 C 语言示例,是开发自定义设备服务的好起点:

  • /edgex 目录下克隆仓库:

    git clone https://github.com/edgexfoundry/device-sdk-c.git
    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.

5.添加第三方依赖库

编译 device-sdk-c 需要一系列依赖库,参考官方 README(https://github.com/edgexfoundry/device-sdk-c/blob/main/README.md

  • A Linux build host
  • A version of GCC supporting C11.
  • CMake version 3 or greater and make.
  • Development libraries and headers for:
    • curl (version 7.56 or later)
    • microhttpd (version 0.9)
    • libyaml (version 0.1.6 or later)
    • libcbor (version 0.5)
    • paho (version 1.3.x)
    • libuuid (from util-linux v2.x)
    • IOTech's C utilities package (version 1.5)
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

6.编译-C SDK

在C SDK 顶层目录下, 运行 make,最终结果显示如下:

root@ubuntu:/home/ubuntu/edgex/device-sdk-c# make

...
[100%] Built target device-file

7.编译运行 random 设备服务示例

  • 编译前的准备工作,参考https://github.com/edgexfoundry/device-sdk-c/blob/main/src/c/examples/random/README.md

    此示例设备服务模拟了一个具有两个随机数生成器和一个可读取和写入状态的开关的设备。先配置环境变量,注意自己的路径:

    export CSDK_DIR=/home/logan/edgex/device-sdk-c/build/release/_CPack_Packages/Linux/TGZ/csdk-0.0.0
    export LD_LIBRARY_PATH=$CSDK_DIR/lib:/opt/iotech/iot/1.5/lib

    涉及头文件和库文件的环境变量很重要,并且运行程序的时候也需要用到。

  • /random 目录下执行编译命令:

    gcc -I$CSDK_DIR/include -I/opt/iotech/iot/1.5/include -L$CSDK_DIR/lib -L/opt/iotech/iot/1.5/lib -o device-random device-random.c -lcsdk -liot
  • 将编译好的可执行文件 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

      ​ 或者在/etc/hosts 中添加127.0.0.1 edgex-mqtt-broker,然后在执行命令 ./device-random -o -cp=keeper.http://localhost:59890 中去掉 -o

      /etc/hosts
      
      127.0.0.1 localhost
      127.0.0.1 edgex-core-metadata
      127.0.0.1 edgex-mqtt-broker
      # 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
  • 如果程序运行成功,将显示如下:

  ...
  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 可发现一个设备服务,可成功读取随机数,如下:

3.jpg
4.jpg

总结

通过以上步骤,我们成功地在 Ubuntu 22.04 上完成了 EdgeX 的安装,并运行了 device-sdk-c 的 random 设备服务示例。从源码的克隆到 Docker 环境的搭建,再到依赖库的安装和配置文件的调整,每一个环节都环环相扣,考验着我们的耐心和解决问题的能力。

过程中可能遇到的报错,如安全性 token 问题、Curl 解析失败或健康检查间隔配置缺失,也提醒我们在操作复杂系统时,细节的重要性不容忽视。

最终,当我们在浏览器中看到 localhost:4000 界面上显示的设备服务和随机数据时,那份成就感无疑是对所有努力的最好回报。这不仅是一个技术实现的过程,更是一次对 EdgeX 架构和边缘计算理念的深入学习之旅。未来,我们还可以基于此基础,进一步扩展功能、优化性能,让边缘计算的潜力在更多场景中得以释放!

标签: EdgeX

添加新评论