Compute Engine 및 Cloud Storage에서 Cloud DNS를 사용하여 복구 가능한 웜 웹 서버 배포

Last reviewed 2021-06-28 UTC

이 문서는 운영팀 및 관리팀에 근무하는 설계자와 사용자를 대상으로 합니다. 이 문서에서는 Google Cloud에서 고유한 배포에 사용할 수 있는 패턴의 예시를 설명합니다.

이 아키텍처에서 Cloud DNS는 콘텐츠를 제공하는 관리형 인스턴스 그룹Compute Engine 인스턴스로 트래픽을 전달합니다. 서비스 중단 시에는 Cloud DNS 영역을 업데이트하고 Cloud Storage의 정적 사이트로 장애 조치합니다.

이 솔루션을 배포하려면 본인이 제어하고 있으며 이 문서에서 사용하려는 등록된 도메인 이름이 필요합니다.

프로덕션 배포 시 웹사이트에는 이 문서에 나와 있는 것보다 더 많은 파일과 관리형 인스턴스 그룹 가상 머신(VM)의 추가 애플리케이션 코드가 포함될 수 있습니다. 그러면 Cloud Storage가 최소한의 기능을 제공하는 보다 제한된 정적 버전을 호스팅합니다. 웜 장애 조치 시나리오에서는 관리형 인스턴스 그룹이 복구되고 전체 웹사이트 환경을 위해 트래픽을 제공할 수 있을 때까지 사용자에게 이 제한된 웹사이트가 표시됩니다.

아키텍처

이 아키텍처에서는 다음 이미지와 같이 리소스를 배포하여 환경을 만듭니다.

Cloud DNS는 외부 부하 분산기 뒤의 관리형 인스턴스 그룹으로 사용자를 안내하고 전체 웹사이트 경험을 표시합니다.

장애 조치를 수행해야 하는 경우 다음 이미지와 같이 Cloud Storage로 트래픽을 보내도록 Cloud DNS 구성을 업데이트합니다.

Cloud DNS는 이제 사용자를 Cloud Storage에서 호스팅되고 더 제한적인 환경을 표시하는 정적 웹사이트로 안내합니다.

이 웜 장애 조치 패턴은 기본 리전에 장애가 발생할 때만 사용하는 다른 리전에서 다른 관리형 인스턴스 그룹을 실행하는 비용의 균형을 맞춥니다. Cloud Storage를 사용하는 정적 사이트의 비용은 다른 관리형 인스턴스 그룹을 실행하는 비용보다 저렴하지만 호스팅 옵션 간 Cloud DNS를 업데이트할 때 약간의 지연이 발생합니다. Cloud Storage의 제한된 웹사이트 환경은 완전히 사용할 수 없는 웹사이트와 열악한 고객 경험을 제공하는 것보다 낫습니다.

장애 조치 제어를 위해 Cloud DNS 대신 외부 애플리케이션 부하 분산기를 사용하는 대체 접근 방법은 Compute Engine 및 Cloud Storage를 사용하여 복구 가능한 웜 웹 서버 배포를 참조하세요. 이 패턴은 아직 Cloud DNS가 없거나 이를 사용하길 원하지 않는 경우에 유용합니다.

Google Cloud에서 안정적인 애플리케이션을 실행하려면 서비스 중단을 처리하도록 애플리케이션 인프라를 설계하는 것이 좋습니다. 애플리케이션 및 비즈니스 요구사항에 따라 콜드 장애 조치, 웜 장애 조치 또는 핫 장애 조치 패턴이 필요할 수 있습니다. 고유 애플리케이션별로 최적의 방법을 결정하는 방법에 대한 자세한 내용은 재해 복구 계획 가이드를 참조하세요.

이 문서에서는 기본 Apache 웹 서버를 사용하지만 인프라 배포에 적용되는 동일한 접근 방식이 만들어야 하는 다른 애플리케이션 환경에도 적용됩니다.

목표

  • 커스텀 VM 이미지를 사용하여 리전 관리형 인스턴스 그룹을 만듭니다.
  • Cloud Storage 버킷을 만듭니다.
  • Cloud DNS 영역을 만들고 구성합니다.
  • 업데이트된 Cloud DNS 레코드를 사용하여 웜 웹 서버 장애 조치를 테스트합니다.
  • 업데이트된 Cloud DNS 레코드를 사용하여 복구 및 장애 복구를 테스트합니다.

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

조직에서 정의한 보안 제약조건으로 인해 다음 단계를 완료하지 못할 수 있습니다. 문제 해결 정보는 제한된 Google Cloud 환경에서 애플리케이션 개발을 참조하세요.

  1. Google Cloud 계정에 로그인합니다. Google Cloud를 처음 사용하는 경우 계정을 만들고 Google 제품의 실제 성능을 평가해 보세요. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.
  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Compute Engine API 사용 설정

    API 사용 설정

  5. Google Cloud CLI를 설치합니다.
  6. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

    gcloud init
  7. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기로 이동

  8. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  9. Compute Engine API 사용 설정

    API 사용 설정

  10. Google Cloud CLI를 설치합니다.
  11. gcloud CLI를 초기화하려면 다음 명령어를 실행합니다.

    gcloud init
  12. Google Cloud CLI를 설치하지 않고도 Google Cloud 콘솔에서 Google Cloud CLI를 실행할 수 있습니다. Google Cloud 콘솔에서 gcloud CLI를 실행하려면 Cloud Shell을 사용합니다.

환경 준비

이 섹션에서는 리소스 이름과 위치에 대한 몇 가지 변수를 정의합니다. 이러한 변수는 리소스를 배포할 때 Google Cloud CLI 명령어에서 사용됩니다.

이 배포를 통틀어 달리 명시하지 않는 한, 모든 명령어를 Cloud Shell 또는 로컬 개발 환경에 입력합니다.

  1. 여기서 PROJECT_ID는 프로젝트 ID로 바꿉니다. 원하는 경우 app과 같이 리소스를 검색하고 식별하는 데 도움이 되는 자체 이름 서픽스를 리소스에 제공합니다.

    us-west1us-west2과 같은 두 개의 리전과 이러한 리전 중 하나 내에 있는 영역(예: us-west1-a)을 지정합니다. 이 영역은 관리형 인스턴스 그룹의 이미지를 만드는 데 사용되는 초기 기본 VM이 생성되는 위치를 정의합니다.

    마지막으로 정적 웹사이트에 사용되는 도메인을 설정합니다(예: example.com).

    PROJECT_ID=PROJECT_ID
    NAME_SUFFIX=app
    REGION1=us-west1
    REGION2=us-west2
    ZONE=us-west1-a
    DOMAIN=example.com
    

VPC 및 서브넷 만들기

VM에 대한 네트워크 액세스 권한을 제공하려면 Virtual Private Cloud(VPC) 및 서브넷을 만듭니다. 두 리전에 관리형 인스턴스 그룹이 필요하므로 각 리전에 하나의 서브넷을 만듭니다. 환경에서 사용 중인 IP 주소 범위를 관리하기 위한 커스텀 서브넷 모드의 이점에 대한 자세한 내용은 커스텀 모드 VPC 네트워크 사용을 참조하세요.

  1. 커스텀 서브넷 모드로 VPC를 만듭니다.

    gcloud compute networks create network-$NAME_SUFFIX --subnet-mode=custom
    
  2. 이제 새 VPC에서 각 리전에 하나씩 두 개의 서브넷을 만듭니다. 네트워크 범위에 적합한 자체 주소 범위(예: 10.1.0.0/2010.2.0.0/20)를 정의합니다.

    gcloud compute networks subnets create \
        subnet-$NAME_SUFFIX-$REGION1 \
        --network=network-$NAME_SUFFIX \
        --range=10.1.0.0/20 \
        --region=$REGION1
    
    gcloud compute networks subnets create \
        subnet-$NAME_SUFFIX-$REGION2 \
        --network=network-$NAME_SUFFIX \
        --range=10.2.0.0/20 \
        --region=$REGION2
    

방화벽 규칙 만들기

VPC에서 네트워크 트래픽 흐름을 올바르게 하려면 방화벽 규칙을 사용합니다.

  1. 부하 분산기 및 관리형 인스턴스 그룹의 웹 트래픽 및 상태 확인을 허용하는 방화벽 규칙을 만듭니다.

    gcloud compute firewall-rules create allow-http-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --rules=tcp:80 \
        --source-ranges=0.0.0.0/0 \
        --target-tags=http-server
    
    gcloud compute firewall-rules create allow-health-check-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --action=allow \
        --direction=ingress \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 \
        --target-tags=allow-health-check \
        --rules=tcp:80
    

    HTTP 규칙은 http-server 태그가 적용되는 모든 VM에 대한 트래픽과 0.0.0.0/0 범위를 사용하는 모든 소스로부터의 트래픽을 허용합니다. 상태 확인 규칙의 경우 Google Cloud의 기본 범위는 플랫폼이 리소스 상태를 올바르게 확인할 수 있도록 설정됩니다.

  2. 기본 VM 이미지의 초기 구성에 대해 SSH 트래픽을 허용하려면 --source-range 매개변수를 사용하여 해당 환경에 대한 방화벽 규칙 범위를 지정합니다. 조직에 사용되는 소스 범위를 결정하려면 네트워크 팀과 협력이 필요할 수 있습니다.

    IP_ADDRESS_SCOPE를 고유 IP 주소 범위로 바꿉니다.

    gcloud compute firewall-rules create allow-ssh-$NAME_SUFFIX \
        --network=network-$NAME_SUFFIX \
        --direction=INGRESS \
        --priority=1000 \
        --action=ALLOW \
        --rules=tcp:22 \
        --source-ranges=IP_ADDRESS_SCOPE
    
  3. 방화벽 규칙을 만든 후 다음 세 가지 규칙이 추가되었는지 확인합니다.

    gcloud compute firewall-rules list \
        --project=$PROJECT_ID \
        --filter="NETWORK=network-$NAME_SUFFIX"
    

    다음 예시 출력은 3개 규칙이 올바르게 생성된 것을 보여줍니다.

    NAME                    NETWORK      DIRECTION  PRIORITY  ALLOW
    allow-health-check-app  network-app  INGRESS    1000      tcp:80
    allow-http-app          network-app  INGRESS    1000      tcp:80
    allow-ssh-app           network-app  INGRESS    1000      tcp:22
    

기본 VM 이미지 만들기 및 구성

추가 구성 없이 배포하는 VM을 만들려면 커스텀 VM 이미지를 사용합니다. 이 이미지는 OS 및 Apache 구성을 캡처하며 다음 단계에서 관리형 인스턴스 그룹에 각 VM을 만드는 데 사용됩니다.

VM에서 영구 디스크에 기본 index.html 파일을 만들고 /var/www/example.com에 마운트합니다. /etc/apache2/sites-available/example.com.conf의 Apache 구성 파일은 마운트된 영구 디스크 위치로부터 웹 콘텐츠를 제공합니다.

다음 다이어그램은 영구 디스크에 저장된 Apache에서 제공하는 기본 HTML 페이지를 보여줍니다.

VM에는 마운트된 디스크 위치에서 로드할 Apache 구성 파일이 있는 영구 디스크에 저장된 기본 HTML 페이지가 포함됩니다.

다음 단계에서 이 환경을 빌드합니다.

  1. 연결된 영구 디스크가 있는 기본 VM을 만듭니다.

    gcloud compute instances create vm-base-$NAME_SUFFIX \
        --zone=$ZONE \
        --machine-type=n1-standard-1 \
        --subnet=subnet-$NAME_SUFFIX-$REGION1 \
        --tags=http-server \
        --image=debian-10-buster-v20210420 \
        --image-project=debian-cloud \
        --boot-disk-size=10GB \
        --boot-disk-type=pd-balanced \
        --boot-disk-device-name=vm-base-$NAME_SUFFIX \
        --create-disk=type=pd-ssd,name=disk-base-$NAME_SUFFIX,size=10GB,device-name=disk-base-$NAME_SUFFIX
    

    이 문서의 시작 부분에 정의된 매개변수를 사용하여 VM의 이름을 지정하고 올바른 서브넷에 연결합니다. 또한 부팅 디스크 및 데이터 디스크에 대한 매개변수로부터 이름을 할당합니다.

  2. 간단한 웹사이트를 설치하고 구성하려면 먼저 SSH를 사용하여 기본 VM에 연결합니다.

    gcloud compute ssh vm-base-$NAME_SUFFIX --zone=$ZONE
    
  3. VM에 대한 SSH 세션에서 원하는 편집기로 VM을 구성하는 스크립트를 만듭니다. 다음 예시에서는 Nano를 편집기로 사용합니다.

    nano configure-vm.sh
    

    다음 구성 스크립트를 파일에 붙여넣습니다.

    #!/bin/bash
    
    NAME_SUFFIX=app
    
    # Create directory for the basic website files
    sudo mkdir -p /var/www/example.com
    sudo chmod a+w /var/www/example.com
    sudo chown -R www-data: /var/www/example.com
    
    # Find the disk name, then format and mount it
    DISK_NAME="google-disk-base-$NAME_SUFFIX"
    DISK_PATH="$(find /dev/disk/by-id -name "${DISK_NAME}" | xargs -I '{}' readlink -f '{}')"
    
    sudo mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard $DISK_PATH
    sudo mount -o discard,defaults $DISK_PATH /var/www/example.com
    
    # Install Apache
    sudo apt-get update && sudo apt-get -y install apache2
    
    # Write out a basic HTML file to the mounted persistent disk
    sudo tee -a /var/www/example.com/index.html >/dev/null <<'EOF'
    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a Compute Engine website with warm failover to Cloud Storage!</p>
    </body>
    </html>
    EOF
    
    # Write out an Apache configuration file
    sudo tee -a /etc/apache2/sites-available/example.com.conf >/dev/null <<'EOF'
    <VirtualHost *:80>
            ServerName www.example.com
    
            ServerAdmin webmaster@localhost
            DocumentRoot /var/www/example.com
    
            ErrorLog ${APACHE_LOG_DIR}/error.log
            CustomLog ${APACHE_LOG_DIR}/access.log combined
    </VirtualHost>
    EOF
    
    # Enable the Apache configuration file and reload service
    sudo a2dissite 000-default
    sudo a2ensite example.com.conf
    sudo systemctl reload apache2
    

    NAME_SUFFIX를 이 문서의 시작 부분에서 설정한 값과 일치하도록 업데이트합니다(예: app).

  4. 파일을 작성하고 편집기를 종료합니다. 예를 들어 Nano에서 Ctrl-O를 사용하여 파일을 작성하고 Ctrl-X로 종료합니다.

  5. 구성 스크립트를 실행 가능하게 만든 다음 실행합니다.

    chmod +x configure-vm.sh
    ./configure-vm.sh
    
  6. VM에 대한 SSH 세션을 종료합니다.

    exit
    
  7. VM의 IP 주소를 가져오고 curl을 사용하여 기본 웹페이지를 확인합니다.

    curl $(gcloud compute instances describe vm-base-$NAME_SUFFIX \
        --zone $ZONE \
        --format="value(networkInterfaces.accessConfigs.[0].natIP)")
    

    다음 예시 출력에 표시된 것처럼 기본 웹사이트가 반환됩니다.

    <!doctype html>
    
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a Compute Engine website with warm failover to Cloud Storage!</p>
    </body>
    </html>
    

    이 단계는 Apache가 올바르게 구성되었고 페이지가 연결된 영구 디스크에서 로드되었는지 확인합니다. 다음 섹션에서는 이 기본 VM을 사용하여 이미지를 만들고 시작 스크립트로 인스턴스 템플릿을 구성합니다.

Compute Engine 리소스 배포

이 웜 장애 조치 패턴은 관리형 인스턴스 그룹을 사용하여 VM을 실행합니다. 관리형 인스턴스 그룹은 두 리전에서 실행되며 각 그룹은 VM의 상태를 모니터링합니다. 서비스 중단이 발생하여 VM 중 하나가 실패하면 관리형 인스턴스 그룹이 VM을 다시 만듭니다. 이 구성은 Cloud Storage의 정적 사이트로의 웜 장애 조치 없이도 가용성이 높은 애플리케이션을 만듭니다.

  1. 이미지를 만들려면 먼저 VM을 중지해야 합니다.

    gcloud compute instances stop vm-base-$NAME_SUFFIX --zone=$ZONE
    
  2. 다음 명령어 집합을 실행하여 VM 이미지, 인스턴스 템플릿, 관리형 인스턴스 그룹을 만듭니다.

    # Create the base VM images
    gcloud compute images create image-$NAME_SUFFIX \
        --source-disk=vm-base-$NAME_SUFFIX \
        --source-disk-zone=$ZONE
    
    gcloud compute images create image-disk-$NAME_SUFFIX \
        --source-disk=disk-base-$NAME_SUFFIX \
        --source-disk-zone=$ZONE
    
    # Create instance templates
    gcloud compute instance-templates create template-$NAME_SUFFIX-$REGION1 \
        --machine-type=n1-standard-1 \
        --subnet=projects/$PROJECT_ID/regions/$REGION1/subnetworks/subnet-$NAME_SUFFIX-$REGION1 \
        --region=$REGION1 \
        --tags=http-server \
        --metadata=^,@^startup-script=\!\#\ /bin/bash$'\n'echo\ UUID=\`blkid\ -s\ UUID\ -o\ value\ /dev/sdb\`\ /var/www/example.com\ ext4\ discard,defaults,nofail\ 0\ 2\ \|\ tee\ -a\ /etc/fstab$'\n'mount\ -a \
        --image=image-$NAME_SUFFIX \
        --create-disk=image=image-disk-$NAME_SUFFIX,auto-delete=yes
    
    gcloud compute instance-templates create template-$NAME_SUFFIX-$REGION2 \
        --machine-type=n1-standard-1 \
        --subnet=projects/$PROJECT_ID/regions/$REGION2/subnetworks/subnet-$NAME_SUFFIX-$REGION2 \
        --region=$REGION2 \
        --tags=http-server \
        --metadata=^,@^startup-script=\!\#\ /bin/bash$'\n'echo\ UUID=\`blkid\ -s\ UUID\ -o\ value\ /dev/sdb\`\ /var/www/example.com\ ext4\ discard,defaults,nofail\ 0\ 2\ \|\ tee\ -a\ /etc/fstab$'\n'mount\ -a \
        --image=image-$NAME_SUFFIX \
        --create-disk=image=image-disk-$NAME_SUFFIX,auto-delete=yes
    
    # Create a health check for VM instances
    gcloud compute health-checks create http http-basic-check-$NAME_SUFFIX \
        --port 80
    
    # Create the managed instance groups
    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$REGION1 \
        --template=template-$NAME_SUFFIX-$REGION1 \
        --size=2 \
        --region=$REGION1 \
        --health-check=http-basic-check-$NAME_SUFFIX
    
    gcloud compute instance-groups managed create instance-group-$NAME_SUFFIX-$REGION2 \
        --template=template-$NAME_SUFFIX-$REGION2 \
        --size=2 \
        --region=$REGION2 \
        --health-check=http-basic-check-$NAME_SUFFIX
    

부하 분산기 만들기 및 구성

사용자가 웹사이트에 액세스하기 위해서는 관리형 인스턴스 그룹에서 실행되는 VM으로의 트래픽을 허용해야 합니다. 또한 관리형 인스턴스 그룹에 영역 오류가 발생할 경우 새로운 VM으로 트래픽을 자동으로 리디렉션해야 할 수 있습니다.

다음 섹션에서는 포트 80에서 HTTP 트래픽에 대한 백엔드 서비스를 사용하여 외부 HTTPS 부하 분산기를 만들고, 이전 단계에서 만든 상태 확인을 사용하고, 외부 IP 주소를 백엔드 서비스에 매핑합니다.

자세한 내용은 간단한 외부 HTTP 부하 분산기 설정 방법을 참조하세요.

  1. 애플리케이션의 부하 분산기를 만들고 구성합니다.

    # Configure port rules for HTTP port 80
    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$REGION1 \
        --named-ports http:80 \
        --region $REGION1
    
    gcloud compute instance-groups set-named-ports \
        instance-group-$NAME_SUFFIX-$REGION2 \
        --named-ports http:80 \
        --region $REGION2
    
    # Create a backend service and add the managed instance groups to it
    gcloud compute backend-services create \
        web-backend-service-$NAME_SUFFIX \
        --protocol=HTTP \
        --port-name=http \
        --health-checks=http-basic-check-$NAME_SUFFIX \
        --global
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$REGION1 \
        --instance-group-region=$REGION1 \
        --global
    
    gcloud compute backend-services add-backend \
        web-backend-service-$NAME_SUFFIX \
        --instance-group=instance-group-$NAME_SUFFIX-$REGION2 \
        --instance-group-region=$REGION2 \
        --global
    
    # Create a URL map for the backend service
    gcloud compute url-maps create web-map-http-$NAME_SUFFIX \
        --default-service web-backend-service-$NAME_SUFFIX
    
    # Configure forwarding for the HTTP traffic
    gcloud compute target-http-proxies create \
        http-lb-proxy-$NAME_SUFFIX \
        --url-map web-map-http-$NAME_SUFFIX
    
    gcloud compute forwarding-rules create \
        http-content-rule-$NAME_SUFFIX \
        --global \
        --target-http-proxy=http-lb-proxy-$NAME_SUFFIX \
        --ports=80
    
  2. 웹 트래픽에 대한 전달 규칙의 IP 주소를 가져옵니다.

    IP_ADDRESS=$(gcloud compute forwarding-rules describe http-content-rule-$NAME_SUFFIX \
        --global \
        --format="value(IPAddress)")
    
  3. curl을 사용하거나 웹브라우저를 열어 이전 단계의 부하 분산기 IP 주소를 사용하여 웹사이트를 확인합니다.

    curl $IP_ADDRESS
    

    부하 분산기 배포가 완료되고 백엔드로 트래픽을 올바르게 연결하려면 몇 분 정도 걸립니다. 부하 분산기 배포가 계속 수행되면 HTTP 404 오류가 반환됩니다. 필요한 경우 몇 분 정도 기다린 후 웹사이트 액세스를 다시 시도합니다.

    다음 예시 출력에 표시된 것처럼 기본 웹사이트가 반환됩니다.

    <!doctype html>
    
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a Compute Engine website with warm failover to Cloud Storage!</p>
    </body>
    </html>
    

스토리지 버킷 만들기 및 구성

Cloud Storage는 정적 웹사이트 파일을 저장하는 데 사용됩니다. 이 기본 예시에서는 VM과 약간 다른 텍스트를 사용하여 단일 파일을 만듭니다.

프로덕션 배포 시 웹사이트에는 이 문서에 나와 있는 것보다 더 많은 파일과 관리형 인스턴스 그룹 VM의 추가 애플리케이션 코드가 포함될 수 있습니다. Cloud Storage에서 호스팅되는 정적 버전은 최소한의 기능을 제공하는 좀 더 제한된 버전인 경우가 많습니다. 웜 장애 조치 시나리오에서 관리형 인스턴스 그룹이 복구되고 전체 웹사이트 환경을 위해 트래픽을 제공할 수 있을 때까지 Cloud Storage의 이 제한된 웹사이트가 표시됩니다.

  1. Cloud Storage 버킷에 사용할 도메인을 확인합니다.

  2. 소유하고 있으며 사용하려는 도메인의 이름과 일치하는 Cloud Storage 버킷을 만듭니다.

    gsutil mb gs://static-web.$DOMAIN
    

    이 문서의 시작 부분에서 정의한 DOMAIN 변수가 사용됩니다(예: example.com). 이 예시에서는 정적 파일을 static-web.example.com에 저장합니다.

  3. 다음 단계에서 Cloud Storage 버킷으로 복사할 로컬 파일을 만듭니다.

    cat <<EOF > index.html
    <!doctype html>
    <html lang=en>
    <head>
    <meta charset=utf-8>
        <title>HA / DR example</title>
    </head>
    <body>
        <p>Welcome to a test static web server with warm failover from Cloud Storage!</p>
    </body>
    </html>
    EOF
    
  4. 기본 HTML 파일을 Cloud Storage 버킷에 업로드합니다.

    gsutil cp index.html gs://static-web.$DOMAIN
    
  5. 사용자가 정적 웹 콘텐츠를 볼 수 있도록 Cloud Storage 버킷에서 적절한 권한을 설정합니다.

    gsutil iam ch allUsers:objectViewer gs://static-web.$DOMAIN
    
  6. index.html 파일을 기본 웹페이지로 제공하도록 Cloud Storage 버킷을 구성합니다.

    gsutil web set -m index.html gs://static-web.$DOMAIN
    

DNS 영역 및 레코드 만들기

관리형 인스턴스 그룹에 서비스 중단이 발생했을 때 Cloud Storage의 웜 정적 사이트로 트래픽이 전달되도록 하려면 Cloud DNS 영역을 만듭니다. 정상 조건에서 이 DNS 영역은 외부 부하 분산기를 통해 이전 섹션에서 생성된 관리형 인스턴스 그룹으로 트래픽을 전달합니다.

  1. Cloud DNS 영역을 만듭니다.

    gcloud dns managed-zones create zone-$NAME_SUFFIX \
        --dns-name=$DOMAIN \
        --description="DNS zone for warm site failover"
    

    이 문서의 시작 부분에서 정의한 DOMAIN 변수가 사용됩니다(예: example.com).

  2. Cloud DNS 영역의 세부정보를 가져옵니다.

    gcloud dns managed-zones describe zone-$NAME_SUFFIX
    

    다음 출력 예시는 ns-cloud-b1.googledomains.com과 같은 영역의 nameServers를 보여줍니다.

    [...]
    kind: dns#managedZone
    name: zone-app
    nameServers:
    - ns-cloud-b1.googledomains.com.
    - ns-cloud-b2.googledomains.com.
    - ns-cloud-b3.googledomains.com.
    - ns-cloud-b4.googledomains.com.
    
  3. Cloud DNS는 도메인에 대해 권한이 있어야 합니다. Cloud DNS 영역을 가리키는 도메인 등록 기관으로 네임서버(NS) 레코드를 만듭니다. 이전 단계에서 반환된 네임서버 주소를 사용합니다.

    자세한 내용 및 Google Domains 사용 예시는 네임서버 업데이트 방법을 참조하세요.

  4. Cloud DNS 영역에서 이전 섹션에서 가져온 부하 분산기 IP 주소를 사용하여 www에 대한 레코드를 추가합니다.

    gcloud dns record-sets transaction start \
        --zone=zone-$NAME_SUFFIX
    
    gcloud dns record-sets transaction add $IP_ADDRESS \
        --name=www.$DOMAIN \
        --ttl=300 \
        --type=A \
        --zone=zone-$NAME_SUFFIX
    

    이 레코드는 웹사이트에 대한 사용자 요청을 부하 분산기에서 관리형 인스턴스 그룹으로 안내합니다. 캐시된 DNS 레코드가 사용자에 대해 존재하는 기간을 줄이기 위해 TTL이 300초로 설정됩니다.

  5. 정적 웹사이트에 대해 Cloud Storage 버킷에서 사용되는 레코드를 만듭니다.

    gcloud dns record-sets transaction add c.storage.googleapis.com. \
        --name=static-web.$DOMAIN \
        --ttl=300 \
        --type=CNAME \
        --zone=zone-$NAME_SUFFIX
    

    이 예시에서는 static-web을 하위 도메인으로 사용합니다. c.storage.googleapis.com.은 그대로 둡니다. 사용자에 대해 캐시된 DNS 레코드가 존재하는 기간을 줄이기 위해 TTL이 300초로 설정됩니다.

  6. 마지막으로 영역에 대해 DNS 레코드 추가를 커밋합니다.

    gcloud dns record-sets transaction execute \
        --zone=zone-$NAME_SUFFIX
    

DNS 영역과 레코드 확인 및 테스트

영역 장애 조치를 시뮬레이션하기 전 리소스 배포를 검토합니다. 모든 리소스는 다음 이미지와 같이 환경을 지원하기 위해 생성되었습니다.

Cloud DNS는 외부 부하 분산기 뒤의 관리형 인스턴스 그룹으로 사용자를 안내하고 전체 웹사이트 경험을 표시합니다.

  • Cloud DNS 영역 레코드는 관리형 인스턴스 그룹 VM 간의 배포를 위해 부하 분산기로 사용자를 안내합니다.
  • 관리형 인스턴스 그룹에 장애가 발생하면 정적 웹페이지를 호스팅하도록 Cloud Storage 버킷이 구성됩니다.
  • Cloud DNS 영역은 Cloud Storage의 정적 사이트를 사용하도록 구성되어 있지만 현재 스토리지 버킷에 대한 요청을 해결하지 않습니다.

DNS 레코드와 테스트 결과를 보려면 Cloud DNS 서버에 대해 주소를 변환해야 합니다. 프로덕션 배포에서는 주소가 올바르게 변환되는지 테스트 및 확인한 후 적절하게 변환되도록 고유 DNS 서버를 업데이트해야 합니다. 이 문서에서는 고유 DNS 서버를 업데이트하는 단계에 대해 자세히 설명하지 않고, 정상 및 장애 조치 조건에서 트래픽 흐름을 올바르게 확인하는 방법만 다룹니다.

  1. Cloud DNS 영역의 세부정보를 다시 가져옵니다.

    gcloud dns managed-zones describe zone-$NAME_SUFFIX
    

    다음 출력 예시는 ns-cloud-b1.googledomains.com과 같은 영역의 nameServers를 보여줍니다.

    [...]
    kind: dns#managedZone
    name: zone-app
    nameServers:
    - ns-cloud-b1.googledomains.com.
    - ns-cloud-b2.googledomains.com.
    - ns-cloud-b3.googledomains.com.
    - ns-cloud-b4.googledomains.com.
    
  2. 이러한 네임서버 중 하나로 Cloud DNS 영역의 www 레코드를 변환하려면 dig 명령어를 사용합니다.

    dig @ns-cloud-b1.googledomains.com www.$DOMAIN
    

    이 예시에서는 이전 describe 명령어에서 반환된 ns-cloud-b1.googledomains.com 네임서버 주소를 사용합니다. 이전 명령어의 결과에 표시된 고유 네임스페이스 주소를 제공합니다.

    다음 예시 출력은 레코드가 부하 분산기의 IP 주소로 변환되는 것을 보여줍니다. Cloud DNS 네임서버에 curl--resolve 매개변수를 사용하는 것과 같이 주소 액세스를 위해 이 네임서버를 사용한 경우 부하 분산기 뒤의 관리형 인스턴스 그룹 중 하나로부터 기본 페이지가 표시됩니다.

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com www.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;www.example.com.           IN      A
    
    ;; ANSWER SECTION:
    www.example.com.    300     IN      A       35.227.253.90
    
  3. dig 명령어를 사용하여 Cloud Storage의 정적 웹사이트에 대한 DNS 레코드를 다시 확인합니다.

    dig @ns-cloud-b1.googledomains.com static-web.$DOMAIN
    

    다음 예시 출력은 레코드가 스토리지 버킷으로부터 정적 콘텐츠를 제공할 수 있는 Cloud Storage로 변환되는 것을 보여줍니다.

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com static-web.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;static-web.example.com.    IN      A
    
    ;; ANSWER SECTION:
    static-web.example.com. 300 IN      CNAME   c.storage.googleapis.com.
    

Cloud Storage 버킷으로 장애 조치

프로덕션 환경에서는 관리형 인스턴스 그룹에 문제가 있을 때 Cloud Monitoring 또는 다른 모니터링 솔루션을 사용하여 알림을 받을 수 있습니다. 이 알림은 Cloud Storage에서 호스팅하는 정적 웹사이트로 트래픽을 리디렉션하도록 Cloud DNS 레코드를 업데이트하기 전에 오류 범위를 이해하라는 메시지를 사용자에게 표시합니다. 또 다른 방법은 모니터링 솔루션을 사용하여 관리형 인스턴스 그룹 장애에 자동으로 응답하는 것입니다.

장애 조치를 수행하면 다음 이미지에 표시된 것처럼 Cloud DNS가 Cloud Storage에서 호스팅되는 정적 웹사이트로 트래픽을 변환합니다.

Cloud DNS는 이제 사용자를 Cloud Storage에서 호스팅되고 더 제한적인 환경을 표시하는 정적 웹사이트로 안내합니다.

사용자 또는 모니터링 솔루션 측면에서 트래픽을 Cloud Storage로 전달하도록 Cloud DNS 레코드를 업데이트하는 것이 가장 적합한 조치로 확인된 경우 기존 DNS A 레코드를 업데이트합니다. 이 문서에서는 트래픽을 Cloud Storage에서 호스팅되는 정적 웹사이트로 리디렉션하도록 Cloud DNS 레코드를 수동으로 업데이트합니다.

  1. Cloud DNS 레코드를 장애 조치하려면 부하 분산기로 변환되는 기존 A 레코드를 삭제합니다.

    gcloud dns record-sets transaction start \
        --zone=zone-$NAME_SUFFIX
    
    gcloud dns record-sets transaction remove $IP_ADDRESS \
        --name=www.$DOMAIN \
        --ttl=300 \
        --type=A \
        --zone=zone-$NAME_SUFFIX
    
  2. Cloud Storage에서 호스팅되는 콘텐츠를 가리키는www에 대한 CNAME 레코드를 만듭니다.

    gcloud dns record-sets transaction add static-web.$DOMAIN \
        --name=www.$DOMAIN. \
        --ttl=30 \
        --type=CNAME \
        --zone=zone-$NAME_SUFFIX
    
  3. Cloud DNS 영역에 대해 업데이트를 커밋합니다.

    gcloud dns record-sets transaction execute \
        --zone=zone-$NAME_SUFFIX
    
  4. dig 명령어를 사용하여 www 레코드가 이제 Cloud Storage 스토리지 웹사이트의 주소로 변환되는지 확인합니다.

    dig @ns-cloud-b1.googledomains.com www.$DOMAIN
    

    다음 예시 출력은 www.example.com 레코드가 Cloud Storage 정적 웹사이트의 CNAME 레코드로 변환되는 것을 보여줍니다. www.example.com 액세스 요청은 정적 웹사이트를 표시하는 Cloud Storage 버킷으로 리디렉션됩니다.

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com www.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;www.example.com.           IN      A
    
    ;; ANSWER SECTION:
    www.example.com.    30      IN      CNAME   static-web.example.com.
    static-web.example.com. 300 IN      CNAME   c.storage.googleapis.com.
    

관리형 인스턴스 그룹으로 장애 복구

관리형 인스턴스 그룹 문제가 해결되면 Cloud DNS 레코드를 다시 업데이트하여 부하 분산된 관리형 인스턴스 그룹에서 콘텐츠를 제공하도록 장애 복구할 수 있습니다. 다시 한 번, 사람이 관리형 인스턴스 그룹의 상태에 대한 Cloud Monitoring 통계를 사용하여 이러한 결정을 내릴 수 있습니다. 또는 자동화를 사용하여 관리형 인스턴스 그룹의 복원된 상태에 응답할 수 있습니다. 이 문서에서는 Cloud DNS 레코드를 수동으로 업데이트합니다.

장애 복구를 수행하면 다음 이미지에 표시된 것처럼 Cloud DNS가 다시 트래픽을 관리형 인스턴스 그룹으로 변환합니다.

Cloud DNS는 다시 외부 부하 분산기 뒤의 관리형 인스턴스 그룹으로 사용자를 안내하고 전체 웹사이트 경험을 표시합니다.

  1. 트래픽을 Cloud Storage에서 호스팅되는 콘텐츠로 리디렉션하는 www CNAME 레코드를 삭제합니다.

    gcloud dns record-sets transaction start \
        --zone=zone-$NAME_SUFFIX
    
    gcloud dns record-sets transaction remove static-web.$DOMAIN \
        --name=www.$DOMAIN \
        --ttl=30 \
        --type=CNAME \
        --zone=zone-$NAME_SUFFIX
    
  2. 다시 관리형 인스턴스 그룹 앞에 있는 부하 분산기를 가리키도록 A 레코드를 추가합니다.

    gcloud dns record-sets transaction add $IP_ADDRESS \
        --name=www.$DOMAIN \
        --ttl=300 \
        --type=A \
        --zone=zone-$NAME_SUFFIX
    
  3. Cloud DNS 영역에 대해 업데이트를 커밋합니다.

    gcloud dns record-sets transaction execute \
        --zone=zone-$NAME_SUFFIX
    
  4. dig 명령어를 한 번 더 사용하여 www 레코드가 관리형 인스턴스 그룹 앞에 있는 부하 분산기의 주소로 변환되는지 다시 확인합니다.

    dig @ns-cloud-b1.googledomains.com www.$DOMAIN
    

    다음 예시 출력은 레코드가 부하 분산기의 IP 주소로 변환되고 트래픽이 관리형 인스턴스 그룹 중 하나로부터 제공되는 것을 보여줍니다.

    ; <<>> DiG 9.11.5-P4-5.1+deb10u3-Debian <<>> @ns-cloud-b1.googledomains.com www.example.com
    ; (1 server found)
    
    [...]
    
    ;; QUESTION SECTION:
    ;www.example.com.           IN      A
    
    ;; ANSWER SECTION:
    www.example.com.    300     IN      A       35.227.253.90
    

삭제

이 튜토리얼에서 사용된 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 리소스가 포함된 프로젝트를 삭제하거나 프로젝트를 유지하고 개별 리소스를 삭제하세요.

이 문서에서 만든 개별 리소스를 삭제하려면 다음 단계를 수행합니다.

  1. DNS 영역 및 레코드를 삭제합니다.

    touch empty-file
    gcloud dns record-sets import -z zone-$NAME_SUFFIX \
        --delete-all-existing \
        empty-file
    rm empty-file
    
    gcloud dns managed-zones delete zone-$NAME_SUFFIX
    
  2. Cloud Storage 버킷을 삭제합니다.

    gsutil rm -r gs://static-web.$DOMAIN
    
  3. 부하 분산기 구성을 삭제합니다.

    gcloud compute forwarding-rules delete \
        http-content-rule-$NAME_SUFFIX --global --quiet
    
    gcloud compute target-http-proxies delete \
        http-lb-proxy-$NAME_SUFFIX --quiet
    
    gcloud compute url-maps delete web-map-http-$NAME_SUFFIX --quiet
    
    gcloud compute backend-services delete \
        web-backend-service-$NAME_SUFFIX --global --quiet
    
  4. 관리형 인스턴스 그룹 및 상태 확인을 삭제합니다.

    gcloud compute instance-groups managed delete \
        instance-group-$NAME_SUFFIX-$REGION1 \
        --region=$REGION1 --quiet
    
    gcloud compute instance-groups managed delete \
        instance-group-$NAME_SUFFIX-$REGION2 \
        --region=$REGION2 --quiet
    
    gcloud compute health-checks delete http-basic-check-$NAME_SUFFIX --quiet
    
  5. 인스턴스 템플릿, 이미지, 기본 VM, 영구 디스크를 삭제합니다.

    gcloud compute instance-templates delete \
        template-$NAME_SUFFIX-$REGION1 --quiet
    
    gcloud compute instance-templates delete \
        template-$NAME_SUFFIX-$REGION2 --quiet
    
    gcloud compute images delete image-$NAME_SUFFIX --quiet
    
    gcloud compute images delete image-disk-$NAME_SUFFIX --quiet
    
    gcloud compute instances delete vm-base-$NAME_SUFFIX \
        --zone=$ZONE --quiet
    
  6. 방화벽 규칙을 삭제합니다.

    gcloud compute firewall-rules delete \
        allow-health-check-$NAME_SUFFIX --quiet
    
    gcloud compute firewall-rules delete \
        allow-ssh-$NAME_SUFFIX --quiet
    
    gcloud compute firewall-rules delete \
        allow-http-$NAME_SUFFIX --quiet
    
  7. 서브넷 및 VPC를 삭제합니다.

    gcloud compute networks subnets delete \
        subnet-$NAME_SUFFIX-$REGION1 --region=$REGION1 --quiet
    
    gcloud compute networks subnets delete \
        subnet-$NAME_SUFFIX-$REGION2 --region=$REGION2 --quiet
    
    gcloud compute networks delete network-$NAME_SUFFIX --quiet
    

다음 단계