HAProxy를 이용한 Internal Load Balancer 구성 따라하기

유의사항

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

원문 : https://cloud.google.com/solutions/internal-load-balancing-haproxy

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

load balancer는 들어오는 네트워크 트래픽을 받아서 애플리케이션 서버 그룹에 배포합니다. 예를 들면 Google Compute Engine Load Balancing service는 인터넷으로 들어오는 네트워크 트래픽을 Compute Engine instances 그룹으로 배포합니다.
아래 그림은 Compute Engine Network Load Balancing이 어떻게 운영되는지 보여줍니다.

Imgur

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를 어떻게 사용하는지 보여줍니다.

Imgur

위의 그림처럼 instance 위에서 Internal load balancer로 HAProxy를 운영하면 Internal load balancer가 단일 장애 지점(single point of failure)이 되므로 이를 완화하기 위하여 아래와 같이 instance 자체에 문제가 발생할 때 해당 instance를 새롭게 배포하고 HAProxy Service에 오류 발생하면 서비스를 재시작할 수 있도록 기능을 추가합니다.

  • Instance Group Manager가 HAProxy의 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 Cloud Platform Console에서 project를 새로 생성합니다. Imgur

Google Compute Engine API와 Google Compute Engine Instance Groups API를 사용 가능(ENABLE)하게 설정합니다.
Imgur

Google Cloud SDK를 설치한 후 project 및 region, zone을 설정합니다.

me@local:~$ gcloud config set project project-id  
me@local:~$ gcloud config set compute/zone my-zone  

Imgur

backend Apache server Group 생성

Apache Server가 포함된 custom instance 생성

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

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

Imgur

생성된 instance에 Apache2를 설치합니다.

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

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

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

Imgur

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

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

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

Imgur

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를 구별할 수 있도록 설정합니다.

Imgur

테스트를 위한 micro instance 생성

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

f1-micro 타입의 test instance 생성합니다.

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

Imgur

SSH로 test-instance 접속하여 curl 명령으로 backend web server를 확인합니다.

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

Imgur

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  

Imgur

HAProxy를 설치합니다.

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

Imgur

아래와 같이 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를 설정합니다.

Imgur

Imgur

HAProxy service 가 언제나 재시작하도록 설정
haproxy-base:~$ sudo vi /lib/systemd/system/haproxy.service  

아래 설정을 확인하여 없으면 추가합니다.

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

Imgur

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  

Imgur

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

Imgur

--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 이런 형식의 이름이 생성됩니다.

Imgur

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  

Imgur

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  

Imgur

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

me@local:~$ gcloud compute instances list  

Imgur Imgur

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

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  

Imgur

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  

Imgur

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

GCP에 Internal Load Balancer가 베타버전으로 공개되었다고 합니다.
이제는 HAProxy를 직접 설치할 일이 많이 줄어들 것 같습니다.

https://cloud.google.com/compute/docs/load-balancing/internal/

Martin

Read more posts by this author.