EMD Blog

[GCP] Compute Engine에 대해 알아보자(2) - 스테이트리스 MIG 본문

Public Cloud/GCP

[GCP] Compute Engine에 대해 알아보자(2) - 스테이트리스 MIG

EmaDam 2022. 1. 7. 22:12

이전 포스팅에서 인스턴스를 만들어 봤으니 이제 MIG를 구성해보자. 

 

관리형 인스턴스 그룹(Manged Instance Group)

제목에 있는 MIG는 Managed Instance Group의 약자로 관리형 인스턴스 그룹을 말한다. GCP에서 인스턴스 그룹은 비관리형 인스턴스 그룹과 관리형 인스턴스 그룹으로 나뉘는데, 비관리형 인스턴스 그룹은 인스턴스를 묶은 것이다. 딱히 무슨 기능이 제공되는 것은 아니고 그냥 논리적으로 묶은 것 뿐이다. 이렇게 묶은 인스턴스 그룹은 로드밸런서를 연결할 수 있게 된다. 그럼 관리형 인스턴스 그룹은 뭐가 다를까? 관리형 인스턴스 그룹오토스케일링을 제공해주고 장애 복구 기능을 지원한다. 이 외에도 다양한 zone에 VM을 생성해 가용성을 높히거나 다양한 배포 옵션을 제공하기도 한다. 그리고 가장 중요한 것은 이렇게 가용성과 확장성을 그냥 제공하는 것이 아닌 자동화해서 제공한다. 따라서 우리는 옵션만 정해주거나 배포를 위해 약간의 코드만 작성하면 되는 것이다. 자세한 장점들은 이 문서를 보도록 하자.

 

그럼 비관리형과 관리형 인스턴스의 인스턴스 생성 방식의 차이를 먼저 보고 가자. 비관리형은 이미 만들어 놓은 인스턴스들을 인스턴스 그룹을 만들어 묶는다.(인스턴스 그룹도 하나의 리소스다.) 하지만 관리형 인스턴스 그룹은 생성할 인스턴스를 템플릿으로 정의 해놓고 인스턴스 그룹을 생성할 때 템플릿을 지정해 놓으면 MIG가 해당 템플릿으로 알아서 인스턴스를 만든다. 관리형 인스턴스는 인스턴스 템플릿을 기반으로 VM 인스턴스를 생성한다는 점은 꼭 명심하고 넘어가자.

 

그럼 관리형 인스턴스 그룹의 중요한 요소인 상태에 대해 알아보도록 하자. 관리형 인스턴스 그룹은 스테이트풀(Stateful)과 스테이트리스(Stateless)로 나뉜다. 스테이트풀인스턴스가 재생성되더라도 상태가 유지되는 것이고 스테이트리스재생성되면 상태가 바뀌는 것을 말한다. 일반적으로 MIG는 자동 복구를 하거나 오토스케일링을 할 때 템플릿을 기반으로 해서 인스턴스를 "재생성"한다. 오토스케일링의 경우는 인스턴스 간에 중복되는 정보(예를 들면 IP)가 있으면 안되기 때문에 어쩔 수 없이 정보가 다르게 돼서 생성되어야 하지만 자동 복구의 경우는 어떨까? MIG의 자동 복구는 이상을 확인하면 해당 인스턴스를 제거하고 새로운 인스턴스를 생성한다. 그렇기 때문에 자동으로 복구 되더라도 인스턴스 메타데이터나 IP등은 바뀌게 된다.(이름은 고정이다.) 이런 것들을 고정시켜서 재생성되더라도 정보를 유지된 상태로 생성되게 해주는 인스턴스 그룹 구성을 스테이트풀이라고 한다. 참고로 스테이트풀로 구성하려면 인스턴스 개수를 고정해야 한다. 왜냐하면 스테이트풀 구성은 한번 생성된 인스턴스에 대한 정보를 유지시켜 복구 시에도 그대로 가져가도록 하는 기능이기 때문에 사전에 인스턴스들이 미리 생성되어 있어야 한다. 

 

스테이트풀 : 오토스케일링 안됨 | 복구 시 인스턴스 정보 유지 o

스테이트리스 : 오토스케일링 가능 | 복구 시 인스턴스 정보 유지 x

 

여기서 정말 중요한 것은 스테이트풀이라고 해도 인스턴스 자체는 재생성하는 것이기 때문에 하드웨어 정보는 변경된다. 이것은 라이선스를 구매할 때 매우 중요하니 반드시 알고 있어야 한다.  

 

스테이트풀의 경우 별도의 설명 문서도 제공하고 있으니 한번 보도록 하자. 배포하려는 어플리케이션 특성에 따라 다르게 구성을 해야하기 때문에 이 둘의 차이점을 정확하게 알고 구성해야 한다. 

스테이트풀(Stateful) 관리형 인스턴스 그룹

 

MIG의 중요한 요소들을 확인했으니 이제 MIG를 구성하기 전에 고려할 부분을 체크해보자. 

 

- 배포 방식 : 왜 배포방식을 제일 먼저 언급했냐하면 관리형 인스턴스 그룹을 사용할 경우 인스턴스를 생성할 때 템플릿을 기반으로 자동 생성한다고 했었다. 그럼 새로운 버전의 어플리케이션을 배포할 때 어떻게 배포해야할까? 기존에 생성되어 있는 VM에 접속해 업데이트할 수는 없을 것이다. 그렇게 하면 오토스케일링 시 새로 생성된 인스턴스의 어플리케이션과 기존에 생성되어 있는 VM 내 어플리케이션 버전이 불일치하게 된다. MIG 구성시 CI/CD가 필수는 아니나 구성하지 않으면 기존에 VM에 배포하는 것보다 불편하니 이번 기회에 구성해보는 것을 추천한다. 

- 배포할 어플리케이션 : 배포할 어플리케이션이 어떤 특성을 가지는 지 확인해야 한다. 이 배포할 어플리케이션의 종류에 따라 스테이트풀로 구성할 수도 있고 스테이트리스로 구성할 수도 있으니 배포할 어플리케이션 특성을 보고 잘 선택해야 한다. 만약에 자신이 어떤 구성을 해야할 지 감이 잘 오지 않는다면 문서를 참고해보도록 하자.

- 오토스케일링 : 스테이트리스로 구성했다면 보통은 자동 확장 기능을 사용할 것이다. 자동 확장은 사용량을 기준으로 조정할 수 있지만 시간대에 맞춰서도 조정 가능하니 사용자들의 특성에 맞춰 구성하는 것이 좋다. 만약에 그룹웨어 같은 것을 운영한다고 하면 출퇴근 시간에 맞춰 확장과 축소를 진행하면 될 것이다. 

- 라이선스 : 위에서 한번 언급했었는데 MIG를 스테이트풀로 구성하더라도 하드웨어 정보는 달라지기 때문에 일반적인 라이선스를 적용하면 문제가 발생하는 경우가 종종 있다. 만약에 라이선스 체크를 MAC Address + 하드웨어 정보로 체크한다고 하면 MAC Address야 내부 고정 IP를 사용해 고정 가능하지만 하드웨어 정보는 고정이 불가능하다. 그러면 자동 복구 시 해당 소프트웨어가 작동하지 않는 사태가 발생하게 된다. 요즘에는 퍼블릭 클라우드를 사용하는 회사가 많아 대부분 업체에서 클라우드 용 라이선스를 제공해주는 경우가 많지만 아직 클라우드 라이선스를 제공하지 않는 업체도 많기 때문에 잘 체크하지 않으면 낭패를 보는 일이 생길 수 있다. 

 

이 외에도 체크해야할 부분이 많이 있지만 일단은 넘어가고 구성하면서 생각하도록 하자. 

 

관리형 인스턴스 구성하기

MIG는 리눅스 서버의 경우 스테이트리스, 윈도우는 스테이트풀로 구성할 것이다. 

 

먼저 스테이트리스 인스턴스 그룹을 구성해보자. 관리형 인스턴스 그룹은 인스턴스 템플릿을 기반으로 인스턴스를 생성하고 인스턴스의 상태를 확인해 자동 복구나 오토스케일링을 시작한다. 따라서 아래 세 가지에 대한 리소스를 생성해야 한다.

 

- 인스턴스 템플릿

- 상태 확인(health check)

- 인스턴스 그룹

 

제일 먼저 인스턴스 그룹을 생성해야 하는데 그 전에 이전 포스팅에서 만든 인스턴스를 처리해야 한다. 그냥 삭제해도 되지만 커스텀 이미지를 한 번 만들어 보는 것도 좋다. 이미지는 디스크나 스냅샷, 이미지, Cloud Storage 등 다양한 소스로부터 생성할 수 있는데, 이렇게 만든 이미지는 마이그레이션이나 배포에 필요한 요소들을 사전에 구성해 놓는 용도로 사용할 수 있다. 여기서 사전 구성의 경우 시작 스크립트를 사용할 수도 있는데, 이 부분은 해당 요소를 커맨드 라인으로 설치가 가능한 것인지, 시간이 오래 걸리지는 않는지, 자주 변경되는지 등을 고려해 적절하게 선택하면 된다. 무작정 이미지로 만들어버린다고 좋은 것은 아니니 명심하자. 

 

이미지는 아래의 명령어로 생성할 수 있다. 

gcloud compute images create 명령어

# study-web-dev-1 인스턴스의 부팅 디스크인 study-web-dev-1를 사용해 이미지 생성
gcloud compute images create ubuntu-study-v20220104 --source-disk study-web-dev-1 \
    --source-disk-zone asia-northeast3-a \
    --storage-location asia-northeast3 \
    --force

참고로 --source-disk에는 인스턴스 명이 아닌 디스크 이름이 들어가야 한다. 그리고 이미지는 사용 자체는 무료이지만 보관하는데 요금이 발생한다. 이미지 생성을 안 할거라면 그냥 그렇구나 하고 넘어가면 된다. 그리고 이전에 만든 인스턴스들은 삭제하도록 하자. 만약에 만들겠다 하면 그냥 만들지 말고 무언가 설정을 한 뒤에 이미지로 만들자. 

 

이전에 만들었던 인스턴스들의 정리가 끝났으니 이제 인스턴스 템플릿을 생성해보자. 인스턴스 템플릿은 아래 명령어로 생성할 수 있다. 

gcloud compute instance-templates create 명령어 

$ gcloud compute instance-templates create study-web-dev-1 \
--machine-type=f1-micro \
--image=ubuntu-minimal-2004-focal-v20211209 \
--image-project=ubuntu-os-cloud \
--boot-disk-size=10GB \
--boot-disk-type=pd-balanced \
--boot-disk-device-name=study-web-dev-1

위 처럼 명령어를 실행하면 아래처럼 잘 생성되는 것을 볼 수 있다.

NAME             MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
study-web-dev-1  f1-micro                   2022-01-04T04:33:09.369-08:00

위의 생성 명령어를 보면 느꼈을 수도 있는데 인스턴스 생성 명령어와 거의 동일하다. 사실 저 명령어도 이전 포스팅에서 복사해와서는 zone옵션만 제거한 것이다. 

 

템플릿을 성공적으로 생성했으면 이제 상태확인(Health Check)을 생성하자. 상태확인 말 그대로 인스턴스의 상태를 확인하는 리소스이다. 상태확인은 로드밸런서와 관리형 인스턴스 그룹에서 사용될 수 있다. 로드밸런서에서 사용하는 경우는 나중에 보고 일단 MIG에서 사용하는 경우 부터 살펴보자. 이 상태 확인은 상태를 확인하기 생성되어 있는 VM들에게 프로브라는 연결 시도를 수행하게 된다. 프로브라는 단어를 써서 어색하겠지만 그냥 트래픽을 보낸다고 생각하자. 그렇게 트래픽을 보내면 이 VM에서는 응답을 보내줄 것이고 그 응답을 체크해 VM내 서비스가 정상인지를 확인한다. 예를 들어 다음과 같이 설정할 수 있다. 

생성되어 있는 VM Instance에 /workcheck 경로로 30초마다 요청을 보내 응답코드로 200(성공)을 받으면 정상, 그 외의 응답을 2번 이상 반환하면 비정상.  

상태확인은 그냥 상태확인과 기존 상태확인이 존재한다. GCP 번역이 어색한 부분이 있어 헷갈릴 수도 있는데 GCP에서 말하는 대부분의 "기존"은 Legacy이다. 즉, 기존 상태확인은 옛날 버전 상태확인을 말한다. 그래서 두 상태확인은 지원하는 프로토콜에 차이가 있으니 아래 문서를 꼭 확인하자. 이 부분은 정상 여부를 판별하는 부분을 설정할 때 아주 중요하다.

 

상태확인 프로토콜과 포트

 

그럼 이제 상태확인을 만들어 보자. 상태확인은 어찌됐든 트래픽을 보내서 확인을 하기 때문에 방화벽의 영향을 받는다 . 그래서 먼저 상태확인이 VM에 접근할 수 있도록 프로브 소스의 IP대역을 허용해주어야 한다. 자세한 내용은 이 문서를 확인해보자 

gcloud compute firewall-rules create 명령어

$ gcloud compute firewall-rules create allow-http-ingress-from-healthcheck \
    --action allow \
    --direction ingress \
    --rules tcp:80 \
    --source-ranges 130.211.0.0/22,35.191.0.0/16
    
Creating firewall...done.
NAME                                 NETWORK  DIRECTION  PRIORITY  ALLOW   DENY  DISABLED
allow-http-ingress-from-healthcheck  default  INGRESS    1000      tcp:80        False

포트는 80만 허용해 주었다. 다른 포트로 상태확인을 하고 싶다면 추가로 열어주자. 

 

포트도 열었으니 상태확인을 생성하자. 아래 명령어를 사용하면 된다.

gcloud compute health-checks create http 명령어

$ gcloud compute health-checks create http http-health-check \
    --request-path=/ \
    --check-interval=30s \
    --port 80
    
Created [https://www.googleapis.com/compute/v1/projects/emadam-playground/global/healthChecks/http-health-check].
NAME               PROTOCOL
http-health-check  HTTP

위 상태확인은 / 경로로 30초에 한 번씩 트래픽을 보내겠다는 뜻이다. 별도로 성공 여부에 대한 옵션을 지정해주지 않으면 200 코드를 정상으로 판별한다. 

 

상태확인까지 만들었으니 MIG를 생성해보자. MIG는 아래 명령어로 생성할 수 있다. 

gcloud compute instance-groups managed create 명령어

gcloud compute instance-groups managed create study-managed-instance-group \
--base-instance-name=study-web-dev \
--template=study-web-dev-1 \
--size=1 \
--zone=asia-northeast3-a \
--health-check=http-health-check \
--initial-delay=300

study-managed-instance-group 이라는 이름으로 관리형 인스턴스 그룹을 만들었다. 옵션에 보면 --base-instance-name을 볼 수 있는데 인스턴스가 자동으로 생성될 때 기본 베이스가 되는 이름이다. 인스턴스 생성 시 저 베이스 이름에 랜덤 문자열이 붙게 된다. (ex study-web-dev-d2eq)  --template은 이전에 만들었던 인스턴스 템플릿을, size는 초기 인스턴스 스 생성 개수, initial-delay는 현재 생성된 인스턴스가 비정상일 때 새로 생성하지 않고 대기하는 시간이다. 300이면 5분을 뜻한다. 그리고 중요한 것 중 하나가 --health-check 옵션인데 이 옵션을 지정해야 자동 복구가 적용된다. 

 

여기까지 만들었다면 조금 기다려보자. MIG로 인해서 초기 사이즈 1을 맞추기 위해 인스턴스를 생성하는 것을 볼 수 있다. 

$ gcloud compute instances list
NAME                ZONE               MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP       EXTERNAL_IP      STATUS
study-web-dev-9v63  asia-northeast3-a  f1-micro                   XXX.XXX.XXX.XXX   XXX.XXX.XXX.XXX  RUNNING

 

여기서 중요한 것이 하나있다. 아마 그냥 기본 이미지를 가져다가 템플릿을 만들었다면 VM 인스턴스에 웹서버가 설치되어 있지 않은 상태일텐데, 이렇게 되면 상태 확인에 실패해 인스턴스 삭제와 생성을 계속 반복하게 된다. 직접 확인해보고 싶다면 Google Cloud Console -> Compute Engine -> 인스턴스 그룹으로 이동해 health check에 빨간색 불이 들어와 있는지 확인해보자. 아마 빨간불이 들어와 있을 것이다. 그러니 상태 확인을 생성할 때 지정했던 성공 기준을 만족할 수 있도록 이미지를 세팅하거나 시작 스크립트를 설정해놓아야 한다. 

 

위에서 웹서버가 실행된 상태로 커스텀 이미지를 생성했다면 아마 초록불이 들어와있을 것이다. 커스텀 이미지를 만들었는데도 빨간불이라면 재시작 시 자동실행되도록 설정을 하지 않은 것이니 그 부분만 설정해주고 다시 이미지를 만들거나 재시작 시 웹서버가 실행되도록 스크립트를 작성하자. 일단 기본 이미지를 사용했다면 아래 스크립트 전체를, 웹서버만 설치되어 있다면 맨 아래 줄만 참고하면 된다.

sudo apt-get update
sudo apt-get install -y apache2
sudo service apache2 restart

 

내용은 패키지 업데이트 -> 웹 서버 설치 -> 웹 서버 재시작이다. 굉장히 간단하게 작성했는데 원하는 내용이 있다면 더 작성하자. 그 다음 위 내용을 복사해 start_script.sh 이름으로 파일을 만들어 안에 붙여넣자. 파일 위치는 그냥 홈에다가 하자.

$ vi ~/start_script.sh

#! /bin/bash
sudo apt-get update
sudo apt-get install -y apache2
sudo service apache2 restart

#! /bin/bash도 같이 넣자.(이건 그냥 bash 쉘로 실행한다는 뜻이다.) 다 붙여 넣었으면 esc -> : wq -> enter로 빠져나오자. 참고로 물결은 홈 디렉터리를 의미한다. 

 

이제 아래 명령어를 통해 새로운 인스턴스 템플릿을 생성하자. 위에서 만든 템플릿과 다른 점은 이름 끝에 숫자가 바뀐것과 메타데이터로 방금 만든 파일을 지정한 것이다. 메타데이터로 시작 스크립트를 구성하는 방법은 이 문서를 참고하자.

$ gcloud compute instance-templates create study-web-dev-2 \
--machine-type=f1-micro \
--image=ubuntu-minimal-2004-focal-v20211209 \
--image-project=ubuntu-os-cloud \
--boot-disk-size=10GB \
--boot-disk-type=pd-balanced \
--boot-disk-device-name=study-web-dev-2 \
--metadata-from-file=startup-script=<PATH>/start_script.sh

위에서 <PATH> 부분은 아래처럼 확인하자. 참고로 PATH에 물결 넣으면 안된다.

$ cd ~ 
$ pwd
/home/ldy

<PATH>를 위 경로로 변경하고 실행하면 성공적으로 인스턴스 템플릿이 생성된다. 

Created [https://www.googleapis.com/compute/v1/projects/emadam-playground/global/instanceTemplates/study-web-dev-2].
NAME             MACHINE_TYPE  PREEMPTIBLE  CREATION_TIMESTAMP
study-web-dev-2  f1-micro                   2022-01-07T04:08:59.349-08:00

위 명령어에서 option중 --metadata-from-file의 값을 startup-script=<PATH>/start_script.sh로 주었는데 이것은 key가 startup-script이고 값이 <PATH>/start_script.sh라는 뜻이다. key를 startup-script로 지정하면 시작 스크립트로 인식해서 인스턴스가 시작될 때마다 값으로 지정한 스크립트를 실행한다. 이런식으로 metadata는 key값에 따라 특정 동작을 수행하는 경우가 있으니 알고 있도록 하자.

 

인스턴스 템플릿을 생성 했으니 인스턴스 그룹을 수정하자. 인스턴스 그룹은 아래의 명령어로 수정할 수 있다.

gcloud compute instance-groups managed set-instance-template 명령어

$ gcloud compute instance-groups managed set-instance-template study-managed-instance-group \
--template=study-web-dev-2 \
--zone=asia-northeast3-a

이렇게 수정했으면 끝이 아니고 이미 생성된 VM 인스턴스들을 새 템플릿 기반으로 교체해주어야 한다. 아래 명령어로 교체하자. 

gcloud compute instance-groups managed rolling-action replace 명령어

gcloud compute instance-groups managed rolling-action replace study-managed-instance-group \
--zone=asia-northeast3-a

이제 다시 Google Cloud Console -> Compute Engine -> 인스턴스 그룹으로 이동해 health check를 확인하면 초록불이 들어와 있는 것을 확인할 수 있다. 

 

그럼 이제 오토스케일링이 남았는데 오토스케일링은 아래 명령어로 간단하게 추가할 수 있다. 

gcloud compute instance-groups managed set-autoscaling 명령어

$ gcloud compute instance-groups managed set-autoscaling study-managed-instance-group \
--zone asia-northeast3-a \
--cool-down-period "60" \
--max-num-replicas "3" \
--min-num-replicas "1" \
--set-schedule "business-hours" \
--schedule-cron "0 9 * * 1-5" \
--schedule-min-required-replicas 2 \
--target-cpu-utilization "0.6" \
--schedule-duration-sec 32400 \
--schedule-time-zone "Asia/Seoul" \
--mode "on"

위 옵션들을 한번 살펴보자.

--cool-down-period : 인스턴스가 새로 생성된 뒤 정보를 수집하기 전 대기하는 시간이다. 위에는 60으로 되어 있는데, 이는 인스턴스가 생성되었더라도 60초 동안은 인스턴스의 정보를 수집하지 않겠다는 뜻이다. 초반에 인스턴스가 생성되면서 불필요한 수치들이 측정될 수 있으니 너무 짧게 잡는 것은 추천하지 않는다.

--max-num-replicas, --min-num-replicas : 각각 최대 인스턴스 개수, 최소 인스턴스 개수를 뜻한다. 오토스케일링은 인스턴스 수가 확장될 수도 있고 축소될 수도 있는데 위의 범위를 벗어나지 않는다. 

--set-schedule : 일정을 생성하며 일정의 이름을 지정한다. 단순히 이름만 지정하는 것이 아니라 일정 생성에 대한 기능도 포함되어 있기 때문에 일정을 생성할 것이라면 반드시 지정해야 한다. 지정하지 않으면 나머지 일정 관련 옵션을 설정하더라도 적용되지 않는다.

--schedule-cron : 일정을 설정하며 분 시 일 월 요일 순으로 입력한다. 위 경우는 매 월(1)-금(5) 오전 9시에 반복한다는 것을 의미한다. 자세한 작성법은 이 문서를 참고하자.

--schedule-min-required-replicas : 일정이 시작되면 유지할 최소 인스턴스 개수이다. 원래는 1~3개의 인스턴스 수를 유지하지만 이 값을 2로 지정했으므로 9시 ~ 18시 까지는 2~3개의 인스턴스를 유지하게 된다.

–-schedule-duration-sec : 위 일정을 유지하는 시간이다. 이 경우에는 오전 9시에 일정을 시작해서 얼마나 유지할 것인지 초단위로 설정한다. 지금처럼 32400으로 설정했다면 60 * 60 * 9 이므로 9시간 동안 유지하겠다는 뜻이 된다.

--schedule-time-zone : timezone을 설정한다. 기본 값은 UTC이니 꼭 설정하자.

--mode : 오토스케일링 모드를 설정한다. on이면 인스턴스 추가/감소를 둘 다 사용한다는 뜻이며, 감소는 허용하지 않고 증가만 허용하는 옵션도 존재한다.

--target-cpu-utilization : 오토스케일링의 기준이 되는 사용량으로 0.6이면 cpu 사용량 60% 기준으로 인스턴스를 추가, 감소하겠다는 뜻이 된다.

 

이렇게 스테이트리스 관리형 인스턴스 그룹을 설정해 보았다. 참고로 스테이트리스기 때문에 인스턴스가 재생성되면 모든 정보가 바뀐다. 그럼 다음 포스팅에서는 윈도우 인스턴스를 스테이트풀로 구성해보자.