이 문서에서는 사용자가 다음에 익숙하다고 가정합니다.
목표
- 사용되지 않는 IP 주소 삭제: Google Cloud에서 고정 IP 주소는 부하 분산기 또는 가상 머신(VM) 인스턴스에 연결되었을 때 무료 리소스입니다. 고정 IP 주소가 예약된 경우에는 사용되지 않더라도 시간당 비용이 누적됩니다. 고정 IP 주소 및 대규모 동적 프로비저닝에 크게 의존하는 앱의 경우 시간이 지날수록 이러한 낭비가 커질 수 있습니다.
- 분리되었거나 사용되지 않는 영구 디스크 삭제: 영구 디스크는 생성되었지만 다른 VM에 연결되지 않은 경우 또는 머신에 여러 디스크가 있고 하나 이상의 디스크가 분리되었을 때 사용되지 않거나 분리됩니다.
- 비용이 낮은 스토리지 클래스로 마이그레이션: Google Cloud는 여러 클래스의 객체 스토리지를 제공합니다. 사용자 요구에 가장 적합한 클래스를 사용하세요.
아키텍처
다음 다이어그램은 사용되지 않는 IP 주소를 식별하고 삭제하도록 Cloud 함수를 예약하는 배포의 첫 번째 부분을 설명합니다.
첫 번째 예시에는 다음 내용이 포함됩니다.
- 고정 외부 IP 주소로 Compute Engine VM을 만들고 사용되지 않는 개별 고정 외부 IP 주소를 만듭니다.
- 사용되지 않은 주소를 찾기 위한 Cloud 함수를 배포합니다.
- HTTP 트리거를 사용해서 함수를 실행하도록 예약하는 Cloud Scheduler 작업을 만듭니다.
다음 다이어그램에서는 연결되지 않았고 분리된 영구 디스크를 찾아서 삭제하도록 Cloud 함수를 예약합니다.
두 번째 예시에는 다음 내용이 포함됩니다.
- 2개의 영구 디스크와 1개의 연결되지 않은 개별 영구 디스크로 Compute Engine VM을 만듭니다. VM에서 분리하여 디스크 중 하나를 분리시킵니다.
- 연결되지 않고 분리된 영구 디스크를 찾도록 Cloud 함수를 배포합니다.
- HTTP 트리거를 사용해서 Cloud 함수의 실행을 예약하도록 Cloud Scheduler 작업을 만듭니다.
다음 다이어그램에서는 Monitoring 알림 정책에 따라 덜 비싼 스토리지 클래스로 스토리지 버킷을 마이그레이션하도록 Cloud 함수를 트리거합니다.
세 번째 예시에는 다음 내용이 포함됩니다.
- 스토리지 버킷 2개를 만들어서 서비스 제공 버킷에 파일을 추가하고 이에 대해 트래픽을 생성합니다.
- 버킷 사용률을 시각화하기 위해 Monitoring 대시보드를 만듭니다.
- 유휴 버킷을 덜 비싼 스토리지 클래스로 마이그레이션하도록 Cloud 함수를 배포합니다.
- Monitoring 알림 정책으로부터 수신된 알림을 시뮬레이션하도록 의도된 페이로드를 사용하여 함수를 트리거합니다.
비용
이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.
프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요.
이 문서에 설명된 태스크를 완료했으면 만든 리소스를 삭제하여 청구가 계속되는 것을 방지할 수 있습니다. 자세한 내용은 삭제를 참조하세요.
시작하기 전에
- Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
-
Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
-
API Compute Engine, Cloud Functions, and Cloud Storage 사용 설정
-
Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
-
API Compute Engine, Cloud Functions, and Cloud Storage 사용 설정
-
Google Cloud 콘솔에서 Cloud Shell을 활성화합니다.
Google Cloud 콘솔 하단에서 Cloud Shell 세션이 시작되고 명령줄 프롬프트가 표시됩니다. Cloud Shell은 Google Cloud CLI가 사전 설치된 셸 환경으로, 현재 프로젝트의 값이 이미 설정되어 있습니다. 세션이 초기화되는 데 몇 초 정도 걸릴 수 있습니다.
Cloud Shell에서 이 문서의 모든 명령어를 실행합니다.
환경 설정
이 섹션에서는 이 아키텍처에 필요한 인프라 및 ID를 구성합니다.
Cloud Shell에서 저장소를 클론하고
gcf-automated-resource-cleanup
디렉터리로 변경합니다.git clone https://github.com/GoogleCloudPlatform/gcf-automated-resource-cleanup.git && cd gcf-automated-resource-cleanup/
환경 변수를 설정하고 저장소 폴더를
$WORKDIR
폴더로 만듭니다. 여기서 모든 명령어를 실행합니다.export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) WORKDIR=$(pwd)
오픈소스 부하 생성 도구인 Apache Bench를 설치합니다.
sudo apt-get install apache2-utils
사용되지 않은 IP 주소 삭제
이 섹션에서는 다음 단계를 완료합니다.
- 2개의 고정 IP 주소를 만듭니다.
- 고정 IP 주소를 사용하는 VM을 만듭니다.
- Cloud Functions 코드를 검토합니다.
- Cloud 함수를 배포합니다.
- Cloud Scheduler 작업을 사용하여 Cloud 함수를 테스트합니다.
IP 주소 만들기
Cloud Shell에서
unused-ip
디렉터리로 변경합니다.cd $WORKDIR/unused-ip
IP 주소 이름을 변수로 내보냅니다.
export USED_IP=used-ip-address export UNUSED_IP=unused-ip-address
2개의 고정 IP 주소를 만듭니다.
gcloud compute addresses create $USED_IP \ --project=$PROJECT_ID --region=us-central1 gcloud compute addresses create $UNUSED_IP \ --project=$PROJECT_ID --region=us-central1
이 예시에서는
us-central1
리전이 사용되지만 다른 리전을 선택하고 이 문서의 나머지 부분에서 일관되게 참조할 수 있습니다.2개 주소가 생성되었는지 확인합니다.
gcloud compute addresses list --filter="region:(us-central1)"
출력에서
RESERVED
상태는 IP 주소가 사용 중이 아님을 나타냅니다.NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 RESERVED
사용된 IP 주소를 환경 변수로 설정합니다.
export USED_IP_ADDRESS=$(gcloud compute addresses describe $USED_IP \ --region=us-central1 --format=json | jq -r '.address')
VM 만들기
Cloud Shell에서 인스턴스를 만듭니다.
gcloud compute instances create static-ip-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --subnet=default \ --address=$USED_IP_ADDRESS
이제 IP 주소 중 하나가 사용 중인지 확인합니다.
gcloud compute addresses list --filter="region:(us-central1)"
출력은 다음과 비슷합니다.
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS unused-ip-address 35.232.144.85 EXTERNAL us-central1 RESERVED used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
Cloud 함수 코드 검토
Cloud Shell에서 코드의 기본 섹션을 출력합니다.
cat $WORKDIR/unused-ip/function.js | grep "const compute" -A 31
출력은 다음과 같습니다.
const compute = new Compute(); compute.getAddresses(function(err, addresses){ // gets all addresses across regions if(err){ console.log("there was an error: " + err); } if (addresses == null) { console.log("no addresses found"); return; } console.log("there are " + addresses.length + " addresses"); // iterate through addresses for (let item of addresses){ // get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used AND if it's at least ageToDelete days old: if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){ // delete address item.delete(function(err, operation, apiResponse2){ if (err) { console.log("could not delete address: " + err); } }) } }) } // return number of addresses evaluated res.send("there are " + addresses.length + " total addresses"); }); }
앞의 코드 샘플에서 다음 사항에 유의하세요.
compute.getAddresses(function(err, addresses){ // gets all addresses across regions
getAddresses
메서드를 사용하여 프로젝트의 모든 리전에서 IP 주소를 검색합니다.// get metadata for each address item.getMetadata(function(err, metadata, apiResponse) { // if the address is not used: if (metadata.status=='RESERVED'){
각 IP 주소에 대한 메타데이터를 가져오고 해당
STATUS
필드를 확인합니다.if ((metadata.status=='RESERVED') & (calculateAge(metadata.creationTimestamp) >= ageToDelete)){
IP 주소가 사용 중인지 확인하고 도우미 함수를 사용해서 해당 사용 기간을 계산하고, 이 기간을 상수(이 문서에서는
0
으로 설정됨)와 비교합니다.// delete address item.delete(function(err, operation, apiResponse2){
IP 주소를 삭제합니다.
Cloud 함수 배포
Cloud Shell에서 Cloud 함수를 배포합니다.
gcloud functions deploy unused_ip_function --trigger-http --runtime=nodejs8
트리거 URL을 환경 변수로 설정합니다.
export FUNCTION_URL=$(gcloud functions describe unused_ip_function \ --format=json | jq -r '.httpsTrigger.url')
Cloud 함수 예약 및 테스트
Cloud Shell에서 매일 오전 2시에 이 Cloud 함수를 실행하도록 Cloud Scheduler 태스크를 만듭니다.
gcloud scheduler jobs create http unused-ip-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
수동으로 트리거하여 작업을 테스트합니다.
gcloud scheduler jobs run unused-ip-job
사용되지 않은 IP 주소가 삭제되었는지 확인합니다.
gcloud compute addresses list --filter="region:(us-central1)"
출력은 다음과 비슷합니다.
NAME ADDRESS/RANGE TYPE REGION SUBNET STATUS used-ip-address 104.197.56.87 EXTERNAL us-central1 IN_USE
사용되지 않고 분리된 영구 디스크 삭제
이 섹션에서는 다음 단계를 완료합니다.
- 2개의 영구 디스크를 만듭니다.
- 디스크 중 하나를 사용하는 VM을 만듭니다.
- VM에서 디스크를 분리합니다.
- Cloud 함수 코드를 검토합니다.
- Cloud 함수를 배포합니다.
- Cloud Scheduler 작업을 사용하여 Cloud 함수를 테스트합니다.
영구 디스크 만들기
Cloud Shell에서
unattached-pd
디렉터리로 변경합니다.cd $WORKDIR/unattached-pd
디스크 이름을 환경 변수로 내보냅니다.
export ORPHANED_DISK=orphaned-disk export UNUSED_DISK=unused-disk
2개의 디스크를 만듭니다.
gcloud beta compute disks create $ORPHANED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a gcloud beta compute disks create $UNUSED_DISK \ --project=$PROJECT_ID \ --type=pd-standard \ --size=500GB \ --zone=us-central1-a
2개의 디스크가 생성되었는지 확인합니다.
gcloud compute disks list
출력은 다음과 같습니다.
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS orphaned-disk us-central1-a zone 500 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY unused-disk us-central1-a zone 500 pd-standard READY
VM 만들기 및 디스크 검사
Cloud Shell에서 인스턴스를 만듭니다.
gcloud compute instances create disk-instance \ --zone=us-central1-a \ --machine-type=n1-standard-1 \ --disk=name=$ORPHANED_DISK,device-name=$ORPHANED_DISK,mode=rw,boot=no
VM에 연결된 디스크를 검사합니다.
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
출력은 다음과 비슷합니다.
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "users": [ "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/instances/disk-instance" ], "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
앞의 코드 샘플에서 다음 사항에 유의하세요.
users
는 디스크가 연결된 VM을 식별합니다.lastAttachTimestamp
는 디스크가 VM에 마지막으로 연결된 시간을 식별합니다.
VM에 연결되지 않은 디스크를 검사합니다.
gcloud compute disks describe $UNUSED_DISK \ --zone=us-central1-a \ --format=json | jq
출력은 다음과 비슷합니다.
{ "creationTimestamp": "2019-06-12T12:21:30.905-07:00", "id": "1313096191791918677", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "name": "unused-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/unused-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
앞의 코드 샘플에서는 다음 내용이 중요합니다.
- 현재 VM에서 사용되지 않기 때문에 디스크에
users
가 나열되지 않습니다. - 지금까지 사용된 적이 없기 때문에 디스크에
lastAttachedTimestamp
가 없습니다.
- 현재 VM에서 사용되지 않기 때문에 디스크에
VM에서 분리된 영구 디스크를 분리합니다.
gcloud compute instances detach-disk disk-instance \ --device-name=$ORPHANED_DISK \ --zone=us-central1-a
분리된 디스크를 검사합니다.
gcloud compute disks describe $ORPHANED_DISK \ --zone=us-central1-a \ --format=json | jq
출력은 다음과 비슷합니다.
{ "creationTimestamp": "2019-06-12T12:21:25.546-07:00", "id": "7617542552306904666", "kind": "compute#disk", "labelFingerprint": "42WmSpB8rSM=", "lastAttachTimestamp": "2019-06-12T12:24:53.989-07:00", "lastDetachTimestamp": "2019-06-12T12:34:56.040-07:00", "name": "orphaned-disk", "physicalBlockSizeBytes": "4096", "selfLink": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/disks/orphaned-disk", "sizeGb": "500", "status": "READY", "type": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a/diskTypes/pd-standard", "zone": "https://www.googleapis.com/compute/v1/projects/automating-cost-optimization/zones/us-central1-a" }
앞의 코드 샘플에서는 다음 내용이 중요합니다.
- 현재 사용 중이 아니므로 디스크에
users
가 나열되지 않습니다. - 이제 디스크가 VM에서 마지막으로 분리된 시간 즉, 마지막으로 사용된 시간을 나타내는
lastDetachTimestamp
항목이 표시됩니다. lastAttachTimestamp
필드는 계속 있습니다.
- 현재 사용 중이 아니므로 디스크에
Cloud 함수 코드 검토
Cloud Shell에서 프로젝트의 모든 영구 디스크를 검색하는 코드 섹션을 출력합니다.
cat $WORKDIR/unattached-pd/main.py | grep "(request)" -A 12
출력은 다음과 같습니다.
def delete_unattached_pds(request): # get list of disks and iterate through it: disksRequest = compute.disks().aggregatedList(project=project) while disksRequest is not None: diskResponse = disksRequest.execute() for name, disks_scoped_list in diskResponse['items'].items(): if disks_scoped_list.get('warning') is None: # got disks for disk in disks_scoped_list['disks']: # iterate through disks diskName = disk['name'] diskZone = str((disk['zone'])).rsplit('/',1)[1] print (diskName) print (diskZone)
이 함수는
aggregatedList
메서드를 사용하여 실행되는 Google Cloud 프로젝트의 모든 영구 디스크를 가져오고, 각 디스크에 대해 작업을 반복합니다.lastAttachTimestamp
필드를 확인하고 존재하지 않으면 디스크를 삭제하는 코드 섹션을 출력합니다.cat $WORKDIR/unattached-pd/main.py | grep "handle never" -A 11
출력은 다음과 같습니다.
# handle never attached disk - delete it # lastAttachedTimestamp is not present if disk.get("lastAttachTimestamp") is None: print ("disk " + diskName + " was never attached - deleting") deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") Continue
이 섹션에서는
lastAttachTimestamp
가 없는 경우 즉, 이 디스크가 사용된 적이 없는 경우, 디스크를 삭제합니다.디스크가 분리된 경우 디스크의 사용 기간을 계산하고, 디스크의 스냅샷을 만들고, 디스크를 삭제하는 코드 섹션을 출력합니다.
cat $WORKDIR/unattached-pd/main.py | grep "handle detached" -A 32
출력은 다음과 같습니다.
# handle detached disk - snapshot and delete # lastAttachTimestamp is present AND users is not present AND it meets the age criterium if disk.get("users") is None \ and disk.get("lastDetachTimestamp") is not None \ and diskAge(disk['lastDetachTimestamp'])>=deleteAge: print ("disk " + diskName + " has no users and has been detached") print ("disk meets age criteria for deletion") # take a snapshot snapShotName = diskName + str(int(time.time())) print ("taking snapshot: " + snapShotName) snapshotBody = { "name": snapShotName } snapshotRequest = compute.disks().createSnapshot(project=project, zone=diskZone, disk=diskName, body=snapshotBody) snapshotResponse = snapshotRequest.execute() waitForZoneOperation(snapshotResponse, project, diskZone) print ("snapshot completed") # delete the disk print ("deleting disk " + diskName) deleteRequest = compute.disks().delete(project=project, zone=diskZone, disk=diskName) deleteResponse = deleteRequest.execute() waitForZoneOperation(deleteResponse, project, diskZone) print ("disk " + diskName + " was deleted") continue
이 코드 섹션은 디스크에
users
가 나열되고lastDetachTimestamp
가 있어서 디스크를 현재 사용 중이 아니지만 한 때 사용되었음을 나타내는 경우에 사용됩니다. 이 경우 Cloud 함수는 데이터를 보존하기 위해 디스크의 스냅샷을 만들고 나서 디스크를 삭제합니다.
Cloud 함수 배포
Cloud Shell에서 Cloud 함수를 배포합니다.
gcloud functions deploy delete_unattached_pds \ --trigger-http --runtime=python37
Cloud 함수의 트리거 URL을 환경 변수로 설정합니다.
export FUNCTION_URL=$(gcloud functions describe delete_unattached_pds \ --format=json | jq -r '.httpsTrigger.url')
Cloud 함수 예약 및 테스트
Cloud Shell에서 매일 오전 2시에 이 Cloud 함수를 실행하도록 Cloud Scheduler 태스크를 만듭니다.
gcloud scheduler jobs create http unattached-pd-job \ --schedule="* 2 * * *" \ --uri=$FUNCTION_URL
작업을 테스트합니다.
gcloud scheduler jobs run unattached-pd-job
분리된 디스크의 스냅샷이 생성되었는지 확인합니다.
gcloud compute snapshots list
출력은 다음과 비슷합니다.
NAME DISK_SIZE_GB SRC_DISK STATUS orphaned-disk1560455894 500 us-central1-a/disks/orphaned-disk READY
사용되지 않은 디스크 및 분리된 디스크가 삭제되었는지 확인합니다.
gcloud compute disks list
출력은 다음과 같습니다.
NAME LOCATION LOCATION_SCOPE SIZE_GB TYPE STATUS disk-instance us-central1-a zone 10 pd-standard READY static-ip-instance us-central1-a zone 10 pd-standard READY
스토리지 버킷을 덜 비싼 스토리지 클래스로 마이그레이션
Google Cloud는 해당 생성 날짜 또는 활성 상태와 같은 속성 집합을 기준으로 서로 다른 스토리지 클래스로 자동으로 객체를 이동하기 위해 사용할 수 있는 스토리지 객체 수명 주기 규칙를 제공합니다. 하지만 이러한 규칙은 객체가 액세스되었는지 여부를 알 수 없습니다. 일부 경우에는 특정 기간 동안 액세스되지 않은 경우 새 객체를 Nearline Storage로 이동해야 할 수 있습니다.
이 섹션에서는 다음 단계를 완료합니다.
- 2개의 Cloud Storage 버킷을 만듭니다.
- 버킷 중 하나에 객체를 추가합니다.
- 버킷 객체 액세스를 관찰하도록 Monitoring을 구성합니다.
- Regional Storage 버킷에서 Nearline Storage 버킷으로 객체를 마이그레이션하는 Cloud 함수 코드를 검토합니다.
- Cloud 함수를 배포합니다.
- Monitoring 알림을 사용하여 Cloud 함수를 테스트합니다.
Cloud Storage 버킷 만들기 및 파일 추가
Cloud Shell에서
migrate-storage
디렉터리로 변경합니다.cd $WORKDIR/migrate-storage
나중에 스토리지 클래스를 변경하기 위해 사용되는
serving-bucket
Cloud Storage 버킷을 만듭니다.export PROJECT_ID=$(gcloud config list \ --format 'value(core.project)' 2>/dev/null) gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-serving-bucket
버킷을 공개로 만듭니다.
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket
텍스트 파일을 버킷에 추가합니다.
gsutil cp $WORKDIR/migrate-storage/testfile.txt \ gs://${PROJECT_ID}-serving-bucket
파일을 공개합니다.
gsutil acl ch -u allUsers:R gs://${PROJECT_ID}-serving-bucket/testfile.txt
파일에 액세스할 수 있는지 확인합니다.
curl http://storage.googleapis.com/${PROJECT_ID}-serving-bucket/testfile.txt
출력은 다음과 같습니다.
this is a test
데이터를 제공하지 않는
idle-bucket
이라는 두 번째 버킷을 만듭니다.gsutil mb -c regional -l us-central1 gs://${PROJECT_ID}-idle-bucket
Cloud Monitoring 작업공간 설정
이 섹션에서는 버킷 객체가 사용되지 않을 때를 파악하기 위해 버킷 사용량을 측정하도록 Cloud Monitoring을 구성합니다. 서비스 제공 버킷이 사용되지 않을 때는 Cloud 함수가 해당 버킷을 Regional Storage 클래스에서 Nearline Storage 클래스로 마이그레이션합니다.
Google Cloud 콘솔에서 Monitoring으로 이동합니다.
새 작업공간을 클릭한 후 추가를 클릭합니다.
초기 구성이 완료될 때까지 기다립니다.
Cloud Monitoring 대시보드 만들기
Monitoring에서 대시보드로 이동한 후 대시보드 만들기를 클릭합니다.
차트 추가를 클릭합니다.
이름 필드에
Bucket Access
를 입력합니다.Cloud Storage 버킷에 대한 요청 콘텐츠 측정항목을 찾으려면 리소스 및 측정항목 찾기 필드에서
request
를 입력한 후gcs_bucket
리소스에 대해 요청 수 측정항목을 선택합니다.버킷 이름으로 측정항목을 그룹으로 묶으려면 그룹화 기준 드롭다운 목록에서
bucket_name
을 클릭합니다.메서드 이름으로 필터링하려면 필터 필드에서 ReadObject를 입력한 후 적용을 누릅니다.
저장을 클릭합니다.
이름 필드에
Bucket Usage
를 입력합니다.대시보드에 액세스할 수 있는지 확인하려면 포인터를 대시보드 위에 두고 버킷 사용량이 표시되는지 확인합니다.
버킷에서 객체 액세스를 관찰하도록 Monitoring을 구성했습니다. Cloud Storage 버킷에 대한 트래픽이 없기 때문에 이 차트에 데이터가 표시되지 않습니다.
서비스 제공 버킷에서 부하 생성
이제 모니터링이 구성되었으므로 Apache Bench를 사용하여 서비스 제공 버킷으로 트래픽을 전송할 수 있습니다.
Cloud Shell에서 서비스 제공 버킷의 객체로 요청을 전송합니다.
ab -n 10000 \ http://storage.googleapis.com/$PROJECT_ID-serving-bucket/testfile.txt
Google Cloud 콘솔에서 Monitoring으로 이동합니다.
버킷 사용량 대시보드를 선택하려면 포인터를 대시보드 위에 두고 버킷 사용량을 선택합니다. 서비스 제공 버킷에만 트래픽이 있는지 확인합니다. 유휴 버킷에 트래픽이 없기 때문에
request_count metric
시계열이 서비스 제공 버킷에 대해서만 표시됩니다.
Cloud 함수 검토 및 배포
Cloud Shell에서 Cloud 함수를 사용해서 스토리지 버킷을 Nearline Storage 클래스로 마이그레이션하는 코드를 출력합니다.
cat $WORKDIR/migrate-storage/main.py | grep "migrate_storage(" -A 15
출력은 다음과 같습니다.
def migrate_storage(request): # process incoming request to get the bucket to be migrated: request_json = request.get_json(force=True) # bucket names are globally unique bucket_name = request_json['incident']['resource_name'] # create storage client storage_client = storage.Client() # get bucket bucket = storage_client.get_bucket(bucket_name) # update storage class bucket.storage_class = "NEARLINE" bucket.patch()
Cloud 함수는 요청에 전달된 버킷 이름을 사용하여 해당 스토리지 클래스를 Nearline Storage로 변경합니다.
Cloud 함수를 배포합니다.
gcloud functions deploy migrate_storage --trigger-http --runtime=python37
트리거 URL을 다음 섹션에서 사용하는 환경 변수로 설정합니다.
export FUNCTION_URL=$(gcloud functions describe migrate_storage \ --format=json | jq -r '.httpsTrigger.url')
알림 자동화 테스트 및 검사
유휴 버킷 이름을 설정합니다.
export IDLE_BUCKET_NAME=$PROJECT_ID-idle-bucket
incident.json
파일을 사용하여 배포한 Cloud 함수로 테스트 알림을 전송합니다.envsubst < $WORKDIR/migrate-storage/incident.json | curl -X POST \ -H "Content-Type: application/json" $FUNCTION_URL -d @-
출력은 다음과 같습니다.
OK
출력이 줄바꿈으로 종료되지 않으며, 따라서 바로 다음에 명령 프롬프트가 옵니다.
유휴 버킷이 Nearline Storage로 마이그레이션되었는지 확인합니다.
gsutil defstorageclass get gs://$PROJECT_ID-idle-bucket
출력은 다음과 같습니다.
gs://automating-cost-optimization-idle-bucket: NEARLINE
프로덕션 환경 고려사항
고유 Google Cloud 환경에서 비용 최적화를 자동화할 때는 다음을 고려하세요.
- 일반 고려사항: Google Cloud 리소스를 수정하거나 삭제할 수 있는 권한이 있는 Cloud Functions에 대해 보안을 강화해야 합니다.
- 낭비 확인: 이 문서에서는 낭비된 지출에 대한 몇 가지 예시를 보여줍니다.
이외에도 이 세 가지 범주 중 하나에 포함되는 예시가 많이 있습니다.
- 초과 프로비저닝된 리소스: CPU 및 메모리가 필요한 것보다 많이 설정된 VM과 같이, 제공된 워크로드에 대해 필요한 것보다 많이 프로비저닝된 리소스입니다.
- 유휴 리소스: 완전히 사용되지 않는 리소스입니다.
- 시간제 유휴 리소스: 업무 시간 중에만 사용되는 리소스입니다.
- 삭제 자동화: 이 문서에서는 디스크를 스냅샷하고 삭제하기 위해 여러 비동기 작업이 포함된 다단계 프로세스가 필요합니다. 사용되지 않는 IP 주소와 같은 다른 Google Cloud 리소스는 동기 작업을 사용할 수 있습니다.
- 대규모 배포: 이 문서에서는 Google Cloud 프로젝트 ID가 Cloud 함수 코드에 정의됩니다. 대규모로 이러한 솔루션을 배포하기 위해서는 Cloud Billing 또는 Cloud Resource Manager API를 사용하여 청구 계정 또는 조직의 프로젝트 목록을 가져올 수 있습니다. 그런 후 이러한 Google Cloud 프로젝트 ID를 함수에 대한 변수로 전달합니다. 이러한 구성에서는 Cloud 함수의 서비스 계정을 리소스 정리 또는 삭제가 가능한 프로젝트에 추가해야 합니다. Cloud Deployment Manager 또는 Terraform과 같은 자동화된 배포 프레임워크를 사용하는 것이 좋습니다.
- 알림 자동화: 이 문서에서는 Monitoring 알림에서 모의 페이로드를 사용하여 스토리지 클래스 마이그레이션을 트리거하는 방법을 보여줍니다. Monitoring 알림 정책은 최대 23시간 59분 내에 평가할 수 있습니다. 프로덕션 환경에서 이러한 제한은 버킷을 유휴 상태로 판단해서 해당 스토리지 클래스를 마이그레이션하는 데 충분히 길지 않을 수 있습니다. Cloud Storage 버킷에서 데이터 액세스 감사 로그를 사용 설정하고 버킷이 이전 30일 동안 서비스 제공을 위해 사용되었는지 여부를 확인하기 위해 이러한 감사 로그를 사용하는 파이프라인을 만드는 것이 좋습니다. 자세한 내용을 보려면 감사 로그 이해를 검토하고, 처리를 위해 Pub/Sub 및 Dataflow 파이프라인에 로그를 전송하도록 집계 싱크를 만듭니다.
삭제
이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.
프로젝트 삭제
- Google Cloud 콘솔에서 리소스 관리 페이지로 이동합니다.
- 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제를 클릭합니다.
- 대화상자에서 프로젝트 ID를 입력한 후 종료를 클릭하여 프로젝트를 삭제합니다.
다음 단계
- 비용 관리 동영상 보기
- 비용 관리 홈페이지 방문
- Cloud Billing 문서 검토
- Google Cloud에 대한 참조 아키텍처, 다이어그램, 권장사항 살펴보기. Cloud 아키텍처 센터 살펴보기