이번 실습에서는 EdgeX Foundry의 기본적인 구조를 이해하고, edgex-compose를 이용하여 EdgeX 환경을 구성해 보았다.
이후 실습에서는 USB Camera Device Service, Application Service Export, TensorFlow Serving Object Detection까지 연결하기 때문에 먼저 EdgeX의 전체 구조와 기본적인 Compose 실행 방법을 이해하는 것을 목표로 했다.
EdgeX Foundry는 장치, 센서, 액추에이터 및 기타 IoT 객체가 존재하는 물리적 세계와 상호작용하기 위한 오픈소스 플랫폼이다.
EdgeX는 여러 개의 마이크로서비스로 구성되어 있으며, 이를 이해하기 위해서는 먼저 전체적인 계층 구조를 이해할 필요가 있다.
EdgeX의 계층은 크게 다음 네 가지로 구성된다.
일반적인 데이터 흐름은 가장 아래쪽의 Device Services Layer에서 시작하여 Core Services Layer를 거친 뒤, 필요한 경우 Application Services Layer를 통해 외부 시스템으로 전달되는 구조이다.
전체적인 구조를 단순하게 표현하면 다음과 같다.
[ Sensor / Device ]
↓
Device Services Layer
↓
Core Services Layer
↓
Supporting Services Layer
↓
Application Services Layer
↓
[ External System ]
다만 모든 데이터가 반드시 네 계층을 순서대로 통과해야 하는 것은 아니다.
각 계층은 서로 다른 역할을 담당하며, 실제 EdgeX 환경에서는 필요한 서비스만 선택하여 구성할 수 있다.
Device Services Layer는 실제 센서와 장치를 EdgeX에 연결하는 역할을 한다.
카메라, 온도 센서 등의 장치와 통신하고 장치에서 얻은 데이터를 EdgeX가 사용할 수 있는 데이터 구조로 변환하여 다른 계층으로 전달한다.
즉, EdgeX에서 실제 장치와 가장 가까운 계층이라고 볼 수 있다.
이번 실습에서 사용할 device-usb-camera 역시 이 계층에 해당한다.
Core Services Layer는 Device Services에서 전달받은 데이터를 관리하고 장치와 상위 시스템 사이에서 중개 역할을 수행한다.
PDF에서는 다음과 같은 주요 마이크로서비스를 설명한다.
Device Services Layer에서 수집한 데이터를 저장하고 관리한다.
Application Services Layer에서 장치를 제어할 수 있도록 명령을 전달하는 역할을 한다.
장치의 Provisioning 및 페어링과 관련된 메타데이터를 저장하고 관리한다.
EdgeX를 구성하는 여러 마이크로서비스의 설정과 구성을 관리한다.
따라서 Core Services는 단순히 데이터를 저장하는 것뿐만 아니라 장치와 데이터, 서비스 설정을 관리하는 EdgeX의 핵심 영역이라고 이해할 수 있다.
Supporting Services Layer는 다른 세 계층에 포함되지 않는 부가적인 마이크로서비스를 담당한다.
이 계층은 모든 환경에서 반드시 필요한 것은 아니며, 필요에 따라 선택적으로 사용할 수 있다.
EdgeX에서는 대표적으로 다음과 같은 서비스를 제공한다.
예를 들어 Rules Engine을 이용하면 특정 조건에 따라 데이터를 처리하거나 특정 동작을 수행하도록 구성할 수 있다.
Application Services Layer는 EdgeX 내부에서 수집된 데이터를 외부 시스템에서 사용할 수 있도록 처리하는 역할을 한다.
PDF에서는 이 계층을 데이터를 추출, 처리, 변환하고 Endpoint를 제공하거나 지정된 프로세스로 내보내는 계층으로 설명한다. 또한 함수 파이프라인을 이용하여 EdgeX 내부에서 데이터를 가공한 후 외부로 전달할 수도 있다.
이번 실습의 후반부에서 다루게 될 Application Service HTTP Export / MQTT Export가 바로 이 계층에 해당한다.
EdgeX에서는 다양한 장치와 통신하기 위해 여러 종류의 Device Services를 제공한다.
PDF는 EdgeX 2.2 Kamakura 기준으로 다음과 같은 Device Services를 제시한다.
| Device Service | Protocol | Status |
|---|---|---|
device-onvif-camera | ONVIF | Active |
device-usb-camera | USB | Active |
device-camera-go | ONVIF | Deprecated |
device-rest-go | REST | Active |
device-rfid-llrp-go | LLRP | Active |
device-snmp-go | SNMP | Active |
device-virtual-go | - | Active |
device-mqtt-go | MQTT | Active |
device-modbus-go | Modbus | Active |
device-gpio | GPIO | Active |
device-grove-c | 2.x | TBD |
device-bacnet-c | BACnet | TBD |
device-coap-c | CoAP | Active |
device-uart | UART | In Development |
이번 실습에서는 이후 카메라 실습을 진행하기 위해 device-usb-camera를 사용한다.
내가 실습에 참고한 PDF에서 사용한 기본 환경은 다음과 같다.
실제 실습은 현재 사용하고 있는 환경에서 진행했다.
| 항목 | 실제 실습 환경 |
|---|---|
| OS | Ubuntu 22.04.5 LTS |
| CPU | Intel Core i7-14700 |
| EdgeX | 2.2 Kamakura |
| Docker | 29.7.2 |
| Docker Compose | v2 |
| Git | 2.34.1 |
원본 자료와 OS 및 CPU가 다르지만 EdgeX 버전은 PDF와 동일하게 2.2 Kamakura를 사용했다.
EdgeX에서는 여러 마이크로서비스를 Docker Compose를 통해 쉽게 구성할 수 있도록 edgex-compose 저장소를 제공한다.
PDF에서는 원하는 브랜치를 지정하여 저장소를 내려받도록 안내하고 있다.
이번 실습에서는 Kamakura 브랜치를 사용했기 때문에 다음 명령어를 사용했다.
git clone --recursive -b kamakura https://github.com/edgexfoundry/edgex-compose.git
각 옵션은 다음과 같은 의미를 가진다.
git clone: 원격 Git 저장소를 현재 컴퓨터로 복제--recursive: Git submodule까지 함께 가져옴-b kamakura: kamakura 브랜치를 선택다운로드가 완료되면 edgex-compose 디렉터리가 생성된다.
이후 Compose 파일을 생성하고 실행하는 compose-builder 디렉터리로 이동한다.
cd ~/edgex-compose/compose-builder
EdgeX는 하나의 프로그램으로 동작하는 것이 아니라 여러 마이크로서비스가 함께 동작하는 구조이다.
따라서 각 서비스를 하나씩 직접 실행하는 대신 edgex-compose에서 제공하는 Makefile을 이용하면 필요한 서비스들을 한 번에 구성할 수 있다.
PDF에서 기본적인 실행 방법으로 제시한 명령어는 다음과 같다.
make run no-secty
여기서 make run은 EdgeX Compose를 실행하는 명령이고, no-secty는 보안 기능을 제외한 비보안 모드로 실행하기 위한 옵션이다.
또한 이 명령은 단순히 하나의 컨테이너만 실행하는 것이 아니라 EdgeX에서 기본적으로 사용하는 여러 서비스를 Docker Compose를 통해 구성한다.
실행이 완료되면 done 메시지가 출력되는 것을 확인할 수 있다.
EdgeX가 정상적으로 실행되었는지 확인하기 위해 다음 명령어를 사용했다.
docker ps
docker ps는 현재 실행 중인 Docker 컨테이너 목록을 보여준다.
실습에서는 EdgeX의 여러 서비스가 각각 Docker 컨테이너로 실행되는 것을 확인할 수 있었다.

이 단계에서 중요한 점은 EdgeX가 하나의 컨테이너가 아니라 여러 개의 마이크로서비스 컨테이너로 구성되어 있다는 것이다.
예를 들어 다음과 같은 서비스들이 별도의 컨테이너로 실행된다.
edgex-core-data
edgex-core-metadata
edgex-core-command
edgex-core-consul
edgex-redis
edgex-support-scheduler
edgex-support-notifications
edgex-app-rules-engine
edgex-ui-go
...
각 컨테이너는 서로 다른 역할을 담당하며 EdgeX 전체 시스템을 구성한다.
컨테이너가 실행되었다고 해서 실제 서비스가 모두 정상적으로 동작한다고 단정할 수는 없다.
따라서 EdgeX에서는 각 서비스가 제공하는 /api/v2/ping API를 이용하여 서비스 상태를 확인할 수 있다.
PDF에서도 다음과 같은 방식으로 서비스의 Ping API를 호출하도록 안내한다.
curl http://localhost:[service port]/api/v2/ping
이번 실습에서는 Core Data를 대상으로 확인했다.
curl http://localhost:59880/api/v2/ping
정상적으로 동작한다면 다음과 같이 JSON 형태의 응답을 확인할 수 있다.
{
"apiVersion": "v2",
"timestamp": "...",
"serviceName": "core-data"
}
여기서 serviceName이 core-data로 표시되므로 Core Data 서비스가 정상적으로 요청을 처리하고 있다는 것을 확인할 수 있다.
기본적인 Compose 실행과 서비스 확인이 끝났다면 PDF의 다음 단계에서는 EdgeX Compose를 종료한다.
make clean
make clean은 실행 중인 EdgeX Compose 환경을 정리하는 명령이다.
PDF에서는 내부적으로 docker-compose down을 이용하며, EdgeX와 관련된 컨테이너뿐만 아니라 볼륨과 네트워크까지 정리한다고 설명한다.
즉,
make clean
↓
docker-compose down
↓
EdgeX 관련 컨테이너 / 볼륨 / 네트워크 정리
와 같은 방식으로 이해할 수 있다.
앞에서 사용한
make run no-secty
에서 no-secty는 단순한 문자열이 아니라 make run에서 인식하는 실행 옵션이다.
PDF에서는 make run이 실행 모드와 실행할 서비스를 옵션으로 받을 수 있다고 설명한다.
예를 들어 Device Service나 Application Service를 추가하고 싶다면 해당 서비스에 대응하는 옵션을 추가할 수 있다.
대표적으로 다음과 같은 옵션이 있다.
ds-usb-camera
ds-rest
asc-http
asc-mqtt
mqtt-broker
mqtt-bus
그중 이번 실습 이후에 사용할 주요 옵션은 다음과 같다.
| 옵션 | 역할 |
|---|---|
ds-usb-camera | USB Camera Device Service 추가 |
ds-rest | REST Device Service 추가 |
asc-http | Application Service HTTP Export 추가 |
asc-mqtt | Application Service MQTT Export 추가 |
mqtt-bus | MQTT Message Bus 구성 |
실제로 PDF에서도 asc-http를 App Service HTTP Export 포함 옵션으로 정의하고 있다.
EdgeX Compose는 Docker 컨테이너와 이미지를 기반으로 실행되기 때문에 실제 서비스의 설정 파일에 직접 접근하여 수정하기 어렵다.
이를 보완하기 위해 edgex-compose에서는 여러 개의 .env 파일을 이용한 설정 오버라이딩 방식을 제공한다.
.env 파일은 다음 위치에서 확인할 수 있다.
edgex-compose/
└── compose-builder/
├── common.env
├── common-security.env
├── asc-common.env
├── asc-http-export.env
├── asc-mqtt-export.env
├── mqtt-bus.env
└── nats-bus.env
PDF에서는 각각의 파일이 다음과 같은 용도로 사용된다고 설명한다.
| 파일 | 역할 |
|---|---|
common.env | 모든 EdgeX 서비스의 공통 환경 변수 |
common-security.env | 보안 관련 공통 환경 변수 |
asc-common.env | Application Service 공통 환경 변수 |
asc-http-export.env | HTTP Export 프로필 설정 |
asc-mqtt-export.env | MQTT Export 프로필 설정 |
mqtt-bus.env | MQTT Message Bus 관련 설정 |
nats-bus.env | NATS Message Bus 관련 설정 |
.env 파일은 전체 설정을 가지고 있는 파일이 아니다.
기존 설정 중에서 변경하고 싶은 값만 오버라이딩하는 방식으로 사용한다.
예를 들어 기존 설정 파일에서 다음과 같이 작성되어 있다고 가정한다.
[Trigger]
Type = "edgex-messagebus"
이 설정을 .env에서 변경하고 싶다면 해당 설정의 계층을 환경 변수 형태로 표현하여 값을 덮어쓸 수 있다.
PDF에서도 .env 파일에서는 설정 속성의 .을 _로 바꾸어 접근하고 =을 사용하여 값을 지정한다고 설명한다.
즉,
Trigger.Type
과 같은 설정을 환경 변수 형태로 표현할 때 _를 이용하는 방식이다.
이번에는 실제 예제로 asc-http-export.env를 수정했다.
PDF에서는 asc-http-export.env를 오버라이딩하여 HTTP Trigger를 사용하도록 변경하는 과정을 설명한다.
기본값은 다음과 같이 edgex-messagebus이다.
edgex-messagebus
이를 HTTP Trigger로 변경하기 위해 asc-http-export.env의 설정을 수정했다.
TRIGGER_TYPE=http
그리고 .env 변경사항을 실제 Compose 구성에 반영하기 위해 반드시 다음 명령어를 실행해야 한다.
make build
PDF에서도 소스 및 구성 파일의 변경사항이 있을 경우 make build를 사용하여 적용해야 한다고 설명한다.
즉, 단순히 .env 파일만 수정한다고 끝나는 것이 아니라,
.env 수정
↓
make build
↓
변경된 Compose 구성 생성
↓
EdgeX 실행
↓
변경사항 확인
과정을 거쳐야 한다.
설정이 제대로 적용되었는지 EdgeX Console에서 직접 확인했다.
브라우저에서 다음 주소로 접속한다.
http://localhost:4000
EdgeX Console의 AppService 메뉴에서 Application Service 설정 화면으로 이동한다.
기존 설정에서는 Trigger Type이 다음과 같이 표시된다.
Type
edgex-messagebus
설정을 변경한 후에는 다음과 같이 표시된다.
Type
http
그리고 아래에 HTTP Trigger가 표시되는 것도 확인할 수 있다.


따라서 asc-http-export.env에서 변경한 설정이 단순히 파일에만 존재하는 것이 아니라 실제 EdgeX Console의 Application Service 설정에 반영된 것까지 확인할 수 있었다.
PDF에서도 동일하게 기존 edgex-messagebus 설정과 변경 후 http 설정을 비교하고, HTTP Trigger로 변경된 것을 확인하도록 구성되어 있다.
이번 1~2장 실습에서는 먼저 EdgeX Foundry의 전체적인 구조를 이해하고, edgex-compose를 이용하여 실제 EdgeX 환경을 실행해 보았다.
EdgeX는 하나의 프로그램이 아니라 여러 마이크로서비스가 계층적으로 구성되어 있으며, 각각의 서비스가 담당하는 역할이 다르다.
전체적인 구조를 다시 정리하면 다음과 같다.
┌─────────────────────────────────────┐
│ Application Services Layer │
│ 데이터 처리 / 변환 / 외부 전송 │
└─────────────────────────────────────┘
↑
┌─────────────────────────────────────┐
│ Supporting Services Layer │
│ Rules Engine / Scheduler / Alert 등 │
└─────────────────────────────────────┘
↑
┌─────────────────────────────────────┐
│ Core Services Layer │
│ Data / Command / Metadata / Config │
└─────────────────────────────────────┘
↑
┌─────────────────────────────────────┐
│ Device Services Layer │
│ 실제 센서 및 장치 연결 │
└─────────────────────────────────────┘
↑
[ Sensor / Device ]