HAProxy를 이용한 Internal Load Balancer 구성

유의사항

Jeong. Deoksu
Oct 5, 2016 · 17 min read

아래의 원문을 스터디 목적으로 따라하면서 작성한 문서여서 용어도 부정확하고 읽기에 거북할 수 있습니다.

따라하면서 배울 수 있는 무엇?

  • load balancer가 무엇인지 대충 알 수 있다.
  • Compute Engine에서 gcloud 명령으로 instance를 배포하는 방법과 instance 배포 시 외부 IP를 할당하지 않는 방법을 알수 있다.
  • image와 template 생성하는 방법을 알 수 있다.
  • instance groups를 만드는 방법을 알 수 있다. (중요)
  • 가장 기본적인 HAProxy 설정을 알 수 있다.
  • instance-instance ssh 접속 방법을 알 수 있다.
  • systemd를 이용한 서비스 자동 재시작 방법을 알 수 있다.

원문

load balancer는 들어오는 네트워크 트래픽을 받아서 애플리케이션 서버 그룹에 배포한다. 예를 들면 Google Compute Engine Load Balancing service는 인터넷으로 들어오는 네트워크 트래픽을 Compute Engine instances 그룹으로 배포한다.

아래 그림은 Compute Engine Network Load Balancing이 어떻게 운영되는지 보여준다.

internal load balancer는 인터넷에 노출되지 않은 private network에 트래픽을 분배한다. internal load balancer는 모든 트래픽이 private network에서 흐르는 구조에서도 유용하지만 frontend Server가 요청을 받아서 private network에 있는 backend server들에게 보내는 복잡한 웹 애플리케이션에 더 유용하다.

Compute Engine에서는 software load balancer를 사용하여 internal load balancer를 구성할 수 있다. 여기서는 Compute Engine instance에 open source software load balancer인 HAProxy를 사용하여 구성한다.

아래 그림은 Google Cloud Platform에서 internal load balancer로 HAProxy를 어떻게 사용하는지 보여준다.

위의 그림처럼 instance 위에서 internal load balancer로 HAProxy를 운영하면 internal load balancer가 단일 장애 지점(single point of failure)이 된다.

이를 완화하기 위하여 아래와 같이 Instance가 문제가 있을 때 새로 배포하고 HAProxy Service에 오류 발생하면 서비스를 재시작하는 기능을 추가한다.

  • Instance Group Manager가 HAProxy’s Compute Engine instance의 상태를 모니터링하고 있다가 해당 instance가 멈추면 새로 배포한다.
  • HAProxy load balancer service가 항상 동작하도록 보증하기 위해서 systemd를 이용해 오류 이벤트가 발생하면 HAProxy service를 재시작한다.

목표

  • 3대의 Apache Backend Server 구성
  • HAProxy가 운영되고 있는 Compute Engine instance를 managed instance group로 구성
  • 테스트를 위해 외부 IP를 가지는 Compute Engine micro instance 구성
  • backend Apache server들에게 트래픽을 전달할 수 있도록 HAProxy 설정

참고

  • Unmanaged Group 인스턴스를 수동으로 묶어 놓은 그룹이다. 인스턴스의 크기나 종류에 상관 없이 그냥 묶어만 놓은 것이다. 수동으로 아무 종류의 인스턴스나 추가해넣을 수 있기 때문에 오토 스케일링은 불가능하다. 비관리 그룹을 이해하려면 반대로 관리 그룹 개념을 이해하면 쉽다.
  • Managed Group 템플릿을 만들어 인스턴스 생성을 클라우드가 담당하게 한다. 인스턴스는 사용자가 직접 추가할 수 없다. 템플릿이란 인스턴스를 만들기 위한 틀과 같은 것이다. VM의 크기, OS 이미지 등의 설정을 미리 정해놓으면, 클라우드가 인스턴스를 생성할 때 해당 템플릿이 정의한 설정에 따라서 인스턴스를 추가하게 된다.

사전에 해야 할 일

  • Google Compute Engine API와 Google Compute Engine Instance Groups API를 사용 가능(ENABLE)하게 설정한다.
me@local:~$ gcloud config set project project-id
me@local:~$ gcloud config set compute/zone my-zone

backend Apache server Group 생성

Apache Server가 포함된 custom instance 생성

debian-8을 기반으로하는 Compute Engine instance 생성한다.

gcloud compute instances create apache-base --image debian-8

생성된 instance에 Apache2를 설치한다.

me@local:~$ gcloud compute ssh apache-base
apache-base:~$ sudo apt-get update && sudo apt-get install -y apache2
apache-base:~$ exit

boot disk를 남겨두고 생성했던 instance를 삭제한다.

me@local:~$ gcloud compute instances delete apache-base --keep-disks boot

아래와 같이 instance는 삭제되었지만 apahce-base의 disk는 그대로 있다.

위의 디스크로 부터 이미지를 생성한다.

me@local:~$ gcloud compute images create apache-base-image --source-disk apache-base

custom image로 부터 backend Apache Server 3대 생성

me@local:~$ gcloud compute instances create apache1 apache2 apache3 --image \
apache-base-image --no-address --metadata startup-script='#! /bin/bash
HOSTNAME=$(hostname)
sudo cat << EOF | sudo tee /var/www/html/index.html
This is $HOSTNAME
EOF'
  • — no-address : 대상 instance가 외부 IP 가지지 않음
  • — metadata : startup script 포함 statrup script는 /var/www/html/index.html에 자신의 호스트 이름을 등록하여 각 backend apache server를 구별할 수 있도록 설정한다.

테스트를 위한 micro instance 생성

바로 전에 생성한 backend server들과 생성할 internal load balancer는 외부 IP가 없기때문에 외부 IP를 가지고 있는 micro instance를 생성하여 backend server들과 load balancer를 테스트할 것이다.

test instance 생성

me@local:~$ gcloud compute instances create test-instance --machine-type f1-micro

SSH로 test-instance 접속하여 curl 명령으로 backend web server 확인

gcloud compute ssh test-instanceme@test-instance:~$ curl apache1
me@test-instance:~$ curl apache2
me@test-instance:~$ curl apache3
me@test-instance:~$ exit

internal load balancer 생성

internal load balance의 단일 장애 지점의 위험을 줄이기 위해 Compute Engine instance과 HAProxy service에 대하여 서비스를 지속적으로 유지할 수 있는 방안을 마련할 것이다.

Compute Engine instance가 계속 가동되는 것을 보장하기 위하여 managed instance group를 사용한다. HAProxy instance가 managed instance group에 있으면 Instance Group Manage는 서버의 상태를 체크하여 만약 중지되면 새로 생성한다. Instance Group Manager는 gcloud compute instances 명령 (또는 Compute Engine API)으로 해당 instance를 중지시키거나 삭제할 때 조차도 다시 생성한다. 그러나 gcloud compute instance-groups managed delete-instances 명령 (또는 Instance Group Manager API)을 사용하여 해당 instance를 삭제한다면 더 이상 다시 생성되지 않는다.

HAProxy instance base image 생성

debian-8을 기반으로 Compute Engine instance 생성한다.

me@local:~$ gcloud compute instances create haproxy-base --image debian-8

HAProxy를 설치한다.

me@local:~$ gcloud compute ssh haproxy-base
haproxy-base:~$ sudo apt-get update && sudo apt-get -y install haproxy

아래와 같이 backend server 리스트를 HAProxy configuration에 추가를 통해 HAProxy를 설정한다.

haproxy-base:~$ echo -e "\n\n# Listen for incoming traffic
listen apache-lb *:80
    mode http
    balance roundrobin
    option httpclose
    option forwardfor
    server apache1 internal-ip:80 check
    server apache2 internal-ip:80 check
    server apache3 internal-ip:80 check" | sudo tee -a /etc/haproxy/haproxy.cfg

위 설정 중 internal-ip는 backend server의 Internal IP를 설정한다.

HAProxy service 가 언제나 재시작하도록 설정

haproxy-base:~$ sudo vi /lib/systemd/system/haproxy.service

아래 설정 확인하여 없으면 추가한다.

[Service]
Environment=CONFIG=/etc/haproxy/haproxy.cfg
...
Restart=always

custom image 생성

boot disk를 남겨두고 생성했던 instance를 삭제한다.

me@local:~$ gcloud compute instances delete haproxy-base --keep-disks boot

source disk로부터 custom image를 생성한다.

me@local:~$ gcloud compute images create haproxy-base-image --source-disk haproxy-base

HAProxy instance template 생성

me@local:~$ gcloud compute instance-templates create haproxy-template \
 --image haproxy-base-image --no-address

— no-address옵션으로 template를 생성하면 외부 IP를 할당하지 않는다.

haproxy란 이름으로 managed instance group 생성

me@local:~$ gcloud compute instance-groups managed create haproxy \
--base-instance-name haproxy-server --size 1 --template haproxy-template

— base-instance-name 옵션은 Instance Group Manager가 instance를 생성할 때 할당되는 이름를 설정한다. 통상적으로 haproxy-server-xxxx 이런 형식의 이름이 생성된다.

HAProxy 이름 확인 및 load balancer 테스트

HAProxy instance의 이름을 확인 후 test-instance에 SSH로 접속한다.

me@local:~$ gcloud compute instances list | grep -oE "haproxy-server-[a-z0-9]{4}"
me@local:~$ gcloud compute ssh test-instance

test-instance에서 curl 명령으로 웹서버가 정상적으로 동작하는지 확인한다.

me@test-instance:~$ curl haproxy-server-xxxx

haproxy.cfg 설정에 balance를 roundrobin으로 되어 있어서 curl 명령어 실행 시 apache1 부터 차례로 호출되는 것을 볼수 있다.

load balancer 복구 테스트

HAProxy instance 테스트

gcloud compute instances 명령으로 HAProxy instance를 중지시키고 haproxy-server-xxxx란 이름으로 HAProxy instance가 교체되는 지 확인한다.

me@local:~$ gcloud compute instances stop haproxy-server-xxxx

몇분을 기다린 후 HAProxy instance가 정상적으로 동작하는 지 확인한다.

me@local:~$ gcloud compute instances list

test-instance에 접속해서 HAProxy instance가 정상적으로 동작하는 지 확인한다.

HAProxy service 테스트

HAProxy service를 테스트하기 위해서 test-instance에 SSH로 접속 후 HAProxy instance로 SSH 접속한다. instance to instance ssh 접속을 하기 위해서는 아래 과정을 거쳐야 한다.

아래와 같이 instance to instance ssh 설정을 한다.

me@local:~$ eval `ssh-agent`
me@local:~$ ssh-add ~/.ssh/google\_compute\_engine

ssh-flag 옵션을 사용하여 test-instance에 접속한다.

me@local:~$ gcloud compute ssh test-instance --ssh-flag="-A"

test-instance에서 haproxy-server-xxxx instance으로 SSH 접속을 한다.

me@test-instance:~$ ssh haproxy-server-xxxx

haproxy server가 Active 상태인지 확인한다.

me@haproxy-server-xxxx:~$ sudo service haproxy status | grep Active

HAProxy server process를 강제로 종료시킨다.

me@haproxy-server-xxxx:~$ sudo pkill haproxy

HAProxy service가 다시 실행되었는지 확인한다.

me@haproxy-server-xxxx:~$ sudo service haproxy status | grep Active

수정이 필요하거나 오류가 있는 곳을 알려주시면 친절하게 수정하도록 하겠습니다.

GCP에 Internal Load Balancer가 베타버전으로 공개되었다고 합니다. 이제는 HAProxy를 직접 설치할 일은 없겠네요.