13.6 Zenoh-Flow 파이프라인 배포 및 라이프사이클 관리
도면(YAML) 도 다 짜고, 노드(코드) 도 다 만들었다면 이제 그 생명체에 숨을 불어넣을 차례다.
이 챕터는 노트북 환경부터 전 지구 단위의 클라우드망까지 한 장의 파일로 데이터를 뿌리는 “운영자적 지휘 기법” 과 무중단 파이프라인 제어(Control) 를 다룬다.
1. 제공되는 CLI 도구를 활용한 파이프라인 제어 명령어
리모트 원격 조종기인 zfctl 의 숙련도에 따라 전체 시스템이 순식간에 복구되기도 하고 망가지기도 한다.
1.0.1 [Runbook] 데몬 정복을 위한 마스터 커맨드
당신이 치는 모든 커맨드는 zenoh 통신망을 타고 저격수처럼 특정 데몬의 심장을 타격한다.
1. 파이프라인 밀어 넣기 (Deploy)
## graph.yaml 설계도를 데몬 클러스터에 제출하여 메모리에 노드를 찍어낸다!
## (이때 파이프 배관만 완성될 뿐, 아직 물은 흐르지 않는다)
zfctl deploy graph.yaml
이때 시스템은 내부적으로 파이프라인 인스턴스 ID (UUID) 를 하나 부여하며, 이 ID 가 앞으로 이루어질 모든 생사결의 코드가 된다.
2. 런타임 추적 및 삭제
## 지금 전 세계 데몬에 돌고 있는 파이프라인 목록을 다 가져와라!
zfctl list
## 해당 파이프라인(배관)을 완전히 부수고 메모리에서 말소하라!
zfctl destroy <파이프라인_ID>
명령어들이 로컬이냐 원격이냐를 묻지 않는다. 켜져 있는 모든 Zenoh 데몬이 이 리모컨 하나의 명령을 동시에 받들어 움직인다.
2. 로컬(Local) 테스트 베드 환경에서의 실행 및 디버깅 파이프라인
로봇에 태우기 전, 내 노트북 안에서 모든 C/Python 모듈이 잘 엮이는지 검열하는 과정. 네트워크 병목이라는 변수를 차단한 가장 순수한 파이프라인 검증기법이다.
2.0.1 [인스펙션] 격리 없는 원-박스(One-Box) 실험실 구축
1. 개발용 데몬 (Run) 모드 사용
zfctl deploy 나 백그라운드 환경 없이 제일 직관적으로 테스트하는 방법이다.
## 별도의 백그라운드 데몬 없이, 이 명령어 하나가
## 임시 데몬을 띄운 후 YAML 을 주입하고 포그라운드(화면) 에 로그를 다 뿌린다!
zf-daemon --run graph.yaml
2. 로컬 디버깅의 꽃 - 트레이스(Trace) 추적
내 필터 모듈에서 Segmentation Fault 가 나는지, 파이썬이 뻗었는지 잡으려면 로그를 최고 수준으로 올려라.
## Rust, Python 노드의 모든 메모리 할당과 파이프 통신 로그가 터미널에 쏟아진다!
RUST_LOG=zenoh_flow=trace zf-daemon --run graph.yaml
이 환경에서는 모든 노드가 당신의 노트북 메모리 1개 안에서 포인터(Zero-Copy) 로만 오가기 때문에, 파이프라인 고유의 “로직 붕괴” 원인을 가장 빠르게 타격할 수 있다.
3. 물리적으로 분산된 이기종(Heterogeneous) 환경으로의 배포 전략
라즈베리 파이(ARM) 에는 카메라 소스 모듈을 띄우고, Intel 서버(x86) 에는 추론 모듈을 띄우는 실제 분산 환경에서의 배포.
3.0.1 [Runbook] 플러그인 바이너리 딜리버리 및 바인딩
Zenoh-Flow 데몬은 마법사가 아니다. 당신이 YAML 에 mapping: aws_server 라 적었다고 당신 노트북의 my_logic.so 파일이 AWS 로 날아가지 않는다.
1. 타겟 장비별 라이브러리(SO/DLL) 선행 배포
- 각각의 기계(라즈베리파이, 서버) 마다 그 기계의 CPU 아키텍처에 맞게 컴파일된 노드 바이너리(
*.so나*.py) 가 미리 파일 시스템 어딘가에 깔려 있어야 한다. - 이 과정을 Docker 이미지 베이킹(Baking) 을 쓰거나 Ansible 을 통해 물리적으로 먼저 배포하라.
2. YAML 속의 환경변수 트릭
물리적 경로가 달라도 하나의 YAML 로 통제하기 위한 런북이다.
operators:
- id: "infer"
# 절대 경로 대신 환경변수를 써서,
# 라즈베리 파이든 AWS 든 자기가 속한 환경의 변수값을 치환하게 만든다!
uri: "file://${ROBOT_PLUGIN_DIR}/lib_infer.so"
mapping: "node_b"
도면 결합은 논리적으로 한 방에 하되, 부품 조달은 각자의 공장(기계) 에서 조달하는 이것이 분산 파이프라인의 핵심 타결책이다.
4. 무중단 런타임에서의 파이프라인 시작, 일시 정지, 중지, 재시작
파이프라인 설계도(Deploy) 를 메모리에 박아 넣었다면 이제 컨베이어 벨트에 전원을 껐다 켤 수 있다. 이 과정은 당신이 운영체제 프로세스를 죽이는(Kill) 야만적인 행위가 아닌, 런타임 위의 우아한 라이프사이클 훅(Hook) 으로 작동한다.
4.0.1 [Runbook] 스테이트 머신(State Machine) 지휘 전술
1. 파이프 관문 개방 (Start)
zfctl start <파이프라인_ID>
이 명령이 떨어지면, 데몬 속에 웅크리고 있던 Source 노드들이 잠에서 깨어나 카메라나 센서 포트를 열고 데이터를 컨베이어 벨트에 쏟아 붓기 시작한다.
2. 즉각적인 동결 (Pause)
배터리가 모자라거나 긴급 에러가 났을 때.
zfctl pause <파이프라인_ID>
물리 스레드가 멈추진 않지만, Source 가 데이터를 밀어 넣는 행위를 멈춘다.
기존 파이프라인(가교) 중간에 머물러 있던 데이터들은 끝까지 필터링을 거쳐 Sink 로 조용히 빠져나가며, 시스템은 파이프가 완전히 비워진 “안전한 정지 상태” 로 동결된다.
3. 재개 (Resume) 와 종료 (Stop)
어떤 환경 변수나 포트 설정의 리부트 없이, 일시정지 된 상태에서 start 를 다시 치면 흐름이 이어진다. destroy(삭제) 가 아닌 이상 파이프라인은 어떤 상황에서도 자신의 로컬 메모리 상태를 잃어버리지 않는 다이하드(Die-hard) 구조다.
5. 동작 중인 파이프라인의 동적 업데이트 및 버전 관리
로봇이 한창 자율주행하며 돌고 있는 파이프라인 시스템을, 로봇을 끄지 않은 상태에서 새로운 딥러닝 모델 필터로 교체할 수 있을까?
5.0.1 [인스펙션] 핫-스와핑(Hot-swapping) 과 무중단 아키텍처 한계선
1. Zenoh-Flow 의 동적 재설계 사상
이론적으로 데몬은 Pause 를 걸어 파이프라인에 구르는 데이터를 완전히 비워낸(Drain) 후, 특정 노드의 구성이나 파이프 연결 고리를 갈아 끼울 수 있는 디자인 철학을 가지고 있다.
2. 운영 환경의 매뉴얼 패치 (현재의 모범 사례)
하지만 아직까지 실무에서는 로컬 변수(State Context) 의 무결성 보장을 위해 완전한 동적 라이브러리 교체보다는 “안전한 우회” 를 택한다.
-
zfctl deploy new_v2_graph.yaml로 새로운 파이프 배관 전체를 데몬의 허공에 짓는다. (이때 로봇은 아직 기존 V1 파이프로 달리고 있다).
-
- V2 에
zfctl start <v2_id>를 걸어 새로운 물길을 튼다.
- V2 에
-
- 즉각 기존 V1 에
zfctl destroy <v1_id>를 타격하여 레거시 컨베이어 벨트를 메모리에서 강제로 부숴버린다.
- 즉각 기존 V1 에
이 “블루 그린(Blue-Green) 배포” 전술을 타격하면, 로봇은 단 1프레임의 멈춤도 없이 새로운 딥러닝 뇌(Brain) 구조체를 장착하고 컨베이어 벨트를 돌리게 된다.