EMD Blog

[GCP] Compute Engine에 대해 알아보자(5) - 스테이트풀 MIG/메타데이터 및 IP 본문

Public Cloud/GCP

[GCP] Compute Engine에 대해 알아보자(5) - 스테이트풀 MIG/메타데이터 및 IP

EmaDam 2022. 3. 1. 23:01

이번 포스팅에서는 스테이트풀 구성 중 메타데이터와 IP에 대한 부분을 진행해보자. 

구성은 이전 포스팅 내용에 해당하는 리소스가 존재한다고 가정하고 진행하겠다. 

 

메타데이터

메타데이터(Metadata)에 제대로 설명한 적은 없는 것 같다. 인터넷에 메타데이터로 검색하면 데이터에 대한 데이터라고 설명이 나온다. 메타데이터에 익숙하지 않은 사람이라면 저 말이 잘 와닿지 않을 수도 있는데, 휴대폰 사진을 생각하면 쉽게 이해할 수 있다. 스마트폰 일반 카메라로 아무사진이나 찍고 사진첩에 들어가서 보자. 안드로이드는 어떻게 나올지 모르겠는데 아이폰이라면 사진 상단에 언제 어디서 찍었는지 표시가 될 것이다. 이런 정보들이 메타데이터이다. 예시라서 그냥 간단하게 사진에 대한 위치, 시간 정도로만 예시를 들었는데 메타데이터는 무엇이든 될 수 있다. 그리고 누구나 자유롭게 메타데이터를 입력시킬 수 있다. 그냥 라벨 같은거라 생각하자.

 

라벨처럼 쓴다는 말이 과장은 아닌게 주로 검색 용도로 많이 사용하고 대부분 키/값으로 구성되어 있다. 그렇다면 여기서 의문이 들 수 있는데, 왜냐하면 VM에는 메타데이터를 따로 지정하지 않더라도 GCP에서는 모든 리소스에 대해 이미 라벨 기능을 제공하고 있기 때문이다. 그럼 정말 왜 VM 인스턴스에서 메타데이터를 따로 사용하는 것일까? 

 

사실 VM 인스턴스는 메타데이터를 어떻게 설정하느냐에 따라서 특별한 기능을 제공해주고 있다. 예를 들어 메타데이터의 key로 "startup-script"를 지정하고 값으로 Shell Script를 지정하면 인스턴스 시작 시 "startup-script"키에 지정한 스크립트를 실행 시킨다. 이런 특수한 동작을 하는 스크립트는 매우 많기 때문에 아래 문서들을 보고 필요한 것들을 찾아서 사용해보는 것이 좋다.

- 기본 VM 메타데이터 값

- 시작 스크립트

- 종료 스크립트

 

위에 몇 가지 링크들을 올려 놓긴 했는데 메타데이터 부분은 그냥 전부 보는 것을 권장한다. 생각보다 자주 사용된다

 

그럼 이제 인스턴스를 생성할 때 스테이트풀 메타데이터를 지정해서 생성해보도록 하자. 사실 방법은 스테이트풀 디스크를 구성할 때와 동일하기 때문에 별다른 설명이 필요가 없다. 

gcloud compute instance-groups managed create-instance 명령어

$ gcloud compute instance-groups managed create-instance study-managed-instance-group-windows \
   --instance study-web-dev-metadata \
   --zone=asia-northeast3-a \
   --stateful-metadata test-metadata=emadam

Creating instance....done.

위 명령어는 인스턴스를 수동으로 생성하면서 스테이트풀 메타데이터로 Key(test-metadata), Value(emadam)를 지정해 준 것이다. 지정하는 것이 디스크 구성때와 크게 다르지 않다는 것을 알 수 있다. 

 

그런데 이미 존재하는 인스턴스스테이트풀 구성을 적용하고 싶을 수도 있다. 그럴때는 아래 명령어를 사용하자.

gcloud compute instance-groups managed instance-configs create 명령어

위 명령어는 이미 존재하는 인스턴스에 사용해야하는 명령어이기 때문에 아무 인스턴스나 하나 만들도록 하자.

$ gcloud compute instance-groups managed create-instance study-managed-instance-group-windows \
  --instance study-web-dev-metadata-2 \
  --zone=asia-northeast3-a

그 다음 instance-configs 명령어로 스테이트풀 메타데이터를 지정하자. 

$ gcloud compute instance-groups managed instance-configs create study-managed-instance-group-windows \
  --instance study-web-dev-metadata-2 \
  --zone asia-northeast3-a \
  --stateful-metadata test-metadata-2=emadam-2
  
  Creating instance config....done.
Applying updates to instances....done.

잘 설정되었는지는 아래 명령어로 확인할 수 있다. 

gcloud compute instances describe 명령어

$ gcloud compute instances describe study-web-dev-metadata-2 \
--zone asia-northeast3-a

...
metadata:
  fingerprint: MohG5QxQYdk=
  items:
...
  - key: test-metadata-2
    value: emadam-2
...

메타데이터가 잘 설정된 것을 볼 수 있다. instance-configs 명령어는 메타데이터 뿐만 아니라 스테이트풀 디스크도 설정할 수 있고, 이렇게 구성한 것을 어느 시점에 적용할지도 옵션으로 지정할 수 있다.

 

스테이트풀 IP 구성

스테이트풀 IP구성을 해보자. 스테이트풀 IP를 구성한다면 인스턴스가 재생성 되더라도 IP를 유지할 수 있게 된다. 

 

스테이트풀 IP를 사용해야할 때는 다음과 같다.

- Kafka처럼 고정된 IP주소를 유지해야하는 어플리케이션이 배포될 경우

- DNS 서버에 IP가 등록되어 있는 경우

- NFS처럼 IP를 통해 마운트 되어 있는 경우

- 네트워크 구성 변경없이 워크로드를 마이그레이션 해야할 경우

 

문서에 있는 예시들을 가져와서 적어 놓았는데, 사실 그냥 구성하다가 필요성을 느끼면 그때 구성하면 된다. 만약에 정말 필요할 상황에서 이것을 활용하지 않으면 불필요한 Script를 작성해야 할 수도 있으니 필요할 때 적극 활용하자.

 

그럼 이제 스테이트풀 구성을 해보도록 하자. IP도 디스크처럼 스테이트풀 정책을 통해 전체 VM에 적용하거나 인스턴스 별로 따로 구성할 수도 있다. 스테이트풀 IP를 구성하면 아래와 같이 구성이 적용된다.

- 새 인스턴스의 경우 고정 IP주소를 자동할당/예약

- 기존 인스턴스의 경우 내/외부 IP를 고정 IP로 승격

- 기존 인스턴스 중 외부 IP가 없다면 네트워크 인터페이스에 엑세스 구성을 추가(없으면 만들어 준다는 뜻)

(참고로 스테이트풀 구성 시 MIG는 주소를 고정시키기 위해 IP주소를 예약(리소스 생성)한다.)

 

먼저 스테이트풀 정책으로 스테이트풀 IP를 구성해보자. 아래 명령어를 사용하면 스테이트풀 정책을 구성할 수 있다.

gcloud beta compute instance-groups managed update 명령어 

스테이트풀 IP를 지정하는 옵션은 아직 beta에만 있으니 참고.

$ gcloud beta compute instance-groups managed update study-managed-instance-group-windows \
    --stateful-internal-ip enabled \
    --stateful-external-ip enabled \
   --zone asia-northeast3-a

참고로 위 명령어 사용 시 네트워크 인터페이스를 지정할 수 있다. 위처럼 이 옵션을 지정하지 않으면 기본 네트워크 인터페이스가 지정되며, 만약 인스턴스 템플릿에 네트워크 인터페이스가 여러개 지정되어 있고 스테이트풀 IP를 다른 네트워크 인터페이스에 설정하고 싶다면 --interface-name 옵션을 추가로 지정해주면 된다. 인스턴스 템플릿의 네트워크 인터페이스는 아래 명령어로 확인할 수 있다.

gcloud compute instance-templates describe 명령어

# 전체 네트워크 인터페이스 이름 확인
gcloud compute instance-templates describe study-web-dev-3 --format=json | jq .properties.networkInterfaces[].name | tr -d '"'

jq를 사용하면 json형식의 표준출력을 쉽게 다룰 수 있다. 설치도 쉽고 사용법도 쉬우니 이 링크를 한번 확인해보자. 

마지막에 보면 tr로 쌍따옴표를 제거했는데 이게 jq로 특정 값을 검색하면 쌍따옴표가 함께 출력돼서 사용한 것이다. 만약 jq에 대한 출력을 변수로 사용할 생각이 있다면 꼭 쌍따옴표를 제거해주도록 하자. (jq의 -r 옵션을 사용해도 쌍따옴표가 제거된다.)

 

어쨋든 스테이트풀 정책으로 스테이트풀 IP를 구성했다. 아래 명령어로 한번 확인해 보도록 하자.

gcloud compute instance-groups managed describe 명령어

$ gcloud compute instance-groups managed describe study-managed-instance-group-windows \
--zone asia-northeast3-a

...
statefulPolicy:
  preservedState:
    internalIPs:
      nic0:
...

 

 

원래는 위처럼 statefulPolicy에 IP 구성 정보가 표시되어야 하지만 이상하게 나는 표시가 되지 않는다. 스테이트풀이 적용된 것은 확인했고 테스트도 다 해봤는데 이상하게 위 명령어에 표시가 안된다. 만약에 다른분들도 위 명령어로 확인이 안된다면 주소가 예약되는지, 예약된 주소가 인스턴스들에게 적용이 되는지, 새로 생성했을 때도 적용이 되는지 확인해 보시는 것이 좋을 듯 하다.

 

아래 명령어로 주소가 잘 예약되었는지도 확인해보자.

gcloud compute addresses list 명령어

$ gcloud compute addresses list

위 명령어는 예약(리소스로 생성된)된 주소만 출력시켜준다. 따로 예약한 IP가 없는데 생성이 되어있다면 정상적으로 적용이 된 것이다. 

 

스테이트풀 정책을 구성해 보았으니 이제 인스턴스 별로 적용을 해보자. 그 전에 스테이트풀 정책부터 제거하자. 

스테이트풀 정책 제거는 아래처럼 명령어를 사용하면 된다.

참고로 스테이트풀 정책을 제거해도 인스턴스별 구성이 남아있다면 IP는 계속 스테이트풀로 유지된다. 

interface_name=`gcloud compute instance-templates describe study-web-dev-3 --format=json | jq .properties.networkInterfaces[0].name | tr -d '"'`

gcloud beta compute instance-groups managed update study-managed-instance-group-windows \
    --remove-stateful-internal-ips $interface_name \
    --remove-stateful-external-ips $interface_name \
   --zone asia-northeast3-a

 

[아주 중요] 스테이트풀 정책을 제거하더라도 주소는 예약된 채로 남아있다. 예약된 주소는 인스턴스나 로드밸런서같은 다른 리소스에 연결되어 있을 경우 과금이 되지 않지만 연결이 되지않은 상태로 방치되면 요금이 발생한다. 꼭 주소를 예약 해제하도록 하자.

명령어를 실행했더라도 예약된 IP는 그대로 연결되어 있을 것이다. 하지만 인스턴스가 재생성될 경우 연결이 해지 되고 임시 IP가 할당된다. 일단 인스턴스별 구성을 설정해야 하니 IP를 전부 예약 해제 시키도록 하자. 

gcloud compute addresses delete 명령어

addresses=`gcloud compute addresses list | awk '{ print $1 }' | grep study | tr '\n' ' '`

gcloud compute addresses delete $addresses --region=asia-northeast3

 

linux 명령어에 익숙하지 않다면 위 명령어가 눈에 잘 안들어 올 수도 있는데 address list 명령어로 나온 테이블에서 awk명령어첫 번째 필드(주소명)를 추출한 다음 그 중에서 study문자열을 포함하는 주소만을 골라낸 것이다. 원래는 이렇게 뽑아내면 줄바꿈(\n)으로 구분되어 있는데 addresses delete명령어에서는 공백을 기준으로 한번에 삭제하는 기능이 있기 때문에 tr명령어 줄바꿈을 공백으로 변경해주었다. 

 

이렇게 하면 모든 주소가 깔끔하게 해제된다. 이제 인스턴스별 구성을 할 수 있게 됐다. 먼저 인스턴스에 연결할 고정 IP를 예약하자. IP예약은 아래 명령어로 예약할 수 있다.

참고로 GCP에서는 관리적인 측면때문에 개별 구성보다는 정책으로 한번에 구성하기를 권장한다. 

gcloud compute addresses create 명령어

$ gcloud compute addresses create study-address-1 \
--region=asia-northeast3

그 다음 아래 명령어로 인스턴스별 구성을 업데이트 하자. 기존에 인스턴스별 구성이 있다면 update를, 없다면 create를 사용하자. 나는 이전에 metadata를 설정했던 인스턴스에 적용할 것이라 update를 사용하겠다.

gcloud beta compute instance-groups managed instance-configs create 명령어

gcloud beta compute instance-groups managed instance-configs update 명령어

$ gcloud beta compute instance-groups managed instance-configs update study-managed-instance-group-windows \
    --instance study-web-dev-metadata-2 \
    --stateful-internal-ip address=10.178.0.51 \
    --stateful-external-ip address=projects/project-name/regions/asia-northeast3/addresses/study-address-1 \
   --zone=asia-northeast3-a

address로는 리터럴을 지정 할 수도 있고 주소의 URL을 지정 할 수도 있다. 리터럴의 경우 꼭 예약되어 있지 않아도 되며 URL의 경우 당연히 예약이 된 상태여야한다. address를 리터럴로 지정할 경우 해당 주소가 예약되어 있지 않으면 자동으로 고정 IP로 예약한다. 그렇기 때문에 내부는 리터럴로, 외부는 URL로 지정하는 것이 편하다. 

주소 URL 형식은 아래와 같으니 참고하자.

projects/example-project/regions/us-east1/addresses/example-ip-name

 

이렇게 하면 인스턴스별 구성도 끝이다. 사실 몇 가지가 더 있긴 하지만 디스크 구성때와 거의 비슷한 방법으로 진행되기 때문에 관심이 있다면 문서를 보고 진행해보는 것도 좋다.

 

이렇게 인스턴스 그룹을 전부 진행해보았다. 이제 로드밸런서도 구성해야되는데 학교 과제를 해야돼서 여름쯤에나 진행하지 싶다.