군만두의 IT 개발 일지

[구글 클라우드 스터디잼] API Developer Learning Path 본문

학습일지

[구글 클라우드 스터디잼] API Developer Learning Path

mandus 2026. 5. 8. 20:46

목차

     

    구글 클라우드 스터디잼에 참가하여 'API Developer Learning Path' 중 'Google Cloud 기초: Cloud Storage 및 Cloud SQL 시작하기' 실습을 위주로 학습한 내용을 정리했습니다.

    1. 클라우드 컴퓨팅의 기초

    1.1 클라우드 컴퓨팅의 5가지 특성

    • 사람의 개입 없이 웹 인터페이스로 컴퓨팅 자원을 직접 확보함.
    • 인터넷을 통해 어디서나 자원에 접근 가능함.
    • 클라우드 제공업체가 거대한 리소스 풀을 보유하며, 물리적 위치를 신경 쓸 필요 없음.
    • 필요할 때 빠르게 확장하고, 불필요하면 축소 가능함.
    • 사용한 만큼만 비용을 지불함.

    1.2 클라우드 서비스 모델

    모델 관리 책임 특징 Google Cloud 예시
    IaaS 고객이 OS 이상 관리 가상 인프라 자원 제공 Compute Engine
    PaaS 고객은 코드만 관리 인프라 추상화, 실사용량 과금 App Engine
    Serverless 고객은 함수/컨테이너만 관리 서버 관리 불필요, 이벤트 기반 Cloud Run, Cloud Run Functions
    SaaS 제공업체가 전부 관리 완성된 애플리케이션 제공 Gmail, Google Docs

     

    이번 실습은 IaaS(Compute Engine) + 관리형 서비스(Cloud SQL, Cloud Storage)으로 진행했습니다.

    1.3 Google Cloud 리소스 계층 구조

    • Google Cloud는 리소스 → 프로젝트 → 폴더 → 조직 노드의 4단계 계층으로 구성됨.
      • 리소스: VM, Cloud Storage 버킷, BigQuery 테이블 등 실제 자원
      • 프로젝트: 모든 리소스가 속하는 기본 단위 (결제, API, 권한의 기준)
      • 폴더: 부서나 팀 단위로 프로젝트를 그룹화
      • 조직 노드: 회사 전체를 대표하는 최상위 노드
    • 상위에서 정의한 정책은 하위 리소스로 자동 상속됨 → 권한 관리가 효율적임
    프로젝트는 프로젝트 ID(전역 고유, 변경 불가), 프로젝트 이름(변경 가능), 프로젝트 번호(Google이 할당)의 3가지 식별자를 가짐. 실습에서 사용하는 $DEVSHELL_PROJECT_ID가 프로젝트 ID에 해당함.

    1.4 리전(Region)과 영역(Zone)

    • 리전: 독립적인 지리적 구역 (예: us-central1, asia-northeast3)
    • 영역: 리전 내부의 배포 단위 (예: us-central1-c) *한 리전은 보통 3개 이상의 영역으로 구성됨.
    • 리소스는 영역에 배포되며, 자연재해 등으로 한 영역에 장애가 나도 다른 영역의 복제본으로 가용성을 확보할 수 있음.
    • 현재 Google Cloud는 40개 이상의 리전과 121개 이상의 영역을 운영 중임.
    이번 실습에서 bloghost VM과 blog-db Cloud SQL을 모두 us-central1-c 영역에 배치한 이유는 클라이언트와 데이터베이스를 같은 영역에 두면 네트워크 지연 시간이 가장 짧아지기 때문임.

    2. Google Cloud의 스토리지 옵션

    2.1 5가지 주요 스토리지 제품

    제품 데이터 유형 주 사용 사례
    Cloud Storage 비정형 (객체) 이미지, 동영상, 백업, 정적 파일
    Cloud SQL 관계형 (트랜잭션) MySQL/PostgreSQL/SQL Server 기반 OLTP
    Spanner 관계형 (글로벌 분산) 전 세계 단위의 강한 일관성 트랜잭션
    Firestore NoSQL 문서 모바일/웹 앱의 실시간 동기화
    Bigtable NoSQL 와이드 컬럼 대규모 분석, 시계열, IoT 데이터

     

    이번 실습에서는 Cloud Storage(이미지)Cloud SQL(관계형 DB) 두 가지를 함께 사용함.

    2.2 Cloud Storage 핵심 개념

    객체 스토리지란

    • 파일 계층(파일 스토리지)이나 디스크 청크(블록 스토리지)가 아닌 '객체' 단위로 데이터를 관리하는 아키텍처임.
    • 각 객체는 실제 데이터 + 메타데이터(생성일, 작성자, 권한 등) + 전역 고유 식별자(URL)로 구성됨.
    • 고유 키가 URL 형식이므로 웹 기술과 자연스럽게 통합됨 → 이번 실습에서 <img src='...'>로 바로 이미지를 불러올 수 있는 이유임.

    버킷(Bucket)의 특성

    • Cloud Storage 파일은 버킷이라는 컨테이너로 조직됨.
    • 버킷 이름은 전역적으로 고유해야 함. 실습에서는 $DEVSHELL_PROJECT_ID를 그대로 버킷 이름으로 사용함.
    • 버킷은 단일 리전 또는 멀티 리전(US/EU/ASIA)과 연결됨. 사용자에게 가까운 위치를 선택해 지연 시간을 줄임.

    객체 불변성과 버전 관리

    • Cloud Storage 객체는 변경 불가(immutable)하므로 수정하지 않고 새 버전을 생성함.
    • 버전 관리(versioning)를 활성화하면 덮어쓰기/삭제 이력이 모두 보관되므로 복원 가능함.
    • 비활성화 시 새 버전이 이전 버전을 완전히 덮어씀.

    액세스 제어(IAM vs ACL)

    IAM ACL(Access Control List)
    프로젝트/버킷 단위 권한 객체 단위의 세밀한 권한
    대부분의 경우 IAM만으로 충분 특정 객체만 공개하는 등 세밀한 제어가 필요할 때 사용
    역할이 상위에서 하위로 상속됨 '범위(누가)'와 '권한(무엇을)'으로 구성됨
    실습에서 gsutil acl ch -u allUsers:R 명령어로 특정 이미지 객체만 모두에게 읽기 권한을 부여한 부분이 ACL의 사용 예시임. 버킷 전체가 아니라 해당 객체 하나만 공개로 만든 것임.

    수명 주기 관리(Lifecycle)

    • 비용 최적화를 위해 자동 삭제/이동 규칙을 설정할 수 있음.
    • 예: 365일 지난 객체 자동 삭제, 최신 3개 버전만 유지 등

    2.3 Cloud SQL 핵심 개념

    • MySQL, PostgreSQL, SQL Server를 완전 관리형으로 제공하는 서비스임.
    • 백업, 복제, 패치, 장애 조치(failover)를 Google이 자동 처리함. → 개발자는 데이터 모델링과 쿼리에만 집중 가능함.
    • 네트워크 보안 모델: 기본적으로 외부 접근이 차단됨. → 접속을 허용하려면 승인된 네트워크(Authorized Networks)에 클라이언트 IP를 등록해야 함.

    3. 실습 아키텍처

    이번 실습에서 구축하는 미니 블로그 시스템의 구조는 다음과 같습니다.

    구성 요소 역할 위치
    Compute Engine VM (bloghost) Apache + PHP 웹 서버 us-central1-c
    Cloud SQL (blog-db) MySQL 데이터베이스 us-central1-c
    Cloud Storage 버킷 배너 이미지(정적 파일) 저장 US 멀티 리전

     

    요청 흐름: 사용자 브라우저 → bloghost VM의 Apache → (PHP가 Cloud SQL에 PDO로 연결) + (Cloud Storage 공개 URL로 이미지 로드) → 응답

    4. 실습 진행 과정

    4.1 Compute Engine VM 인스턴스 배포

    웹 서버 역할을 할 bloghost VM을 생성했습니다. 설정은 다음과 같습니다.

    항목
    이름 bloghost
    리전 / 영역 us-central1 / us-central1-c
    머신 유형 e2-standard-2
    OS 이미지 Debian GNU/Linux 12 (bookworm)
    방화벽 HTTP 트래픽 허용

     

    시작 스크립트(Startup Script)를 통해 VM이 부팅될 때 자동으로 Apache, PHP, php-mysql 모듈을 설치합니다.

    #!/bin/bash
    apt-get install apache2 php php-mysql -y
    service apache2 restart
    VM을 여러 번 재배포하거나 오토스케일링으로 인스턴스를 늘릴 때, 매번 SSH로 들어가 패키지를 설치하는 것은 비효율적임. 시작 스크립트는 인프라를 코드로 관리하는 첫 단계임.

    ▲ VM 인스턴스 생성 / bloghost VM 생성 완료

    4.2 Cloud Storage 버킷 생성 및 객체 업로드

    콘솔 UI 대신 Cloud Shell의 gcloud storage 명령어를 사용합니다. 자동화 관점에서 CLI가 훨씬 강력합니다.

    # 1. 위치 환경 변수 설정
    export LOCATION=US
    
    # 2. 프로젝트 ID와 동일한 이름으로 버킷 생성 (전역 고유성 확보)
    gcloud storage buckets create -l $LOCATION gs://$DEVSHELL_PROJECT_ID
    
    # 3. Google이 제공한 샘플 배너 이미지를 로컬로 다운로드
    gcloud storage cp gs://cloud-training/gcpfci/my-excellent-blog.png my-excellent-blog.png
    
    # 4. 내 버킷으로 업로드
    gcloud storage cp my-excellent-blog.png gs://$DEVSHELL_PROJECT_ID/my-excellent-blog.png
    
    # 5. 해당 객체만 모든 사용자에게 읽기 권한 부여 (ACL 변경)
    gsutil acl ch -u allUsers:R gs://$DEVSHELL_PROJECT_ID/my-excellent-blog.png
    $DEVSHELL_PROJECT_ID란? Cloud Shell 환경에 자동으로 주입되는 환경 변수임. 현재 활성화된 프로젝트 ID가 담겨 있어서 별도로 입력하지 않아도 명령어에서 바로 사용할 수 있음.

    ▲ Cloud Shell에서 버킷 생성 및 파일 업로드 명령어 실행

    4.3 Cloud SQL 인스턴스 생성

    항목
    엔진 MySQL
    버전 사전 설정 샌드박스 (학습/실습용 저비용 구성)
    인스턴스 ID blog-db
    리전 / 영역 us-central1 / us-central1-c (단일 영역)
    비밀번호 Passw0rd1!
    보안 암호화되지 않은 네트워크 트래픽 허용 (실습용)

    인스턴스 생성 후 다음 두 가지를 추가로 설정함.

    1. 사용자 추가: blogdbuser / Passw0rd1!
    2. 승인된 네트워크 추가: web front end라는 이름으로 bloghost VM의 외부 IP + /32를 등록 (단일 IP만 허용한다는 의미)
    /32인 이유는? CIDR 표기법에서 /32는 단 하나의 IPv4 주소를 의미함. "오직 이 IP 한 대에서만 접속을 허용한다"는 가장 좁은 범위의 화이트리스트임. 보안의 기본 원칙인 최소 권한(Principle of Least Privilege)을 따른 것임.

    ▲ Cloud SQL 인스턴스 생성 / 사용자 추가 / 네트워크 등록

    4.4 PHP 애플리케이션에서 Cloud SQL 연결

    bloghost VM에 SSH로 접속하여 /var/www/html/index.php를 작성합니다. PDO(PHP Data Objects)를 통한 MySQL 연결이 핵심입니다.

    <?php
    $dbserver = "CLOUDSQLIP";   // Cloud SQL 인스턴스의 공개 IP
    $dbuser = "blogdbuser";
    $dbpassword = "DBPASSWORD"; // 실제 운영에서는 Secret Manager 사용
    
    try {
      // PDO 객체로 MySQL 연결
      $conn = new PDO("mysql:host=$dbserver;dbname=mysql", $dbuser, $dbpassword);
      // 에러 발생 시 예외를 던지도록 설정
      $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
      echo "Connected successfully";
    } catch(PDOException $e) {
      echo "Database connection failed:: " . $e->getMessage();
    }
    ?>
    실제 서비스에서는 DB 비밀번호를 소스 코드에 평문으로 넣어선 안 됨. Google Cloud는 이를 위해 Secret Manager를 제공하며, 환경 변수나 IAM 기반 인증(예: Cloud SQL Auth Proxy)을 사용하는 것이 권장됨.

     

    설정 후 Apache를 재시작하고 브라우저에서 http://[VM 외부 IP]/index.php로 접속하면 Connected successfully 메시지를 확인할 수 있습니다.

    ▲ SSH 터미널에서 nano로 index.php 편집 / 브라우저에서 Connected successfully 메시지 확인

    4.5 Cloud Storage 객체를 웹페이지에 통합

    앞서 ACL로 공개해둔 이미지의 URL을 index.php에 추가합니다.

    <img src='https://storage.googleapis.com/[버킷명]/my-excellent-blog.png'>
    <h1>Welcome to my excellent blog</h1>

    Apache 재시작 후 페이지를 새로고침하면 배너 이미지가 정상 표시됩니다. 이때 이미지는 VM의 디스크가 아니라 Cloud Storage에서 직접 서빙되고 있습니다.

    아키텍처 관점: 정적 파일(이미지, CSS, JS)을 VM 디스크가 아닌 객체 스토리지에 분리하면, ① VM 디스크 용량을 절약하고 ② CDN과 연동하기 쉬우며 ③ VM이 여러 대로 늘어나도 모든 인스턴스가 동일한 파일을 참조할 수 있음. Stateless 웹 서버를 만드는 출발점임.

    ▲ 최종 완성된 블로그 페이지

    5. 트러블슈팅: 승인된 네트워크에 잘못된 IP를 입력

    실습 도중 가장 헷갈렸던 부분입니다. Cloud SQL의 승인된 네트워크에 DB 인스턴스 자신의 공개 IP를 입력하는 실수를 했습니다.

    • 승인된 네트워크는 이 DB에 접속해 올 클라이언트의 IP를 등록하는 곳임.
    • DB 입장에서 외부에서 들어오는 요청의 출발지 IP를 화이트리스트에 추가해야 함.
    • DB 자기 자신의 IP를 등록하는 것은 의미가 없음. "누가 누구에게 접속하는가"를 명확히 머릿속에 그리지 못하여 발생한 실수임.

    6. 정리

    • 관심사의 분리: 컴퓨팅(VM), 관계형 데이터(Cloud SQL), 정적 파일(Cloud Storage)을 각각 적합한 서비스에 위임함.
    • 관리형 서비스의 가치: MySQL을 VM에 직접 설치하지 않고 Cloud SQL을 사용함으로써 백업/패치/복제를 위임함.
    • 네트워크 보안의 기본: 승인된 네트워크와 /32 CIDR로 최소 권한 원칙을 실천함.
    • 객체 스토리지의 사용 패턴: ACL로 객체 단위 공개 권한을 부여하고, URL 형태의 고유 식별자를 그대로 <img> 태그에 사용함.
    전통적인 방식 이번 실습 방식
    한 서버에 Apache + MySQL + 정적 파일을 모두 배치 역할별로 서비스를 분리
    스케일 아웃이 어려움 (DB와 파일이 한 서버에 묶임) 각 계층을 독립적으로 확장 가능
    장애 시 전체 서비스 중단 장애 영역이 분리되어 가용성 향상
    백업/패치를 직접 관리 관리형 서비스에 위임

     

    이 글은 '2026 구글 클라우드 스터디잼'에서 학습한 내용을 바탕으로 작성되었습니다.
    Comments