홈서버 4대로 분산 시스템 구축 해보기 (feat. 생각보다 겁나 쉬움!)

2025. 10. 21. 02:17·Infra/DevOps

분산 뉴비를 위한 가이드(가 되고 싶은 포스팅)

공유기 포스팅 이후 지난 며칠간 정말 열심히 분산, 부하 시스템을 구축했습니다

https://ratatou2.tistory.com/278

 

공유기 브릿지 모드 설정하기 (feat. ipTIME & 삼성 공유기)

해보고 싶은게 (또) 생겼어요사실 예전부터 해보고 싶었던 것들인데 이번에 OCI도 뚫었고 해서 진짜 도전해보기로 한 [분산/부하/K8S] 세가지임 기왕하는거 제대로 하는게 더 재밌을 것 같아서 잠

ratatou2.tistory.com

서버실 하나 만들어줘 그냥...

공유기도 열심히 설치하고 방 한켠이 아주 난리가 났더랬죠

이걸 하게된 이유는 단순히 흥미로 시작 ㅎㅎ

그렇게 순서는 (1) 분산 시스템 구축 - (2) 부하 테스트 - (3) K8S 도전할 예정

과연 직접 분산 시스템을 구축해보고 K8S이 얼마나 편리한지를 체감 해보겠습니다

분산 시스템 구축 자체는 굉장히 단순해서 금방할 수 있음!


1. 목표

내가 구현할 분산 구조

- 내 목표는 총 서버 4대를 사용할 것이고, 1대는 중계기(nginx), 나머지 3대는 App 서버로 사용할 것이다 

- 지난 공유기 포스팅 때는 3대를 쓴다고 해놓고 오늘와서 4대를 쓰겠다는 이유는 중계기로 서버 한대를 온전히 써야하기 때문이다

- 중계 서버는 하이브리드(중계 + App 서버)로 두기 싫었고, 중계에만 온전한 성능을 쏟고자 했다

- App 서버를 돌리는 리소스로 인해 중계가 방해받지 않길 원했음

- 근데 이렇게 구상하니 App 서버가 두대뿐이라 3대는 써봐야지~ 싶어서 한대 더 늘렸다

- 서버들의 사양은 아래와 같다 (모두 우분투 22.04.5로 통일)

맥미니: 중계기 / 나머지: App 서버

ps. 나중에 스트레스 테스트를 하며 배운 내용이지만, 중계기의 성능이 굉장히 중요하더라... ㅠ


2. 기본 서버 구조 띄우기

- 중계기는 nginx만, 나머지 3대의 App 서버는 간단한 Flask 앱을 띄워두었다 

- 또한 nginx의 로드밸런싱 알고리즘은 기본 세팅(Round Robin)으로 뒀고, weight를 수정하는 등 다른 알고리즘으로 수정하진 않았음

- 나중에 튜닝하면서 weight를 수정하긴 했는데 이 부분은 부하 테스트 포스팅에서 이어가겠다


1) 각 서버들 IP 세팅

- 각 서버들의 IP들은 공유기에서 고정해뒀고 다음과 같다

# 중계기 - Mac Mini 2018
192.168.0.201

# 1번 App 서버 - SAMSUNG-Laptop-2015
192.168.0.202

# 2번 App 서버 - LG-Desktop-2015
192.168.0.203

# 3번 App 서버 - SAMSUNG-All-in-one-PC
192.168.0.204

2) App 서버 띄우기

아래 네 가지 파일을 같은 디렉토리에 만든다

(1) docker-compose.yml

# 템플릿
services:
  app:
    build: .
    hostname: <각 PC 이름>
    ports:
      - "5000:5000"
      
# 예시
services:
  app:
    build: .
    hostname: SAMSUNG-Laptop-2015
    ports:
      - "5000:5000"

(2) requirment.txt

flask

(3) Dockerfile

FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]

(4) app.py

from flask import Flask
import socket
app = Flask(__name__)

@app.route("/api/hello")
def hello():
    return f"Hello from {socket.gethostname()}!\n"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)

- 다 작성했으면 docker compose up -d로 컨테이너를 띄운다

- 이후엔 각 App 서버에서 아래 명령어로 정상적으로 응답이 오고 가는지 확인한다

curl http://localhost:5000/api/hello

3) 중계 서버 띄우기 (nginx)

- 나는 중계 서버에 nginx를 로컬에 직접 설치하여 진행하였다

- 어차피 중계로만 쓸 것이고, N100 서버에서 I/O 과부하로 터졌기 때문이다

- 뭔 말이냐면 Docker의 nginx가 host 모드가 아니라 생긴 문제였다
- 외부에서 요청이 오면 docker를 통해 받고, docker를 통해 내보내야 해서 같은 작업을 두배로 해야했고, 이것이 I/O의 과부하를 불러왔다
- 기존의 서비스들을 돌려두는게 있어서 N100의 nginx를 쉽게 host 모드로 돌릴 수 있는 것도 아니었음
- 이것이 주요 원인이 되어 기존 3대의 서버에서 4대로 늘린 것이다
- 그리고 후술할테지만, N100이 중계 서버로써 터진 이슈 때문에 찾아보니, 중계서버는 성능이 좋아야한다는 것이다
- 그래서 자연스레 현 서버들 중 가장 성능이 좋은 맥미니가 중계 서버를 하게 되었다

- 결국 아래는 중계 서버인 맥미니의 /etc/nginx/nginx.conf 파일 내용인 셈이다

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile      on;
    tcp_nopush    on;
    tcp_nodelay   on;
    keepalive_timeout 0;
    types_hash_max_size 2048;
    server_tokens off;

    # 로그 최소화
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log warn;

    log_format upstreamlog '$remote_addr → $upstream_addr [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           'in $request_time sec';

    access_log /var/log/nginx/access.log upstreamlog;

    upstream backend_pool {
        server 192.168.0.202:5000;  # LG_Desktop
        server 192.168.0.203:5000;  # Laptop
        server 192.168.0.204:5000;  # 500A2M
    }
 
    server {
        listen 80;
        server_name _;
    
        location / {
            proxy_pass http://backend_pool;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
            # 연결/응답 제한
            proxy_connect_timeout 4s;   # 연결 안 되면 빠르게 failover
            proxy_read_timeout 12s;     # 느린 응답 방지
            proxy_send_timeout 10s;
    
            proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
        }
    }
}

- 이제 nginx 서비스를 시작해두면 된다


3. 테스트

- 잘 동작하는지 테스트해보자

- nginx를 띄워둔 '중계 서버'에서 아래 명령어를 실행하면 된다

- App 서버들이 잘 동작한다면 요청이 분배되는대로 각 서버의 host 이름이 반환될 것이다

# 템플릿
for i in {1..6}; do curl -s http://localhost:<포트번호>/<API 경로>; echo; done

# 예시
for i in {1..6}; do curl -s http://localhost:52837/api/hello; echo; done

잘 동작한다! (당시엔 N100이 중계서버, App 서버는 2대뿐이었다)

- 잘된다!

- 별거 없게도 분산 구축 자체는 쉬웠다

- 진짜 어렵고 많은 시간을 쏟았던 것은 부하 테스트랑 튜닝...

- App 서버 3대가 요청의 처리 성능이 다름에도 round robin으로 분산이 되어있기 때문에 골고루 요청을 받는 형태이다

- 이 때, 수많은 요청이 한번에 들어오게 되면, 각 서버의 처리 속도에 따라 성능에 편차가 생기게 되고 이는 곧 불안정한 서비스로 이어진다

- 따라서 서버 3대의 성능과 사양에 따라 튜닝이 필요하며 이를 위해 정말 많은 테스트를 해야만 했다

- 글이 기니까! 다음 포스트에서 계속!

반응형

'Infra > DevOps' 카테고리의 다른 글

나만의 VPN 서버 만들기 (feat. 홈서버 + WireGuard)  (4) 2025.10.23
서버 부하 테스트 해보기 (feat. K6 스트레스 테스트 & 분산 구조 튜닝)  (0) 2025.10.23
서버 CPU 과부하 시 알림 보내기 (feat. Grafana 알림 설정 방법)  (0) 2025.10.13
오라클 클라우드(OCI) 퍼블릭 IP 적용 및 SSH 접속하기  (0) 2025.10.04
오라클 클라우드(OCI) 서버 한방에 만들기 (feat. 인스턴스 생성)  (0) 2025.10.04
'Infra/DevOps' 카테고리의 다른 글
  • 나만의 VPN 서버 만들기 (feat. 홈서버 + WireGuard)
  • 서버 부하 테스트 해보기 (feat. K6 스트레스 테스트 & 분산 구조 튜닝)
  • 서버 CPU 과부하 시 알림 보내기 (feat. Grafana 알림 설정 방법)
  • 오라클 클라우드(OCI) 퍼블릭 IP 적용 및 SSH 접속하기
Ratatou2
Ratatou2
온갖 정보들을 기록해두는 메모보드 블로그
  • Ratatou2
    nak-z
    · Ratatou2 ·
  • 전체
    오늘
    어제
  • 공지사항

    • 블로그 이전 진행 중 (24.11.25 ~)
    • 분류 전체보기 (303) N
      • OS (89) N
        • Linux (39)
        • Window (24)
        • Mac (21) N
        • Android (5)
      • Infra (83) N
        • DevOps (38) N
        • Docker (14)
        • Jenkins (9)
        • n8n (13)
        • Nextcloud (8)
        • Rasberry Pi (1)
      • Dev (17)
        • JAVA (7)
        • Python (1)
        • DB (3)
        • Vue (2)
        • AI (4)
        • Git (0)
      • Tools (10)
      • Study (69)
        • Algorithm (66)
        • CS (3)
      • Game (10)
        • Project Zomboid (9)
        • Don't Starve Together (1)
      • etc (24)
        • Temp (0)
      • 개발 외 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
Ratatou2
홈서버 4대로 분산 시스템 구축 해보기 (feat. 생각보다 겁나 쉬움!)
상단으로

티스토리툴바