서비스를 운영할 때 단일 서버로 구성된 애플리케이션이 속도는 가장 빠르다. 하지만 여러 가지 애로사항이 존재한다. 물리적인 한계에 도달했을 때 확장이 불가능하다.


가장 단순한 방법은 서버 부품(Cpu, Memory, Disk)를 더 빠른 부품으로 교체한다. 기존 업무프로세스에 변동이 없는 대신 큰 비용을 사용해야 한다. 대기업에서 주로 사용하는 방법이며, 수직 확장 Scale up이다.


소규모 기업은 보통 비용 사용에 부담을 느끼기 때문에 다른 방법을 모색하는데, 서버를 같은 구성으로 추가하는 모습을 띠게 된다. 여기서 한가지 짚고 넘어가야 할 부분이 있다. 진입점이 여러 개가 되는데 한곳으로 만들어줘야만 클라이언트가 손쉽게 이용할 수 있다. 그렇지 않다면 직접 판단해서 접근해야 한다. 수평 확장 Scale out이다.


하나의 진입점에서 여러 개의 서버로 분배해주는 것을 Load Balancing 이라고하며 OSI 7 Layer 중 L4 Layer 이상이 되어야 tcp, udp등 프로토콜을 구분할 수 있다. 추가로 L7 Layer 애플리케이션 간의 프로토콜을 확인할 수 있으며 보통 http, https, smtp등 을 사용한다. 훨씬 많은 정보를 얻기 때문에 체계적인 Load Balancing이 가능하다.


HAProxy는 Scale out으로 확장할 때 진입점을 관리해주는 L4/L7 로드밸런서이며 tcp, http, https를 지원한다.



무료로 사용할 수 있는 HAProxy Community Edition이 있으며, 기업을 대상으로는 로드밸런서 HAProxy Enterprise Edition를 제공한다. 추가로 ALOHA Load Balancer는 하드웨어 장비에 HAProxy를 결합해서 판매하는 상품이다.


마이크로서비스로 아키텍처를 사용할수록 진입점이 많아지게 되는데, 이 부분을 HAProxy를 사용하면 효과적으로 관리할 수 있다.

GitHub, Instagram, Stackoverflow, Tumblr, Amazon web service, Openstack등 글로벌 기업들도 많이 사용하고 있다.


HAProxy Community Edition을 설치해보도록 하겠다. 사용하려면 아래 모듈이 설치되어 있어야 한다.


yum install gcc gcc-c++ pcre-devel openssl-devel


준비가 완료되면 아래 명령어를 이용하여 설치한다. Https 사용이 필요하다면 USE_OPENSSL 옵션을 활성화하도록 한다.


wget http://www.haproxy.org/download/1.8/src/haproxy-1.8.3.tar.gz
tar zxvf haproxy-1.8.3.tar.gz
make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 
make PREFIX=/usr/local/haproxy DESTDIR= install


설정은 global, defaults, frontend, backend, listen 총 5가지 그룹으로 관리된다.



global은 프로세스 전체에 적용된다. 모든 영역에 적용하려는 값만 선언해야 한다.

defaults는 frontend, backend, listen 3가지를 선언했을 때 기본적으로 적용되는 옵션이다. 진입점을 1개만 선언해서 사용할 때에는 기본값에 명시해도 되지만, 진입점이 여러 개인 경우 각각 선언하는 편이 좋다.


frontend는 진입점을 선언하는 곳이며, 조건이 일치하는 경우 backend로 연결해주는 역할을 한다.

backend는 frontend가 실질적으로 연결할 server들을 선언하여 관리한다.


listen은 frontend, backend를 합쳐서 선언할 수 있다.


실제로 설정을 frontend, backend 2가지를 나눠서 하는 편이좀 더 명확한 것 같다. 


설치가 완료되면 /etc/haproxy.cfg을 생성하고 아래 샘플을 참고하여 작성하자.

실제 테스트 하면서 작성했던 설정 값이며, 필요한 옵션만 간략하게 정리하였다.


global
        daemon # 백그라운드에서 동작
 
        user    haproxy 
        group   haproxy
        log     127.0.0.1   local0
        log     127.0.0.1   local1 notice
        maxconn 4096 # 프로세스 별 최대 connection 갯수
 
        ssl-default-bind-options no-sslv3 # Bind SSL 프로토콜 정의
        ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:... # Bind SSL 사용 알고리즘 목록 정의
 
        ssl-default-server-options no-sslv3 # Server SSL 프로토콜 정의
        ssl-default-server-ciphers ECDHE-RSA-AES128-GCM-SHA256:... # Server SSL 사용 알고리즘 목록 정의
 
        tune.ssl.cachesize 100000 # SSL Session Cache 크기 설정
        tune.ssl.lifetime 600 # SSL Session 유효시간 설정
        tune.ssl.default-dh-param 2048 # Diffie-Hellman 키 교환 시 최대 크기 설정
 
defaults
        maxconn 4096 # 프로세스 별 최대 connection 갯수
 
frontend https-in
        mode    http
        log     global
        option  httplog
        option  dontlognull
 
        bind *:80 # listening 되어야하는 ip, port 설정
        bind *:443 ssl crt ./key.pem ca-file ./key.ca verify optional alpn h2,http/1.1 # (listening 되어야하는 ip, port + ssl + http/1.1, http/2) 설정
 
        timeout client  30s # client에서 haproxy 접속 시 timeout 설정
        timeout http-keep-alive 5s # 새로운 http 요청이 들어오기까지의 대기시간
 
        # host 지정 모든문자열이 일치 할 경우
        acl stats hdr(host) -i test.haproxy.com 
        acl host_api_cluster hdr(host) -i test.server.com
 
        # host가 일치할 때 지정 된 backend로 진행
        use_backend haproxy_stats if host_haproxy_stats 
        use_backend test_server if host_api_cluster
 
backend stats
        mode    http
        log     global
        option  httplog
        option http-server-close # 응답이 완료되면 server 측에서 연결을 종료함
 
        stats enable # 모니터링 활성화
        stats auth id:password # 모니터링 인증 활성화 basic auth 아이디, 비밀번호 설정
        stats uri /stats # 모니터링 페이지 url 설정
        stats hide-version # 버전 숨김
 
backend test_server
        mode    http
        log     global
        option  httplog
 
        balance leastconn # 요청 분배 알고리즘 설정
 
        timeout connect 10s # haproxy에서 server 접속 시 timeout 설정
        timeout check   5s # haproxy에서 check 목적으로 접속 시 timeout 설정
        timeout server  30s # haproxy에서 server 접속 시 timeout 설정
        timeout http-keep-alive 5s # 새로운 http 요청이 들어오기까지의 대기시간
 
        acl valid_method method GET POST PUT DELETE # 허용할 메소드 설정
        http-request deny if ! valid_method # 메소스 조건 확인
 
        http-request replace-value Host (.*):.* 1 # server에 client에서 요청한 Host 전달
        http-request set-header x-forwarded-for %ci # server에 remoteAddress 전달
 
        option httpchk GET /status # server에 지정된 상태 체크 url로 요청하여 확인
        http-check expect status 200 string OK # 응답 시 상태코드 200 + 문자열 OK 확인
 
        default-server inter 100 rise 2 fall 5 # 검사 조건 (확인 주기 100/ms, 2번이상 성공시 정상 확인, 5번이상 실패 시 제외)
        server server-001 192.168.0.1:8080 check # 서버 alias, ip:port, 검사 여부
        server server-002 192.168.0.2:8080 check 
        server server-003 192.168.0.3:8080 check


작성이 완료되었다면 /usr/local/haproxy/sbin/haproxy -f /etc/haproxy.cfg 명령어를 입력하여 시작하자.

자세한 내용은 http://cbonte.github.io/haproxy-dconv/ HAProxy 1.8 Documentation를 참고 하도록한다.


참고 사이트

  • http://www.haproxy.org/
  • http://www.haproxy.com/
  • http://cbonte.github.io/haproxy-dconv/
  • https://networkel.com/osi-model-7-layer-network-communication/
  • http://d2.naver.com/helloworld/284659
  • https://www.haproxy.com/documentation/aloha/7-0/traffic-management/lb-layer7/health-checks/
  • https://www.haproxy.com/blog/ssl-client-certificate-management-at-application-level/
  • https://www.haproxy.com/documentation/aloha/6-5/haproxy/tls/
  • http://inor.tistory.com/35
  • https://www.haproxy.com/blog/haproxy-amazon-aws-best-practices-part-1/


+ Recent posts