<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>삽질일기</title>
    <link>https://devwantap.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 15 May 2026 11:28:50 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>dev-wantap</managingEditor>
    <image>
      <title>삽질일기</title>
      <url>https://tistory1.daumcdn.net/tistory/7063243/attach/675bf96ce8bd4c4b8cddd21f50e11250</url>
      <link>https://devwantap.tistory.com</link>
    </image>
    <item>
      <title>Apple Container로 PostgreSQL 실행하기: 권한 문제와 해결책</title>
      <link>https://devwantap.tistory.com/2</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Apple Container는?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple이 WWDC 2025에서 발표한 Containerization 프레임워크와 container는 macOS에서 네이티브로 Linux 컨테이너를 실행할 수 있는 새로운 도구입니다. Swift로 작성되었고 Apple Silicon에 최적화된 이 도구는 기존 Docker Desktop와는 근본적으로 다른 접근 방식을 취합니다. (&lt;a href=&quot;https://github.com/apple/container&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/apple/container&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Desktop이 하나의 큰 Linux VM 안에서 모든 컨테이너를 공유 방식으로 실행하는 반면, Apple container는 각 컨테이너마다 독립적인 경량 VM을 할당합니다. 이러한 설계는 더 강력한 보안 격리를 제공하면서도 서브초 시작 시간과 향상된 성능을 달성했다고 Apple은 주장합니다. 또한 Apple의 네이티브 Virtualization.framework와 직접 통합되어 Docker Desktop의 VM 오버헤드 없이 진정한 네이티브 성능을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이런 아키텍처 차이는 기존 Docker 환경에서 작동하던 설정이 Apple container에서는 다르게 동작할 수 있음을 의미합니다. 실제로 PostgreSQL을 마이그레이션하는 과정에서 흥미로운 권한 문제를 경험했고, 이를 해결한 과정을 공유하고자 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 Docker 환경에서 사용하던 PostgreSQL 설정을 Apple Container로 옮기려고 했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758287764445&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 기존 Docker 명령어
docker run --rm -d --name postgres \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  -v /Users/username/data:/var/lib/postgresql/data \
  postgres&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758287787329&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Apple Container CLI로 변경
container run -d --rm --name postgres \
  -e POSTGRES_PASSWORD=postgres \
  -p 5432:5432 \
  -v /Users/username/data:/var/lib/postgresql/data \
  postgres&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 컨테이너가 즉시 종료되며 다음과 같은 에러가 발생했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758287814986&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted
chown: changing ownership of '/var/lib/postgresql/data': Operation not permitted&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 분석&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Docker Desktop과 Apple Container의 아키텍처 차이&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Desktop&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하나의 큰 Linux VM 내에서 모든 컨테이너 실행&lt;/li&gt;
&lt;li&gt;호스트 파일시스템을 VM 전체와 공유&lt;/li&gt;
&lt;li&gt;VM 내부에서 bind mount 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple Container&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;각 컨테이너마다 독립적인 경량 VM&lt;/li&gt;
&lt;li&gt;virtiofs를 통해 개별 디렉토리를 직접 마운트&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;권한 문제의 근본 원인&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PostgreSQL의 보안 요구사항: PostgreSQL은 시작할 때 데이터 디렉토리의 소유권을 postgres 사용자로 변경하고 권한을 700으로 설정해야 합니다.&lt;/li&gt;
&lt;li&gt;virtiofs의 제한사항: Apple Container가 사용하는 virtiofs 파일시스템 공유 방식에서는 마운트 포인트 자체에 대한 메타데이터 변경이 제한되어, PostgreSQL이 요구하는 권한 설정이 실패합니다.&lt;/li&gt;
&lt;li&gt;Docker Desktop에서는 작동했던 이유: 호스트 파일시스템을 LinuxKit VM 전체와 공유한 후, VM 내부에서 bind mount를 수행하기 때문에 실제 권한 변경이 VM의 파일시스템에서 이루어져 문제없이 동작합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결 과정&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;시도한 방법들&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. --user 옵션 사용: 현재 사용자 ID로 실행 시도&lt;/p&gt;
&lt;pre id=&quot;code_1758289128974&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;container run --user $(id -u):$(id -g) ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과: exit code -1로 실패&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. PGDATA 경로 변경: PostgreSQL 데이터 디렉토리 경로 변경&lt;/p&gt;
&lt;pre id=&quot;code_1758289139178&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-e PGDATA=/var/lib/postgresql/data/pgdata&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과: 기존 데이터와 호환되지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;최종 해결책&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/apple/container/issues/333&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Apple의 공식 GitHub 이슈 #333&lt;/a&gt;에서 해결책을 발견했습니다. 핵심은 &lt;b&gt;마운트 포인트를 데이터 디렉토리의 상위 디렉토리로 설정&lt;/b&gt;하는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 상황&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;crystal&quot; style=&quot;color: #abb2bf; text-align: left;&quot;&gt;&lt;code&gt;마운트: /host/data &amp;rarr; /var/lib/postgresql/data
PostgreSQL 시도: chmod /var/lib/postgresql/data (마운트 포인트 자체)
결과: virtiofs가 마운트 포인트 메타데이터 변경 거부&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결 후&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;crystal&quot; style=&quot;color: #abb2bf; text-align: left;&quot;&gt;&lt;code&gt;마운트: /host/parent &amp;rarr; /var/lib/postgresql
PostgreSQL 시도: chmod /var/lib/postgresql/data (마운트 포인트 내부 디렉토리)
결과: virtiofs가 내부 디렉토리 권한 변경 허용&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구체적인 적용 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 디렉토리 구조&lt;/p&gt;
&lt;pre id=&quot;code_1758289272123&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/Users/username/
├── data/          # PostgreSQL 데이터 파일들
└── shared/        # 공유 폴더&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결된 명령어&lt;/p&gt;
&lt;pre id=&quot;code_1758289312887&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;container run -d --rm --name postgres \
  -e POSTGRES_PASSWORD=postgres \
  -e PGDATA=/var/lib/postgresql/data \
  -p 5432:5432 \
  -v /Users/username:/var/lib/postgresql \
  postgres&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;/var/lib/postgresql/data&lt;/b&gt; &amp;rarr; 기존 PostgreSQL 데이터&lt;/li&gt;
&lt;li&gt;&lt;b&gt;/var/lib/postgresql/shared&lt;/b&gt; &amp;rarr; 공유 폴더 접근 가능&lt;/li&gt;
&lt;li&gt;마운트 포인트는 &lt;b&gt;/var/lib/postgresql &lt;/b&gt;이므로 권한 문제 회피&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple container가 사용하는 virtiofs는 마운트 포인트 자체에 대한 메타데이터 변경을 제한합니다. PostgreSQL처럼 시작 시 데이터 디렉토리 권한을 설정하는 애플리케이션에서는 마운트 포인트를 한 단계 위로 설정하는 것이 해결책입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일한 컨테이너 이미지라도 런타임에 따라 볼륨 마운트 동작이 다를 수 있습니다. Docker Desktop의 VM 내부 bind mount 방식과 Apple container의 직접 마운트 방식은 서로 다른 제약사항을 가집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub 이슈 트래커에서 동일한 문제를 겪은 사용자들과 해결책을 찾을 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Apple Container</category>
      <category>Apple Silicon</category>
      <category>Docker</category>
      <category>MacOS</category>
      <category>postgresql</category>
      <category>virtiofs</category>
      <category>권한</category>
      <category>마이그레이션</category>
      <category>문제해결</category>
      <category>컨테이너</category>
      <author>dev-wantap</author>
      <guid isPermaLink="true">https://devwantap.tistory.com/2</guid>
      <comments>https://devwantap.tistory.com/2#entry2comment</comments>
      <pubDate>Fri, 19 Sep 2025 22:56:03 +0900</pubDate>
    </item>
    <item>
      <title>홈서버 게임 서버 원격 관리: 모니터링 시스템 구축</title>
      <link>https://devwantap.tistory.com/1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;홈서버에서 Minecraft Bedrock 서버를 운영하면서 가장 큰 과제 중 하나는 &lt;b&gt;원격 관리와 모니터링&lt;/b&gt;이었습니다. 특히 물리적으로 서버에 접근할 수 없는 환경에서 발생하는 문제들과 이를 해결하기 위한 자동화 시스템 구축 과정을 정리했습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서버 운영 환경&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Ubuntu 22.04 LTS 기반 홈서버&lt;/li&gt;
&lt;li&gt;Minecraft Bedrock Dedicated Server&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;프로세스 관리 솔루션 선택&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 프로세스 관리를 위해 여러 옵션을 검토했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;systemd&lt;/b&gt; 서비스: &lt;b&gt;자동 재시작&lt;/b&gt;, &lt;b&gt;로그 관리&lt;/b&gt; 등 &lt;b&gt;장점&lt;/b&gt;이 있지만, Bedrock 서버의 특성(관리 프로토콜 부재)상 &lt;b&gt;실시간 콘솔 접근이 필수&lt;/b&gt;적이어서 부적합했습니다. RCON 프로토콜이 없는 상황에서 서버 명령어 실행, 플레이어 관리 등은 모두 콘솔을 통해서만 가능하기 때문입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;컨테이너&lt;/b&gt;화 (Docker): 당시에는 Docker에 대한 &lt;b&gt;경험이 부족&lt;/b&gt;했고, 단순히 게임 서버 하나만 돌리는 상황에서 컨테이너화의 필요성을 느끼지 못했습니다. &lt;b&gt;복잡성&lt;/b&gt;을 추가할 이유가 명확하지 않았죠.&lt;/li&gt;
&lt;li&gt;Terminal Multiplexer: 세션 관리와 콘솔 접근을 모두 만족하는 솔루션으로 판단했습니다. 초기에는 레퍼런스를 따라 &lt;b&gt;GNU Screen&lt;/b&gt;을 사용했고, 이후 더 현대적인 &lt;b&gt;tmux&lt;/b&gt;를 도입해봤지만, 단순한 게임 서버 운영에는 Screen의 직관적인 사용법이 더 적합하다고 판단해 다시 돌아왔습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;screen -S MC ./bedrock_server
# Ctrl+A, D로 detach하여 백그라운드 실행

# 이후 ssh로 접속하여 아래 명령어로 콘솔 접근
screen -x MC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 &lt;b&gt;콘솔 접근 용이성&lt;/b&gt;과 &lt;b&gt;운영 단순성&lt;/b&gt; 사이의 균형점으로 Screen을 선택하게 되었습니다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기술적 제약사항과 운영 이슈&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Bedrock 서버의 관리 인터페이스 부족&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Minecraft Bedrock Dedicated Server는 Java Edition과 달리 RCON 프로토콜을 지원하지 않습니다. 이로 인해 원격 관리에 상당한 제약이 있습니다. 명령어 실행은 ssh를 비롯한 서버 자체에 무조건 접근해야만 가능했고 플레이어 관리도, 서버 상태 확인도 마찬가지입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;운영상 발생하는 주요 작업들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정기 재시작&lt;/b&gt;&lt;br /&gt;메모리 누수로 인한 성능 저하 문제로 주기적인 재시작이 필수적입니다. 플레이어 수가 증가하거나 장시간 운영 시 명확한 성능 차이가 발생했습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;서버 업데이트&lt;/b&gt;&lt;br /&gt;Bedrock 서버 업데이트는 완전한 수동 프로세스입니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;서버 프로세스 중지&lt;/li&gt;
&lt;li&gt;새 바이너리 다운로드 및 교체&lt;/li&gt;
&lt;li&gt;월드 데이터 무결성 확인&lt;/li&gt;
&lt;li&gt;재시작&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 단계에서 SSH 접근이 필요하며, 실수 시 데이터 유실이 있을 수 있습니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;백업 관리&lt;/b&gt;&lt;br /&gt;초기에는 수동으로 백업을 생성했지만, 이후 간단한 스크립트를 작성해 자동화했습니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&quot;~/minecraft/backups&quot;
WORLD_DIR=&quot;~/minecraft/worlds&quot;

mkdir -p $BACKUP_DIR
tar -czf &quot;$BACKUP_DIR/backup_$DATE.tar.gz&quot; -C &quot;$WORLD_DIR&quot; .&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 cron을 통해 매일 자동 백업이 실행되도록 구성했습니다.&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;# 매일 새벽 3시에 백업 실행
0 3 * * * ~/minecraft/scripts/backup.sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;원격 접근의 한계: IP 변경으로 인한 서비스 중단&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;홈서버 환경의 네트워크 특성&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 가정용 인터넷 환경에서는 ISP가 동적 IP(Dynamic IP)를 할당하는 것이 일반적입니다. 고정 IP 서비스와 달리 주기적으로 또는 특정 조건에서 IP 주소가 변경됩니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;DHCP 갱신&lt;/b&gt;: 일정 주기마다 자동으로 IP 재할당&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모뎀/라우터 재부팅&lt;/b&gt;: 네트워크 장비 재시작 시 새로운 IP 할당 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ISP 정책&lt;/b&gt;: 트래픽 관리나 유지보수 목적의 강제 IP 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;홈서버로 외부 서비스를 제공하는 환경에서는 이러한 IP 변경이 &lt;b&gt;직접적인 서비스 중단&lt;/b&gt;으로 이어집니다. &amp;nbsp;&lt;br /&gt;문제는 군 복무 중 발생했습니다. 서버를 이용하는 멤버들에게 갑자기 오늘부터 접속이 불가능하다는 연락을 받았습니다. 당연히 그저 게임 서버 구동기가 다운된 줄 알고 ssh 접속을 시도하였으나, 전혀 접속이 불가능했습니다. 그제야 홈 서버의 공인 IP가 변경되었음을 추정할 수 있었습니다. 서버 자체는 정상 작동하고 있지만, 새로운 IP 주소를 아무도 모르니 플레이어들도 저도 모두 접속할 수 없는 상황이 된 거였죠.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 게임 클라이언트는 물론 관리를 위한 ssh 접속 등 모든 접속이 불가능한 상황까지 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 때 생각할 수 있는 해결책으로는 DDNS 서비스 활용, 물리적 접근을 통한 서버 체크가 있었지만, 이미 IP가 바뀐 뒤에는 DDNS 세팅 자체가 불가능했고 군 복무 중인 특성상 물리적 접근 자체가 불가능했습니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 &lt;b&gt;물리적 접근이 가능할 때까지 서비스 중단&lt;/b&gt;이 불가피했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모니터링 시스템 구축 결정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP 변경 사건 이후, 동일한 상황의 재발을 방지하기 위한 여러 방안을 검토했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 고정 IP 서비스의 경우 가장 근본적인 해결책이지만, 홈서버 운영에 비해 과도한 월 비용 발생. 비용 대비 효과가 떨어진다고 판단했습니다. DDNS는 기술적으로는 적합한 솔루션이지만, 유료 서비스가 많았고 무료 서비스의 경우 안정성에 대한 우려가 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 서버가 직접 상태 정보를 외부로 전송하는 방식으로, 비용이 거의 들지 않으면서도 확장 가능성이 높은 방법을 도입하기로 결정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;능동적 모니터링 시스템을 선택한 핵심 이유는 IP 변경을 작업 가능한 시간대에 파악하여 가능한 가장 빠른 대응이 가능했습니다. 또한&amp;nbsp;&lt;b&gt;비용 효율성&lt;/b&gt;도 큰 영향을 미쳤습니다. 추가 비용 없이 기존 인프라를 활용하여 구축할 수 있다는 점이 가장 큰 메리트였습니다. 추후 확장 시에도 IP 모니터링 외에도 다양한 서버 상태를 감시할 수 있다는 점도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 확장성 측면에서 중요한 고려사항이 있었습니다. 과거 백업 파일이 누적되면서 디스크 용량이 가득 차서 &lt;b&gt;서버가 중단된 사건&lt;/b&gt;이 있었는데, 이런 문제들도 함께 감지할 수 있는 통합 모니터링 시스템이 필요했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 바탕으로 다음과 같은 시스템 요구사항을 도출했습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;능동적 상태 보고&lt;/b&gt;: 서버가 자발적으로 상태 정보를 전송&lt;/li&gt;
&lt;li&gt;&lt;b&gt;접근성&lt;/b&gt;: 제한된 환경에서도 정보 수신 가능&lt;/li&gt;
&lt;li&gt;&lt;b&gt;신뢰성&lt;/b&gt;: 네트워크 변경 상황에도 동작&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성&lt;/b&gt;: 추가 모니터링 항목 수용 가능&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Telegram Bot API&lt;/b&gt; 선택 근거&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;python-telegram-bot 라이브러리를 활용한 간단한 구현&lt;/li&gt;
&lt;li&gt;다양한 플랫폼에서 접근 가능 (모바일, 웹, 데스크톱)&lt;/li&gt;
&lt;li&gt;외부 의존성 최소화&lt;/li&gt;
&lt;li&gt;제한적 네트워크 환경에서도 사용 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1758157865129&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import telegram
import asyncio
import requests

async def send_ip():
    bot = telegram.Bot(token=&quot;YOUR_BOT_TOKEN&quot;)
    ip = requests.get(&quot;https://ifconfig.me/ip&quot;).text.strip()
    await bot.send_message(chat_id=&quot;YOUR_CHAT_ID&quot;, text=ip)

asyncio.run(send_ip())&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1758157914410&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 매일 17:00에 상태 보고
0 17 * * * /usr/bin/python3 ~/monitor.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;모니터링 시스템 확장&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 IP 모니터링이 안정화된 후, 디스크 사용량 모니터링을 추가했습니다. 위에서 언급했던 대로 백업 파일이 과도하게 누적되어 서버가 다운된 적이 있었습니다. 따라서 이를 예방하고 시스템 리소스 현황을 먼저 파악할 필요가 있어 디스크 용량도 모니터링에 추가했습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1758158078753&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import shutil

def get_disk_usage(self, path=&quot;/&quot;):
    try:
        total, used, free = shutil.disk_usage(path)
        return {
            'total_gb': round(total / (1024**3), 2),
            'used_gb': round(used / (1024**3), 2), 
            'free_gb': round(free / (1024**3), 2),
            'usage_percent': round((used / total) * 100, 1)
        }
    except Exception as e:
        return f&quot;디스크 정보 확인 실패: {str(e)}&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모니터링 시스템 구축을 통해 디스크가 완전히 차기 전에 선제적 대응이 가능했고, 추가 모니터링 통합도 쉽게 가능함을 알 수 있었습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;향후 개선 계획&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재의 단순한 tar 기반 백업을 &lt;b&gt;Restic&lt;/b&gt; 또는 &lt;b&gt;Borg Backup&lt;/b&gt; 같은 오픈소스 솔루션으로 교체할 계획입니다. 이를 통해 Retention policy를 통한 오래된 &lt;b&gt;백업 자동 삭제&lt;/b&gt;, 로컬 외에 &lt;b&gt;클라우드&lt;/b&gt; 백엔드(AWS S3, Cloudflare R2 등)에 백업 등을 시도해 볼 계획입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;또한 현재의 정기적 상태 보고를 넘어서, 문제 상황을 즉시 감지하는 &lt;/span&gt;&lt;b&gt;임계치 기반 알림 시스템&lt;/b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;으로 발전시킬 예정입니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;디스크 사용량 경고&lt;/b&gt;: 90% 초과 시 즉시 알림&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버 다운 감지&lt;/b&gt;: 일정 시간 응답 없을 시 자동 알림&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IP 변경 즉시 감지&lt;/b&gt;: 매일 정기 보고가 아닌 변경 시점 실시간 알림&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 IP를 모니터링 후 직접 받아 A레코드를 직접 입력해주기보다 Cloudflare API를 이용한 업데이트를 도입하여 DDNS처럼 관리자의 개입 없이 업데이트할 수 있도록 개선할 계획입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자동 복구 시스템&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장기적으로는 &lt;b&gt;컨테이너화&lt;/b&gt;를 통한 자동 복구 메커니즘 도입을 고려하고 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Docker Restart Policy&lt;/b&gt;: 프로세스 이상 종료 시 자동 재시작&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Kubernetes Self-Healing&lt;/b&gt;: 컨테이너 레벨에서의 자동 복구 및 스케일링&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Watchdog 서비스&lt;/b&gt;: 서버 상태 모니터링 및 자동 복구 액션&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</description>
      <category>Bedrock Dedicated Server</category>
      <category>GNU-Screen</category>
      <category>minecraft</category>
      <category>ssh</category>
      <category>Telegram</category>
      <category>tmux</category>
      <category>모니터링</category>
      <category>백업</category>
      <category>자동화</category>
      <category>홈서버</category>
      <author>dev-wantap</author>
      <guid isPermaLink="true">https://devwantap.tistory.com/1</guid>
      <comments>https://devwantap.tistory.com/1#entry1comment</comments>
      <pubDate>Wed, 17 Sep 2025 19:24:25 +0900</pubDate>
    </item>
  </channel>
</rss>