HAProxy 는 하드웨어 기반의 L4/L7 스위치을 대체하기 위한 오픈소스 소프트웨어 솔루션으로 TCP 및 HTTP 기반 애플리케이션을 위한 고가용성, 로드 밸런싱 및 프록시 기능을 제공하는 매우 빠르고 안정적인 무료 Reverse프록시이다. HAProxy는 기본적으로 reverse proxy 형태로 동작한다.
로드 밸런싱이란 부하 분산을 위해서 가상(virtual)IP를 통해 여러 서버에 접속하도록 분배하는 기능을 말한다. 로드 밸런싱에서 사용하는 주요 기술은 다음과 같다.
사용자는 로드 밸런서에 접속을 하게 되고, 로드 밸런서는 설정(정의된)된 여러대의 웹서버 중 한곳으로 전달 해주는 구조이다. 일반적으로 IP와 PORT를 기반으로 트래픽 전달에 대한 설정을 하게 되고 정의된 여러 서버에 대한 접속 방식이 여러가지가 있겠으나 보통적으로 사용되는 방식은 라운드 로빈 방식으로 사용되고 있다.
Layer 4가 웹 서버 하나를 선택해서 모든 트래픽을 전달하는 방식이었다면, Layer 7 로드 밸런싱은 Application layer에서의 로드 밸런싱 하는 것의 의미한다.
레이어 7을 사용한 로드 밸랜싱은 사용자 요청의 내용에 따라 다른 백엔드 서버로 요청을 전달한다. 이런 로드 밸런싱 모드를 사용하면 동일한 도메인 및 포트에서 여러 웹 애플리케이션 서버를 실행 및 사용할 수 있게 됩니다.
레이어 4 및 7 로드 밸런싱 설정은 둘 다 로드 밸런서를 사용하여 많은 백엔드 서버 중 하나로 트래픽을 전달한다. 그러나 로드 밸런서는 이러한 설정에서 단일 실패 지점(SPOF, single point of failure)이 된다. 다운되거나 요청에 압도당하면 서비스에 긴 대기 시간 또는 다운타임이 발생할 수 있다.
고 가용성(HA) 설정은 단일 장애 지점이 없는 인프라로 광범위하게 정의된다. 아키텍처의 모든 계층에 중복성을 추가하여 단일 서버 오류가 다운타임 이벤트가 되는 것을 방지한다. 로드 밸런서는 백엔드 레이어(웹/앱 서버)의 중복성을 용이하게 하지만 진정한 고가용성 설정을 위해서는 중복 로드 밸런서도 있어야 한다.
사용자가 웹사이트에 엑세스하면 접속한 외부IP 주소를 통해 활성(Active) 로드 밸런서로 이동하며, 해당 로드 밸런서가 문제가 생긴다면 장애 조치 매커니즘이 이를 감지하고 다른 Passive 서버 중 하나의 IP 주소를 자동으로 재할당하는 형태로 진행이 필요 하다.
📢 HAProxy 동작참고 사이트: https://d2.naver.com/helloworld/284659
<서버 구성>
HAproxy: 192.168.56.108
web1: 192.168.56.101
web2: 192.168.56.107
dns1: 192.168.56.105
dns2: 192.168.56.109
HAProxy 서버에 접속 후 /etc/host 파일에 web서버 2개를 추가해준다.
vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.101 nginx1
192.168.56.107 nginx2
파일저장 후 편집기 종료
각 web 서버에는 HAproxy를 추가해준다.
vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.56.108 loadbalancer
파일저장 후 편집기 종료
haproxy서버에서
yum -y update
yum -y install haproxy
cd /etc/haproxy/
mv haproxy.cfg haproxy.cfg.orig 원본 설정파일 백업
vi haproxy.cfg
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
log 127.0.0.1 local2 #Log configuration
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy #Haproxy running under user and group "haproxy"
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
#---------------------------------------------------------------------
# common defaults that all the 'listen' and 'backend' sections will
# use if not designated in their block
#---------------------------------------------------------------------
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 3000
#---------------------------------------------------------------------
#HAProxy Monitoring Config
#---------------------------------------------------------------------
listen haproxy3-monitoring *:8080 #Haproxy Monitoring run on port 8080
mode http
option forwardfor
option httpclose
stats enable
stats show-legends
stats refresh 5s
stats uri /stats #URL for HAProxy monitoring
stats realm Haproxy\ Statistics
stats auth haproxy:haproxy #User and Password for login to the monitoring dashboard
stats admin if TRUE
default_backend app-main #This is optionally for monitoring backend
#---------------------------------------------------------------------
# FrontEnd Configuration
#---------------------------------------------------------------------
frontend main
bind *:80
option http-server-close
option forwardfor
default_backend app-main
#---------------------------------------------------------------------
# BackEnd roundrobin as balance algorithm
#---------------------------------------------------------------------
backend app-main
balance roundrobin #Balance algorithm
option httpchk HEAD / HTTP/1.1\r\nHost:\ localhost #Check the server application is up and healty - 200 status code
server nginx1 192.168.56.101:80 check #Nginx1
server nginx2 192.168.56.107:80 check #Nginx2
-> 맨 마지막줄에 자신의 web 서버의 ip를 넣는다.
-> 나중에 stats확인하기 위한 id/passwd도 변경한다
haproxy -f /etc/haproxy/haproxy.cfg -c
Configuration file is valid
-> haproxy.cfg 파일 체크, valid가 나오면 정상
HAProxy.cfg 파일구조에 대한 설명은 다음 사이트를 참고하면 된다.
📢 https://lifeplan-b.tistory.com/179
HAProxy 통계를 기록하도록 rsyslog 데몬을 구성한다. rsyslog.conf 파일을 편집하여 rsyslog에서 사용할 UDP 포트 514를 활성화시킨다.
vi /etc/rsyslog.conf
수정 전
# rsyslog configuration file
# For more information see /usr/share/doc/rsyslog-*/rsyslog_conf.html
# If you experience problems, see http://www.rsyslog.com/doc/troubleshoot.html
#### MODULES ####
# The imjournal module bellow is now used as a message source instead of imuxsock.
$ModLoad imuxsock # provides support for local system logging (e.g. via logger command)
$ModLoad imjournal # provides access to the systemd journal
#$ModLoad imklog # reads kernel messages (the same are read from journald)
#$ModLoad immark # provides --MARK-- message capability
# Provides UDP syslog reception
#$ModLoad imudp
#$UDPServerRun 514
# Provides TCP syslog reception
#$ModLoad imtcp
#$InputTCPServerRun 514
수정 후
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
$UDPServerAddress 127.0.0.1
파일 저장후 편집기 종료
rsyslog에 대한 새 haproxy 구성 파일을 생성
cd /etc/rsyslog.d/
vi haproxy.conf
local2.=info /var/log/haproxy-access.log #For Access Log
local2.notice /var/log/haproxy-info.log #For Service Info - Backend, loadbalancer
firewall-cmd --add-service=http --permanent
firewall-cmd --add-service=dns --permanent
firewall-cmd --zone=public --add-port=8080/tcp --permanent
firewall-cmd --reload
systemctl restart rsyslog
systemctl start haproxy
systemctl enable haproxy
이전에 설치한 각 웹서버에서 로드 밸런싱이 되고 있는지 구분하기 위해 /usr/share/nginx/html에 존재하는 index.html에 text를 수정한다. 알아보기 쉽게 web1에는 1, web2는 2를 추가한다.
각 웹 서버에서 systemctl restart nginx 실행한 후, haproxy의 IP인 192.168.1.108 에 액세스하여 브라우저에서 테스트하면 라운드 로빈 방식대로 두 서버가 차례대로 출력되는 것을 확인할 수 있다.
haproxy서버에서 curl 192.168.56.108를 입력해도 ip가 계속 바뀌면서 서버가 호출되는 것을 볼 수 있다.
브라우저에 haproxyip:8080/stats를 입력하면 다음과 같은 화면이 나오는데
위에서 지정해두었던 haproxy, haproxy 입력
로드밸런싱되면서 밑에 두개의 web서버를 번갈아 들어가는 것을 total의 숫자가 바뀌는 것으로 알수 있다.
참고하기 좋은 사이트 📢 https://ko.linux-console.net/?p=658#gsc.tab=0
하이퍼텍스트 전송 프로토콜(HTTP) 503 Service Unavailable 서버 에러 응답 코드는 서버가 요청을 처리할 준비가 되지 않은 것을 의미합니다. 이 문제가 발생한 이유를 생각해보자면 방화벽이나 데몬을 재실행시키지 않아서 생기는 문제가 대다수였다. 따라서 설정를 진행한 후 reload를 해주거나 restart를 진행을 하니 문제가 해결되었다.
$ cd /etc/haproxy
$ mkdir tls
$ cd tls
## 현재경로 : /etc/haproxy/tls
yum install -y openssl
## 1.패스워드없이 개인키 파일 생성
**$ openssl genrsa -out goorm-11th_com.key 1024**
## 2.key파일을 통해 서명파일 csr 파일 생성
**$ openssl req -new -key goorm-11th_com.key -out goorm-11th_com.csr**
(생략)
Country Name (2 letter code) [XX]:**KR**
State or Province Name (full name) []:**Seoul**
Locality Name (eg, city) [Default City]:**Seoul**
Organization Name (eg, company) [Default Company Ltd]:**Goorm**
Organizational Unit Name (eg, section) []:**Goorm**
Common Name (eg, your name or your server's hostname) []:**ha-proxy**
Email Address []:**admin@goorm-11th.com**
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
## 3.유효기간 365일로 crt 파일 생성
**$ openssl x509 -req -days 365 -in goorm-11th_com.csr -signkey goorm-11th_com.key -out goorm-11th_com.crt**
Signature ok
subject=/C=KR/ST=Seoul/L=Seoul/O=Goorm/OU=Goorm/CN=ha-proxy/emailAddress=admin@goorm-11th.com
Getting Private key
## 4.공개키 생성
**$ openssl rsa -in goorm-11th_com.key -text > key.pem**
writing RSA key
## 5.x509 인증서 생성
**$ openssl x509 -inform PEM -in goorm-11th_com.crt > crt.pem**
## 6.pkcs12 파일 생성
## 패스워드 입력하는 항목에서 공백으로 enter 입력함으로써 패스워드 없이 생성했다.
**$ openssl pkcs12 -export -in goorm-11th_com.crt -inkey goorm-11th_com.key -out cert.p12**
Enter Export Password:
Verifying - Enter Export Password:
## 7.pem파일 생성
**$ openssl pkcs12 -in cert.p12 -nodes -out cert.pem**
Enter Import Password:
MAC verified OK
PEM(Privacy Enhanced Mail)
CSR 파일
CRT 파일
x509 인증서
pkcs12 파일
## 생성한 파일 확인
$ ls
cert.p12 crt.pem goorm-11th_com.csr goorm-11th_com.origin
cert.pem goorm-11th_com.crt goorm-11th_com.key key.pem
$ vi /etc/haproxy/haproxy.cfg
#---------------------------------------------------------------------
# main frontend which proxys to the backends
#---------------------------------------------------------------------
frontend main *:5000
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
use_backend static if url_static
frontend web-nginx
mode http
bind :80
**bind :443 ssl crt /etc/haproxy/tls/cert.pem**
default_backend https
option forwardfor
#---------------------------------------------------------------------
# static backend for serving up images, stylesheets and such
#---------------------------------------------------------------------
backend static
balance roundrobin
server static 127.0.0.1:4331 check
#---------------------------------------------------------------------
# round robin balancing between the various backends
#---------------------------------------------------------------------
backend http
balance roundrobin
server web1 192.168.0.20:80 check
server web2 192.168.0.21:80 check
backend https
balance roundrobin
server web1 192.168.0.20:80 check
server web2 192.168.0.21:80 check
frontend web-nginx
mode http
bind :80
bind :443 ssl crt /etc/haproxy/tls/cert.pem
**http-request redirect scheme https unless { ssl_fc }**
default_backend https
option forwardfor
$ haproxy -f /etc/haproxy/haproxy.cfg -c
$ systemctl restart haproxy.service
📢 참고 사이트: https://www.haproxy.com/blog/redirect-http-to-https-with-haproxy/
IP주소로 들어갔을 때, 사용 중인 네트워크에서 로그인 페이지 방문을 요청할 수 있습니다.라는 페이지가 나오고 이 오류에 있는 '연결'을 눌러도 연결이 안 되고 한참 뒤에 www.gstatic.com/generate_204 에 연결할 수 없다는 에러가 또 표시된다.
이 오류는 외부 네트워크가 막힌 상태에서 SSL 인증서가 적용된 사이트를 HTTPS URL로 접속할 때 생기는 문제다. 크롬 브라우저는 https 주소 페이지 열기 전에 SSL 인증서를 먼저 검증을 하는데 이 검증에 문제가 발견되면 SSL 관련 오류 메시지와 오류코드, 오류 안내를 표시하게 된다.
이를 해결하기 위해 크롬 브라우저 대신 다른 브라우저를 사용하는 가장 쉬운 방법이 있다. 다른 방법으로 진행한 방법은 아래 사이트에서 참고해서 하였다.
📢 참고 사이트: https://jennana.tistory.com/115