NGINX HA 고가용성 구성하기
이 포스트에서는 NGINX를 사용하여 NGINX HA 를 구성하는 방법에 대해 설명합니다.
NGINX HA 구성은 주로 Active-Passive와 Active-Active 두 가지 방식으로 이루어집니다. NGINX HA 구성을 통해 더욱 강력하고 안정적인 서비스를 구축할 수 있습니다.
NGINX HA구성은 NGINX Plus를 통해 사용할 수 있습니다.
목차
1. HA(High Availability)란?
2. NGINX HA Active-Passive 구성하기
3. NGINX HA Active-Active 구성하기
4. NGINX HA Cluster 구성하기
4-1. NGINX HA Cluster 구성을 위한 추가 설정하기
4-2. NGINX-sync 구성하기
4-3. NGINX HA Cluster 동기화 확인하기
1. HA(High Availability)란?

HA(High Availability)/고가용성은 네트워크나 프로그램 등의 시스템이 중단되지 않고 연속적으로 작동할 수 있는 시스템이나 컴포넌트를 의미합니다. HA의 종류에는 Active-Passive HA (Active-Standby HA), Active-Active HA 등 여러 방식이 있지만 이 포스트에서는 2가지 방식을 다루겠습니다. 각 구성의 특징은 다음과 같습니다.
- Active-Passive
- 하나의 서버가 활성 상태로 동작하고, 나머지 서버들은 대기 상태로 유지됩니다.
- 활성 서버에 장애가 발생하면 대기 서버 중 하나가 활성화되어 서비스를 이어받습니다.
- 전체 시스템의 가용성이 증가하지만, 활성 서버에만 부하가 집중될 수 있습니다.
- Active-Active
- 모든 서버가 동시에 활성 상태로 운영됩니다
- 각 서버가 특정 부하를 처리하거나 특정 기능을 담당할 수 있습니다
- 자원 사용을 균형 있게 분산하여 성능을 최적화할 수 있습니다
2. NGINX HA Active-Passive 구성하기
Active-Passive 구성을 위해서는 두 개의 서버의 IP와 두 서버를 연결할 VIP(가상 IP)를 필요로 합니다.
여기서는 IP를 다음과 같이 구성했습니다.
- primary 서버 : 192.168.200.160
- backup 서버 : 192.168.200.161
- Cluster IP(VIP) : 192.168.200.165
NGINX HA 구성을 위해서는 패키지 설치가 필요합니다. primary, backup 서버 모두 설치를 진행합니다.
# apt-get install nginx-ha-keepalived
두 서버 모두 명령어를 통해 HA 설정을 시작합니다. 두 환경에서 동시에 진행하는 것을 권장하고 있습니다.
# nginx-ha-setup
설정을 진행 중인 서버의 IP를 설정합니다.
시스템에서 예측한 IP와 사전에 설정한 IP가 일치하므로 y를 입력하여 진행합니다.
# primary
Step 1: configuring internal management IP addresses.
In order to communicate with each other, both nodes must have at least one IP address.
The guessed primary IP of this node is: 192.168.200.160/24
Do you want to use this address for internal cluster communication? (y/n)
# backup
Step 1: configuring internal management IP addresses.
In order to communicate with each other, both nodes must have at least one IP address.
The guessed primary IP of this node is: 192.168.200.161/24
Do you want to use this address for internal cluster communication? (y/n)
현재 설정 중인 서버와 연결할 서버의 IP를 설정해 줍니다.
primary 서버에선 backup 서버의 IP를, backup 서버에선 primary 서버의 IP를 설정합니다.
# primary
Now please enter IP address of a second node: 192.168.200.161
You entered: 192.168.200.161
Is it correct? (y/n)
IP address of the second node is set to: 192.168.200.161
Press <Enter> to continue...
# backup
Now please enter IP address of a second node: 192.168.200.160
You entered: 192.168.200.160
Is it correct? (y/n)
IP address of the second node is set to: 192.168.200.160
Press <Enter> to continue...
Cluster IP를 설정해 줍니다. 두 서버 모두 사전에 준비한 VIP(192.168.200.165)로 설정합니다.
Cluster IP를 통해서 노드에 연결할 수 있습니다.
# primary, backup
Now you have to choose cluster IP address.
This address will be used as en entry point to all your cluster resources.
The chosen address must not be one already associated with a physical node.
Enter cluster IP address: 192.168.200.165
You entered: 192.168.200.165
Is it correct? (y/n)
이후 서버별 master와 backup 역할을 설정합니다.
primary 서버는 1(MASTER), backup 서버는 2(BACKUP)으로 설정합니다.
You must choose which node should have the MASTER role in this cluster.
Please choose what the current node role is:
1) MASTER
2) BACKUP
(on the second node you should choose the opposite variant)
Press 1 or 2.
설정 완료 후, 명령어를 통해 각 서버의 상태를 확인할 수 있습니다.
# primary
root@primary:/# cat /var/run/nginx-ha-keepalived.state
STATE=MASTER
# backup
root@backup1:/# cat /var/run/nginx-ha-keepalived.state
STATE=BACKUP
primary 서버를 중지시킨 후, 다시 확인 시 상태가 변경됨을 확인할 수 있습니다.
# primary
root@primary:/# systemctl stop nginx
root@primary:/# cat /var/run/nginx-ha-keepalived.state
STATE=BACKUP
# backup
root@backup1:/# cat /var/run/nginx-ha-keepalived.state
STATE=MASTER
3. NGINX HA Active-Active 구성하기
NGINX HA Active-Active 구성을 위해서는 2개의 ClusterIP가 필요합니다.
Active-Passive 설정에서 사용한 IP와 함께 추가 IP를 사용했습니다.
Active-Passive 설정의 backup 서버를 secondary 서버로 구성했습니다.
- primary 서버 : 192.168.200.160
- backup 서버 : 192.168.200.161
- 기존 VIP : 192.168.200.165
- 신규 VIP : 192.168.200.166
Active-Passive 설정이 완료된 secondary서버의 keepalived.conf 파일을 수정합니다.
root@backup1:/# vi /etc/keepalived/keepalived.conf
global_defs {
vrrp_version 3
}
vrrp_script chk_manual_failover {
script "/usr/lib/keepalived/nginx-ha-manual-failover"
interval 10
weight 50
}
vrrp_script chk_nginx_service {
script "/usr/lib/keepalived/nginx-ha-check"
interval 3
weight 50
}
vrrp_instance VI_1 {
interface enp0s3
priority 100
virtual_router_id 51
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.161/24
unicast_peer {
192.168.200.160
}
virtual_ipaddress {
192.168.200.165
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
# vrrp_instance VI_1의 내용을 복사 후 수정
vrrp_instance VI_2 { # VI_2로 변경
interface enp0s3
priority 99 # priority 변경
virtual_router_id 61 # virtual_router_id 변경
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.161/24
unicast_peer {
192.168.200.160
}
virtual_ipaddress {
192.168.200.166 # VIP 변경
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
기존에 존재하던 vrrp_instance VI_1 블록을 복사 후 내용을 수정합니다.
- 블록명 수정
- priority 값 수정(99)
- virtual_router_id 값 변경
- virtual_ipaddress를 신규 VIP 값으로 변경
primary 서버의 파일도 수정합니다.
root@primary:/# vi /etc/keepalived/keepalived.conf
global_defs {
vrrp_version 3
}
vrrp_script chk_manual_failover {
script "/usr/lib/keepalived/nginx-ha-manual-failover"
interval 10
weight 50
}
vrrp_script chk_nginx_service {
script "/usr/lib/keepalived/nginx-ha-check"
interval 3
weight 50
}
vrrp_instance VI_1 {
interface enp0s3
priority 101
virtual_router_id 51
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.160/24
unicast_peer {
192.168.200.161
}
virtual_ipaddress {
192.168.200.165
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
# vrrp_instance VI_1의 내용을 복사 후 수정
vrrp_instance VI_2 { # VI_2로 변경
interface enp0s3
priority 98 # priority 변경
virtual_router_id 61 # virtual_router_id 변경
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.160/24
unicast_peer {
192.168.200.161
}
virtual_ipaddress {
192.168.200.166 # VIP 변경
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
secondary 서버와 같이 내용을 수정합니다. VI_2 블록의 priority 값은 secondary 서버의 값보다 낮게 설정했습니다.
명령어를 통해 keepalived를 재가동합니다.
# systemctl restart keepalived.service
각각의 서버에 VIP가 할당된 것을 확인할 수 있습니다.
# primary
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:fa:7e:e8 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.160/24 brd 192.168.200.255 scope global enp0s3
valid_lft forever preferred_lft forever
inet 192.168.200.165/32 scope global enp0s3
valid_lft forever preferred_lft forever
# secondary
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:a3:fa:11 brd ff:ff:ff:ff:ff:ff
inet 192.168.200.161/24 brd 192.168.200.255 scope global enp0s3
valid_lft forever preferred_lft forever
inet 192.168.200.166/32 scope global enp0s3
valid_lft forever preferred_lft forever
NGINX VM Active-Active 구성을 확인하기 위해 primary 서버에 할당된 VIP 주소(102.168.200.165)로 요청을 전송하여 테스트했습니다.
root@backup1:/# curl 192.168.200.165
primary server
primary 서버의 서버로 연결됨을 알 수 있습니다.
이후 primary 서버를 중지시키고, 다시 요청을 전송했습니다.
# primary
root@primary:/# systemctl stop nginx
# backup
root@backup1:/# curl 192.168.200.165
backup server
primary 서버를 중지하고, primary 서버의 주소로 요청을 하자, secondary 서버가 응답을 하는 것을 확인할 수 있습니다.
4. NGINX HA Cluster 구성하기
3개의 서버를 NGINX Cluster(Active-Active-Active)로 구성하기 위해 기존의 서버에서 third 서버(backup2)를 추가했습니다. 192.168.200.167 IP를 추가 VIP로 사용했습니다. 서버와 IP 설정은 다음과 같습니다.
- primary(primary) : 192.168.200.160
- secondary(backup1) : 192.168.200.161
- third(bakcup2) : 192.168.200.163
- VIP1 : 192.168.200.165
- VIP2 : 192.168.200.166
- VIP3 : 192.168.200.167
4-1. NGINX Cluster 구성을 위한 추가 설정하기
third 서버에 패키지를 설치합니다.
apt-get install nginx-ha-keepalived
secondary 서버의 keepalived 설정 파일을 복사 후 수정하여 설정을 했습니다.
클러스터 구성을 위해 vrrp_instance VI_3 블록도 추가합니다.
/etc/keepalived/keepalived.conf
global_defs {
vrrp_version 3
}
vrrp_script chk_manual_failover {
script "/usr/lib/keepalived/nginx-ha-manual-failover"
interval 10
weight 50
}
vrrp_script chk_nginx_service {
script "/usr/lib/keepalived/nginx-ha-check"
interval 3
weight 50
}
vrrp_instance VI_1 {
interface enp0s3
priority 100 # priority 설정
virtual_router_id 51
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.163/24 # third 서버 IP로 수정
unicast_peer {
192.168.200.160
192.168.200.161 # secondary 서버 IP 추가
}
virtual_ipaddress {
192.168.200.165
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
vrrp_instance VI_2 {
interface enp0s3
priority 91 # priority 설정
virtual_router_id 61
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.163/24 # third 서버 IP로 수정
unicast_peer {
192.168.200.160
192.168.200.161 # secondary 서버 IP 추가
}
virtual_ipaddress {
192.168.200.166
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
# 블록 추가
vrrp_instance VI_3 {
interface enp0s3
priority 82 # priority 설정
virtual_router_id 71 # virtual_router_id 변경
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.163/24
unicast_peer {
192.168.200.160
192.168.200.161
}
virtual_ipaddress {
192.168.200.167 # 신규 VIP로 설정
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
- priority를 변경합니다
- unicast_src_ip 를 third 서버의 IP로 변경합니다
- unicast_peer 에 secondary의 IP를 추가합니다
- vrrp_instance VI_3 블록을 추가하여 priority, virtual_router_id, VIP 설정을 변경합니다
primary 서버와 secondary 서버의 keepalived.conf 파일도 수정합니다.
다음 코드는 primary 서버의 설정 파일 작성 예시입니다.
# primary
vrrp_instance VI_1 {
interface enp0s3
priority 102
virtual_router_id 51
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.160/24
unicast_peer {
192.168.200.161
192.168.200.163
}
virtual_ipaddress {
192.168.200.165
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
vrrp_instance VI_2 {
interface enp0s3
priority 90
virtual_router_id 61
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.160/24
unicast_peer {
192.168.200.161
192.168.200.163
}
virtual_ipaddress {
192.168.200.166
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
vrrp_instance VI_3 {
interface enp0s3
priority 81
virtual_router_id 71
advert_int 1
accept
garp_master_refresh 5
garp_master_refresh_repeat 1
unicast_src_ip 192.168.200.160/24
unicast_peer {
192.168.200.161
192.168.200.163
}
virtual_ipaddress {
192.168.200.167
}
track_script {
chk_nginx_service
chk_manual_failover
}
notify "/usr/lib/keepalived/nginx-ha-notify"
}
unicast_peer 부분에 새로 추가된 third 서버의 ip를 추가했고, vrrp_instance VI_3 블록을 추가했습니다.
4-2. NGINX-sync 구성하기
NGINX-sync 설정을 통해 여러 서버 사이에서 NGINX 설정 파일을 동기화할 수 있습니다.
이를 통해 클러스터 내의 모든 서버가 동일한 NGINX 구성을 유지하고, 한 곳에서 구성이 변경되면 다른 모든 서버에 반영할 수 있습니다.
primary 서버에 nginx-sync 패키지를 설치합니다.
# apt-get install nginx-sync
primary 서버와 backup(1, 2) 서버를 SHH 연결하기 위해 primary 서버에서 SSH 인증키를 생성합니다.
# ssh-keygen -t rsa -b 2048
생성된 SSH 공개키를 확인합니다.
# cat /root/.ssh/id_rsa.pub
ssh-rsa AAAAB ... MwB root@primary
backup 서버에서 다음과 같이 경로를 생성하고, primary 서버에서 생성된 SSH 공개키를 authorized_keys 파일에 추가합니다.
# mkdir /root/.ssh
# echo 'from="192.168.200.160" ssh-rsa AAAAB ..... MwB root@primary' >> /root/.ssh/authorized_keys
- IP를 primary 서버의 ip로 변경
- ssh ~ Mwb 부분은 primary에서 생성한 SSH 공개키로 입력
backup 서버의 /etc/ssh/sshd_config 파일에 다음 구문을 추가합니다.
PermitRootLogin without-password
적용한 SSH 키 인증을 활성화하기 위해 backup 서버에서 명령어를 실행합니다.
# systemctl restart ssh
primary 서버에서 명령어를 통해 backup 서버에 암호 없이 SSH 연결이 되는 것을 확인합니다.
root@primary:/# ssh root@192.168.200.161
...
root@backup1:~#
primary 서버에서 다음 경로에 파일을 작성합니다.
vi /etc/nginx-sync.conf
NODES="192.168.200.161 192.168.200.163" # backup 서버의 ip
CONFPATHS="/etc/nginx/nginx.conf /etc/nginx/conf.d"
EXCLUDE="" # 제외할 파일 설정
명령어를 입력하여 primary 서버와 backup 서버의 설정을 동기화합니다.
nginx-sync.sh
* Synchronization started at Mon Mar 25 06:53:18 AM UTC 2024
* Checking prerequisites
* Testing local nginx configuration file
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
nginx version: nginx/1.25.3 (nginx-plus-r31-p1)
* Deleting remote backup directory
* Backing up configuration on 192.168.200.161
* Updating configuration on 192.168.200.161
* Testing nginx config on 192.168.200.161
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
nginx version: nginx/1.25.3 (nginx-plus-r31-p1)
* Deleting remote backup directory
* Backing up configuration on 192.168.200.163
* Updating configuration on 192.168.200.163
* Testing nginx config on 192.168.200.163
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
* Synchronization ended at Mon Mar 25 06:53:28 AM UTC 2024
primary 서버에서 명령어를 통해 동기화 상태를 확인할 수 있습니다.
root@primary:/# nginx-sync.sh -C
* Synchronization started at Mon Mar 25 07:38:38 AM UTC 2024
* Checking prerequisites
* Comparing local and remote configs
* Comparing configs on master node and 192.168.200.161:
* Comparing local and remote configs
* Comparing configs on master node and 192.168.200.163:
* Synchronization ended at Mon Mar 25 07:38:41 AM UTC 2024
4-3. NGINX HA Cluster 동기화 확인하기
NGINX HA Cluster 동기화 확인을 위해, primary 서버의 nginx.conf 파일을 수정 후, backup 서버의 nginx.conf 파일이 수정되는지 확인해보겠습니다.
root@primary:/# vi /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
# text text
...
파일에 # test text 를 추가했습니다.
명령어를 통해 primary 서버의 구성과, backup서버의 구성 차이를 확인합니다.
root@primary:/# nginx-sync.sh -C
* Synchronization started at Mon Mar 25 08:03:53 AM UTC 2024
* Checking prerequisites
* Comparing local and remote configs
* Comparing configs on master node and 192.168.200.161:
Files local:/etc/nginx/nginx.conf and remote:/etc/nginx/nginx.conf differ
* Comparing local and remote configs
* Comparing configs on master node and 192.168.200.163:
Files local:/etc/nginx/nginx.conf and remote:/etc/nginx/nginx.conf differ
* Synchronization ended at Mon Mar 25 08:03:57 AM UTC 2024
/etc/nginx/nginx.conf 경로의 파일의 구성이 다름을 나타냅니다.
명령어를 통해 구성을 동기화합니다.
root@primary:/# nginx-sync.sh
* Synchronization started at Mon Mar 25 08:04:46 AM UTC 2024
* Checking prerequisites
* Testing local nginx configuration file
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
nginx version: nginx/1.25.3 (nginx-plus-r31-p1)
* Deleting remote backup directory
* Backing up configuration on 192.168.200.161
* Updating configuration on 192.168.200.161
* Testing nginx config on 192.168.200.161
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
nginx version: nginx/1.25.3 (nginx-plus-r31-p1)
* Deleting remote backup directory
* Backing up configuration on 192.168.200.163
* Updating configuration on 192.168.200.163
* Testing nginx config on 192.168.200.163
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
* Synchronization ended at Mon Mar 25 08:04:58 AM UTC 2024
nginx.conf 파일이 동기화된것을 확인합니다.
root@backup1:/# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
# test text
....
root@backup2:/# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
# test text
...
NGINX HA 를 Active-Active 방식과 Active-Passive, Clustering 방식으로 구성하는 방법에 대해 알아보았습니다. 보다 자세한 내용은 NGINX Plus 관리자 가이드를 참조하세요.
아래 뉴스레터를 구독하고 NGINX와 NGINX STORE의 최신 정보들을 빠르게 전달받아보세요.
댓글을 달려면 로그인해야 합니다.