Nginx + Docker로 Load Balancing하기

0

현재 우리 서버의 구조이다. Docker ImageDocker-compose 파일로 컨테이너화 한다.
nginx80 port, 443 port 로 들어온 요청을 컨테이너가 실행되는 3000 portreverse-proxy시킨다.


version: '3'
services:
  egusajo-0:
    image: ghcr.io/inha-commit/egusajo-nest:latest
    container_name: egusajo-0
    ports:
      - "3000:3000"
    restart: always
		networks:
      - egusajo_network
networks:
  egusajo_network:
    external: true

먼저 현재 우리의 서버를 생성하는 docker-compose 파일이다. docker-compose 파일을 수정해서 container로 늘려주자.


Docker-container 늘리기

version: '3'
services:
  egusajo-0:
    image: ghcr.io/inha-commit/egusajo-nest:latest
    container_name: egusajo-0
    ports:
      - "3000:3000"
    restart: always
		networks:
      - egusajo_network
  egusajo-1:
    image: ghcr.io/inha-commit/egusajo-nest:latest
    container_name: egusajo-1
    ports:
      - "3001:3000"
    restart: always
		networks:
      - egusajo_network
  egusajo-2:
    image: ghcr.io/inha-commit/egusajo-nest:latest
    container_name: egusajo-2
    ports:
      - "3002:3000"
    restart: always
		networks:
      - egusajo_network
  egusajo-3:
    image: ghcr.io/inha-commit/egusajo-nest:latest
    container_name: egusajo-3
    ports:
      - "3003:3000"
    restart: always
		networks:
      - egusajo_network
  egusajo-4:
    image: ghcr.io/inha-commit/egusajo-nest:latest
    container_name: egusajo-4
    ports:
      - "3004:3000"
    restart: always
		networks:
      - egusajo_network

networks:
  egusajo_network:
    external: true

이렇게 docker-compose파일에 설정을 추가하여 컨테이너를 다섯개로 늘려 준다.


5개의 컨테이너가 실행되고 있는 것을 확인할 수 있다.


늘려주면 이렇게 되었다. 컨테이너는 다섯개가 되었지만(그림에선 4개만 그림) nginx3000 port로만 요청을 전달한다. 이제 nginx 파일을 수정해서 요청을 분산하도록 하자.


nginx 파일 수정

server {
        server_name [your_server_domain];

        location / {
                proxy_pass http://127.0.0.1:3000;
        }

        listen 443 ssl; # managed by Certbot
        ...
}

server {
    if ($host = [your_server_domain]) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen       80;
    listen  [::]:80;
    server_name [your_server_domain];
    return 404; 
}

기존의 nginx 설정 파일이다. domain에 맞는 http요청이 들어오면 nginx가 reverse-proxy시켜주어 우리의 컨테이너에게 정보를 전달해준다.


upstream servers {
  least_conn;
  server 127.0.0.1:3000 weight=10 max_fails=3 fail_timeout=30s;
  server 127.0.0.1:3001 weight=10 max_fails=3 fail_timeout=30s;
  server 127.0.0.1:3002 weight=10 max_fails=3 fail_timeout=30s;
  server 127.0.0.1:3003 weight=10 max_fails=3 fail_timeout=30s;
  server 127.0.0.1:3004 weight=10 max_fails=3 fail_timeout=30s;
}

server {
    server_name your_server_domain];

    location / {
        proxy_pass http://servers;
		}

    listen 443 ssl; # managed by Certbot
     ...
}
...

위 옵션을 추가해주자.

least_conn은 Nginx에서 사용되는 업스트림 서버의 로드 밸런싱 방식 중 하나이다. 이 옵션은 연결 요청을 처리할 때 현재 가장 적은 활성 연결 수를 가진 서버에 우선적으로 연결을 전달한다.
least_conn을 사용하면 현재 연결 상태를 고려하여 트래픽을 분산시키기 때문에 서버 간의 부하를 균등하게 분배할 수 있다. 나는 이 방식이 서버에 필요하여 least_conn 방식을 사용했다.

other method

다른 로드 밸런싱 방식에는 round-robinip_hash 등이 있다.

Round Robin (라운드 로빈):
라운드 로빈 방식은 연속된 요청을 순차적으로 다음 서버로 배분한다. 맨 처음 요청은 첫 번째 서버에, 다음 요청은 두 번째 서버에, 그 다음은 세 번째 서버에 순서대로 전달된다. 이 패턴이 반복된다.
모든 서버에 대해 균등하게 트래픽을 분산시키지, 서버 간의 상태를 고려하지 않으므로, 각 서버의 부하나 성능 차이를 고려하지 않는다.

IP Hash (IP 해시):
IP 해시 방식은 클라이언트의 IP 주소를 기반으로 요청을 서버로 분배한다. 클라이언트의 IP 주소에 대한 해시값을 계산하고, 그 해시값을 이용하여 어느 서버로 요청을 보낼지 결정한다. 이를 통해 특정 클라이언트가 항상 동일한 서버로 요청을 보낼 수 있다.
특정 세션에 대해 항상 동일한 서버로 요청을 보내기 때문에 세션 유지가 필요한 경우에 유용하다.
하지만 서버가 추가되거나 제거될 때 해시값이 변경되어 새로운 서버로 연결되는 문제가 발생할 수 있다. 또한, 서버 간 부하 차이를 고려하지 않는다.


이제 우리 서버는 이런 형식이 되었다.


요창을 20개 보냈을때 한 서버에 5개만 도달한 것을 확인할 수 있다. 성공!

profile
https://www.youtube.com/watch?v=__9qLP846JE

0개의 댓글

관련 채용 정보