
kioku-mesh #4 - kioku-mesh로 hub를 세우고 spoke를 연결하여 머신 간 공유 메모리 만들기
요약
kioku-mesh를 사용하여 hub-spoke 구조의 분산 공유 메모리 네트워크를 구축하는 방법을 설명합니다. Zenoh를 기반으로 여러 머신 간의 데이터 복제와 통신 설정을 단계별로 안내합니다.
핵심 포인트
- hub-spoke 토폴로지를 통한 머신 간 공유 메모리 구성
- Zenoh를 활용한 양방향 데이터 복제(Replication) 확인
- Linux 환경에서 systemd를 이용한 서비스 상주 설정
- TCP 7447 포트를 이용한 폐쇄 네트워크 통신 전제
목표
- 1대를 hub로 설정하기 (
init --mode hub) - 1대 이상의 spoke를 hub에 연결하기 (
init --mode spoke --connect <hub>) zenohd를 실행하여save/search로 양방향 replication (복제) 확인하기--install-systemd로 상주시키기 (Linux)- 3~5대로 확장할 때의 정석적인 절차
전제 조건
-
피어(Peer) 간에 TCP 7447이 통신 가능한 폐쇄된 네트워크 (LAN / Tailscale / WireGuard / VPN 중 하나)
-
각 호스트에
uv tool install kioku-mesh완료 (연재 제2회 참조) -
각 호스트의 PATH에
zenohd와zenoh-backend-rocksdb가 포함되어 있을 것 -
현재 타겟은 Zenoh 1.9.0
-
패키지 도입은 Zenoh의 공식 설치 가이드를 참조. Debian/Ubuntu 계열이라면 apt repository가 빠름
-
Linux에서
--install-systemd를 사용하는 경우, user-scope systemd를 사용할 수 있을 것
토폴로지 설계
제1회에서 제시했던 hub-spoke 도표를 다시 게시합니다.
실례로서, 본 기사에서는 아래의 3대 구성을 일관되게 사용합니다. 독자의 PC 환경에 맞춰 바꾸어 읽어주세요. example_5peer.md의 5대 구성으로 확장할 때의 변환 방법도 표의 맨 아래에 적어두었습니다.
| 호스트명 | 역할 | LAN IP | 예상 머신 |
|---|---|---|---|
| desktop | hub (항시 가동) | 192.168.1.10 | 자택 데스크톱 |
| laptop | spoke | 192.168.1.11 | 휴대용 노트북 PC |
| agent-server | spoke | 192.168.1.12 | 에이전트 상주 서버 |
이후의 커맨드 블록은 "어느 호스트에서 실행하는지"를 서두에 명시합니다. 예를 들어 # [on desktop / 192.168.1.10]라는 주석 줄로 시작하는 덩어리는, 해당 호스트의 shell에 접속한 뒤 입력해 주세요.
Step 1: hub 세우기 (desktop / 192.168.1.10)
hub는 spoke로부터의 인바운드(Inbound)를 받는 측입니다. desktop(192.168.1.10)에 로그인하여, init --mode hub로 zenohd.json5를 생성합니다.
# [on desktop / 192.168.1.10]
kioku-mesh init --mode hub \
--listen 127.0.0.1 \
...
--listen 192.168.1.10은 spoke 입장에서 desktop을 가리키는 주소입니다. LAN IP 외에 Tailscale IP / VPN IP가 있다면--listen을 반복하여 추가합니다.--listen 127.0.0.1도 넣어두면, desktop 자신의 CLI / MCP 클라이언트가 TCP/loopback으로 접속할 수 있습니다.--out을 명시하면 호스트명과 설정 파일의 대응 관계를 한눈에 알 수 있습니다.--force는 기존 파일 덮어쓰기 허용
init --mode hub는 connect.endpoints: [] 상태 그대로, 즉 외부로 dial(다이얼)하지 않습니다.
zenohd 실행하기
desktop에서
# [on desktop / 192.168.1.10]
zenohd -c ~/.config/kioku-mesh/zenohd_desktop.json5
다른 터미널(동일한 desktop 상)에서 동작을 확인합니다.
# [on desktop / 192.168.1.10]
kioku-mesh doctor
doctor는 backend / Zenoh 도달성 / SQLite index 등을 종합적으로 체크해 줍니다.
desktop에 상주시키기 (user-scope systemd)
desktop은 항시 가동되는 hub이므로, 로그인 시 자동으로 실행되도록 합니다. --install-systemd
를 init
에 전달해 두면, ~/.config/systemd/user/kioku-mesh-zenohd.service
에 unit이 작성됩니다.
# [on desktop / 192.168.1.10]
kioku-mesh init --mode hub \
--listen 127.0.0.1 \
...
Step 2: spoke를 연결하기 (laptop / agent-server)
spoke 측은 hub인 desktop(192.168.1.10)
만 다이얼(dial)합니다.
192.168.1.11
laptop(````
[on laptop / 192.168.1.11]
kioku-mesh init --mode spoke
--listen 127.0.0.1
...
- `--listen 192.168.1.11`은 laptop 자신의 IP입니다. 동일 호스트의 CLI/MCP용으로 `127.0.0.1`도 넣습니다.
- `--connect 192.168.1.10`은 hub인 desktop의 IP입니다.
### `192.168.1.12`
agent-server(````
# [on agent-server / 192.168.1.12]
kioku-mesh init --mode spoke \
--listen 127.0.0.1 \
...
각 spoke에서 할 일은 '자신의 IP를 --listen에, hub의 IP를 --connect에'만 하는 것입니다. 대수가 늘어나도 템플릿은 같습니다.
spoke도 systemd로 상주시키기
spoke 측에서도 --install-systemd가 그대로 사용 가능합니다. 항상 가동되는 agent-server나, 로그인 시 자동으로 실행되길 원하는 laptop에는 붙여두는 것이 편리합니다.
# [on agent-server / 192.168.1.12]
kioku-mesh init --mode spoke \
--listen 127.0.0.1 \
...
unit 이름은 hub와 같은 kioku-mesh-zenohd.service입니다. 1호스트 1 zenohd 전제 이름이므로, 여러 zenohd를 동일 호스트에서 구동할 계획이 없다면 그대로 문제없습니다.
시작 순서는 신경 쓰지 않아도 됩니다
desktop(hub)과 spoke의 시작 순서는 어느 쪽이 먼저여도 문제가 없습니다. spoke 측 zenohd는 --connect 192.168.1.10에 도달할 때까지 재시도(retry)를 계속합니다. 35대 규모에서 60초 만에 수렴합니다.mem/**가 아직 적은 상태의 콜드 스타트라면, 대략 30
Step 3: 양방향 replication을 확인하기
local 모드에서는 1대에 국한되어 있던 공유 메모리가 정말 호스트 간에 동기화되고 있는지 체크합니다.
desktop → laptop 방향
먼저 hub인 desktop에서 엔트리를 저장합니다.
# [on desktop / 192.168.1.10]
kioku-mesh save
를 입력하고, 양쪽 엔트리가 모두 나타나는지 확인하십시오 (이는 spoke-to-spoke 통신이 hub의 router transit를 통과하고 있다는 증거가 됩니다).
[on agent-server / 192.168.1.12]
kioku-mesh search "mesh-test"
### 나타나지 않을 때 확인해야 할 사항
제3회에서 다루었던 계층 분해 (Layer Decomposition) 방식을 그대로 사용할 수 있습니다.
| 증상 | 우선 확인할 것 |
|---|---|
| 자기 호스트에서조차 save 직후의 search에 나타나지 않음 | 동일 호스트의 `zenohd`가 기동 중인지, SQLite의 upsert 여부 |
| 다른 호스트에서 보이지 않음 | `zenohd` 간의 링크 (`TCP 7447`이 통과하는지, `--connect` 주소가 올바른지) |
| 목록에 오래된 데이터가 부족함 | 기동 시 rebuild skip → `MESH_MEM_FORCE_REBUILD=1 kioku-mesh search ...` |
| 삭제가 반영되지 않음 | tombstone의 전파 / `gc` 실행 여부 |
잘 모르겠다면 우선 `kioku-mesh doctor`를 실행하십시오.
## Step 4: MCP 클라이언트를 연결하기
제2회에서 `mcp install`까지 완료했다면, 추가로 필요한 것은 없습니다. `mcp install`은 백엔드 (backend)를 자동으로 판별하여, `hub` / `spoke` 모드라면 Zenoh를 경유하게 됩니다.
호스트를 넘나들며 동작 확인을 하려면:
- laptop (`192.168.1.11`)에서 Claude Code를 열고, kioku-mesh에 "설계 하나를 저장"하게 함
- desktop (`192.168.1.10`)에서 Codex CLI를 열고, kioku-mesh에서 검색하게 함
이 2단계 과정을 통해, 제1회 서두에서 언급했던 "노트북 PC에서 Claude Code로 결정한 사항이 데스크톱의 Codex CLI에 전달되는" 상태가 완성됩니다.
## 스케일: 4번째, 5번째 기기 추가하기
스케일 아웃 (Scale-out)은 spoke를 늘리기만 하면 됩니다. 예를 들어 SBC (`192.168.1.13`)와 Tailscale을 경유하는 원격 머신 (`10.0.0.14`)을 추가한다고 가정해 봅시다.
[on sbc / 192.168.1.13]
kioku-mesh init --mode spoke
--listen 127.0.0.1
...
[on remote / 10.0.0.14, Tailscale 경유]
kioku-mesh init --mode spoke
--listen 127.0.0.1
...
포인트는 다음과 같습니다:
- desktop (hub)의 설정을 건드리지 않는다
- 기존 spoke (laptop / agent-server)의 설정도 건드리지 않는다
- 새로운 spoke 측에서 "자신의 IP를 `--listen`으로, desktop의 IP를 `--connect`로" 한 번만 실행한다
기존 메쉬 (mesh)는 1 replication interval 이내에 새로운 피어 (peer)를 인식합니다. hub-spoke의 본질은 "인바운드 (inbound)를 받는 상자를 desktop 하나로 압축함으로써, 신규 참여와 방화벽 (FW) 설정 비용을 spoke 측으로만 한정하는 것"이므로, 기기 수가 늘어나도 운영 체감은 변하지 않습니다.
## 여기까지로 연재의 목표 달성
- 1대에서 동작시키기 → 도구 간 연동 (제2회)
- 메쉬 구성하기 → 머신 간 연동 (이번 회차)
이로써 kioku-mesh의 주요 가치를 수중에 재현할 수 있는 상태가 되었습니다.
## 차기 (임의·최종회) 예고
제5회 (임의)에서는, 지금까지의 구성에 mTLS를 입혀 피어 간 통신을 "네트워크에 도달 가능함 = 신뢰함"에서 "인증서를 가진 피어만 신뢰함"으로 격상시킵니다. Tailscale ACL 사고 방지 대책이나, 타인이 함께 사용하는 LAN에서 구동할 경우의 안전책으로서 유효합니다. `kioku-mesh tls init-ca` / `enroll` / `install` 흐름과, SSH 없이 copy-paste를 통한 프로비저닝 (provisioning)을 다룹니다.
mTLS까지 필요하지 않은 독자라면, 여기까지로 연재를 완결 지어도 무방합니다.
## 참고 링크
- 리포지토리 내부: `config/peers/example_5peer.md`
(5피어 실례) - 리포지토리 내부:
`docs/mtls.md`
(다음 회 예습) - Zenoh 공식 문서
- 연재 제1회: kioku-mesh란 무엇인가
- 연재 제2회: kioku-mesh를 Claude Code와 Codex CLI에 MCP로서 연결하기
- 연재 제3회: kioku-mesh의 내부 이해하기 — Zenoh와 RocksDB와 SQLite index
### Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기