3.1 Zenoh 생태계 및 환경 구축 개요
데이터의 생산지(Edge)부터 소비지(Cloud)까지 단절 없는 통신 연속성(Continuum)을 제공하기 위해, Zenoh(제노) 생태계는 매우 방대한 언어와 이기종 플랫폼을 전방위적으로 지원한다.
단순히 데몬 하나를 설치하고 끝나는 레거시 미들웨어와 달리, Zenoh 기반의 시스템 아키텍처를 세우기 위해서는 자신이 목표로 하는 하드웨어 타겟(마이크로컨트롤러, 라즈베리파이, 클라우드 쿠버네티스 클러스터 등)과 개발 언어(Rust, C++, Python 등)에 최적화된 맞춤형 환경 구축이 선행되어야 한다.
이 장(Chapter 3)에서는 본격적인 코드 작성과 시스템 라우팅에 앞서, Zenoh의 다양한 패키지와 바이너리를 시스템에 안착시키는 핵심 설치 과정을 다룬다.
1. Zenoh 시스템 컴포넌트 생태계의 구성
Zenoh 생태계는 크게 세 가지의 계층적 구성 요소로 나뉘어 개발 및 운영 환경을 뒷받침한다.
- 인프라스트럭처 컴포넌트 (Infrastructure Components):
네트워크의 백본(Backbone)과 브릿지 역할을 담당하는 실행 가능한 바이너리(Executable Binaries)들이다.zenohd(라우터 데몬)를 필두로, MQTT나 DDS 시스템과 데이터를 중계해 주는zenoh-bridge-mqtt,zenoh-bridge-dds플러그인 바이너리 등이 여기에 속한다. - 프로그래밍 언어 API 및 바인딩 (Client APIs):
애플리케이션(퍼블리셔/서브스크라이버)을 직접 개발하기 위한 SDK 라이브러리다. Zenoh 코어 엔진이 작성된 Rust 언어의 크레이트(Crate)를 기본으로 하여, C/C++, Python, TypeScript, Go 등 현대적인 대부분의 언어 환경을 위한 바인딩 라이브러리를 공식 지원한다. - 플러그인 및 생태계 확장 모듈 (Plugins & Extensions):
설치된 라우터(zenohd)의 능력을 극대화하기 위한 동적 라이브러리(.so, .dll) 형태의 플러그인들이다. 스토리지 백엔드 연동(InfluxDB, RocksDB), REST API 쿼리 지원, 시계열 모니터링 메트릭(Metrics) 추출 통합 플러그인 등이 존재한다.
2. 모놀리식(Monolithic) 종속성의 탈피
기존 ROS1이나 DDS 환경을 구축해 본 엔지니어라면, 시스템 코어 패키지와 수십 개의 언어 바인딩, 그리고 무거운 컴파일러 체인이 마치 한 몸처럼 뒤엉켜 설치되는 모놀리식 종속성의 끔찍함을 기억할 것이다.
반면, Zenoh의 환경 구축 철학은 극단적인 **모듈화(Modularity)**와 **무의존성(Zero-dependency)**을 지향한다.
- 라우터(
zenohd) 바이너리 단 하나만 다운로드받아 실행하면 그 즉시 네트워크 백본이 완성된다. - Python 클라이언트를 개발하고 싶다면 단지
pip install eclipse-zenoh한 줄만 치면 된다. 시스템에 무거운 사스코(C++ 빌드 툴)나 거대한 미들웨어 데몬이 억지로 깔려있을 필요가 없다. - 크로스 컴파일(Cross-compile) 환경에서도 대상 에지 보드에 런타임 종속성을 설치하지 않고, 정적 링킹(Static Linking)된 바이너리 하나만 던져 넣으면 곧바로 실행된다.
이어지는 하위 절들에서는 인프라 엔지니어가 시스템 요구사항을 파악하고, 로컬 디버깅 환경과 클라우드 운영 환경에 맞춰 네트워크를 어떻게 개방해야 하는지 필수적인 기초 설정들을 점검한다. 완전히 통일된 C/Rust 빌드 툴체인 위에 올라선 이 매끄러운 생태계의 진수를 경험하게 될 것이다.
3. 시스템 요구사항 및 지원 플랫폼 확인
퍼블릭 클라우드의 가상 머신(VM)부터 손톱만 한 크기의 아두이노(Arduino) 보드까지, 데이터가 흐르는 모든 곳을 타겟으로 삼는 **Zenoh(제노)**는 지원하는 하드웨어의 스펙에 따라 코어 엔진을 세밀하게 분할하여 제공한다. 엔지니어는 자신이 다룰 하드웨어의 메모리와 OS 환경을 명확히 파악하고 올바른 배포판을 선택해야 한다.
3.1 운영체제(OS) 및 시스템 아키텍처 호환성
Zenoh의 메인 코어 엔진과 라우터(zenohd)는 하드웨어 제어가 매우 용이한 Rust 언어로 밑바닥부터 작성되었기 때문에, 현존하는 거의 모든 주요 POSIX 호환 시스템 및 상용 OS에서 네이티브 수준의 성능을 발휘한다.
- Linux (운영 환경 1순위):
Ubuntu, Debian, RHEL 등 메인스트림 리눅스 생태계를 완벽 지원한다. 특히 x86_64, aarch64(라즈베리파이 4, 젯슨 나노 등 ARM64 기반) 아키텍처에 대한 공식 바이너리가 빌드되어 배포된다. - macOS (로컬 개발 환경):
Apple Silicon(M1/M2 등 aarch64) 및 Intel x86_64 아키텍처를 원활히 지원한다. 개발자들의 로컬 랩탑 코딩 환경으로 가장 적합하다. - Windows:
Windows 10 이상의 환경에서 MSVC 컴파일러 툴체인을 통해 네이티브 바이너리로 구동할 수 있다. (WSL2 환경을 통한 리눅스 컨테이너 구동도 적극 권장된다.) - RTOS (실시간 운영체제):
FreeRTOS, Zephyr, Mbed OS 등은 일반적인 Zenoh 코어가 아닌 경량화된 분기점인 Zenoh-Pico (C언어 기반)를 통해 지원한다. (관련 상세 설정은 Chapter 10 참조)
3.2 단계별 하드웨어 최소 요구사항
Zenoh는 런타임 가비지 컬렉터(Garbage Collector)가 없는 Rust로 작성되어 메모리 풋프린트(Footprint)가 극도로 작다. 그러나 운용 목적에 따라 다음과 같이 하드웨어 스펙을 산정해야 한다.
3.2.1 Tier 1. 라우터 백본 (Cloud / 5G Edge Server)
다수의 클라이언트 노드가 붙어 수만 개의 패킷이 쏟아지고, 인네트워크 캐싱(In-network Caching) 메모리를 유지해야 하는 중앙 라우터 역할이다.
- 권장 사양: 최소 2 CPU 코어 이상, 2GB 이상의 가용 RAM
- Storage: RocksDB 등의 백엔드 플러그인을 활성화할 경우 분산 데이터 저장을 위한 빠른 NVMe SSD 공간 필수
3.2.2 Tier 2. 에지 피어 노드 (SBC / Robotics Gateway)
라즈베리파이 4, 엔비디아 젯슨(Nvidia Jetson) 계열 보드 등에서 카메라 센서 데이터를 처리하거나 ROS2 미들웨어 브릿지로 작동하는 역할이다.
- 권장 사양: ARM 프로세서 기반, 최소 256MB~512MB RAM 공간 (비디오 스트리밍 여부에 따라 프로세스 메모리가 가변적임)
- 특징: 표준 Linux 환경이 구동되므로 일반적인 Zenoh Rust/Python API 사용이 원활하다.
3.2.3 Tier 3. 마이크로컨트롤러 (MCU / Sensor Nodes)
ESP32, STM32 등 운영체제가 없거나 RTOS만 깔려있는 센서 말단이다.
- 권장 사양: 메모리가 몇 십 킬로바이트(KB) 수준.
- 특징: 표준 Zenoh 패키지는 절대 구동 불가능하며, 오로지 C언어 기반의 Zenoh-Pico 라이브러리만을 크로스 컴파일(Cross-compile)하여 펌웨어에 구워 올려야 한다.
3.3 네트워크 프로토콜 스택 요구사항
Zenoh는 UDP 멀티캐스트(Multicast), TCP, QUIC, 심지어 Bluetooth Low Energy(BLE), Serial 단자까지 다루는 플러그인 전송 계층(Transport Layer)을 갖고 있다.
따라서 호스트 하드웨어가 단순한 네트워크 칩셋 외에도 방화벽에서 QUIC 구동을 위한 UDP 터널링이나 브로드캐스트 패킷을 OS 레벨에서 허용할 수 있는지(컨테이너 가상화 여부에 따라 다름)의 여부를 사전에 반드시 진단해야 한다. 세부적인 포트 설정에 관한 규칙은 3.1.3절에서 연이어 다룬다.
4. 로컬 개발 환경 vs 에지 및 클라우드 배포 환경 비교
개발자의 랩탑 환경에서 완벽하게 동작하던 분산 애플리케이션 코드가 실제 에지(Edge) 보드나 클라우드(Cloud)의 컨테이너 환경 위로 올라가는 순간, 수많은 네트워크 파티셔닝(Partitioning) 이슈와 마주하며 침몰하는 것은 미들웨어 엔지니어링의 일상적인 비극이다.
**Zenoh(제노)**는 이를 방지하고 ‘한 번 작성하면 어디든 배포 가능한(Write Once, Deploy Anywhere)’ 아키텍처를 구현하기 위해, 코딩 시점부터 로컬과 상용 배포 환경의 근본적인 차이점에 맞추어 환경 구축 전략을 달리 해야 한다.
4.1 랩탑 중심의 로컬 개발 환경 (Local Development Environment)
앱 개발 초기 혹은 디버깅 용도로 자신의 랩탑 하나에 퍼블리셔, 서브스크라이버 앱, 그리고 로컬 테스트용 라우터까지 모두 띄워놓고 작업하는 단일 노드 샌드박스 환경이다.
- 운영 체제: 주로 macOS 랩탑 환경이나 Windows WSL2 리눅스 터미널을 이용한다.
- 네트워크 설정: 별도의 라우팅 테이블 고민 없이 터미널 여러 개를 열고
localhost(127.0.0.1)혹은 공유 메모리(Shared Memory) 전송 플러그인을 사용하여 개발한다. - 디스커버리 체계: Zenoh의 핵심 탐색 기법인 **멀티캐스트 스카우팅(Multicast Scouting)**이 매우 강력하게 작동한다. 즉, IP를 몰라도 데몬을 켜는 즉시 툴이 알아서 서로를 발견하고 세션을 수립하는 마법 같은 디버깅 경험을 제공한다.
- 구축 전략: 가벼운 Homebrew 패키지 매니저나 Cargo(Rust 빌드 툴)를 통해 곧바로 바이너리를 땡겨와서 실행(Runner)하는 것이 시간 효율을 극대화한다.
4.2 에지 노드 배포 환경 (Edge Devices & IoT Gateways)
개발된 코드가 크로스 컴파일(Cross-compile)되어 라즈베리파이나 로봇 내장 보드와 같은 물리적 장비로 내려가는 환경이다.
- 네트워크 제약: 언제 끊어질지 모르는 열악한 Wi-Fi 환경, 혹은 사설망(Private IP) 안쪽에 갇힌 채 클라우드로 통신을 뚫어내야 하는 NAT(네트워크 주소 변환) 환경의 최전선이다.
- 자원 제약 방어: 제한된 RAM 공간 위에서 구동해야 하므로 언어 런타임 오버헤드가 극심한 Python보다는 Rust나 C++를 이용한 네이티브 컴파일 바이너리 형태가 가장 선호된다.
- 구축 전략: 각 에지 보드마다 수동으로 툴을 설치하기보다는 시스템 데몬(
systemd) 스크립트로 엮어 하드웨어 부팅 즉시 백그라운드 서비스 형태로 실행되도록 설정해야 한다. 외부망(Cloud 등)과 연결을 수립하기 위해 동적 스카우팅보다는 정적(Static) IP 연결 방식인 TCP/QUIC 엔드포인트를 애플리케이션 시작 파라미터로 명시적으로 주입하는 것이 장애를 막는 방어적 설계다.
4.3 클라우드 백본 배포 환경 (Cloud / Data Center)
수천 대의 로봇이 쏟아내는 글로벌 트래픽을 한데 모으기 위해 AWS, GCP, Azure 등에 거대한 Zenoh 라우터 클러스터 구조를 구축하는 환경이다.
- 네트워크 제약: 퍼블릭 클라우드 내부의 가상 사설망(VPC) 서브넷 환경은 **기본적으로 브로드캐스트나 멀티캐스트 패킷을 완벽히 차단(Drop)**한다. 따라서 로컬 개발 환경처럼 켜놓기만 하면 서로를 발견하는 마법 따윈 클라우드에서는 통하지 않는다.
- 구축 전략: 베어메탈 직배포 보다는 Docker 이미지 및 Kubernetes의 헬름(Helm) 차트를 활용하여 마이크로서비스 형식으로
zenohd인스턴스들을 무한 확장(Scale-out) 시키는 것이 일반적이다. - 가십 스카우팅 도입: 멀티캐스트가 막혀 있다면 어떻게 피어망을 찾을까? 클라우드 배포 시에는 반드시 초기 시드 노드(Seed Node) IP를 명시하여 점대점(Point-to-Point)으로 통신을 뚫어낸 다음, 피어들끼리 알음알음 상대방 주소를 알려주는 가십 프로토콜(Gossip Protocol, 4.5.3절 참고) 설정 옵션을 활성화해야만 클러스터링이 완성된다.
결국 Zenoh 망을 통합 관리하는 아키텍트라면 이 세 가지 환경에 따른 “어떻게 타겟을 발견할 것인가(Discovery)” 에 대한 네트워크 접근 방식을 각각 다르게 통제하고 격리해야만 한다.
5. 필수 네트워크 설정 및 방화벽 요구사항
Zenoh(제노) 데몬을 백그라운드 프로세스로 띄웠음에도 서로 통신이 되지 않는 대부분의 장애 사례 뒤에는 방화벽(Firewall)과 운영체제의 네트워크 보안 정책이라는 거대한 벽이 존재한다. L7 애플리케이션 계층 위에서만 놀던 개발자가 L4 트랜스포트 계층과 씨름해야 하는 순간이 온 것이다.
Zenoh가 서로를 발견하고(Discovery) 데이터를 주고받기(Routing) 위해 시스템 인프라 담당자가 반드시 열어두어야 하는 최소한의 네트워크 포트 규칙과 라우팅 정책을 짚고 넘어간다.
5.1 Zenoh 시스템 통신을 위한 기본 포트 목록
Zenoh 네트워크는 기본적으로 정해진 표준 포트(Default Ports)를 사용하여 통신을 시도한다. 사내망이나 클라우드 보안 그룹(Security Group) 설정 시 인바운드/아웃바운드 규칙에 다음의 포트들을 반드시 허용(Allow) 목록에 추가해야 한다.
- UDP 포트 7447 (필수):
Zenoh의 가장 핵심적인 디스커버리(멀티캐스트 스카우팅) 용 포트다. 동일한 서브넷(Subnet) 내에 있는 두 대의 라즈베리파이가 서로를 찾기 위해서는 이 포트를 통한 UDP 멀티캐스트 브로드캐스팅이 반드시 정상 동작해야 한다. - TCP 포트 7447 (권장 - 라우팅용):
라우터(zenohd) 간의 안정적인 데이터 교환을 위해 가장 널리 쓰이는 기본 엔드포인트 포트이다. 디스커버리가 끝난 노드들은 이 포트를 통해 실질적인 퍼블리시-서브스크라이브 세션을 맺는다. - UDP 포트 7447 (QUIC 프로토콜 활용 시):
클라우드와 에지 사이의 원거리 통신망 지연을 줄이기 위해 최신 QUIC 프로토콜을 백본으로 사용할 경우 점유하는 포트이다. (QUIC은 TCP 대신 UDP 위에서 구동됨에 주의) - TCP 포트 8000 (관리 및 REST API용):
Zenoh 라우터의 현재 헬스 체크(Health Check)나 라우팅 테이블 상태를 조회할 수 있는 내장 어드민(Admin) REST API를 오픈할 때 사용된다. 보안상 퍼블릭 망에는 절대 열지 말고 사설망 관제 서버쪽으로만 열어두는 것이 좋다.
5.2 Docker 및 컨테이너 가상화 환경에서의 주의사항
최신 배포 트렌드에 따라 zenohd를 리눅스의 Docker 컨테이너 위에서 구동할 경우, 단순히 포트 포워딩(-p 7447:7447)을 하는 것만으로는 에지 디바이스 간의 자동 탐색(Scouting)이 처참하게 실패한다.
- 원인: 도커의 기본 브릿지(Bridge) 네트워크는 호스트 OS의 물리적 네트워크 카드(eth0)와 완전히 격리된 별도의 서브넷 공간을 갖기 때문에, 멀티캐스트 UDP 패킷이 호스트 밖으로 새어 나가지 못하고 컨테이너 내부에서만 맴돌다 소멸한다.
- 해결책 (호스트 네트워크 모드):
컨테이너 내의 Zenoh 라우터가 물리적 로컬 네트워크의 다른 노드를 마법처럼 찾게 하려면,docker run명령 시 반드시--net=host옵션을 부여하여 도커의 가상 네트워크 격리를 무력화시켜야 한다.
## 잘못된 예: 외부 로봇이 이 라우터를 자동으로 찾을 수 없음
docker run -p 7447:7447/tcp -p 7447:7447/udp eclipse/zenoh
## 올바른 예: 호스트의 물리망에 직접 멀티캐스트 핑을 뿌리도록 허용
docker run --net=host eclipse/zenoh
5.3 기업망(Enterprise Network)과 프록시 설정
사내 보안팀에 의해 멀티캐스트 트래픽 자체가 스위치 장비 레벨에서 완벽히 통제(Drop)당하는 팍팍한 엔터프라이즈 환경이라면 어떻게 해야 할까? 혹은 방화벽이 TCP 80이나 443번 포트를 제외한 모든 외부 통신을 차단하는 환경이라면?
- 가십(Gossip) 프로토콜로의 선회:
4.5.3절에서 상세히 배우게 될 가십 프로토콜을 이용해, 정적으로 지정된 첫 번째 시드(Seed) 피어의 IP 주소 하나만을 신뢰 목록에 박아두고 TCP 점대점(Point-to-Point) 통신만으로 클러스터링을 엮어 나가야 한다. - WebSocket 트랜스포트로 우회:
방화벽이 오직 80/443 포트의 웹 트래픽만 허용할 때, Zenoh 프로토콜을 HTTP 웹소켓으로 부드럽게 감싸서 방화벽을 기만(Bypass)하는 WebSocket 트랜스포트를 사용하도록 라우터를 재구성하여 이 문제를 돌파할 수 있다.