반응형
 
구글클라우드 Compute Engine(VM)을 워크로드에 맞추어 Autoscaling 하는 방법에 대한 가이드입니다.
 
 
Autoscaling 기능 자체의 개념은 간단하지만, 실제 운영 환경에서 원하는 Autoscaling이 장점을 얻기 위해서는 다음과 같은 과정을 잘 따라야 합니다.
특히 Autoscaling에 사용되는 정책은 최대한 보수적(가능하면 부하보다는 높은 용량 유지) 이해해야 실제 VM의 개수가 증가하고 감소하는 현상에 대한 납득이 가능하기도 합니다.
 
0.Autoscaling 환경 아키텍처
 
먼저 Autoscaling에 사용되는 주요 컴포넌트와 설정들을 도식화한 것입니다. 
Autoscaling 기능은 주로 Load Balancer와 같이 사용되지만, 반드시 그래야 하는 것은 아닙니다. Autoscaling 기능은 Instance Group에서 설정을 하도록 되어 있습니다.
  • Instance Group: 동일한 VM들의 집합으로서 Instance Template을 통해서 새로운 VM을 생성할 수 있음
  • Instance Template: VM을 만들기 위한 Template으로서 기본적으로 어떤 운영체제(VM) Image를 사용할지 지정하고, 그 외에도 리전/존, 머신 타입, 네트워크 구성 등을 미리 정함
  • Health Check: Instance Group 내에서 VM이 기동되면 해당 인스턴스가 정상적으로 업무 처리가 가능한지 검사하는 기능. TCP 포트만 체크할 수도 있고, HTTP 요청을 통해 실제 성공적인 응답이 오는지 체크할 수도 있음
  • Autoscaler: Instance Group 설정 내에 포함되어 그룹 내 VM 인스턴스의 개수를 자동으로 조절(scaling)하는데 사용되는 정책이자 조건. 기본적으로 CPU 점유율이나 요청의 개수(초당 또는 분당)를 기반으로 scaling 가능하며, Stackdriver의 모니터링 metric을 사용한 scaling도 가능 함. Stackdriver는 CPU 사용률은 물론 네트워크 트래픽, 디스크 사용량 등 다양한 metric을 수집할 수 있고, Custom metric을 만들어 애플리케이션 specific한 조건을 사용할 수도 있음 (예: 자체 큐에 쌓여 있는 메시지의 개수)
  • VM Image: Instance Template에 지정하며 생성될 VM의 Base Image를 지정. GCP에서 제공하는 기본적인 운영체제(예: CentOS, Window)를 사용할 수도 있지만 VM에 필요한 소프트웨어들을 설치하여 Custom Image를 만들어 사용할 수도 있음
 
 
Instance Group은 독립적으로도 동작이 가능하지만 실제로 많은 경우는 클라이언트의 요청을 배분하는 Load Balancer에 연결하여 사용하게 됩니다. Load Balancer는 클라이언트의 요청을 받아 Backend 설정을 통해 Instance Group으로 요청들을 분배 및 전달하게 됩니다
 
  • Cloud Load Balancer: 클라이언트의 요청을 받는 Frontend와 해당 요청을 처리할 Backend를 가지고 있으며, Backend에는 Static 컨텐츠를 처리하는 CDN과 Dynamic 컨텐츠를 처리하기 위한 VM들의 Instance Group이 올 수 있음
  • Frontend: 클라이언트의 요청을 받는 수신 프토로콜을 지정. TCP, HTTP, HTTPS, UDP 등이 가능
  • Backend: 실제로 요청을 처리할 CDN이나 Instance Group을 연결. 하나 이상의 Backend를 연결하여 여러 Region이나 여러 Zone에 있는 Instance Group을 통해 요청을 분산 처리하게 할 수 있음. Ausoscaler에서 Instance Group 안에 포함된 VM들의 scaling 조건에 부가적으로 Max CPU Utilization, Max RPS, Capacity 등의 조건을 지정할 수 있음 (적용 방법은 아래에서 설명)
 
아래에서는 실제 테스트 프로젝트를 통해 Autoscaling 기능과 Load Balancer를 설정하는 방법에 대해 알아봅니다.
 
1.인스턴스 Image 준비
 
먼저 Google Cloud Console(http://console.cloud.google.com)에서 서비스에 사용할 VM을 생성하고 필요한 소프트웨어를 설치합니다. Autoscaling을 사용하게 되면 VM이 자동으로 기동되어 관리자가 개입 없이도 서비스가 가능해야 하므로, 부팅 스크립트 등을 통해 요청 처리에 필요한 모든 과정이 이루어지도록 해야 합니다. 여기서는 CentOS 7 이미지에 Apache HTTPD를 설치해서 서비스 하도록 테스트합니다.
 
sudo yum install httpd
 
sudo vi /var/www/html/index.html
# 임의의 HTML 컨텐츠 추가
 
curl http://loalhost
# HTML 정상 서비스 여부 체크
 
sudo chkconfig httpd on
# HTTPD 부탕 시 자동 실행
 
 
그리고 VM에 대한 기본적인 모니터링은 물론, Stackdriver를 통한 Autoscaling 기능을 활용을 위해서는 Stackdriver Monitoring Agent가 미리 설치되어야 합니다. Stackdriver Monitoring Agent 설치는 다음 문서를 참고합니다.
 
 
VM이 정상적으로 요청을 처리할 수 있는지 확인이 되면 VM을 정상 종료하고 Image로 생성합니다.
 
 
 
2.VM 생성용 Instance Template
 
VM Image가 만들어졌으면, 해당 Image 기반으로 VM이 기동되었을 때 필요한 디스크, 네트워크, 보안 등에 대한 설정을 Instance Template으로 생성합니다. SSH 로그인이 필요하면 SSH Public Key도 등록합니다.
 
 
3.Instance Group 생성
 
앞에서 생성된 Instance Template을 기반으로 Instance Group을 생성합니다. 생성할 VM Instance의 리전(region), 존(zone)도 결정합니다. 그리고 Autoscaling 조건을 지정하는데, 이번 테스트에서는 CPU 사용률이 40% 이상(Instance Group 내 VM들의 CPU 사용률 총합을 VM 개수로 나눈 결과)이면, 최대 10대까지 증가하도록 합니다. Autoscaling 조건은 VM 기동 후 60초(Cool down period)가 지난 시점(VM 시작 직후에는 CPU 사용률이 높을 수 있으므로)부터 수집합니다.
 
 
Instance Group 생성 화면의 하단에서는 Health Check 조건을 생성 및 지정할 수 있는데, 앞에서 말한 것처럼 Health Check는 동작 중인 VM이 실제 업무 요청을 처리할 수 있는지(GCP uses the overall health state of each VM to determine its eligibility for receiving new requests) 조건을 지정하는 것입니다. Health Check는 VM 기동 후 30초(Initial delay)가 지난 시점부터 체크합니다.
 
여기서는 다음과 같은 조건의 Health Check를 생성합니다.
 
  • Protocol: HTTP
  • Port: 80
  • Port Specification: Fixed port
  • Request path: /
  • Healthcheck 옵션 가이드: Fixed port (옵션이 내용은 아래 참고. --port가 Fixed port에 해당)
  • 10초 마다 체크해서 5초 내로 응답이 2회 오면 정상으로 판정... 3회 이상 오지 않으면 실패로 판정
 
다음은 위의 조건을 기반으로 생성된 Health Check입니다.
 
 
Instance Group을 생성하면 다음과 같이 실제 런타임 상의 변화가 발생합니다. 먼저 Minimum number of instances가 1이므로 하나의 VM이 생성됩니다.
 
 
그리고 나서 Autoscaling 기능을 테스트 하기 위해 첫 번째 VM에 SSH로 접속해서 부하를 발생시킵니다.
 
stress --cpu 1
 
그러면 아래와 같이 추가로 VM들이 기동되는데 이유는 총 4개의 VM이 각각 40%의 용량(Target CPU usage)을 가지고 있으므로 40% * 4 = 160% 가 전체 Instance Group의 용량입니다. 그리고 현재 하나의 VM이 100% CPU 사용 중이므로 100% 이상의 용량을 가진 Instance Group을 만들기 위해 늘린 것입니다. 다만, 3개의 VM만 띄워도 120%이기 때문에 현재 사용량을 넘어서지만, Autoscaler는 VM 기동 시간 동안 처리가 안된다는 보수적으로 관점에서 필요한 용량보다 더 많은 VM을 띄우게 됩니다. 이렇게 넘치는 용량은 Cooling down 과정을 통해 다시 줄어들게 됩니다.
  • Gaps between target and actual utilization
    • scale up을 할 때 부족한 것을 방지하기 위해 aggressive 하게 진행 (통상 필요한 VM 보다 더 많이 생성)
 
 
위에서 설명한 Instance Group의 용량과 실제 부하는 GCP Console의 Instance Group 모니터링 탭에서 확인할 수 있습니다.
 
다시 한 번 테스트를 위해 4개의 VM 중 두 번째 VM에 접속해서 역시 부하를 주게 되면, 다음과 같이 9개의 VM이 생성되었다가 시간이 지나면 cooling down 과정을 통해 8개로 정리가 됩니다.
 
 
Cooling down 과정 즉, 부하가 줄어들어 VM Instance를 줄이는 과정을 테스트 하기 위해 2번 VM에서 부하를 중지합니다.
 
 
Cooling down 과정은 바로 발생하지 않고 최대한 보수적으로 10분을 기다렸다가 진행하며 위의 그래프를 보면 10분 후에 VM의 개수가 줄어드는 것을 확인할 수 있습니다. 이러한 Cooling down 과정에서 VM이 셧다운될 때 graceful한 종료를 위해 VM의 Shutdown 스크립트를 등록하여 진행 중인 트랜잭션을 정리하는 과정을 넣어주는 것이 좋습니다.
 
[참고] Instance Template을 중간에 변경
 
운영 중인 Instance Group의 Instance Template을 변경(즉, VM을 변경)하게 되면 새로 만들어지는 VM에 대해서만 적용이 되며, 현재 실행 중인 VM들은 영향을 받지 않습니다.
 
 
[참고] Rolling Update 기능
 
여러 개의 Instance Template을 지정하여 종류가 다른 VM 간의 A/B Test나 Canary Test 등을 진행할 수 있는 기능입니다.
 
 
[참고] Rolling Restart/Replace
 
현재 운영 중인 VM들을 재시작 하거나, 새로 지정된 Instance Template 기반의 VM으로 점진적으로 교체합니다.
 
 
4.Load Balancer 생성
 
Instance Group에 외부 클라이언트로부터의 요청을 전달하기 위해 Load Balancer를 생성합니다. 생성 가능한 종류는 다음과 같으며 각각의 기능은 다음 문서를 참고하시기 바랍니다. 여기서는 HTTP Load Balancer를 선택합니다.
 
 
Load Balancer는 크게 Frontend 구성과 Backend 구성으로 나뉘며 생성할 Backend의 내용은 다음과 같습니다.
  • Name: autoscale-vm-a2-be
  • Instance Group으로 위에서 만든 것을 지정
  • Maximum CPU utilization: 100% (Instance Group의 조건을 override 하지 않기 위해)
  • Maximum RPS(Request Per Seconds): N/A
  • Capacity: 100% (Instance Group의 조건을 override 하지 않기 위해)
  • Health Check: Instance Group의 것과 동일한 것 선택
  • Session Affinity: Generated Cookie, 쿠키를 생성해서 그것으로 추적
  • HTTP 서버를 운영 중이므로 80번 포트를 통해서 접속
 
다음은 Instance Group에 지정한 Autoscaling 기능과 유사한 역할을 하는 Backend 설정에 대한 설명입니다.
 
==> Balancing Mode: 어떤 부하를 기준으로 요청을 분배할지... 만약 Max CPU/RPS+Capacity에 지정된 모든 용량이 찼다면 지정된 정책에 따라 적은쪽으로 분배
 
==> Max CPU utilizationBackend Instance Group의 모든 VM들의 평균으로... 복수의 Backend를 둘 경우 허용 가능한 부하 
   Capacity에 차지 않았으면 Instance Group으로 하여금 VM을 증설하도록 하지만, 만약 Capacity에 찼다면 다른 Region이나 Instance Group으로 요청 포워딩
   Instance Group의 Auoscaler에 Target CPU Usage가 80%, LB의 Max CPU가 80%라면 Instance Group의 평균 CPU가 80% * 80% = 64% 일 때 새로운 VM 생성
   결국 Instance Group의 설정에 영향을 주고 싶지 않다면 Max CPU와 Capacity를 100%로 지정
   단, 모든 Backend가 100% 라면 Balancing Mode에 지정된 규칙대로 부하가 적은쪽으로 분배
 
==> Maximum RPS: backend의 instance group으로 갈 수 있는 최대 RPS(Request per second)
 
==> Capacity(CPU, RPS): Max CPU, Max RPS에 부가적인 용량 제어... Max CPU 80%임에도 절반의 CPU만 사용하고 싶다면 여기를 50%로 함. 설정을 override 하고싶지 않다면 100%를 지정
 
Frontend는 다음과 같은 내용으로 생성합니다. 일반적인 HTTP(80) 서비스입니다.
 
  • Frontend
  • Name: autoscale-vm-a2-fe
  • Protocol: HTTP
  • 두 개 이상의 Frontend 생성 가능
 
다음은 Load Balancer를 생성한 직후의 모습입니다.
 
 
Backend VM이 정상 준비(Health Check까지 완료)된 모습입니다.
 
 
 
[참고] 커맨드를 사용한 TCP Health Check 생성
 
TCP Health Check 생성
[jerryj@jerrydev load-balancing-scaling]$ cat create_tcp_healthcheck.sh
gcloud compute health-checks create tcp hc-tcp-80 \
    --project jerry-vpc-test \
    --description="Health check: TCP 80" \
    --check-interval=5s \
    --timeout=5s \
    --healthy-threshold=2 \
    --unhealthy-threshold=2 \
    --port=80
 
[참고] TCP Load Balancer 생성
 
Backend 구성 내용입니다. Health Check는 TCP 용으로 새로 만들었습니다.
 
 
Frontend 구성 내용입니다.
 
 
 
5.Stackdriver Metric으로 Scaling 하는 방법
 
다음은 Stackdriver의 metric 그 중에서도 특정 NIC 카드의 네트워크 트래픽을 기준으로 autoscaling을 하는 방법입니다.
 
먼저 VM에 Monitoring Agent를 설치하는 방법으로 이미 위에서 VM Image 생성 단계에서 완료한 내용입니다.
 
 
sudo chkconfig stackdriver-agent on
 
 
[jerryj@autoscale-vm-a2-1 ~]$ gcloud auth list
                  Credentialed Accounts
ACTIVE  ACCOUNT
 
다음은 VM의 Service Account가 Monitoring Metric Write 가능하도록 하는 것인데, IAM에서 확인한 아래의 예에서는 Project Editor 권한이 있어 가능합니다.
 
만약 안되면 다음과 같이 IAM에서 Service Account에 권한을 부여해야 합니다.
 
다음 두 개의 권한으로 Account 생성 후 Key 파일 다운로드
 
다음 경로로 Key 파일 복사
 
자 그러면 이번에는 Stackdriver 모니터링 기능을 통해 autoscaling에 사용할 metric을 찾습니다.
 
GCP. Console의 Stackdriver 모니터링 화면
  • Resources ==> Instances ==> VM ==> Network Traffic (또는 Metric Explorer에서 더 다양한 모니터링 항목 선택 가능)
  • 네트워크 부하를 주었을 때 아래 분홍색 그래프처럼 수치가 증가하는 것이 보임
 
Instance Group의 Autoscaling 부분에서 Stackdriver monitoring metric을 선택한 후 다음과 같이 설정합니다.
 
 
Metric identifier에서는 다음을 지정합니다. "traffic"이라고만 치면 조회가 됩니다.
  • agent.googleapis.com/inerface/traffic
 
Utilization target type에서는 Gauge를 선택합니다.
  • Gauge: 최근 몇 분간 수집된 데이터들의 평균 값
  • [참고] 아래와 같은 옵션들이 있습니다.
 
Additional filter expression for metric labels에는 다음을 입력하여 VM 내 여러 개의 NIC 중에서 eth0의 Outbound 트래픽만을 선택합니다.
  • metric.label.device=eth0 AND metric.label.direction=tx
 
다음은 입력한 결과입니다.
 
 
Instance Group의 모니터링 탭을 보면 아래와 같이 autoscaling이 동작할 네트워크 트래픽의 기준점이 1M(1,048,576)임이 보입니다.
 
 
다음과 같은 curl 명령과 쉘스크립트로 부하를 발생시켜 네트워크 트래픽 기반의 autoscaling 기능을 확인합니다.
 
부하 발생
  • GLB로 부하 발생
[jerryj@jerrydev load-balancing-scaling]$ cat load_generate.sh
while true
do
curl -s -o /dev/null 35.227.216.228
done
 
 
 
 
 
 
Posted by Hey Jerry
,