3.9 통합 네트워크 분석 및 트러블슈팅 도구 준비
3.8장까지 구축한 모니터링 대시보드와 트레이싱 인터페이스가 환자의 겉으로 드러난 ’생체 신호(Vital Sign)’를 관찰하는 역할이라면, 애플리케이션 레벨에서조차 원인을 파악할 수 없는 깊은 통신 장애(예: 커널 레벨 패킷 드롭, 포트 충돌, 방화벽 차단 등)에 직면했을 때는 네트워크의 해부학적 구조를 직접 메스로 갈라보는 하드코어 트러블슈팅이 불가피하다.
아무리 뛰어난 로보틱스 엔지니어나 IoT 백엔드 개발자라도 네트워크 프로토콜의 밑바닥을 들여다보지 않고 분산 시스템의 완전한 안정성을 보장할 수는 없다.
이 장에서는 Zenoh 프로토콜 위를 오가는 패킷의 파형을 캡처하여 바이트 단위로 분석하고, 고질적인 멀티캐스트(Multicast) 및 포트 충돌 문제를 진단하며, 인프라의 동맥경화를 예방하기 위해 주기적으로 양 종단 간의 무결성을 테스트하는 엔지니어링 스크립트를 작성하는 과정을 다룬다. 진정한 마스터가 되기 위한 수술 도구들을 준비해 보자.
1. Wireshark를 활용한 Zenoh 패킷 캡처 및 디코딩 설정
인터넷 트래픽 분석의 영원한 업계 표준 도구인 **Wireshark(와이어샤크)**는 Zenoh의 와이어 프로토콜(Wire Protocol)을 분석하는 데 있어서도 가장 강력한 현미경이다. 하지만 Zenoh는 상대적으로 신생 프로토콜이므로 Wireshark 내부에 기본 디세터(Dissector, 프로토콜 해석기)가 포함되어 있지 않을 수도 있다.
이 절에서는 Wireshark를 설치하고, Zenoh 커뮤니티에서 제공하는 전용 플러그인을 컴파일하여 이진(Binary)으로 암호화된 듯한 Zenoh 패킷을 인간이 읽을 수 있는 구조적 텍스트로 디코딩(Decoding)하는 환경을 구성한다.
1.1 Wireshark 및 기본 의존성 설치
Ubuntu 환경을 기준으로 네트워크 인터페이스를 캡처할 수 있는 권한과 함께 Wireshark를 설치한다.
## Wireshark 핵심 패키지 및 tshark(CLI 버전) 설치
sudo apt update
sudo apt install wireshark tshark
## 설치 도중 'Should non-superusers be able to capture packets?' 창이 뜨면 <Yes> 선택
## 현재 사용자를 wireshark 그룹에 추가하여 sudo 없이 캡처 허용
sudo usermod -aG wireshark $USER
## 설정 적용을 위해 로그아웃 후 다시 로그인 필요
1.2 Zenoh Wireshark 플러그인 빌드 및 설치
Zenoh 패킷은 고도의 압축과 직렬화(Serialization)를 거치기 때문에 디세터 없이는 단순한 TCP/UDP 페이로드 쓰레기로만 보인다. 공식 리포지터리에서 제공하는 플러그인을 빌드하여 장착하자.
## Zenoh Wireshark 디세터 소스 복제 (C 언어 기반)
git clone https://github.com/eclipse-zenoh/zenoh-wireshark.git
cd zenoh-wireshark
## CMake를 이용한 플러그인 빌드 환경 구성
mkdir build && cd build
cmake ..
make
## 빌드된 디세터(.so 파일)를 Wireshark 플러그인 디렉터리로 복사
mkdir -p ~/.local/lib/wireshark/plugins
cp *.so ~/.local/lib/wireshark/plugins/
(참고: Windows 환경의 경우 빌드 과정이 훨씬 복잡하므로, 릴리즈 탭에서 제공되는 미리 빌드된 .dll 파일을 다운로드하여 %APPDATA%\Wireshark\plugins에 넣는 것을 권장한다.)
1.3 Wireshark 캡처 검증
모든 준비가 완료되었다면 Wireshark를 실행하고 Zenoh 기본 포트인 7447 포트를 타겟으로 패킷 필터링을 걸어보자.
- Wireshark 실행 후
any또는 활성화된 네트워크 인터페이스(예:eth0,wlan0)를 더블클릭하여 캡처를 시작한다. - 상단의 보기(Display) 필터 창에 다음과 같이 입력하고 엔터를 친다.
zenoh또는tcp.port == 7447 || udp.port == 7447 - 터미널을 열고 앞선 장에서 테스트했던
z_ping이나 커스텀 Pub/Sub 앱을 가동해 트래픽을 발생시킨다.
이제 검은 화면 속 이진 데이터들이 Zenoh Protocol이라는 명찰을 달고, 내부의 세션 ID, 프레임 타입(Data, Query, Declaration 등), **라우팅 키(Key Expression)**까지 계층 트리 형태로 우아하게 파싱되어 나타나는 것을 확인할 수 있다. 이 화면을 보는 순간, 여러분은 Zenoh가 네트워크 상에서 어떻게 호흡하고 대화하는지 그 속살을 완벽히 꿰뚫어 보게 된 것이다.
2. 포트(TCP/UDP 7447) 충돌 확인 및 멀티캐스트 네트워크 진단
Zenoh 라우터나 클라이언트 애플리케이션을 구동할 때 가장 빈번하게 발생하는 초보적인 시스템 에러는 “Address already in use” (포트 충돌) 문제이다.
또한, 같은 서브넷(Subnet) 상에 로봇들을 올려놓았음에도 불구하고 서로를 스카우팅(Scouting)하지 못하는 이른바 “유령(Ghost) 네트워크” 현상은 대부분 멀티캐스트(Multicast) 차단으로 인해 발생한다. 이 절에서는 서버 인프라 관리자가 반드시 숙지해야 할 포트 및 네트워크 진단 기법을 서술한다.
2.1 기본 통신 포트(7447) 점유 상태 점검
Zenoh는 기본적으로 피어(Peer) 탐색과 데이터 전송을 위해 TCP와 UDP 7447번 포트를 전면적으로 사용한다. 라우터 데몬이 백그라운드에서 이미 돌고 있는지, 혹은 좀비 프로세스가 포트를 물고 늘어지고 있는지 검사해야 한다.
## 리눅스 환경에서 TCP/UDP 7447 포트를 점유 중인 프로세스 확인 (루트 권한 필요)
sudo netstat -tulnp | grep 7447
## 또는 최신 도구인 ss 활용
sudo ss -tulnp | grep 7447
출력 결과에서 zenohd나 방금 실행하다 강제 종료된 스크립트의 프로세스 ID(PID)가 출력된다면, kill -9 <PID> 명령으로 좀비 프로세스를 사살해야만 새로운 인스턴스가 성공적으로 포트를 바인딩할 수 있다.
2.2 멀티캐스트(Multicast) 라우팅 진단
디스커버리(Discovery) 메커니즘이 동작하지 않아 노드 간 자동 연결이 실패한다면, 십중팔구 회사 보안망이나 클라우드 VPC 내부에서 UDP 멀티캐스트 트래픽(기본 IP: 224.0.0.225, 포트: 7447)을 방화벽 규칙으로 드롭(Drop)시키고 있기 때문이다.
이를 확인하기 위해 iperf3나 socat, 혹은 직관적인 netcat 도구를 이용해 멀티캐스트 루프백 테스트를 진행해 보자.
## 터미널 A (수신 대기): Zenoh 멀티캐스트 그룹 조인 모사
## socat을 이용해 멀티캐스트 그룹 224.0.0.225의 7447 포트를 열고 대기
socat UDP4-RECVFROM:7447,ip-add-membership=224.0.0.225:0.0.0.0,fork -
## 터미널 B (송신 발포): 같은 망에 연결된 다른 장비에서
echo "DISCOVERY_TEST" | socat - UDP4-DATAGRAM:224.0.0.225:7447
터미널 A에 DISCOVERY_TEST 문자열이 나타나지 않는다면, 네트워크 라우터 스위치의 IGMP Snooping 설정이 꼬여있거나 OS 자체의 ufw / iptables가 패킷을 묵살하는 것이다.
이 경우 해결책은 두 가지이다:
- 네트워크 관리자에게 멀티캐스트 대역을 예외 처리해달라고 요청한다.
- 멀티캐스트를 포기하고, Zenoh 설정 파일에서 정적 탐색(Static Discovery) 방식(특정 IP로 직접 유니캐스트 연결)으로 아키텍처를 전면 수정한다. (이 기법은 향후 4장에서 상세히 다룰 것이다.)
3. 클라이언트와 라우터 간 연결 무결성 점검 스크립트 작성
실제 상용(Production) 수준의 로보틱스 서비스나 원격 제어 솔루션을 운영하다 보면, 모니터링 대시보드가 있음에도 불구하고 간헐적인 네트워크 순단(Network Blip) 현상으로 인해 연결 세션이 조용히 끊어져 있는 경우가 발생한다. 이는 라우터 자체의 기능정지가 아니라, 방화벽의 세션 만료(TCP Timeout) 정책 등에 기인한 ‘거짓된 연결 유지(Half-open connection)’ 상태일 확률이 높다.
이러한 사일런트 페일(Silent Fail)을 선제적으로 감지하고 경고를 울리기 위해, 단순히 핑(Ping)만 치는 것을 넘어 실제 페이로드를 읽고 쓰는 엔드 투 엔드(End-to-End) 연결 무결성 점검 스크립트를 작성하여 크론(Cron) 작업이나 헬스 체크(Health Check) 파이프라인에 이식해야 한다.
3.1 무결성 점검 아키텍처 설계
검증 스크립트의 작동 원리는 단순하고 명확해야 한다.
health/check라는 특수 감시 토픽(Topic)에 타임스탬프와 무작위 난수가 포함된 심박(Heartbeat) 메시지를 퍼블리시(Put)한다.- 해당 토픽에서 값을 곧바로 다시 조회(Get)하여, 내가 올린 스탬프가 훼손되지 않고 원격 라우터 스토리지를 거쳐 정확히 반환되는지 시간 내(Timeout) 검증한다.
3.2 Python 기반 워치독(Watchdog) 스크립트 구현
가장 다루기 쉬운 Python을 활용하여 워치독 에이전트(Watchdog Agent) 스크립트를 작성해 보자. (진행하기 전 pip install eclipse-zenoh 명령으로 라이브러리를 설치하라).
## check_zenoh_health.py
import zenoh
import time
import sys
import uuid
## 검증 파라미터 설정
TOPIC = "health/check/main_router"
TIMEOUT_SEC = 2.0
def verify_connection():
# 라우터 연결 초기화
print("Zenoh 라우터에 세션 수립 시도 중...")
session = zenoh.open(zenoh.Config())
# 1. 고유 토큰 발행 및 Put
token = str(uuid.uuid4())
current_time = time.time()
print(f"[{current_time}] 진단 토큰 발송: {token}")
session.put(TOPIC, token)
# 2. Get 검증 시도 (블로킹 인터페이스 활용)
try:
replies = session.get(TOPIC, zenoh.Queue())
for reply in replies:
if reply.ok:
received_token = reply.ok.payload.to_string()
latency = (time.time() - current_time) * 1000
if received_token == token:
print(f"✅ 무결성 검증 성공: {latency:.2f} ms")
sys.exit(0) # 정상 종료
else:
print(f"❌ 토큰 불일치! 기대값: {token}, 수신값: {received_token}")
sys.exit(1) # 불일치 에러 반환
# 응답이 비어있을 경우
print("❌ 스토리지를 통한 응답 수신 실패 (라우터 연결 단절 의심)")
sys.exit(2)
except Exception as e:
print(f"❌ 심각한 에러 발생: {e}")
sys.exit(3)
if __name__ == "__main__":
verify_connection()
3.3 스크립트의 인프라 통합 적용
이 스크립트는 혼자 돌려보고 만족하는 용도가 아니다. 반환하는 종료 코드(Exit Code)를 기반으로 AWS Route 53, 쿠버네티스 레이디니스 프로브(Ready Probe), 혹은 Zabbix/Nagios 같은 레거시 인프라 관제 서버와 완벽히 결합(Integration)할 수 있도록 설계되었다.
만약 위 스크립트가 0(정상)이 아닌 다른 코드(1, 2, 3)를 뱉어낸다면, 인프라 관제 시스템은 즉시 슬랙(Slack) 워크스페이스나 개발자의 휴대폰으로 온콜(On-call) 경고를 폭격하여 드론이 추락하기 전 선제적인 리부트(Reboot)나 라우팅 우회 조치를 강제할 시간을 벌어주게 된다. 이것이 진정한 에지(Edge) 트러블슈팅의 핵심이다.