GCP GCE에서 Serverless 서비스인 Cloud Run (또는 Cloud Functions)을 호출하는 방안에 대해 기술합니다.
Cloud Run은 자동 스케일링, 관리 편의성 등의 장점이 있어, 유연하고 확장성 있는 서비스를 제공하는 목적에 적합한 선택입니다.
지난번 테스트에서는 GCE 인스턴스에서 Cloud Run(Function)을 호출하는 과정을 검증하였습니다.
순서는 아래와 같습니다.
1. GCE 인스턴스에서 GCP Metadata 서버를 통해 ID 토큰을 요청하여 인증 정보를 획득합니다.
2. 획득한 인증 토큰을 사용하여 Cloud Run(Function)을 호출합니다.
3. Function 내에서 GCE의 hostname을 수신 및 확인하고, 응답을 GCE로 반환합니다.
4. Cloud Logging을 통해 실행 여부 및 결과를 모니터링
이번 테스트도 동일하지만, 좀 더 명확하게 확인하기 위해 호출 메시지들을 수정했습니다.
GCE에서는 호출 성공 메시지에 사설, 공인 IP출력 Functions의 Cloud Logging에는 파이썬 버전, GCE의 사설, 공인IP, 호스트명을 출력되도록 설정
- GCE 소스
import socket import requests def get_gce_metadata(metadata_path): """GCE 메타데이터 서버에서 정보를 가져오는 함수""" metadata_server_url = f"http://metadata.google.internal/computeMetadata/v1/{metadata_path}" headers = {"Metadata-Flavor": "Google"} try: response = requests.get(metadata_server_url, headers=headers, timeout=5) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(f"Error fetching metadata from {metadata_path}: {e}") return None def send_info_to_cloud_function(function_url, payload): """주어진 정보를 Cloud Function으로 전송하는 함수""" headers = {"Content-Type": "application/json"} # --- ID 토큰 가져오기 --- audience = function_url id_token = get_gce_metadata(f"instance/service-accounts/default/identity?audience={audience}") if not id_token: print("Failed to get ID token. Aborting.") return headers["Authorization"] = f"Bearer {id_token}" print("✅ ID Token successfully fetched and added to headers.") # --- Cloud Function 호출 --- try: response = requests.post(function_url, json=payload, headers=headers, timeout=10) response.raise_for_status() print(f"✅ Cloud Function Response: {response.json()}") except requests.exceptions.RequestException as e: print(f"Error calling Cloud Function: {e}") if hasattr(e, 'response') and e.response is not None: print(f"Cloud Function error response: {e.response.text}") if __name__ == "__main__": # 1. Cloud Function URL을 설정합니다. (실제 URL로 변경필요) cloud_function_trigger_url = "YOUR_CLOUD_FUNCTION_URL" if "YOUR_CLOUD_FUNCTION_URL" in cloud_function_trigger_url: print("❌ 오류: Cloud Function의 트리거 URL을 스크립트에 정확히 설정필요") else: # 2. GCE VM의 정보를 수집합니다. hostname = socket.gethostname() internal_ip = get_gce_metadata("instance/network-interfaces/0/ip") external_ip = get_gce_metadata("instance/network-interfaces/0/access-configs/0/external-ip") print("--- GCE VM Info ---") print(f"Hostname: {hostname}") print(f"Internal IP: {internal_ip}") print(f"External IP: {external_ip}") print("--------------------") # 3. Cloud Function에 보낼 데이터 '꾸러미(payload)'를 만듭니다. payload_to_send = { "gce_hostname": hostname, "gce_internal_ip": internal_ip, "gce_external_ip": external_ip } # 4. 정보를 담아 Cloud Function을 호출합니다. send_info_to_cloud_function(cloud_function_trigger_url, payload_to_send)
Cloud Run(Function)소스import functions_framework import flask @functions_framework.http def log_caller_info(request: flask.Request) -> flask.Response: """HTTP Cloud Function that logs caller's info and returns it.""" # --- 1. 요청 헤더에서 호출자 정보 확인 --- # request.headers는 '편지 봉투'에 적힌 발신자 정보와 같아요. user_agent = request.headers.get('User-Agent') # 'X-Forwarded-For'는 로드밸런서를 거쳐올 때 실제 클라이언트 IP를 담고 있어요. # GCE에서 호출했으므로, GCE의 외부 IP가 찍힐 거예요. source_ip = request.headers.get('X-Forwarded-For') print("--- [Request Info] ---") print(f"Source IP (from X-Forwarded-For): {source_ip}") print(f"User-Agent: {user_agent}") # --- 2. GCE가 보낸 데이터(payload) 확인 --- caller_data = {} if request.method == "POST": data = request.get_json(silent=True) if data: # GCE가 보낸 정보들을 '편지 내용'에서 꺼내옵니다. caller_data['hostname'] = data.get('gce_hostname') caller_data['internal_ip'] = data.get('gce_internal_ip') caller_data['external_ip'] = data.get('gce_external_ip') print("--- [Caller-Provided Info] ---") print(f"GCE Hostname: {caller_data['hostname']}") print(f"GCE Internal IP: {caller_data['internal_ip']}") print(f"GCE External IP: {caller_data['external_ip']}") # --- 3. 응답 보내기 --- if caller_data.get('hostname'): return flask.jsonify({ "status": "success", "message": "Caller information received and logged.", "received_data": caller_data }) else: return flask.jsonify({"error": "Required information not provided in payload."}), 400
- 결과확인
Cloud logging에서 User-Agent, Hostname, IP를 확인할 수 있습니다.
GCE에서는 토큰 발급 성공과 Cloud Function에 보낸 정보가 정상적으로 보냈는지 확인이 가능합니다.
'Cloud > GCP' 카테고리의 다른 글
GCE에서 Cloud Run(Function) 호출 테스트 (1) | 2025.06.07 |
---|---|
[GCP] 스냅샷으로 신규 VM 만들기: 콘솔(수동) & CLI/쉘(자동화) 가이드 (4) | 2025.06.01 |
[GCP] Cloud SQL Backup을 Cloud Run(Function), Cloud Scheduler을 통해 정기적으로 백업 받기 (0) | 2025.05.25 |
[GCP] Cloud SQL 백업을 타프로젝트 및 다른 인스턴스로 복원하기 (gcloud+shell script) (0) | 2025.05.21 |
[GCP] Secret Manager Key 자동 삭제 스크립트 (0) | 2025.05.13 |
[GCP] Cloud SQL 사용 현황, GUI보다 빠르고 정확하게 파악하기 (gcloud & Shell Script 활용) (0) | 2025.05.03 |
[GCP] 전체 프로젝트의 Cloud storage 사용량 조회 (0) | 2025.04.22 |