프로젝트를 진행하면서 서버 이중화를 위해 LB서버로 Nginx를 이용하여 구성한 내용을 정리했습니다.
이전 글에서 Nginx 컴파일 설치 과정을 정리했습니다.
이번 글에서는 proxy 설정과 서버 이중화를 위한 설정을 정리해보겠습니다.
이전 글에서 nginx 컴파일 설치를 하며 주요 디렉터리 경로를 따로 지정한 후 주로 사용하는 명령어는 다음과 같다.
# nginx 서비스 명령어 - nginx.service 파일을 systemd에 등록하여 아래 명령어로 사용 가능
systemctl daemon-reload
systemctl enable nginx.service
systemctl start nginx
systemctl status nginx
systemctl stop nginx
# nginx.conf 설정 내용 체크
cd /app/nginx/sbin
./nginx -t
# log file 확인
tail -f /app/nginx/logs/*
컴파일 설치를 진행할 때 설정한 nginx.conf의 위치는 /app/nginx/conf/nginx.conf
이다.
단일 서버 proxy
아래의 서버 블록은 apple.com의 80번으로 들어오는 접근을
http://192.168.10.14:8080
http://192.168.10.15:8080
으로 로드밸런싱 시키는 예제이다.
#user nobody;
worker_processes 1;
error_log /app/nginx/logs/error.log info;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /app/nginx/logs/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
server {
listen 80;
server_name apple.com;
location / {
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_set_header X-Forwarded-Proto $scheme;
proxy_pass http://192.168.10.14:8080;
proxy_pass http://192.168.10.15:8080;
proxy_redirect off;
proxy_buffering off;
client_max_body_size 100M; # 업로드 가능한 파일 크기를 지정
}
}
}
nginx.conf 옵션 정리
ip_hash
upstream에서 ip_hash 는 로드밸런싱 방법 중의 하나로
클라이언트의 IP 주소를 해시하여 동일한 클라이언트는 항상 동일한 upstream 서버로 요청이 전달되도록 할 수 있다. session clustering이 구성되지 않은 경우 유용하다.
이를 통해 세션 일관성을 유지하고 클라이언트의 연결을 특정 서버에 고정시킬 수 있다.
ip_hash는 sticky 세션 방식이 아니다.
ip_hash를 사용하면 client ip를 지정한 서버로 연결은 가능하나, jboss에서 세션 클러스터링이 구성 된 경우 세션이 뺑뺑이 돌 수 있다.
ip_hash 방식과 sticky 세션 방식을 함께 사용하는 것은 권고하지 않는다.
많은 다른 브라우저가 동일한 IP주소(프록시 뒤에서)를 사용하여 로드밸런싱이 잘 안될 확률이 있으니, 적절한 방식을 사용하자
proxy_pass
클라이언트로 부터 요청을 받았을 때, 해당 요청을 지정된 다른 서버로 전달하고, 해당 서버로 부터 받은 응답을 클라이언트에게 반환한다.
# 요청을 다른 서버로 전달
proxy_pass http://backend_server/;
# 클라이언트에서 전달된 요청 헤더를 수정하거나 추가할 수 있다.
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# target 서버가 응답하는 리다이렉션 헤더를 수정
proxy_redirect http://backend_server/ http://example.com/;
# 서버의 Response를 버퍼링 설정
proxy_buffering on;
upstream
cluster 구성시 필수로 사용하는 옵션
cluster에 참여하는 서버 정보와 포트를 upstream의 지시자로 설정하며 첫번째 설정한 서버가 우선적으로 응답을 처리한다.
server
웹 서버 정의
server {
listen 80;
server_name example.com;
root /var/www/html; # 웹 페이지 파일의 기본 경로 설정
}
location : 특정 URL 경로에 대한 요청을 처리한다.
location /app/ {
proxy_pass http://localhost:3000/;
limit_req zone=api_limit burst=5 nodelay; # 요청 속도 제한 설정
}
index : 디렉토리에 접근했을 때 보여줄 기본 파일 설정
location / {
index index.html index.html;
}
try_files : 파일이나 디렉토리가 존재하지 않을 경우 대체 동작을 설정
location / {
try_files $uri $uri/ /index.html;
}
error_page : 오류가 발생했을 때 보여줄 페이지 설정
error_page 404 /404.html;
ssl_certificate / ssl_certificcate_key : ssl 인증서 및 키 파일 설정
certbot등의 서비스를 이용하여 ssl 인증서를 발급받은 후 해당 키가 위치한 경로를 작성하여 SSL 을 적용시킬 수 있다.
server {
listen 443 ssl;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
...
}
다중 서버 로드밸런싱
nginx.conf에서 기본적으로 제공하는 블록인 http{} 블록 안에 작성하면 된다.
아래의 예제는 nginx를 하나의 로드밸런싱 서버로 사용하여
apple.com의 80 포트로 들어오는 접근을 apple-cluster로 로드밸런싱 하는 예제이다.
banana.com도 마찬가지로 하나의 도메인으로 들어오는 접근을 각 다른 IP로 로드밸런싱한다.
# stats
server {
listen 9000;
location / {
stub_status;
}
location /stats {
check_status;
}
}
# apple.com
upstream apple-cluster {
ip_hash;
server 192.168.10.14:8080;
server 192.168.10.15:8080;
}
server {
listen 80;
server_name apple.com;
location / {
client_max_body_size 100m;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://apple-cluster;
proxy_read_timeout 3600;
}
}
# banana
upstream banana-cluster {
ip_hash;
server 192.168.10.14:9090;
server 192.168.10.15:9090;
}
server {
listen 80;
server_name banana.com;
location / {
client_max_body_size 100m;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://banana-cluster;
proxy_read_timeout 3600;
}
}
map을 이용하여 다중 서버 클러스터 적용
위와 같이 다중클러스터를 적용하다보니, 동일한 코드가 여러번 반복되는 것을 줄이기 위해 map을 이용한 다중 서버 클러스터를 적용할 수 있다.
nginx를 설치할 때 ngx_http_map_module 모듈이 기본적으로 활성화 되어있는 것을 여기에서 확인할 수 있다.
map $http_host $upstream {
apple.com apple-cluster;
banana.com banana-cluster;
cake.com cake-cluster;
}
# apple.com
upstream apple-cluster {
ip_hash;
server 192.168.10.14:8080;
server 192.168.10.15:8080;
check interval=5000 rise=1 fall=3 timeout=4000;
}
# banana.com
upstream banana-cluster {
ip_hash;
server 192.168.10.14:9090;
server 192.168.10.15:9090;
check interval=5000 rise=1 fall=3 timeout=4000;
}
# cake.com
upstream cake-cluster {
ip_hash;
server 192.168.10.14:7070;
server 192.168.10.15:7070;
check interval=5000 rise=1 fall=3 timeout=4000;
}
server {
listen 80;
location / {
proxy_pass http://$upstream;
client_max_body_size 100m;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 3600;
}
location /stats {
check_status; # health check module
access_log off;
allow all;
deny all;
}
}
이렇게 nginx 컴파일 설치 과정과 nginx.conf 설정을 적용하는 방법을 정리해봤습니다.
다음 글에서는 Let's Encrypt를 이용하여 간단하게 SSL 인증서를 받아 nginx에서 적용하고, 한달에 한번 인증서를 받아 적용하는 스케줄러를 적용해보려고 합니다.
'DevOps' 카테고리의 다른 글
Nginx 컴파일 설치 (0) | 2024.03.12 |
---|---|
GitHub Action CI/CD 파이프라인 구축하기(1) (0) | 2023.11.26 |
Github Action이란 (0) | 2023.11.26 |
[AWS] ECR - Elastic Container Registry (0) | 2023.11.26 |
Vagrant란? (0) | 2023.06.29 |