본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 18. 23:42

AI를 활용한 홈랩 플릿 관리: 7가지 원격 에이전트 레시피 (2026)

요약

오픈 소스 MCP 서버인 remote-agents를 활용하여 이질적인 홈랩 환경을 단일 AI 채팅으로 제어하는 방법을 소개합니다. 경량 에이전트와 암호화된 릴레이를 통해 여러 호스트를 하나의 플릿으로 관리하는 아키텍처와 7가지 실전 레시피를 다룹니다.

핵심 포인트

  • MCP 서버 기반의 원격 에이전트를 통한 홈랩 통합 제어
  • AES-GCM-256 종단간 암호화를 통한 보안 연결 보장
  • 태그 및 OS 제품군 타겟팅을 통한 이질적 호스트 그룹 관리
  • 시스템 업데이트, 백업, Docker 관리 등 실전 활용 레시피 제공

만약 당신이 생각하는 **홈랩 플릿 관리 (homelab fleet management)**가 현재 5개의 터미널 탭, IP 주소가 적힌 포스트잇, 그리고 어떤 Pi가 apt를 실행하고 어떤 것이 dnf를 실행하는지 기억해야 한다는 공포라면 — 이 가이드는 당신을 위한 것입니다. 우리는 실제 혼합 아키텍처 홈랩(NAS, Raspberry Pi 2대, Docker 미디어 박스, 그리고 당신의 데스크톱)을 연결하여, SSH 세션을 번갈아 가며 사용하는 대신 단 하나의 AI 채팅으로 전체를 제어할 수 있도록 할 것입니다. 그 엔진은 오픈 소스 MCP 서버인 remote-agents입니다.

요약하자면: 경량 에이전트가 모든 머신에서 실행되며 암호화된 릴레이 룸으로 아웃바운드 (outbound) 연결을 시도합니다. 당신의 AI 어시스턴트(Claude 또는 opencode)는 전체 홈랩을 하나의 컴퓨터로 인식하며 fleet_exec, fleet_read, schedule_add, exec, set_mode와 같은 도구(tools)를 호출합니다. 명령 페이로드(Command payloads)는 종단간 암호화(AES-GCM-256)됩니다. 릴레이는 오직 암호문(ciphertext)만 전달할 뿐, 평문(plaintext)이나 키(keys)는 절대 전달하지 않습니다.

목차

  1. 아키텍처: 5개의 호스트, 하나의 룸
  2. 레시피 1 — 에이전트 설치 및 홈랩 태깅
  3. 레시피 2 — 모든 Linux 호스트에 걸친 원클릭 시스템 업데이트
  4. 레시피 3 — 릴레이 중단 시에도 유지되는 NAS로의 야간 백업
  5. 레시피 4 — 전체 플릿의 상태, 디스크 및 온도 스캔
  6. 레시피 5 — 미디어 호스트에서의 Docker 관리
  7. 레시피 6 — 플랜 모드(plan mode)와 차단 목록(denylist)을 활용한 안전한 읽기 전용 검사
  8. FAQ
  9. 마무리

아키텍처: 5개의 호스트, 하나의 룸

홈랩은 좀처럼 균일하지 않습니다. x86 박스, ARM 보드, 대부분 Linux에 어쩌다 하나 섞인 macOS mini, 그리고 온갖 스택이 뒤섞여 있습니다. 이러한 이질성(heterogeneity)이야말로 수동적인 **셀프 호스팅 서버 관리 (self-hosted server management)**를 고통스럽게 만드는 원인입니다. 각 호스트마다 약간씩 다른 주문(incantation)을 원하기 때문입니다. 태그(Tags)와 OS 제품군 타겟팅(OS-family targeting)은 이를 매끄럽게 해결해 줍니다. 단 한 번의 호출로 머신 그룹에 명령을 내릴 수 있으며, 오류가 발생하더라도 전체 배치가 아닌 해당 호스트에만 국한됩니다.

이 가이드의 나머지 부분에서 사용할 토폴로지(topology)는 다음과 같습니다:

호스트 (Host)역할 (Role)태그 (Tag)스택 (Stack)
nas스토리지 (Storage), 백업 대상 (backup target), 공유 (shares)storageTrueNAS / Linux, ZFS, NFS/SMB
...

모든 에이전트는 동일한 릴레이 룸(relay room, 예: homelab)에 참여합니다. 이는 **플랫 피어 네트워크 (flat peer network)**입니다. 컨트롤러 노드(controller node)나 에이전트 노드(agent node)의 구분 없이, 모든 머신이 실행과 명령 전달을 모두 수행할 수 있는 동등한 피어(peer)로서 참여합니다. 태그를 사용하면 명령을 확산(fan out)할 수 있습니다: target="pi"는 두 대의 Raspberry Pi 모두에 적용되고, target="os:linux"는 모든 Linux 머신에 적용되며, target="all"은 전체 플릿(fleet)에 적용됩니다.

            ┌───────────── AI (Claude / opencode) ──────────────┐
            │            remote-agents (MCP, stdio)              │
            └──────────────────────┬────────────────────────────┘
...

멋진 점은 이 릴레이가 Cloudflare에서 호스팅하는 Worker가 될 수도 있고, NAS 자체에서 실행되는 사용자의 셀프 호스팅 Rust 릴레이 (self-hosted Rust relay) (remote-agents-relay --bind 0.0.0.0:8080)가 될 수도 있다는 것입니다. 클라우드에 데이터를 전송(phone home)하고 싶지 않은 홈랩의 경우, 릴레이를 셀프 호스팅함으로써 전체 컨트롤 플레인 (control plane)을 자신의 물리적 공간 내에 유지할 수 있습니다.

요약: 6가지 레시피 한눈에 보기

#레시피 (Recipe)기능
1설치 및 태그 지정 (Install & tag)모든 호스트에 에이전트를 설치하고 태그를 지정합니다 (storage, pi, media, workstation)
...

왜 이런 방식으로 홈랩 플릿을 관리해야 하는가

레시피를 살펴보기 전에, 이 접근 방식이 언제 가치를 발휘하는지, 그리고 언제 그렇지 않은지에 대해 솔직하게 짚고 넘어갈 필요가 있습니다. 다음과 같은 상황에서 AI 기반의 **홈랩 자동화 (homelab automation)**를 고려하십시오:

  • SSH 호핑 (SSH hopping)에 지쳤을 때. 5대의 호스트를 수동으로 패치하는 것은 5번의 로그인, 5번의 sudo 프롬프트, 그리고 적어도 한 번은 "잠깐, 이게 Pi였나 NAS였나?" 하는 순간을 의미합니다. 단 하나의 fleet_exec가 이 모든 것을 대체합니다 — 대략 N번의 SSH 세션 대신 단 한 번의 명령으로 가능합니다.
  • 하드웨어가 혼합되어 있을 때. ARM 기반의 Raspberry Pi와 x86 박스는 서로 다른 패키지 관리자 (package manager)를 사용하며 센서 보고 방식도 다릅니다. OS 제품군 타겟팅 (os:linux) 및 태그 (tags)를 사용하면, 사용자가 수동으로 분기 처리를 하지 않아도 하나의 요청이 호스트별로 적응하여 실행됩니다.
  • 무인 방식의 탄력적인 자동화 (unattended, resilient automation)를 원할 때. 노트북이 닫혀 있고 릴레이 (relay)에 접속할 수 없는 상태에서도 예약된 백업은 실행되어야 합니다. schedule_add를 통한 호스트 내 크론 (on-host cron)은 연결 상태와 관계없이 로컬에서 계속 실행됩니다.
  • 단일 감사 표면 (single audit surface)을 원할 때. 전체 플릿 (fleet)에 대해 읽기 전용인 plan-모드로 훑어보면, 모든 머신의 디스크, 온도, 업타임 (uptime) 스냅샷을 한 번에 얻을 수 있습니다 — 이는 매주 진행하는 "조용히 고장 나고 있는 장비가 있는가?"라는 점검에 완벽합니다.

이것은 Ansible 플레이북 (playbooks)이나 Kubernetes 오케스트레이터 (orchestrator)를 대체하는 것이 아닙니다. remote-agents를 하나의 AI 인터페이스를 통해 여러 호스트에 걸쳐 쉘 (shell), 파일, git, 크론 (cron)에 대한 대화형 및 자율적 접근을 제공하는 도구로 생각하십시오 — 소규모~중규모 플릿, 개발/실험실 환경, 그리고 임시 운영 (ad-hoc operations)에 이상적입니다.

레시피 1 — 에이전트 설치 및 홈랩 태깅

모든 것은 각 박스에 에이전트를 설치하고 태그를 부여하는 것에서 시작합니다. 패키지는 단일 Rust 바이너리이므로 설치 방법은 어디서나 동일하며, 호스트마다 --name--tags만 변경하면 됩니다.

1단계. 각 머신에 설치 및 실행. NAS나 미디어 박스와 같이 24시간 가동되는 호스트의 경우, remote-agents install을 사용하여 재부팅 후에도 에이전트가 백그라운드 서비스 (Linux의 경우 systemd, macOS의 경우 launchd)로 다시 실행되도록 합니다. Pi나 데스크톱에서도 동일하게 할 수 있으며, 실험하는 동안에는 단순히 run을 통해 대화형으로 실행할 수도 있습니다.

# 모든 머신에서 한 번 실행
npm i -g remote-agents

...

2단계. 전체 플릿이 온라인인지 확인. AI 채팅창에 다음과 같이 물어보세요:

"홈랩 룸(homelab room)에 있는 에이전트들을 보여줘."

**list_agents**를 호출하는 내부 동작을 살펴보면, 각 피어(peer)의 OS 제품군(OS family), 배포판(distro), 커널(kernel), 셸(shell), 태그(tags), 그리고 update_available 플래그를 반환합니다. 이것이 바로 여러분의 인벤토리(inventory)입니다. 단 한 번의 응답으로 pi-1pi-2aarch64/Debian을 보고하는 반면, nasmediax86_64를 보고한다는 것을 확인할 수 있습니다. 이는 나중에 apt를 사용할지 dnf를 사용할지를 결정하는 바로 그 상세 정보입니다.

팁: 설정의 우선순위는 CLI 플래그 > REMOTE_AGENTS_* 환경 변수(env) > config.toml > 기본값(default) 순입니다. 24시간 가동되는 호스트의 경우, relay/room/token 정보를 config.toml에 넣어두면 systemd 유닛을 깔끔하게 유지할 수 있고 명령줄(command line)에 비밀 정보(secrets)가 노출되지 않습니다.

레시피 2 — 모든 Linux 호스트에 걸친 단일 명령 시스템 업데이트

이것은 **홈랩 플릿 관리(homelab fleet management)**의 핵심적인 이점입니다. 각 장비에 일일이 로그인하는 대신, 단 한 번의 호출로 전체 플릿(fleet)에 패치를 적용하는 것입니다. 호스트가 Debian 기반의 Pi부터 RPM 기반의 NAS까지 다양하므로, OS 제품군을 대상으로 지정하여 각 호스트가 자체 패키지 관리자(package manager)를 실행하도록 합니다.

1단계. 모든 Linux 호스트를 한 번에 패치하기. target="os:linux" 선택자를 사용하면 nas, pi-1, pi-2, media, 그리고 (Linux인 경우) desk를 한 번에 타격합니다. 배포판에 관계없이 작동하도록 두 관리자를 모두 시도하는 명령어를 사용하세요:

fleet_exec  target="os:linux"
            command="(command -v apt-get >/dev/null && sudo apt-get update && sudo apt-get -y upgrade) || (command -v dnf >/dev/null && sudo dnf -y upgrade)"
            timeout_ms=600000

결과는 호스트별로 반환됩니다: pi-1pi-2apt 업그레이드 결과를 보고하고, NAS는 자체 결과를 보고합니다. 만약 한 장비가 오프라인 상태더라도 다른 장비들은 작업을 완료합니다. 즉, 하나의 호스트가 실패한다고 해서 전체 배치(batch)가 실패하지는 않습니다. ARM 기반인 Raspberry Pi들은 arm64 패키지를 가져오고, x86 장비들은 amd64 패키지를 가져옵니다. 여러분이 신경 쓸 필요 없이, 각 호스트가 자신의 아키텍처(architecture)를 스스로 해결합니다.

참고: 업그레이드 시에는 timeout_ms를 늘려주세요. 느린 SD 카드를 사용하는 1세대 Pi에서 대규모 apt upgrade를 수행하면 기본값을 쉽게 초과할 수 있습니다. 600000 ms(10분)는 홈랩을 위한 안전한 상한선입니다.

2단계. 에이전트 자체를 업데이트합니다. 플릿 (fleet)을 관리하는 소프트웨어는 스스로 최신 상태를 유지해야 합니다. **fleet_update_check**는 어떤 유휴 (idle) 호스트가 이전 버전을 실행 중인지 보고합니다:

fleet_update_check

그 다음, 버전이 뒤처진 호스트들을 갱신합니다:

fleet_exec  target="all"  command="npm i -g remote-agents@latest"

중요: fleet_update_check는 의도적으로 유휴 (idle) 호스트만 표시합니다. 작업 중인 호스트는 실행 중인 작업 도중에 강제로 중단되지 않으며, 다음 패스 (pass)에서 패치할 수 있습니다.

레시피 3 — 릴레이 장애 시에도 생존하는 NAS 대상 야간 백업

백업은 노트북이 깨어 있는 상태에 절대 의존해서는 안 되는 단 하나의 작업입니다. 여기서 핵심은 **schedule_add**입니다. 이는 호스트 자체에서 실행되는 크론 잡 (cron job)을 설치하므로, 릴레이 링크가 끊기거나, AI 클라이언트가 닫혀 있거나, 인터넷이 끊겨 있더라도 매일 밤 실행됩니다.

1단계. Pi에서 NAS로의 야간 풀 (pull)을 예약합니다. 크론 규격 (cron spec)은 6개 필드 문자열(sec min hour day month dow)로, 클래식 크론탭 (crontab)보다 필드가 하나 더 많습니다. 맨 앞에 추가된 필드가 초 (seconds)입니다. 매일 밤 02:30에 실행하려면 0 30 2 * * *입니다:

schedule_add  agent_id=pi-1  name=nightly-backup
              cron="0 30 2 * * *"
              command="rsync -aH --delete /home/pi/data/ nas:/mnt/tank/backups/pi-1/"

2단계. 다른 Pi와 미디어 박스에 대해서도 동일하게 수행하되, 각각 NAS 백업 풀 내의 고유한 폴더를 가리키도록 설정합니다:

schedule_add  agent_id=pi-2   name=nightly-backup  cron="0 35 2 * * *"  command="rsync -aH --delete /home/pi/data/ nas:/mnt/tank/backups/pi-2/"
schedule_add  agent_id=media  name=config-backup   cron="0 40 2 * * *"  command="tar czf - /srv/docker | ssh nas 'cat > /mnt/tank/backups/media/docker-configs.tgz'"

시작 시간(02:30, 02:35, 02:40)을 엇갈리게 배치하면 세 대의 머신이 동시에 NAS를 몰아치는 것을 방지할 수 있습니다. 백업은 TrueNAS의 ZFS 기반 스토리지에 저장되므로, 시점 복구 (point-in-time recovery)를 위해 그 위에 스냅샷 (snapshot)을 계층화할 수 있습니다.

3단계. 예약된 작업 확인. 언제든지 작업을 목록화하거나 정리할 수 있습니다:

schedule_list    agent_id=pi-1
schedule_remove  agent_id=pi-1  name=nightly-backup

Tip: 스케줄은 호스트(host)에 저장되기 때문에, 오늘 설정한 schedule_add는 이후에 AI 채팅을 다시 열지 않더라도 계속 실행됩니다. schedule_list를 "과거의 내가 어떤 cron 작업들을 설정해 두었지?"를 확인하는 감사(audit) 도구로 활용하세요. 아무것도 모르는 미스터리로 남지 않도록 가끔씩 호스트 전체에 실행해 보는 것이 좋습니다.

레시피 4 — 전체 플릿(fleet)의 상태, 디스크 및 온도 점검

일주일에 한 번, "내 홈랩에서 조용히 죽어가고 있는 장치가 있는가?"라는 질문에 단 하나의 답변을 얻고 싶을 때가 있습니다. 단 한 번의 fleet_exec 명령으로 모든 호스트의 디스크 사용량, 온도, 가동 시간 (uptime)을 확인하고, 결과를 기기별로 그룹화하여 볼 수 있습니다.

1단계. 전체 플릿의 디스크 사용량. 여유 공간 부족은 전형적인 소리 없는 살인자입니다. / 경로가 가득 차면 Raspberry Pi가 먹통이 되거나 미디어 박스의 Docker가 중단될 수 있습니다:

fleet_exec  target="all"  command="df -h / /mnt 2>/dev/null"

2단계. x86 대 ARM을 고려한 온도 측정. 이 부분에서 아키텍처 차이가 중요하게 작용합니다. x86 박스(nas, media, desk)에서는 lm-sensorssensors가 표준 도구입니다. 반면 ARM 기반의 Raspberry Pi에서는 sensors가 유용한 정보를 반환하지 않는 경우가 많으며, 대신 vcgencmd를 통해 표준 값을 읽어와야 합니다. 각 호스트에 맞춰 적응하는 명령어는 다음과 같습니다:

fleet_exec  target="all"
            command="(vcgencmd measure_temp 2>/dev/null) || (sensors 2>/dev/null | grep -iE 'temp|core' | head -n 5) || echo 'no temp sensor'"

Raspberry Pi는 vcgencmd를 통해 temp=48.3'C와 같은 형식으로 응답하는 반면, x86 호스트는 sensors를 통해 Core 0: +42.0°C와 같이 응답합니다. 완전히 다른 두 종류의 센서 스택을 사용함에도 불구하고, 호스트별로 깔끔하게 정리된 판독값을 얻을 수 있습니다.

3단계. 성능이 저하된 장치를 찾기 위한 가동 시간 (uptime) 및 부하 확인:

fleet_exec  target="all"  command="uptime && free -h | head -n 2"

참고: ARM Raspberry Pi와 x86 호스트는 패키지 관리자, 센서, 심지어 높은 부하(high load)의 의미(4코어 Pi가 데스크톱보다 더 빨리 포화됨)까지 거의 모든 면에서 다르게 보고됩니다. 호스트별 결과가 이상해 보인다면, 당황하기 전에 현재 읽고 있는 데이터가 Pi(os:linux + 태그 pi, aarch64)인지 먼저 확인하세요. Pi에서의 스로틀링(Throttling, vcgencmd get_throttledthrottled=0x...)은 홈랩에서의 엔진 체크 불빛(check-engine light)과 같습니다.

만약 스토리지 계층(storage tier)에 대해서만 별도로 디스크 스윕(disk sweep)을 수행하고 싶다면, target="all"target="storage"로 바꾸면 NAS에만 명령을 전달하게 됩니다.

레시피 5 — 미디어 호스트에서의 Docker 관리

media 박스는 Docker Compose 환경에서 Jellyfin/Plex 스택을 실행합니다. 컨테이너 생명주기(lifecycle) 관리는 해당 단일 호스트에 국한된 일반적인 exec 범위에 매우 적합합니다. 특정 박스 전용 작업에 대해 플릿 운영(fleet operation)을 확장할 필요가 없습니다.

1단계. 업데이트된 이미지를 풀(pull)하고 스택을 재생성합니다. pull을 실행한 뒤 up -d를 수행하는 것이 번거로움 없는 표준 업데이트 방식입니다:

exec  agent_id=media
      command="cd /srv/docker/media && docker compose pull && docker compose up -d"
      cwd=/srv/docker/media
...

docker compose up -d는 이미지가 실제로 변경된 컨테이너만 재생성하므로, 변경되지 않은 서비스(및 현재 시청 중인 Jellyfin 스트림)는 계속 유지됩니다. 미디어 스택의 경우 pull 작업이 무거울 수 있으므로, 300,000ms(5분)라는 넉넉한 타임아웃(timeout)을 설정했습니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0