문제 해결

이 페이지에서는 Cloud Storage 사용 시 발생할 수 있는 일반적인 오류의 문제 해결 방법을 설명합니다.

Cloud Storage와 같은 Google Cloud 서비스에 영향을 미치는 이슈에 대한 자세한 내용은 Google Cloud Service Health 대시보드를 참고하세요.

원시 요청 로깅

gcloud 또는 Cloud Storage 클라이언트 라이브러리와 같은 도구를 사용하면 대부분의 요청 및 응답 정보가 도구에서 처리됩니다. 하지만 문제 해결에 도움이 되거나 Stack Overflow와 같은 포럼에 질문을 게시할 때는 세부정보를 확인하는 것이 유용할 수 있습니다. 다음 안내를 따라 도구에 대한 요청 및 응답 헤더를 반환합니다.

콘솔

요청 및 응답 정보를 보는 방법은 Google Cloud 콘솔에 액세스하는 데 사용하는 브라우저에 따라 다릅니다. Chrome 브라우저의 경우 다음 안내를 따르세요.

  1. Chrome의 기본 메뉴 버튼()을 클릭합니다.

  2. 도구 더보기를 선택합니다.

  3. 개발자 도구를 클릭합니다.

  4. 나타나는 창에서 네트워크 탭을 클릭합니다.

명령줄

요청에 전역 디버깅 플래그를 사용합니다. 예를 들면 다음과 같습니다.

gcloud storage ls gs://my-bucket/my-object --log-http --verbosity=debug

클라이언트 라이브러리

C++

  • 전체 HTTP 트래픽을 가져오려면 환경 변수 CLOUD_STORAGE_ENABLE_TRACING=http를 설정합니다.

  • 환경 변수 CLOUD_STORAGE_ENABLE_CLOG=yes를 설정하여 각 RPC의 로깅을 가져옵니다.

C#

ApplicationContext.RegisterLogger를 통해 로거를 추가하고 HttpClient 메시지 핸들러에서 로깅 옵션을 설정합니다. 자세한 내용은 FAQ 항목을 참조하세요.

Go

GODEBUG=http2debug=1 환경 변수를 설정합니다. 자세한 내용은 Go 패키지 net/http를 참조하세요.

요청 본문도 로깅하려면 커스텀 HTTP 클라이언트를 사용합니다.

Java

  1. 다음 콘텐츠로 'logging.properties'라는 파일을 만듭니다.

    # Properties file which configures the operation of the JDK logging facility.
    # The system will look for this config file to be specified as a system property:
    # -Djava.util.logging.config.file=${project_loc:googleplus-simple-cmdline-sample}/logging.properties
    
    # Set up the console handler (uncomment "level" to show more fine-grained messages)
    handlers = java.util.logging.ConsoleHandler
    java.util.logging.ConsoleHandler.level = CONFIG
    
    # Set up logging of HTTP requests and responses (uncomment "level" to show)
    com.google.api.client.http.level = CONFIG
  2. Maven에 logging.properties 사용

    mvn -Djava.util.logging.config.file=path/to/logging.properties insert_command

자세한 내용은 플러그인 가능한 HTTP 전송을 참조하세요.

Node.js

Node 스크립트를 호출하기 전에 NODE_DEBUG=https 환경 변수를 설정합니다.

PHP

httpHandler를 사용하여 클라이언트에 자체 HTTP 핸들러를 제공하고 요청 및 응답을 로깅하도록 미들웨어를 설정합니다.

Python

로깅 모듈을 사용합니다. 예를 들면 다음과 같습니다.

import logging
import http.client

logging.basicConfig(level=logging.DEBUG)
http.client.HTTPConnection.debuglevel=5

Ruby

require "google/cloud/storage".rb file의 상단에 다음을 추가합니다.

ruby
Google::Apis.logger.level = Logger::DEBUG

맞춤 헤더 추가

요청에 커스텀 헤더를 추가하는 것은 디버그 헤더 사용 설정 또는 요청 추적과 같이 디버깅을 위한 일반적인 도구입니다. 다음 예는 다양한 Cloud Storage 도구의 요청 헤더를 설정하는 방법을 보여줍니다.

명령줄

대부분의 명령에 사용할 수 있는 --additional-headers 플래그를 사용합니다. 예를 들면 다음과 같습니다.

gcloud storage objects describe gs://my-bucket/my-object --additional-headers=HEADER_NAME=HEADER_VALUE

여기서 HEADER_NAMEHEADER_VALUE는 요청에 추가할 헤더를 정의합니다.

클라이언트 라이브러리

C++

namespace gcs = google::cloud::storage;
gcs::Client client = ...;
client.AnyFunction(... args ..., gcs::CustomHeader("header-name", "value"));

C#

다음 샘플은 클라이언트 라이브러리에서 실행하는 모든 요청에 커스텀 헤더를 추가합니다.

using Google.Cloud.Storage.V1;

var client = StorageClient.Create();
client.Service.HttpClient.DefaultRequestHeaders.Add("custom-header", "custom-value");

var buckets = client.ListBuckets("my-project-id");
foreach (var bucket in buckets)

{
  Console.WriteLine(bucket.Name);
}

Go

Go 클라이언트 라이브러리에서 수행된 요청에 커스텀 헤더를 추가하려면 클라이언트에 사용되는 전송을 커스텀 RoundTripper와 함께 래핑해야 합니다. 다음 예에서는 디버그 헤더를 전송하고 상응하는 응답 헤더를 로깅합니다.

package main

import (
  "context"
  "io/ioutil"
  "log"
  "net/http"

  "cloud.google.com/go/storage"
  "google.golang.org/api/option"
  raw "google.golang.org/api/storage/v1"
  htransport "google.golang.org/api/transport/http"
)

func main() {

  ctx := context.Background()

  // Standard way to initialize client:
  // client, err := storage.NewClient(ctx)
  // if err != nil {
  //      // handle error
  // }

  // Instead, create a custom http.Client.
  base := http.DefaultTransport
  trans, err := htransport.NewTransport(ctx, base, option.WithScopes(raw.DevstorageFullControlScope),
            option.WithUserAgent("custom-user-agent"))
  if err != nil {
            // Handle error.
  }
  c := http.Client{Transport:trans}

  // Add RoundTripper to the created HTTP client.
  c.Transport = withDebugHeader{c.Transport}

  // Supply this client to storage.NewClient
  client, err := storage.NewClient(ctx, option.WithHTTPClient(&c))
  if err != nil {
              // Handle error.
  }

  // Use client to make a request
 }

type withDebugHeader struct {
  rt http.RoundTripper
}

func (wdh withDebugHeader) RoundTrip(r *http.Request) (*http.Response, error) {
  headerName := "X-Custom-Header"
  r.Header.Add(headerName, "value")
  resp, err := wdh.rt.RoundTrip(r)
  if err == nil {
    log.Printf("Resp Header: %+v, ", resp.Header.Get(headerName))
  } else {
    log.Printf("Error: %+v", err)
  }
  return resp, err
}

Java

import com.google.api.gax.rpc.FixedHeaderProvider;
import com.google.api.gax.rpc.HeaderProvider;
import com.google.cloud.WriteChannel;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

import java.io.IOException;
import java.nio.ByteBuffer;
import static java.nio.charset.StandardCharsets.UTF_8;

public class Example {

  public void main(String args[]) throws IOException {
    HeaderProvider headerProvider =
            FixedHeaderProvider.create("custom-header", "custom-value");
    Storage storage = StorageOptions.getDefaultInstance()
            .toBuilder()
            .setHeaderProvider(headerProvider)
            .build().getService();
    String bucketName = "example-bucket";
    String blobName = "test-custom-header";

    // Use client with custom header
    BlobInfo blob = BlobInfo.newBuilder(bucketName, blobName).build();
    byte[] stringBytes;
    try (WriteChannel writer = storage.writer(blob)) {
      stringBytes = "hello world".getBytes(UTF_8);
      writer.write(ByteBuffer.wrap(stringBytes));
    }
  }
}

Node.js

const storage = new Storage();

storage.interceptors.push({
  request: requestConfig => {
    Object.assign(requestConfig.headers, {
      'X-Custom-Header': 'value',
      });
    return requestConfig;
  },
});

PHP

HTTP 요청을 트리거하는 모든 메서드 호출은 마지막 인수로 선택적 $restOptions 인수를 수락합니다. 요청별 또는 클라이언트별로 커스텀 헤더를 제공할 수 있습니다.

use Google\Cloud\Storage\StorageClient;

$client = new StorageClient([
   'restOptions' => [
       'headers' => [
           'x-foo' => 'bat'
       ]
   ]
]);

$bucket = $client->bucket('my-bucket');

$bucket->info([
   'restOptions' => [
       'headers' => [
           'x-foo' => 'bar'
       ]
   ]
]);

Python

from google.cloud import storage

client = storage.Client(
    extra_headers={
        "x-custom-header": "value"
    }
)

Ruby

require "google/cloud/storage"

storage = Google::Cloud::Storage.new

storage.add_custom_headers { 'X-Custom-Header'=> 'value' }

CORS 구성으로 버킷에 액세스

버킷에 CORS 구성을 설정했는데 클라이언트 브라우저에서 들어오는 요청이 실패하는 경우 다음 문제 해결 단계를 시도해 보세요.

  1. 대상 버킷에서 CORS 구성을 검토합니다. CORS 구성 항목이 여러 개 있는 경우 문제 해결에 사용하는 요청 값이 단일 CORS 구성 항목의 값에 매핑되어야 합니다.

  2. CORS 요청을 실행하는 테스트를 할 때는 CORS 요청을 허용하지 않는 storage.cloud.google.com 엔드포인트에 요청을 보내지 않는지 확인합니다. CORS가 지원되는 엔드포인트에 대한 자세한 내용은 Cloud Storage CORS 지원을 참고하세요.

  3. 원하는 도구를 사용하여 요청 및 응답을 검토합니다. Chrome 브라우저에서는 표준 개발자 도구를 사용하여 이 정보를 볼 수 있습니다.

    1. 브라우저 툴바에서 Chrome 메뉴()를 클릭합니다.
    2. 도구 더보기 > 개발자 도구를 선택합니다.
    3. 네트워크 탭을 클릭합니다.
    4. 애플리케이션이나 명령줄에서 요청을 보냅니다.
    5. 네트워크 활동을 표시하는 창에서 요청을 찾습니다.
    6. 이름 열에서 요청에 해당하는 이름을 클릭합니다.
    7. 응답 헤더를 보려면 헤더 탭을 클릭하고, 응답 내용을 보려면 응답 탭을 클릭합니다.

    요청 및 응답이 보이지 않으면 이전에 실패한 실행 전 요청 시도를 브라우저가 캐시한 것일 수도 있습니다. 브라우저의 캐시를 지우면 실행 전 캐시도 지워집니다. 그렇지 않은 경우 CORS 구성의 MaxAgeSec 값을 기본값 1800 (30분)보다 낮은 값으로 설정하고 이전의 MaxAgeSec이 얼마나 길었는지 관계없이 요청을 다시 시도합니다. 그러면 새로운 CORS 구성을 가져오고 캐시 항목을 삭제하는 새로운 실행 전 요청이 수행됩니다. 문제를 디버깅한 후에는 MaxAgeSec을 다시 더 높은 값으로 올려서 버킷에 대한 실행 전 트래픽을 줄입니다.

  4. 요청에 Origin 헤더가 있고, 이 헤더 값이 버킷의 CORS 구성에서 최소한 하나의 Origins 값과 일치하는지 확인합니다. 스키마, 호스트, 포트의 값이 정확히 일치해야 합니다. 허용되는 일치의 몇 가지 예시는 다음과 같습니다.

    • http://origin.example.comhttp://origin.example.com:80과 일치하지만(80이 기본 HTTP 포트이기 때문) https://origin.example.com, http://origin.example.com:8080, http://origin.example.com:5151 또는 http://sub.origin.example.com과는 일치하지 않습니다.

    • https://example.com:443https://example.com과 일치하지만 http://example.com 또는 http://example.com:443과는 일치하지 않습니다.

    • http://localhost:8080http://localhost:8080과만 정확하게 일치하며 http://localhost:5555 또는 http://localhost.example.com:8080과는 일치하지 않습니다.

  5. 단순 요청의 경우 요청의 HTTP 메서드가 버킷의 CORS 구성에 있는 Methods 값 중 하나와 일치하는지 확인합니다. 실행 전 요청의 경우 Access-Control-Request-Method에 지정된 메서드가 Methods 값 중 하나 이상과 일치하는지 확인합니다.

  6. 실행 전 요청의 경우 하나 이상의 Access-Control-Request-Header 헤더를 포함하는지 확인합니다. 포함하고 있으면 각 Access-Control-Request-Header 값이 버킷의 CORS 구성에 있는 ResponseHeader 값과 일치하는지 확인합니다. 실행 전 요청이 성공하고 응답에 CORS 헤더를 포함하려면 Access-Control-Request-Header에 명명된 모든 헤더가 CORS 구성에 있어야 합니다.

오류 코드

다음은 일반적으로 발생할 수 있는 HTTP 상태 코드입니다.

301: 영구 이전

문제: 정적 웹사이트를 설정 중인데 디렉터리 경로에 액세스하면 빈 객체와 301 HTTP 응답 코드가 반환됩니다.

해결 방법: http://www.example.com/dir/과 같은 디렉터리에 액세스할 때 브라우저에서 0바이트 객체가 다운로드되고 301 HTTP 응답 코드가 반환되는 경우 버킷에 해당 이름의 빈 객체가 있을 가능성이 높습니다. 이러한 경우인지 확인하고 문제를 해결하려면 다음 단계를 따릅니다.

  1. Google Cloud 콘솔에서 Cloud Storage 버킷 페이지로 이동합니다.

    버킷으로 이동

  2. Google Cloud 콘솔 상단에 있는 Cloud Shell 활성화 버튼을 클릭합니다.
  3. gcloud storage ls --recursive gs://www.example.com/dir/를 실행합니다. 출력에 http://www.example.com/dir/이 포함된 경우 해당 위치에 빈 객체가 있는 것입니다.
  4. gcloud storage rm gs://www.example.com/dir/ 명령어를 사용하여 빈 객체를 삭제합니다.

이제 http://www.example.com/dir/에 액세스하여 빈 객체 대신 해당 디렉터리의 index.html 파일을 반환할 수 있습니다.

400: 잘못된 요청

문제: 재개 가능한 업로드를 수행하는 동안 이 오류 및 Failed to parse Content-Range header. 메시지가 발생했습니다.

해결 방법: Content-Range 헤더에 사용된 값이 잘못되었습니다. 예를 들어 Content-Range: */*는 유효하지 않으며 대신 Content-Range: bytes */*로 지정해야 합니다. 이 오류가 발생하면 현재 재개 가능한 업로드가 더 이상 활성 상태가 아니므로 재개 가능한 새 업로드를 시작해야 합니다.

401: 승인되지 않음

문제: 직접 또는 Cloud CDN을 사용하여 공개 버킷에 대한 요청이 HTTP 401: UnauthorizedAuthentication Required 응답으로 실패합니다.

해결 방법: 클라이언트 또는 모든 중간 프록시가 Cloud Storage에 대한 요청에 Authorization 헤더를 추가하지 않는지 확인합니다. Authorization 헤더가 있는 모든 요청은 비어 있더라도 인증 시도인 것처럼 검증됩니다.

403: 계정이 사용 중지됨

문제: 버킷을 만들려 했지만 403 Account Disabled 오류가 발생했습니다.

해결 방법: 이 오류는 관련 프로젝트에서 결제를 사용 설정하지 않은 경우에 발생합니다. 결제 설정 방법은 프로젝트에 대한 결제 설정을 참조하세요.

결제를 사용 설정해도 오류 메시지가 계속 나타나는 경우 프로젝트 ID와 문제에 대한 설명을 제공하여 지원을 받을 수 있습니다.

403: 금지됨

문제: 특정 버킷 또는 객체에 액세스할 수 있는 권한이 있는데도 불구하고 액세스를 시도하면 다음과 비슷한 메시지와 함께 403 - Forbidden 오류가 발생합니다. example@email.com does not have storage.objects.get access to the Google Cloud Storage object.

해결 방법: 요청을 완료하는 데 필요한 버킷이나 객체에 대한 IAM 권한이 없습니다. 요청할 수 있지만 할 수 없으면 다음 검사를 수행합니다.

  1. 오류 메시지에 나오는 피부여자가 예상과 일치하나요? 오류 메시지에 예상치 못한 이메일 주소 또는 '익명 호출자'가 나온다면 요청에서 의도한 사용자 인증 정보를 사용하지 않는 것입니다. 요청을 수행하는 데 사용하는 도구에 다른 별칭 또는 항목의 사용자 인증 정보가 설정되었기 때문이거나, 서비스 계정이 요청을 대신 수행했기 때문일 수 있습니다.

  2. 오류 메시지에 나오는 권한이 필요하다고 생각되는 권한인가요? 예상치 못한 권한이라면 사용 중인 도구에서 요청을 완료하는 데 추가적인 액세스 권한이 필요할 가능성이 높습니다. 예를 들어 버킷의 객체를 일괄 삭제하려면 gcloud이 먼저 버킷에서 삭제할 객체의 목록을 구성해야 합니다. 일괄 삭제 작업의 이 부분에 storage.objects.list 권한이 필요한데, 객체 삭제에는 일반적으로 storage.objects.delete 권한만 필요하므로 이 사실을 예상하지 못할 수 있습니다. 이것이 오류 메시지의 원인인 경우 추가로 필요한 권한이 있는 IAM 역할이 부여되었는지 확인하세요.

  3. 의도한 리소스 또는 상위 리소스에 대한 IAM 역할이 부여되었나요? 예를 들어 프로젝트에 대한 Storage Object Viewer 역할을 부여받은 상태에서 객체 다운로드를 시도할 때는 객체가 있는 버킷이 해당 프로젝트에 속해야 합니다. 의도치 않게 다른 프로젝트에 대한 Storage Object Viewer 권한이 있을 수 있습니다.

  4. 특정 버킷 또는 객체에 액세스할 권한이 편의 값을 통해 부여되나요? 편의 값에 부여된 액세스 권한을 삭제하면 이전에 사용 설정된 주 구성원이 리소스에 액세스하지 못하게 될 수 있습니다.

    예를 들어 jane@example.com에 my-example-project라는 프로젝트 소유자(roles/owner) 기본 역할이 있고 프로젝트의 IAM 정책이 스토리지 객체 생성자(roles/storage.objectCreator) 역할을 단축값 projectOwner:my-example-project에 부여한다고 합시다. 이는 jane@example.com에 my-example-project 내의 버킷에 대한 스토리지 객체 생성자 역할과 연결된 권한이 있다는 의미입니다. 이 부여가 삭제되면 jane@example.com은 스토리지 객체 생성자 역할과 연결된 권한을 잃게 됩니다.

    이러한 시나리오에서는 필요한 작업을 실행하는 데 필요한 버킷 수준 또는 객체 수준 권한을 자신에게 부여하여 버킷 또는 객체에 대한 액세스 권한을 다시 얻을 수 있습니다.

  5. 특정 권한을 사용하지 못하도록 하는 IAM 거부 정책이 있나요? 조직 관리자에게 문의하여 IAM 거부 정책이 적용되었는지 확인할 수 있습니다.

409: 충돌

문제: 버킷을 만들려고 시도했지만 다음 오류가 발생했습니다.

409 Conflict. Sorry, that name is not available. Please try a different one.

해결 방법: 사용하려 했던 버킷 이름(예: gs://cats 또는 gs://dogs)이 이미 사용 중입니다. Cloud Storage에는 전역 네임스페이스가 있으므로 기존 버킷과 동일한 이름을 사용해서는 안 됩니다. 사용 중이 아닌 이름을 선택하세요.

412: 커스텀 제약조건 위반

문제: 412 orgpolicy 오류와 함께 요청이 거부됩니다.

문제: 412 Multiple constraints were violated 오류와 함께 요청이 거부됩니다.

해결 방법: 보안 관리자팀에 문의하여 요청을 보내는 버킷이 맞춤 제약 조건을 사용하는 조직 정책의 영향을 받고 있는지 확인하세요. 서로 충돌하는 다른 조직 정책의 버킷도 영향을 받을 수 있습니다. 예를 들어 한 정책에서 버킷에 표준 스토리지 클래스가 있어야 한다고 지정하고 다른 정책에서는 버킷에 Coldline Storage 클래스가 있어야 한다고 지정하는 경우입니다.

429: 요청한 횟수가 너무 많음

문제: 429 Too Many Requests 오류와 함께 요청이 거부됩니다.

해결 방법: Cloud Storage가 특정 리소스에 허용하는 요청 수 한도에 도달하고 있습니다. Cloud Storage의 한도에 대한 설명은 Cloud Storage 할당량을 참조하세요.

  • 버킷에 대한 초당 요청 1,000개로 구성된 워크로드의 경우 요청 비율 및 액세스 분배 가이드라인에서 워크로드를 점진적으로 늘리고 순차적 파일 이름을 방지하는 방법을 포함한 권장사항을 알아보세요.

  • 워크로드가 특정 위치로 50Gbps 이상의 네트워크 이그레스를 사용할 가능성이 있는 경우 대역폭 사용량을 확인하여 대역폭 할당량이 초과되지 않았는지 확인합니다.

Google Cloud Console 오류 진단

문제: Google Cloud Console을 사용하여 작업을 수행하면 일반 오류 메시지가 표시됩니다. 예를 들어 버킷을 삭제하려고 할 때 오류 메시지가 표시되지만 작업이 실패한 이유에 대한 세부정보는 표시되지 않습니다.

해결 방법: Google Cloud 콘솔의 알림을 사용하여 실패한 작업에 대한 자세한 정보를 확인합니다.

  1. Google Cloud 콘솔 헤더에서 알림 버튼()을 클릭합니다.

    Google Cloud 콘솔에서 가장 최근에 수행한 작업이 드롭다운에 표시됩니다.

  2. 자세히 알아보려는 항목을 클릭합니다.

    페이지가 열리고 작업에 대한 자세한 정보가 표시됩니다.

  3. 각 행을 클릭하여 자세한 오류 정보를 펼칩니다.

문제: Google Cloud 콘솔을 사용할 때 특정 열이 표시되지 않습니다.

해결 방법: Google Cloud 콘솔에 특정 열을 표시하려면 열 표시 옵션 아이콘()을 클릭하고 표시할 열을 선택합니다.

시뮬레이션된 폴더 및 관리 폴더

문제: 버킷에서 객체 일부를 삭제했는데 해당 객체가 포함된 폴더가 Google Cloud 콘솔에 표시되지 않습니다.

해결 방법: Google Cloud 콘솔은 디렉터리 구조가 있는 것처럼 버킷의 콘텐츠를 표시하지만 Cloud Storage에는 기본적으로 폴더가 존재하지 않습니다. 따라서 버킷에서 공통 프리픽스가 있는 모든 객체를 삭제하면 이 객체 그룹을 나타내는 폴더 아이콘이 더 이상 Google Cloud 콘솔에 표시되지 않습니다.

문제: 관리형 폴더를 만들 수 없습니다.

해결 방법: 관리형 폴더를 만들려면 다음 요구사항이 충족되어야 합니다.

  • 스토리지 객체 관리자(roles/storage.objectAdmin) 역할과 같은 storage.managedfolders.create 권한이 포함된 IAM 역할이 있습니다. 역할을 부여하는 방법은 IAM 권한 사용을 참조하세요.

  • 균일한 버킷 수준 액세스가 관리형 폴더를 만들 버킷에 사용 설정되어 있습니다.

  • 버킷 리소스 유형(storage.googleapis.com/Bucket) 또는 객체 리소스 유형(storage.googleapis.com/Object)을 사용하는 버킷이나 프로젝트에 IAM 조건이 없습니다. 프로젝트 내 버킷에 이러한 리소스 유형 중 하나를 사용하는 IAM 조건이 있으면 나중에 조건이 삭제되더라도 프로젝트 내 모든 버킷에 관리형 폴더를 만들 수 없습니다.

문제: 버킷에 관리형 폴더가 있으므로 균일한 버킷 수준 액세스를 중지할 수 없습니다.

해결 방법: 버킷에 관리형 폴더가 있으면 균일한 버킷 수준 액세스를 중지할 수 없습니다. 균일한 버킷 수준 액세스를 중지하려면 먼저 버킷에서 모든 관리형 폴더를 삭제해야 합니다.

정적 웹사이트 오류

다음은 정적 웹사이트를 호스팅할 버킷을 설정할 때 일반적으로 발생하는 문제입니다.

HTTPS 제공

문제: 부하 분산기를 사용하지 않고 HTTPS를 통해 콘텐츠를 제공하고 싶습니다.

해결 방법: https://storage.googleapis.com/my-bucket/my-object와 같은 직접 URI를 사용하여 HTTPS를 통해 정적 콘텐츠를 제공할 수 있습니다. SSL을 통해 커스텀 도메인으로 콘텐츠를 제공하는 다른 옵션은 다음과 같습니다.

도메인 확인

문제: 내 도메인을 인증할 수 없습니다.

해결 방법: 일반적으로 Search Console의 확인 프로세스에서는 파일을 도메인에 업로드하도록 지시하지만 도메인 확인을 수행한 후에만 만들 수 있는 관련 버킷이 없어 이 작업을 수행하지 못할 수 있습니다.

이러한 경우 도메인 이름 공급업체 인증 방법을 사용하여 소유권을 인증하세요. 이 작업을 수행하는 방법은 소유권 인증을 참조하세요. 버킷을 만들기 전에 이 인증을 수행할 수 있습니다.

액세스 불가 페이지

문제: 웹사이트에서 제공하는 웹페이지에 Access denied 오류 메시지가 표시됩니다.

해결 방법: 객체가 공개로 공유되는지 확인하세요. 그렇지 않은 경우 데이터 공개 설정을 참조하세요.

이전에 객체를 업로드하고 공유했지만 이후에 새 버전을 업로드하면 객체를 다시 공개적으로 공유해야 합니다. 공개 권한이 새 업로드로 대체되기 때문입니다.

권한을 업데이트하지 못함

문제: 데이터를 공개로 설정하려고 하면 오류가 발생합니다.

해결 방법: storage.buckets.setIamPolicy 권한 또는 storage.objects.setIamPolicy 권한이 있는지 확인합니다. 예를 들어 이러한 권한은 스토리지 관리자(roles/storage.admin) 역할에서 부여됩니다. storage.buckets.setIamPolicy 또는 storage.objects.setIamPolicy 권한이 있는데도 오류가 발생하면 버킷에 공개 액세스 방지가 적용되어 allUsers 또는 allAuthenticatedUsers에 대한 액세스가 허용되지 않을 수 있습니다. 공개 액세스 방지는 버킷에 직접 설정되거나 더 높은 수준에서 설정된 조직 정책을 통해 적용될 수 있습니다.

콘텐츠 다운로드

문제: 내 페이지의 콘텐츠를 브라우저에서 보는게 아니라 다운로드하라는 메시지가 표시됩니다.

해결 방법: MainPageSuffix를 웹 콘텐츠 유형이 아닌 객체로 지정하면 사이트 방문자에게 제공되는 페이지 콘텐츠가 표시되는 대신 콘텐츠를 다운로드하라는 메시지가 표시됩니다. 이 문제를 해결하려면 Content-Type 메타데이터 항목을 적절한 값(예: text/html)으로 업데이트하세요. 자세한 내용은 객체 메타데이터 수정을 참고하세요.

지연 시간

다음은 일반적으로 발생하는 지연 시간 문제입니다. 또한 Google Cloud Service Health 대시보드는 Cloud Storage와 같이 Google Cloud 서비스에 영향을 미치는 이슈에 대한 정보를 제공합니다.

업로드 또는 다운로드 지연 시간

문제: 업로드 또는 다운로드할 때 지연 시간이 길어집니다.

해결 방법: 업로드 및 다운로드 지연 시간의 일반적인 원인은 다음과 같습니다.

  • CPU 또는 메모리 제약조건: 영향을 받는 환경의 운영체제에는 CPU 사용량 및 메모리 사용량과 같은 로컬 리소스 소비를 측정하는 도구가 있어야 합니다.

  • 디스크 IO 제약조건: 로컬 디스크 IO로 성능 영향이 발생할 수 있습니다.

  • 지리적 거리: 성능은 Cloud Storage 버킷과 영향을 받는 환경의 물리적 분리의 영향을 받을 수 있으며 대륙 간 사례에서 특히 그렇습니다. 영향을 받는 환경과 동일한 리전에 있는 버킷으로 테스트하면 지리적 분리로 인해 지연 시간에 영향을 주는 정도를 파악할 수 있습니다.

    • 해당하는 경우 영향을 받는 환경의 DNS 리졸버는 환경의 요청이 적절한 Google 프런트엔드를 통해 라우팅되도록 EDNS(0) 프로토콜을 사용해야 합니다.

CLI 또는 클라이언트 라이브러리 지연 시간

문제: Google Cloud CLI 또는 클라이언트 라이브러리 중 하나로 Cloud Storage에 액세스할 때 지연 시간이 길어집니다.

해결 방법: gcloud CLI 및 클라이언트 라이브러리가 유용한 경우 요청을 자동으로 재시도하며, 이 동작은 최종 사용자에게 표시되는 지연 시간을 크게 늘릴 수 있습니다. Cloud Monitoring 측정항목 storage.googleapis.com/api/request_count를 사용하여 Cloud Storage가 재시도 가능한 응답 코드(예: 429 또는 5xx)를 일관되게 제공하는지 확인합니다.

프록시 서버

문제: 프록시 서버를 통해 연결 중입니다. 무엇을 해야 하나요?

해결 방법: 프록시 서버를 통해 Cloud Storage에 액세스하려면 다음 도메인에 대한 액세스를 허용해야 합니다.

  • accounts.google.com: OAuth2 인증 토큰 생성
  • oauth2.googleapis.com: OAuth2 토큰 교환 수행
  • *.googleapis.com: 저장 요청

프록시 서버 또는 보안 정책이 도메인별 허용 목록을 지원하지 않고 대신 IP 네트워크 블록별 허용 목록만 지원하는 경우 모든 Google IP 주소 범위에 대해 프록시 서버를 구성하는 것이 좋습니다. ARIN에서 WHOIS 데이터를 쿼리하여 주소 범위를 찾을 수 있습니다. 프록시 설정이 Google의 IP 주소와 일치하는지 정기적으로 검토하는 것이 좋습니다.

oauth2.googleapis.comstorage.googleapis.com의 일회성 조회를 기반으로 얻은 개별 IP 주소로 프록시를 구성하지 않는 것이 좋습니다. Google 서비스는 시시각각 변하는 매우 많은 IP 주소에 매핑되는 DNS 이름을 통해 노출되기 때문에 한 번의 조회를 기반으로 프록시를 구성하면 Cloud Storage에 연결하지 못할 수 있습니다.

프록시 서버를 통해 요청이 라우팅되는 경우, 네트워크 관리자의 도움을 받아 사용자 인증 정보를 포함한 Authorization 헤더가 프록시에서 삭제되지 않았는지 확인해야 합니다. Authorization 헤더가 없으면 요청이 거부되고 MissingSecurityHeader 오류가 발생합니다.

Storage Insights 오류

문제: 인벤토리 보고서 구성에서 매일 여러 인벤토리 보고서가 생성됩니다.

해결 방법: 버킷에 1,000,000개가 넘는 객체가 있는 경우 여러 인벤토리 보고서가 샤드로 생성될 수 있습니다. 인벤토리 보고서 구성은 버킷의 1,000,000개 객체마다 하나의 인벤토리 보고서를 생성합니다. 예를 들어 3,500,000개의 객체가 있는 버킷이 있는 경우 버킷의 인벤토리 보고서 구성은 생성된 인벤토리 보고서 샤드 수와 해당 파일 이름이 포함된 매니페스트 파일과 함께 지정하는 빈도별로 인벤토리 보고서 샤드 4개를 생성합니다.

문제: 인벤토리 보고서가 대상 버킷에 표시되지 않습니다.

해결 방법: 인벤토리 보고서 구성을 만들었으나 대상 버킷에 인벤토리 보고서가 생성되지 않는 경우 다음을 확인하세요.

  • 인벤토리 보고서 구성에 지정된 시작일이 인벤토리 보고서가 생성되어야 하는 예상 날짜와 일치하는지 확인합니다. 시작일을 지정하는 방법에 관한 안내는 인벤토리 보고서 구성 만들기를 참고하세요.

  • 인벤토리 보고서 기록을 확인하여 오류 및 근본 원인을 확인합니다. 인벤토리 보고서 기록을 보려면 다음 단계를 완료하세요.

    1. Google Cloud 콘솔에서 Cloud Storage 버킷 페이지로 이동합니다.

      버킷으로 이동

    2. 버킷 목록에서 인벤토리 보고서 구성이 포함된 소스 버킷의 이름을 클릭합니다.

    3. 버킷 세부정보 페이지에서 인벤토리 보고서 탭을 클릭합니다.

    4. 인벤토리 보고서 구성 목록에서 확인하려는 보고서를 생성한 인벤토리 보고서 구성의 UUID를 클릭합니다.

    5. 인벤토리 보고서 기록 섹션에서 오류가 있는지 확인합니다. 도움말() 위에 마우스 포인터를 올려놓으면 실패 이유에 대한 세부정보를 볼 수 있습니다.

  • 프로젝트 수준 서비스 에이전트에 인벤토리 보고서 읽기 및 쓰기에 필요한 IAM 역할이 부여되었는지 확인합니다. 자세한 내용은 서비스 에이전트에 필요한 역할 부여를 참고하세요.

문제: 인벤토리 보고서 생성 시 무작위 지연이 발생합니다.

해결 방법: 인벤토리 보고서가 생성되는 시간 간격은 다를 수 있습니다. 최대 1일 지연될 수 있습니다.

다음 단계