Service Extensions을 사용하여 GKE 게이트웨이 트래픽 맞춤설정

이 페이지에서는 Google Kubernetes Engine(GKE)에서 Service Extensions를 사용하여 Cloud Load Balancing에 커스텀 로직을 추가하는 방법을 설명합니다.

이 페이지는 Service Extensions를 사용하여 커스텀 트래픽 관리 로직을 구성해야 하는 GKE ID 및 계정 관리자와 개발자를 대상으로 합니다.

이 페이지를 읽기 전 다음 내용을 숙지해야 합니다.

개요

GKE는 Service Extensions를 사용하여 Cloud Load Balancing에 커스텀 로직을 추가합니다. 고급 트래픽 분할, 맞춤 인증 또는 요청 로깅과 같은 작업에 Service Extensions를 사용할 수 있습니다.

GKE Gateway Controller는 다음 Service Extensions를 지원합니다.

  • GCPRoutingExtension: 이 확장 프로그램은 Cloud Load Balancing에 커스텀 로직을 추가하여 트래픽 라우팅을 제어합니다.
  • GCPTrafficExtension: 이 확장 프로그램은 Cloud Load Balancing에 커스텀 로직을 삽입해 트래픽을 수정합니다. 이 로직은 서비스가 선택된 후 트래픽에 적용됩니다. 부하 분산기는 HTTP 요청 및 응답의 헤더와 페이로드를 추가하거나 변경할 수 있습니다. GCPTrafficExtension은 서비스 선택이나 서비스 보안 정책에 영향을 미치지 않습니다.
  • GCPEdgeExtension: 이 확장 프로그램을 사용하면 요청 헤더를 수정하여 백엔드 서비스 선택 및 Cloud CDN 캐시 키에 영향을 줄 수 있습니다. 전역 외부 관리형 부하 분산기에서만 지원됩니다.
  • GCPAuthzExtension: 이 확장 프로그램을 사용하면 승인 결정을 맞춤 또는 서드 파티 승인 엔진(예: 외부 웹 애플리케이션 방화벽) 또는 IAP(Identity-Aware Proxy)에 위임할 수 있습니다. 이 확장 프로그램은 게이트웨이에 들어오는 트래픽에 액세스 제어를 적용하고 확장 프로그램에 대한 호출이 발생해야 하는 시점을 지정하는 GCPAuthzPolicy 리소스와 함께 사용됩니다.

확장 프로그램은 게이트웨이에 연결됩니다. 단일 클러스터 게이트웨이의 경우 확장 프로그램은 서비스 리소스, GCPWasmPlugin 리소스 또는 GoogleAPIServiceName 리소스를 참조합니다. 멀티 클러스터 게이트웨이의 경우 확장 프로그램은 ServiceImport 리소스 또는 GoogleAPIServiceName 리소스를 참조합니다.

  • 서비스 리소스 또는 ServiceImport 리소스 참조: 이 모델에서는 커스텀 로직을 별도의 백엔드 애플리케이션으로 배포하고 Kubernetes 서비스로 노출합니다. 부하 분산기는 트래픽을 처리하기 위해 이 서비스에 콜아웃을 만듭니다. 이 방식은 다재다능하며 커스텀 라우팅 로직을 구현하거나 헤더 수정이나 페이로드 검사와 같은 트래픽 조작을 수행할 수 있습니다.

  • GCPWasmPlugin 리소스 참조: 고성능 사용 사례의 경우 WebAssembly (Wasm) 모듈을 사용하여 사용자가 작성한 커스텀 로직을Cloud de Confiance by S3NS 부하 분산기 데이터 경로에 직접 삽입할 수 있습니다. Artifact Registry에서 Wasm 모듈 이미지를 가리키는 GCPWasmPlugin 리소스를 정의합니다. 이 메서드는 GCPTrafficExtension 및 GCPEdgeExtension 리소스와 전역 외부 애플리케이션 부하 분산기에서만 사용됩니다.

  • Google API 서비스 참조: GCPTrafficExtension 또는 GCPAuthzExtension 내에서 googleAPIServiceName 필드를 사용하여 Google API 서비스를 직접 참조할 수도 있습니다.

다음 다이어그램에서 GCPRoutingExtension 리소스는 게이트웨이에 연결되어 있으며 여러 서비스를 참조합니다. 확장 프로그램은 서비스로의 트래픽 라우팅을 제어합니다.

GCPRoutingExtension 리소스는 게이트웨이에 연결되고 서비스를 참조합니다. 확장 프로그램에서 트래픽 라우팅을 제어합니다.
그림: GCPRoutingExtension이 게이트웨이에서 작동하는 방식

다음 다이어그램에서 GCPTrafficExtension 리소스는 게이트웨이에 연결되어 있고 서비스, GoogleAPIServiceName 또는 GCPWasmPlugin을 참조합니다. 확장 프로그램은 요청 및 응답의 헤더와 페이로드를 변경합니다.

GCPTrafficExtension 리소스는 게이트웨이에 연결되고 서비스, GoogleAPIServiceName 또는 GCPWasmPlugin을 참조합니다. 확장 프로그램은 요청 및 응답의 헤더와 페이로드를 변경합니다.
그림: GCPTrafficExtension이 게이트웨이에서 작동하는 방식

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치했으면 gcloud components update 명령어를 실행하여 최신 버전을 가져옵니다. 이전 gcloud CLI 버전에서는 이 문서의 명령어를 실행하지 못할 수 있습니다.
  • 필요한 경우 Compute Engine API, Network Services API, Model Armor API를 사용 설정합니다.

    API 액세스 사용 설정으로 이동하여 안내를 따릅니다.

  • Cloud de ConfianceService Extensions 가격 책정에 대한 자세한 내용은 가격 책정을 참고하세요.

  • Service Extensions 액세스 제어에서 필요한 역할과 권한을 검토합니다.

  • Service Extensions 할당량의 할당량과 한도를 숙지합니다.

  • Common Expression Language(CEL) 일치자를 사용하려면 CEL 일치자 언어 참조에서 지원되는 속성과 연산자를 검토합니다.

  • Service Extensions의 제한 및 한도를 검토합니다.

GKE Gateway Controller 요구사항

  • 클러스터에서 GKE 버전 1.33 이상을 사용해야 합니다.
  • GCPWasmPlugin을 사용하려면 클러스터에서 GKE 버전 1.33.3 이상을 사용해야 합니다.
  • ServiceImport 리소스를 사용하려면 클러스터에서 GKE 버전 1.34.3 이상을 사용해야 합니다.
  • 내부 멀티 클러스터 게이트웨이의 게이트웨이 리소스가 구성되어 있어야 합니다. 이 리소스는 전역 외부 애플리케이션 부하 분산기, 리전 간 내부 애플리케이션 부하 분산기, 리전 외부 애플리케이션 부하 분산기 또는 리전 내부 애플리케이션 부하 분산기 게이트웨이일 수 있습니다.
  • 클러스터에서 Gateway API가 사용 설정되어 있어야 합니다.
  • 게이트웨이 리소스가 구성되어 있어야 합니다. 이 리소스는 전역 외부 애플리케이션 부하 분산기, 리전 외부 애플리케이션 부하 분산기 또는 리전 내부 애플리케이션 부하 분산기 게이트웨이일 수 있습니다. GCPWasmPlugin 리소스를 사용하는 경우 전역 외부 애플리케이션 부하 분산기 게이트웨이만 배포해야 합니다.
  • HTTPRoute 리소스가 구성되어 있어야 합니다.

제한 및 한도

다음 표에는 GKE의 게이트웨이 Service Extensions 구성과 관련된 제한사항이 나와 있습니다.

카테고리 제한 및 한도
부하 분산기 GCPRoutingExtension은 다음 부하 분산기에서 지원됩니다.
  • 리전 외부 애플리케이션 부하 분산기(gke-l7-regional-external-managed 게이트웨이 클래스)
  • 리전 외부 애플리케이션 부하 분산기(gke-l7-regional-external-managed-mc 게이트웨이 클래스)
  • 리전 내부 애플리케이션 부하 분산기(gke-l7-rilb 게이트웨이 클래스)
  • 리전 내부 애플리케이션 부하 분산기(gke-l7-rilb-mc 게이트웨이 클래스)
  • 리전 간 내부 애플리케이션 부하 분산기 (gke-l7-cross-regional-internal-managed-mc 게이트웨이 클래스)
GCPTrafficExtension은 다음 부하 분산기에서 지원됩니다.
  • 리전 외부 애플리케이션 부하 분산기(gke-l7-regional-external-managed 게이트웨이 클래스)
  • 리전 외부 애플리케이션 부하 분산기(gke-l7-regional-external-managed-mc 게이트웨이 클래스)
  • 리전 내부 애플리케이션 부하 분산기(gke-l7-rilb 게이트웨이 클래스)
  • 리전 내부 애플리케이션 부하 분산기(gke-l7-rilb-mc 게이트웨이 클래스)
  • 전역 외부 애플리케이션 부하 분산기(gke-l7-global-external-managed 게이트웨이 클래스)
  • 전역 외부 애플리케이션 부하 분산기(gke-l7-global-external-managed-mc 게이트웨이 클래스)
  • 리전 간 내부 애플리케이션 부하 분산기 (gke-l7-cross-regional-internal-managed-mc 게이트웨이 클래스)
GCPEdgeExtension은 전역 외부 관리형 부하 분산기 (gke-l7-global-external-managed 게이트웨이 클래스)에서만 지원됩니다.
확장 프로그램 체인 및 사양
  • GCPTrafficExtension의 경우 각 ExtensionChain에 최대 3개의 Extensions가 있을 수 있습니다.
  • GCPRoutingExtension과 GCPEdgeExtension 모두 각 ExtensionChain는 1개의 Extension로 제한됩니다.
  • 모든 확장 프로그램 유형 (트래픽, 라우팅, 에지)은 리소스당 최대 5개의 ExtensionChains를 가질 수 있습니다.
제한 시간
  • 확장 프로그램 내 스트림의 각 개별 메시지 제한 시간은 10~10,000밀리초여야 합니다. 기본 제한 시간은 1초입니다.
MatchCondition
  • ExtensionChain 내 각 MatchConditionCELExpressions 최대 10개로 제한됩니다.
  • GCE로 전송되는 결과 MatchCondition 문자열의 글자 수 제한은 512자(영문 기준)입니다.
  • CELExpressionCELMatcher 문자열의 최대 길이는 512자(영문 기준)입니다.
  • GCPEdgeExtension의 경우:
    • CELMatcher의 응답 속성 (예: response.code)은 지원되지 않습니다.
    • 지원되지 않는 요청 속성에는 backend_service_namebackend_service_project_number이 포함됩니다.
    • 정규 표현식의 수는 1개로 제한됩니다.
  • CELExpression에서는 종류가 Service 또는 ServiceImport인 backendRefs 필드만 지원됩니다.
  • backendRefs 필드는 gke-l7-global-external-managedgke-l7-global-external-managed-mc Gateway Classes와 함께 지원되지 않습니다.
헤더
  • ExtensionForwardHeaders 목록에는 HTTP 헤더 이름이 최대 50개까지 포함될 수 있습니다.
메타데이터
  • ExtensionMetadata 맵에는 속성이 최대 16개까지 있을 수 있습니다.
  • Metadata 맵 내의 키 길이는 1~63자(영문 기준)여야 합니다.
  • Metadata 맵 값의 길이는 1~1,023자(영문 기준)여야 합니다.
이벤트
  • GCPTrafficExtension에는 SupportedEvents가 필요합니다.
  • SupportedEvents는 GCPRoutingExtension에 선택사항입니다.
  • GCPEdgeExtension의 경우 SupportedEvents 목록에 RequestHeaders만 포함되어야 합니다.
  • 지정하지 않으면 RequestHeaders 이벤트가 지원되는 것으로 간주됩니다.
RequestBodySendMode
  • RequestBodySendMode는 종류가 Service 또는 ServiceImport인 backendRef와만 사용할 수 있습니다.
  • SupportedEventsRequestBody이 포함된 경우에만 RequestBodySendMode을 설정할 수 있습니다.
  • SupportedEventsRequestBody가 포함되지만 RequestBodySendMode가 설정되지 않은 경우 기본값 Streamed이 사용됩니다.
  • RequestBodySendModeFullDuplexStreamed로 설정된 경우 SupportedEvents에는 RequestBodyRequestTrailers이 모두 포함되어야 합니다.
  • GCPTrafficExtension의 경우 FullDuplexStreamed만 지원됩니다.
ResponseBodySendMode
  • ResponseBodySendMode 필드는 GCPTrafficExtension에만 지원됩니다.
  • ResponseBodySendMode는 종류가 Service 또는 ServiceImport인 backendRef와만 사용할 수 있습니다.
  • 이 필드는 SupportedEventsResponseBody이 포함된 경우에만 설정할 수 있습니다.
  • SupportedEventsResponseBody가 포함되지만 ResponseBodySendMode가 설정되지 않은 경우 기본값 Streamed이 사용됩니다.
  • 이 필드가 FullDuplexStreamed로 설정된 경우 SupportedEvents에는 ResponseBodyResponseTrailers가 모두 포함되어야 합니다.
리소스 참조
  • GCPEdgeExtension의 경우 지원되는 유일한 백엔드 종류는 GCPWasmPlugin입니다.
  • googleAPIServiceName 필드는 GCPEdgeExtension에서 지원되지 않습니다.
  • 게이트웨이, Edge 확장 프로그램, 플러그인은 모두 동일한 네임스페이스에 있어야 합니다.
GCPWasmPlugin
  • GCPWasmPlugin 필드는 GCPTrafficExtension 및 GCPEdgeExtension에만 지원됩니다.
  • GCPWasmPlugin이 있는 확장 프로그램은 다음 필드를 지원하지 않습니다.
    • authority
    • timeout
    • metadata
    • requestBodySendMode
    • responseBodySendMode
  • GCPWasmPlugin이 있는 확장 프로그램은 RequestHeaders, RequestBody, ResponseHeaders, ResponseBody 이벤트만 지원합니다.
GCPAuthzPolicy 및 GCPAuthzExtension
  • 지정된 게이트웨이에는 CUSTOM 작업이 있는 승인 정책이 하나만 있을 수 있습니다.
  • CUSTOM 작업이 있는 승인 정책은 맞춤 확장 프로그램 하나로 제한됩니다.
  • 게이트웨이당 리소스 수준 승인 정책은 총 5개로 제한됩니다.
  • 프로젝트당 GCPAuthzExtension 리소스는 10개, GCPAuthzPolicy 리소스는 10개로 제한됩니다.
  • 단일 GCPAuthzPolicy 리소스는 최대 100개의 전달 규칙을 가리킬 수 있습니다.
  • 게이트웨이, GCPAuthzPolicy, GCPAuthzExtension은 모두 동일한 네임스페이스에 있어야 합니다. 네임스페이스 간 참조는 허용되지 않습니다.
  • GCPAuthzExtension은 백엔드 서비스 선택에 영향을 줄 수 없습니다.
  • GCPAuthzExtension은 요청 헤더만 수신하고 본문이나 응답의 일부는 수신하지 않습니다.
  • IAP는 GCPAuthzExtension이 있는 리전 부하 분산기에서만 지원됩니다.
  • GCPAuthzExtension과 함께 IAP를 사용하는 경우 전달 규칙에 IAM 권한을 설정할 수 없습니다. 프로젝트 수준 또는 조직 수준 권한만 허용됩니다. 자세한 내용은 리소스에 권한 적용을 참고하세요.
googleAPIServiceName
  • googleAPIServiceName 필드는 GCPTrafficExtension 및 GCPAuthzExtension에서 지원됩니다.
  • googleAPIServiceName이 설정된 경우 authority를 설정하면 안 됩니다.
  • 확장 프로그램에 backendRef 또는 googleAPIServiceName 중 하나만 설정할 수 있습니다.
backendRef 확장 프로그램에서 backendRef를 사용하는 서비스를 참조하는 경우 다음 조건이 충족되어야 합니다.
  • HTTP2를 appProtocol로 사용해야 합니다.
  • 확장 프로그램 및 확장 프로그램에서 참조하는 게이트웨이와 동일한 네임스페이스에 있어야 합니다.
  • IAP를 사용할 수 없습니다.
  • Google Cloud Armor 보안 정책을 사용할 수 없습니다.
  • Cloud CDN을 사용할 수 없습니다.
  • ExtensionbackendRef 또는 googleAPIServiceName 중 하나만 설정해야 합니다.
  • backendRef가 설정되고 kind가 서비스인 경우 authority를 설정해야 합니다.
observabilityMode observabilityMode 필드는 다음 제한사항과 함께 Extension에 설정할 수 있습니다.
  • 버전 1.35.0-gke.3047000 이상의 GKE 클러스터에서 지원됩니다.
  • 리전 게이트웨이 클래스가 있는 게이트웨이에 연결된 GCPTrafficExtension 및 GCPRoutingExtension 리소스에서 지원됩니다.
  • requestBodySendModeresponseBodySendMode 필드가 모두 설정되지 않았거나 Streamed로 설정된 경우에만 사용 설정된 observabilityMode이 지원됩니다.

서비스 참조

Service Extensions에서 부하 분산기에서 실행할 커스텀 로직을 호스팅하는 서비스를 참조할 수 있습니다. 게이트웨이에는 기본적으로 Service Extensions가 없습니다.

GKE Service Extensions를 구성하려면 다음 단계를 따르세요.

  1. 백엔드 콜아웃 서비스 배포: 커스텀 로직 실행에 사용되는 백엔드 서비스를 나타내는 Kubernetes 서비스를 만듭니다. 부하 분산기에서 이 서비스를 호출합니다.

  2. Service Extensions 구성: 부하 분산기 유형에 따라 적절한 확장 프로그램을 사용합니다.

    1. 리전 게이트웨이의 GCPRoutingExtension: 리전 외부 애플리케이션 부하 분산기 및 리전 내부 애플리케이션 부하 분산기에서 이 확장 프로그램을 사용하여 리전 내에서 커스텀 라우팅 로직을 구현합니다.

    2. 전역 외부, 리전 외부, 내부 게이트웨이용 GCPTrafficExtension: 전역 외부 애플리케이션 부하 분산기, 리전 외부 애플리케이션 부하 분산기, 리전 내부 애플리케이션 부하 분산기에서 이 확장 프로그램을 사용하여 다양한 부하 분산기 유형에서 헤더 수정 또는 페이로드 검사와 같은 트래픽 조작을 실행합니다.

백엔드 콜아웃 서비스 배포

콜아웃 서비스는 GKE의 게이트웨이 Service Extensions에 사용할 커스텀 로직을 구현합니다. 게이트웨이는 GCPTrafficExtension 또는 GCPRoutingExtension 구성에 따라 이러한 백엔드 애플리케이션을 호출하여 트래픽을 수정하거나 라우팅합니다.

콜아웃 서비스를 배포하여 게이트웨이에 커스텀 로직을 추가합니다. 이 별도의 서비스는 헤더 조작, 페이로드 변환 또는 트래픽 라우팅과 같은 커스텀 처리를 처리합니다.

게이트웨이의 콜아웃으로 작동할 수 있는 서비스를 배포하려면 다음 단계를 수행합니다.

  1. (선택사항) TLS용 보안 비밀 만들기: 이 명령어는 TLS 인증서와 비공개 키가 포함된 TLS 유형의 Kubernetes 보안 비밀을 만듭니다.

    콜아웃 서비스의 TLS 보안 비밀을 만들려면 다음을 바꿉니다.

    • SECRET_NAME: 콜아웃 서비스의 보안 비밀 이름
    • path-to-cert: 인증서의 파일 경로
    • path-to-key: 키의 파일 경로
  2. 보안 비밀이 추가되었는지 확인하려면 다음 명령어를 실행합니다.

    kubectl get secrets SECRET_NAME
    

    SECRET_NAME을 콜아웃 서비스의 보안 비밀 이름으로 바꿉니다.

    출력은 다음과 비슷하게 표시됩니다.

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. 배포 및 서비스 리소스를 정의합니다.

    다음을 정의해야 합니다.

    • 배포: Service Extensions의 커스텀 로직이 포함된 애플리케이션 포드를 관리합니다.
    • 서비스: 배포에서 관리하는 애플리케이션 포드를 네트워크 서비스로 노출합니다.
    1. 배포 및 서비스 정의가 있는 샘플 매니페스트 extension-service-app.yaml을 만듭니다.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: extension-service-app
      spec:
        selector:
          matchLabels:
            app: store
        replicas: 1
        template:
          metadata:
            labels:
              app: store
          spec:
            containers:
            - name: serviceextensions
              image: us-docker.pkg.dev/service-extensions-samples/callouts/python-example-basic:public-image-e42d951
              ports:
              - containerPort: 8080
              - containerPort: 443
              volumeMounts:
              - name: certs
                mountPath: "/etc/certs/"
                readOnly: true
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              - name: TLS_SERVER_CERT_PATH
                value: "/etc/certs/path-to-cert"
              - name: TLS_SERVER_PRIVKEY
                value: "/etc/certs/path-to-key"
              resources:
                requests:
                  cpu: 10m
            volumes:
            - name: certs
              secret:
                secretName: SECRET_NAME
                optional: false
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: extension-service
      spec:
        ports:
        - port: 443
          targetPort: 443
          appProtocol: HTTP2
        selector:
          app: store
      

      다음을 바꿉니다.

      • POD_NAME: 포드의 이름입니다.
      • SECRET_NAME: 콜아웃 서비스의 보안 비밀 이름입니다.
      • TLS_SERVER_CERT_PATH: 포드 내 TLS 서버 인증서의 경로입니다.
      • TLS_SERVER_PRIVKEY: 포드 내 TLS 서버 비공개 키의 경로입니다.
    2. extension-service-app.yaml 매니페스트를 적용합니다.

      kubectl apply -f extension-service-app.yaml
      
  4. 구성을 확인합니다

    1. 애플리케이션이 배포되었는지 확인합니다.

      kubectl get pod --selector app=store
      

      애플리케이션이 실행되면 출력은 다음과 비슷합니다.

      NAME                                     READY   STATUS    RESTARTS   AGE
      extension-service-app-85f466bc9b-b5mf4   1/1     Running   0          7s
      
    2. 서비스가 배포되었는지 확인합니다.

      kubectl get service extension-service
      

      각 스토어 배포의 서비스를 보여주는 출력이 다음과 같이 표시됩니다.

      NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
      extension-service   ClusterIP   34.118.225.9   <none>        443/TCP   2m40s
      

Service Extensions 구성

GCPRoutingExtension 또는 GCPTrafficExtension을 구성하여 트래픽 흐름을 맞춤설정할 수 있습니다.

리전 게이트웨이의 GCPRoutingExtension 구성

GCPRoutingExtension을 사용하여 트래픽을 리라우팅할 수 있습니다. GCPRoutingExtension을 구성하려면 HTTPRoute를 업데이트하여 service-extensions.com 호스트에 대한 요청을 지정합니다.

  1. HTTPRoute를 업데이트합니다. 라우팅 확장 프로그램을 트리거하는 호스트 이름이나 경로가 포함되도록 HTTPRoute를 수정합니다.

    1. 다음 샘플 매니페스트를 store-route.yaml 파일로 저장합니다.

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name:GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

    2. store-route.yaml 매니페스트를 적용합니다.

      kubectl apply -f store-route.yaml
      
  2. GCPRoutingExtension을 정의합니다.

    1. 샘플 gcp-routing-extension.yaml 파일에 GCPRoutingExtension 구성을 저장합니다.

      kind: GCPRoutingExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-gateway-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
            backendRef:
              group: ""
              kind: Service
              name: extension-service
              port: 443
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

    2. 샘플 매니페스트를 클러스터에 적용합니다.

      kubectl apply -f gcp-routing-extension.yaml
      
  3. GCPRoutingExtension 구성과 게이트웨이와의 바인딩을 확인합니다.

    1. GCPRoutingExtension 배포를 확인합니다.

      kubectl describe gcproutingextension my-gateway-extension
      

      출력은 다음과 비슷합니다.

      Name:         my-gateway-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPRoutingExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      출력에는 기본 네임스페이스에 있는 my-gateway-extension이라는 GCPRoutingExtension 세부정보가 표시됩니다. 출력에는 확장 프로그램 동작 방식 정의가 포함된 Spec 필드가 표시됩니다.

    2. 게이트웨이 바인딩을 확인합니다.

      1. GCPRoutingExtension이 게이트웨이에 바인딩되었는지 확인합니다. 이 작업이 수행되는 데 몇 분 정도 소요될 수 있습니다.

        kubectl describe gateway GATEWAY_NAME
        

        GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

        출력은 다음과 비슷합니다.

        Name:         GATEWAY_NAME
        Namespace:    default
        Labels:       none
        Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                      networking.gke.io/backend-services:
                        /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                      networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                      networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                      networking.gke.io/health-checks:
                        /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                      networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                      networking.gke.io/lb-route-extensions:
                        /projects/1234567890/locations/us-central1/lbRouteExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                      networking.gke.io/lb-traffic-extensions:
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                        /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                      networking.gke.io/target-https-proxies:
                      networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
        API Version:  gateway.networking.k8s.io/v1
        Kind:         Gateway
        Metadata:
          Creation Timestamp:  2025-03-02T16:37:50Z
          Finalizers:
          gateway.finalizer.networking.gke.io
          Generation:        1
          Resource Version:  31284863
          UID:               fd512611-bad2-438e-abfd-5619474fbf31
        ...
        

        출력에는 GKE에서 게이트웨이와 기본Cloud de Confiance 리소스 간의 링크를 저장하는 데 사용하는 주석이 표시됩니다. networking.gke.io/lb-route-extensions 주석은 게이트웨이와 GCPRoutingExtension의 바인딩을 확인합니다.

      2. GCPRoutingExtension에 ProgrammingSucceeded 이유와 함께 Programmed 상태가 있는지 확인하여 확장 프로그램 상태를 확인합니다. 이 명령이 실행되는 데 몇 분 정도 소요될 수 있습니다.

        kubectl describe gcproutingextension my-gateway-extension
        

        출력은 다음과 비슷합니다.

        Name:         my-gateway-extension
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  networking.gke.io/v1
        Kind:         GCPRoutingExtension
        Metadata:
          Creation Timestamp:  2025-03-02T17:12:30Z
          Generation:          1
          Resource Version:    31284378
          UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
        Spec:
          Extension Chains:
            Extensions:
              Authority:  myext.com
              Backend Ref:
                Group:
                Kind:   Service
                Name:   extension-service
                Port:   443
              Name:     ext1
              Timeout:  1s
            Match Condition:
              Cel Expressions:
                Cel Matcher:  request.path.contains("serviceextensions")
            Name:             chain1
          Target Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   GATEWAY_NAME
        Status:
          Ancestors:
            Ancestor Ref:
              Group:      gateway.networking.k8s.io
              Kind:       Gateway
              Name:       GATEWAY_NAME
              Namespace:  default
            Conditions:
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                Accepted
              Status:                True
              Type:                  Accepted
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                ProgrammingSucceeded
              Status:                True
              Type:                  Programmed
            Controller Name:         networking.gke.io/gateway
        Events:
          Type    Reason  Age                From                   Message
          ----    ------  ----               ----                   -------
          Normal  ADD     2m31s              sc-gateway-controller  default/my-gateway-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
          Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
        

        Status.Conditions 필드에는 Status: TrueReason: ProgrammingSucceeded가 포함된 Programmed 조건이 표시됩니다. 이 정보를 사용하여 확장 프로그램이 성공적으로 적용되었음을 확인할 수 있습니다.

  4. 트래픽을 애플리케이션에 전송합니다.

    게이트웨이, 경로, 애플리케이션이 클러스터에 배포되면 트래픽을 애플리케이션에 전달할 수 있습니다.

    1. 애플리케이션에 액세스하려면 게이트웨이의 IP 주소를 찾아야 합니다.

      터미널에서 다음 명령어를 사용합니다.

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      이 명령어에서 게이트웨이 IP 주소를 출력합니다. 후속 명령어에서 GATEWAY_IP_ADDRESS를 출력의 IP 주소로 바꿉니다.

    2. store.example.com/serviceextensions에서 스토어 서비스의 serviceextensions 버전으로 이동하여 경로 업데이트를 테스트합니다.

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

      출력은 다음과 비슷합니다.

      {
      "cluster_name": "gke1",
      "host_header": "service-extensions.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-5d9554f847-cvxpd",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo",
      "timestamp": "2025-03-15T12:00:00",
      "zone": "us-central1-c"
      }
      

GCPTrafficExtension 구성

GCPTrafficExtension을 사용하여 Cloud de Confiance 환경 내에서 고급 트래픽 관리 기능을 사용할 수 있습니다. 전역 외부 애플리케이션 부하 분산기, 리전 외부 애플리케이션 부하 분산기, 리전 내부 애플리케이션 부하 분산기에서 이 확장 프로그램을 구성할 수 있습니다. GCPTrafficExtension을 사용하여 커스텀 HTTP 요청 및 응답 로직, 정교한 라우팅, 변환, 보안 정책을 구현할 수 있습니다.

  1. HTTPRoute를 업데이트합니다. 트래픽 확장 프로그램을 트리거하는 호스트 이름이나 경로가 포함되도록 HTTPRoute를 수정합니다.

    1. 다음 샘플 매니페스트를 store-route.yaml 파일로 저장합니다.

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name: GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다(예: internal-http, external-http, global-external-http).

    2. store-route.yaml 매니페스트를 클러스터에 적용합니다.

      kubectl apply -f store-route.yaml
      
  2. GCPTrafficExtension을 정의합니다.

    1. GCPTrafficExtension 구성을 샘플 gcp-traffic-extension.yaml 파일에 저장합니다.

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
      name: my-traffic-extension
      namespace: default
      spec:
      targetRefs:
      - group: "gateway.networking.k8s.io"
        kind: Gateway
        name: GATEWAY_NAME
      extensionChains:
      - name: chain1
        matchCondition:
          celExpressions:
          - celMatcher: request.path.contains("serviceextensions")
        extensions:
        - name: ext1
          authority: "myext.com"
          timeout: 1s
          backendRef:
            group: ""
            kind: Service
            name: extension-service
            port: 443
          supportedEvents:
            - RequestHeaders
            - RequestBody
            - ResponseHeaders
            - ResponseBody
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다(예: internal-http, external-http, global-external-http).

    2. 샘플 매니페스트를 클러스터에 적용합니다.

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. GCPTrafficExtension 구성과 게이트웨이와의 바인딩을 확인합니다.

    1. GCPTrafficExtension 배포를 확인합니다.

      kubectl describe gcptrafficextension my-traffic-extension
      

      출력은 다음과 비슷합니다.

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      출력에 기본 네임스페이스 내 my-traffic-extension이라는 GCPTrafficExtension 세부정보가 표시됩니다. 확장 프로그램 작동 방식 정의가 포함된 Spec 필드가 표시됩니다.

    2. 게이트웨이 바인딩을 확인합니다.

      GCPTrafficExtension이 게이트웨이에 바인딩되었는지 확인합니다. 이 명령어가 완료되는 데 몇 분이 걸릴 수 있습니다.

      kubectl describe gateway GATEWAY_NAME
      

      출력은 다음과 비슷합니다.

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                    networking.gke.io/backend-services:
                      /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                    networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                    networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                    networking.gke.io/health-checks:
                      /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                    networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                    networking.gke.io/lb-traffic-extensions:
                      /projects/1234567890/locations/us-central1/lbTrafficExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                    networking.gke.io/ssl-certificates:
                    networking.gke.io/target-http-proxies:
                      /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                    networking.gke.io/target-https-proxies:
                    networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      ...
      

      출력에는 GKE에서 게이트웨이와 기본 Cloud de Confiance 리소스 간의 링크를 저장하는 데 사용하는 주석이 표시됩니다. networking.gke.io/lb-traffic-extensions 주석으로 바인딩을 확인할 수 있습니다.

    3. 확장 프로그램 상태를 확인합니다.

      GCPTrafficExtension의 확장 프로그램 상태를 확인하려면 다음 명령어를 실행합니다.

      kubectl describe gcptrafficextension my-traffic-extension
      

      GCPTrafficExtension의 상태가 ProgrammingSucceeded 이유와 함께 Programmed인지 확인합니다. 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다.

      GCPTrafficExtension 리소스 출력은 다음과 비슷합니다.

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:          1
        Resource Version:    31284378
        UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:  myext.com
            Backend Ref:
              Group:
              Kind:   Service
              Name:   extension-service
              Port:   443
            Name:     ext1
            Timeout:  1s
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   GATEWAY_NAME
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       GATEWAY_NAME
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     2m31s              sc-gateway-controller  default/my-traffic-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
        Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        GATEWAY_NAME,
        SectionName: nil,
        Port:        nil} was a success
      

      Status.Conditions 필드에는 Status: TrueReason: ProgrammingSucceeded가 포함된 Programmed 조건이 표시됩니다. 이 정보를 사용하여 확장 프로그램이 성공적으로 적용되었음을 확인할 수 있습니다.

  4. 트래픽을 애플리케이션에 전송합니다.

    게이트웨이, 경로, 애플리케이션이 클러스터에 배포되면 트래픽을 애플리케이션에 전달할 수 있습니다.

    1. 애플리케이션에 액세스하려면 게이트웨이의 IP 주소를 찾아야 합니다.

      터미널에서 다음 명령어를 사용합니다.

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      이 명령어에서 게이트웨이 IP 주소를 출력합니다. 후속 명령어에서 GATEWAY_IP_ADDRESS를 출력의 IP 주소로 바꿉니다.

    2. store.example.com/serviceextensions에서 스토어 서비스의 serviceextensions 버전으로 이동하여 경로 업데이트를 테스트합니다.

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

      출력은 다음과 비슷합니다.

      {
      *   Request completely sent off
      < HTTP/1.1 200 OK
      < server: Werkzeug/2.3.7 Python/3.11.3
      < date: Sun, 02 Mar 2025 16:58:10 GMT
      < content-type: application/json
      < access-control-allow-origin: *
      < hello: service-extensions
      < via: 1.1 google
      < transfer-encoding: chunked
      }
      

GCPAuthzExtension 리소스 구성

GCPAuthzPolicy와 함께 GCPAuthzExtension을 사용하여 외부 서비스 또는 IAP (Identity-Aware Proxy)에 위임하여 복잡한 승인 결정을 적용할 수 있습니다.

  1. GCPAuthzExtension을 정의합니다.

    맞춤 확장 프로그램 서비스 또는 IAP를 콜아웃 서비스로 참조하도록 GCPAuthzExtension을 구성할 수 있습니다.

    • 옵션 1: 맞춤 확장 프로그램 서비스 참조

      1. GCPAuthzExtension 구성을 샘플 gcp-authz-extension.yaml 파일에 저장합니다.
      apiVersion: networking.gke.io/v1
      kind: GCPAuthzExtension
      metadata:
        name: my-authz-ext
        namespace: default
      spec:
        backendRef:
          kind: Service
          name: "${authz-service}"
        forwardHeaders:
        - Authorization
        failOpen: false
        timeout: "0.1s"
        wireFormat: EXT_PROC_GRPC
      

      위 예시에서 "${authz-service}"은 확장 프로그램 서비스이며 GCPAuthzPolicy와 동일한 네임스페이스에 있어야 합니다.

      1. 매니페스트를 적용합니다.
      kubectl apply -f gcp-authz-extension.yaml
      
    • 옵션 2: IAP를 맞춤 호출 서비스로 참조

      googleAPIServiceName 필드에 iap.googleapis.com를 지정하여 IAP를 맞춤 호출 서비스로 구성할 수도 있습니다.

      1. GCPAuthzExtension 구성을 샘플 authz-extension-iap.yaml 파일에 저장합니다.
      apiVersion: networking.gke.io/v1
      kind: GCPAuthzExtension
      metadata:
        name: my-authz-ext-iap
        namespace: default
      spec:
        googleAPIServiceName: iap.googleapis.com
        timeout: 50ms
        failOpen: false
      
      1. 매니페스트를 적용합니다.
      kubectl apply -f authz-extension-iap.yaml
      
  2. GCPAuthzPolicy를 정의합니다.

    GCPAuthzPolicy는 게이트웨이를 타겟팅하고 일치하는 트래픽에 대해 수행할 작업을 지정합니다.

    • CUSTOM 승인 정책 설정:

      CUSTOM 작업은 이전 단계에서 만든 확장 프로그램에 승인 결정을 위임합니다.

      1. 다음 매니페스트를 gcp-authz-policy.yaml에 저장합니다.

        apiVersion: networking.gke.io/v1
        kind: GCPAuthzPolicy
        metadata:
          name: my-gateway-authz
          namespace: default
        spec:
          enforcementLevel: L7
          targetRefs:
          - group: gateway.networking.k8s.io
            kind: Gateway
            name: "GATEWAY_NAME"
          rules:
          - from:
              sources:
              - principals:
                - principal_selector: CLIENT_CERT_URI_SANS
                  principal:
                    exact: "spiffee://cluster.local/ns1/pod1"
          - to:
              operations:
              - paths:
                - exact: "/api/secure-endpoint"
          action: CUSTOM
          customProvider:
            authzExtension:
              extensionRefs:
              - group: networking.gke.io
                kind: GCPAuthzExtension
                name: my-authz-ext
        

        GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      2. 매니페스트를 적용합니다.

        kubectl apply -f gcp-authz-policy.yaml
        

GCPWasmPlugin 리소스 참조

GCPTrafficExtension 또는 GCPEdgeExtension이 포함된 GCPWasmPlugin을 사용하여 부하 분산기 데이터 경로에 직접 커스텀 로직을 삽입할 수 있습니다. 이 방법을 사용하면 Wasm 모듈로 패키징된 맞춤 트래픽 관리 기능을 배포할 수 있습니다.

GKE Service Extensions를 구성하려면 다음 단계를 따르세요.

  1. GCPWasmPlugin 배포: Wasm 모듈의 맞춤 코드가 포함된 GCPWasmPlugin CustomResourceDefinition (CRD)을 만들고 배포합니다. gke-l7-global-external-managed GatewayClass의 경우 GCPTrafficExtension 또는 GCPEdgeExtension과 함께 GCPWasmPlugin을 사용할 수 있습니다.

  2. 서비스 확장 프로그램 구성: GCPWasmPlugin으로 다음 확장 프로그램 중 하나를 구성합니다.

GCPWasmPlugin 배포

GCPWasmPlugin을 사용하면 사용자가 작성한 커스텀 로직을 Cloud de Confiance 부하 분산기 데이터 경로에 직접 삽입할 수 있습니다. GCPWasmPlugin 리소스는 Artifact Registry의 Wasm 모듈 이미지를 가리키며 이 이미지는 부하 분산기에서 실행됩니다.

다음 단계를 계속 진행하기 전에 Wasm 모듈을 Artifact Registry 저장소에 업로드했는지 확인합니다. 자세한 내용은 플러그인 코드 준비를 참고하세요.

GCPWasmPlugin 리소스를 배포하려면 다음 단계를 완료하세요.

  1. 다음 매니페스트를 wasm-plugin.yaml로 저장합니다.

    kind: GCPWasmPlugin
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-wasm-plugin
    spec:
      versions:
      - name: wasm-plugin-version
        description: "Test wasm plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 1000000
      logConfig:
        enabled: true
        # Configures the sampling rate of activity logs.
        # The value of the field must be in range [0, 1e6].
        sampleRate: 1000000
        # Specifies the lowest level of logs that are exported to Cloud Logging.
        minLogLevel: INFO
    

    다음에 유의하세요.

    • spec.versions.name: 버전 이름은 GCPWasmPlugin 리소스 내에서 고유해야 합니다. 버전을 최대 10개까지 나열할 수 있으며 한 버전만 0이 아닌 가중치를 가져야 합니다.
    • spec.versions.image: Artifact Registry에 저장된 플러그인 코드가 포함된 이미지를 참조합니다.
    • spec.versions.weight: 플러그인 버전 가중치를 지정합니다. 가중치는 0~1,000,000 사이의 숫자여야 합니다.
    • spec.logConfig: 이 플러그인에 Cloud Logging을 사용 설정할지 여부를 지정합니다. 값을 지정하지 않으면 기본적으로 Cloud Logging이 사용 중지됩니다.
    • spec.logConfig.sampleRate: 활동 로그 샘플링 레이트를 구성합니다. 비율은 0~1,000,000 사이여야 합니다. Cloud Logging이 사용 설정된 경우 지정하지 않으면 기본값은 1,000,000 (요청 100% 가 로깅됨)입니다.
    • spec.logConfig.minLogLevel: Cloud Logging으로 내보내는 로그의 최저 수준을 지정합니다. Cloud Logging이 사용 설정된 경우 값을 지정하지 않으면 필드가 기본적으로 INFO로 설정됩니다.
  2. wasm-plugin.yaml 매니페스트를 적용합니다.

    kubectl apply -f wasm-plugin.yaml
    
  3. 플러그인이 배포되었는지 확인합니다.

    kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
    

    출력은 다음과 비슷합니다.

    Name:         gcp-wasm-plugin
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         GCPWasmPlugin
    Metadata:
      Creation Timestamp:  2025-08-08T19:54:18Z
      Generation:          1
      Resource Version:    44578
      UID:                 549a12c7-91d1-43ad-a406-d6157a799b79
    Spec:
      Log Config:
        Enabled: true
        Min Log Level: INFO
        Sample Rate: 1000000
      Versions:
        Description:  Test wasm plugin version
        Image:        us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main
        Name:         wasm-plugin-version
        Weight:       1000000
      Events:     <none>
    

GCPTrafficExtension 구성

전역 외부 애플리케이션 부하 분산기에 커스텀 로직을 추가하려면 GCPWasmPlugin을 사용하도록 GCPTrafficExtension을 구성하면 됩니다. GCPTrafficExtension을 사용하여 Cloud de Confiance 환경 내에서 고급 트래픽 관리 기능을 사용할 수 있습니다. 전역 외부 애플리케이션 부하 분산기에서 이 확장 프로그램을 구성할 수 있습니다.

GCPWasmPlugin을 사용하도록 GCPTrafficExtension을 구성하려면 다음 단계를 완료하세요.

  1. GCPTrafficExtension을 정의합니다.

    1. GCPTrafficExtension 구성을 gcp-traffic-extension-with-plugin.yaml로 저장합니다.

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: gcp-traffic-extension-with-plugin
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            supportedEvents:
            - RequestHeaders
            - ResponseHeaders
            backendRef:
              group: "networking.gke.io"
              kind: GCPWasmPlugin
              name: gcp-wasm-plugin
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다(예: global-external-http).

    2. 샘플 매니페스트를 클러스터에 적용합니다.

      kubectl apply -f gcp-traffic-extension-with-plugin.yaml
      
  2. GCPTrafficExtension 구성과 게이트웨이와의 바인딩을 확인합니다.

    1. GCPTrafficExtension 배포를 확인합니다.

      kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
      

      출력은 다음과 비슷합니다.

      Name:         gcp-traffic-extension-with-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Backend Ref:
              Group: networking.gke.io
              Kind: GCPWasmPlugin
              Name: gcp-wasm-plugin
            Name:       ext1
            Supported Events:
              RequestHeaders
              ResponseHeaders
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      출력에 기본 네임스페이스 내 gcp-traffic-extension-with-plugin이라는 GCPTrafficExtension 세부정보가 표시됩니다. 확장 프로그램 작동 방식 정의가 포함된 Spec 필드가 표시됩니다.

    2. 게이트웨이 바인딩을 확인합니다.

      GCPTrafficExtension이 게이트웨이에 바인딩되었는지 확인합니다. 이 명령어가 완료되는 데 몇 분이 걸릴 수 있습니다.

      kubectl describe gateway GATEWAY_NAME
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      출력은 다음과 비슷합니다.

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/922988411345/global/addresses/test-k18j-default-external-http-2jfqxrkgd0fm
                    networking.gke.io/backend-services:
                      /projects/922988411345/global/backendServices/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/backendServices...
                      networking.gke.io/certmap: store-example-com-map
                      networking.gke.io/firewalls: /projects/922988411345/global/firewalls/test-k18j-l7-default-global
                      networking.gke.io/forwarding-rules: /projects/922988411345/global/forwardingRules/test-k18j-default-external-http-wt1tl0cwi6zr
                      networking.gke.io/health-checks:
                        /projects/922988411345/global/healthChecks/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/healthChecks/test-...
                      networking.gke.io/last-reconcile-time: 2025-08-08T20:27:35Z
                      networking.gke.io/lb-route-extensions:
                      networking.gke.io/lb-traffic-extensions:
                        projects/922988411345/locations/global/lbTrafficExtensions/test-k18j-default-external-http-0tdum40yts35
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                      networking.gke.io/target-https-proxies: /projects/922988411345/global/targetHttpsProxies/test-k18j-default-external-http-jy9mc97xb5yh
                      networking.gke.io/url-maps: /projects/922988411345/global/urlMaps/test-k18j-default-external-http-jy9mc97xb5yh
                      networking.gke.io/wasm-plugin-versions:
                        projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk/versions/test-k18j-wasm-plugin-version-i...
                      networking.gke.io/wasm-plugins: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      Spec:
        Gateway Class Name:  gke-l7-global-external-managed
        Listeners:
          Allowed Routes:
            Namespaces:
              From:  Same
          Name:      https
          Port:      443
          Protocol:  HTTPS
      ...
      

      출력에는 GKE에서 게이트웨이와 기본 Cloud de Confiance리소스 간의 링크를 저장하는 데 사용하는 주석이 표시됩니다. networking.gke.io/lb-traffic-extensions, networking.gke.io/wasm-plugin-versions, networking.gke.io/wasm-plugins 주석을 사용하여 바인딩을 확인할 수 있습니다.

    3. 확장 프로그램 상태를 확인합니다.

      GCPTrafficExtension의 상태가 ProgrammingSucceeded 이유와 함께 Programmed인지 확인합니다. 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다.

      kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
      

      출력은 다음과 비슷합니다.

      Name:         gcp-traffic-extension-with-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-08-08T20:08:09Z
        Generation:          1
        Resource Version:    56528
        UID:                 1389f790-9663-45ca-ac4e-a2c082f43359
      Spec:
        Extension Chains:
          Extensions:
            Backend Ref:
              Group:  networking.gke.io
              Kind:   GCPWasmPlugin
              Name:   gcp-wasm-plugin
            Name:     ext1
            Supported Events:
              RequestHeaders
              ResponseHeaders
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   external-http
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       external-http
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                ResolvedRefs
            Status:                True
            Type:                  ResolvedRefs
            Last Transition Time:  2025-08-08T20:16:13Z
            Message:
            Observed Generation:   1
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                  From                   Message
        ----    ------  ----                 ----                   -------
        Normal  ADD     19m                  sc-gateway-controller  default/gcp-traffic-extension-with-plugin
        Normal  SYNC    3m25s (x4 over 11m)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
        Normal  SYNC  3m25s (x4 over 11m)  sc-gateway-controller  All the object references were able to be resolved for GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" bound to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil}
        Normal  SYNC  3m25s (x4 over 11m)  sc-gateway-controller  Programming of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
      
    4. 플러그인 상태를 확인합니다.

      GCPWasmPlugin 리소스가 ProgrammingSucceeded 이유와 함께 Programmed 상태인지 확인합니다. 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다.

      kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
      

      출력은 다음과 비슷합니다.

      Name:         gcp-wasm-plugin
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPWasmPlugin
      Metadata:
        Creation Timestamp:  2025-08-08T19:54:18Z
        Generation:          1
        Resource Version:    44578
        UID:                 549a12c7-91d1-43ad-a406-d6157a799b79
      Spec:
        Log Config:
          Enabled: true
          Min Log Level: INFO
          Sample Rate: 1000000
        Versions:
          Description:  Test wasm plugin version
          Image:        us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main
          Name:         wasm-plugin-version
          Weight:       1000000
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       external-http
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                ResolvedRefs
            Status:                True
            Type:                  ResolvedRefs
            Last Transition Time:  2025-08-08T19:59:06Z
            Message:
            Observed Generation:   1
            Reason:                ProgrammingSucceeded
            Status:                True
            Type:                  Programmed
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                 From                   Message
        ----    ------  ----                ----                   -------
        Normal  ADD     31m                 sc-gateway-controller  default/gcp-wasm-plugin
        Normal  SYNC    2m1s (x7 over 26m)  sc-gateway-controller  Attachment of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
        Normal  SYNC  2m1s (x7 over 26m)  sc-gateway-controller  All the object references were able to be resolved for WasmPlugin "default/gcp-wasm-plugin" bound to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil}
        Normal  SYNC  2m1s (x7 over 26m)  sc-gateway-controller  Programming of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group:       "gateway.networking.k8s.io",
      Kind:        "Gateway",
      Namespace:   "default",
      Name:        "external-http",
      SectionName: nil,
      Port:        nil} was a success
      
  3. 트래픽을 애플리케이션에 전송합니다.

    게이트웨이, 경로, 애플리케이션이 클러스터에 배포되면 트래픽을 애플리케이션에 전달할 수 있습니다.

    1. 애플리케이션에 액세스하려면 게이트웨이의 IP 주소를 찾아야 합니다.

      터미널에서 다음 명령어를 사용합니다.

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      이 명령어에서 게이트웨이 IP 주소를 출력합니다. 후속 명령어에서 GATEWAY_IP_ADDRESS를 출력의 IP 주소로 바꿉니다.

    2. store.example.com/serviceextensions에서 스토어 서비스의 serviceextensions 버전으로 이동하여 경로 업데이트를 테스트합니다.

      curl https://store.example.com/serviceextensions --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
      

      출력에서 Hello World를 반환합니다.

GCPWasmPlugin으로 GCPEdgeExtension 구성

WebAssembly (Wasm) 모듈을 사용하여 전역 외부 애플리케이션 부하 분산기에 커스텀 로직을 추가하려면 GCPWasmPlugin을 참조하는 GCPEdgeExtension을 구성하세요.

  1. 다음 GCPEdgeExtension 매니페스트를 gcp-edge-extension-with-plugin.yaml로 저장합니다.

    kind: GCPEdgeExtension
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-edge-extension-with-plugin
      namespace: default
    spec:
      targetRefs:
      - group: "gateway.networking.k8s.io"
        kind: Gateway
        name: GATEWAY_NAME
      extensionChains:
      - name: chain1
        matchCondition:
          celExpressions:
          - celMatcher: request.path.startsWith("/serviceextensions")
        extensions:
        - name: ext1
          supportedEvents:
          - RequestHeaders
          backendRef:
            group: "networking.gke.io"
            kind: GCPWasmPlugin
            name: gcp-wasm-plugin
    

    GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

  2. 매니페스트를 클러스터에 적용합니다.

    kubectl apply -f gcp-edge-extension-with-plugin.yaml
    
  3. GCPEdgeExtension 구성과 게이트웨이와의 바인딩을 확인합니다.

    1. 확장 프로그램 상태를 확인합니다.

      GCPEdgeExtension의 확장 프로그램 상태를 확인하려면 다음 명령어를 실행합니다.

      kubectl describe gcpedgeextensions.networking.gke.io gcp-edge-extension-with-plugin
      

      GCPEdgeExtension에 ProgrammingSucceeded 이유와 함께 Programmed 상태가 있는지 확인합니다. 이 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다.

    2. 게이트웨이 바인딩을 확인합니다.

      다음 명령어를 실행합니다.

      kubectl describe gateway GATEWAY_NAME
      

      GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

      GCPEdgeExtension이 게이트웨이에 바인딩되었는지 확인합니다. 이 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다. 출력에는 게이트웨이와 에지 확장 프로그램 간의 링크를 확인하는 networking.gke.io/lb-edge-extensions 주석이 포함됩니다.

확장 프로그램으로 트래픽 전송

게이트웨이와 GCPEdgeExtension을 배포한 후 애플리케이션에 트래픽을 전송하여 라우팅 로직을 테스트합니다.

  1. 애플리케이션에 액세스하려면 게이트웨이의 IP 주소를 가져옵니다.

    kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"
    

    출력은 게이트웨이의 IP 주소입니다. 다음 명령어에서 GATEWAY_IP_ADDRESS를 출력의 IP 주소로 바꿉니다.

  2. 기준 URL로 요청을 보냅니다.

    curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    게이트웨이는 요청을 store-v1와 같은 기본 서비스로 라우팅합니다.

  3. celMatcher에 지정된 경로(예: /serviceextensions)로 요청을 보냅니다.

    curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
    

    확장 프로그램이 Wasm 플러그인을 트리거하고, 이 플러그인은 요청을 store-v2와 같은 보조 서비스로 라우팅합니다.

GCPWasmPlugin 리소스 관리

GCPWasmPlugin CRD를 업데이트하고 플러그인을 모니터링할 수 있습니다.

GCPWasmPlugin 업데이트

GCPWasmPlugin 리소스를 업데이트하려면 다음 단계를 따르세요.

  1. GCPWasmPlugin 매니페스트를 변경하고 GCPWasmPlugin 배포에 설명된 단계를 따릅니다.

    예를 들어 한 버전은 트래픽을 처리하고 다른 버전은 트래픽을 처리하지 않는 두 버전의 플러그인이 있는 경우 wasm-plugin.yaml 파일을 다음과 같이 업데이트합니다.

    kind: GCPWasmPlugin
    apiVersion: networking.gke.io/v1
    metadata:
      name: gcp-wasm-plugin
    spec:
      versions:
      - name: wasm-plugin-version-v1
        description: "Serving Wasm Plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 1000000
      - name: wasm-plugin-version-v2
        description: "Non serving Wasm Plugin version"
        image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main"
        weight: 0
      logConfig:
        enabled: true
        sampleRate: 1000000
        minLogLevel: INFO
    

    이 예시에서는 다음이 적용됩니다.

    • wasm-plugin-version-v1weight1000000이므로 모든 트래픽을 제공됩니다.
    • wasm-plugin-version-v2weight0이므로 트래픽을 제공하지 않습니다.
  2. 게이트웨이가 업데이트되었는지 확인하려면 다음 명령어를 실행합니다. 이 명령어가 완료되는 데 몇 분이 걸릴 수 있습니다.

    kubectl describe gateway GATEWAY_NAME
    

    GATEWAY_NAME을 게이트웨이 이름으로 바꿉니다.

GCPWasmPlugin 모니터링

Cloud de Confiance 콘솔에서 GCPWasmPlugin 측정항목을 보려면 플러그인 관점에서 모니터링을 참고하세요.

가이드에서 플러그인 버전 필터 목록에서 값을 선택해야 하는 단계에 도달하면 prefix−WASM_PLUGIN_VERSION_NAME_FROM_FILE−suffix 형식을 찾습니다. 여기서 WASM_PLUGIN_VERSION_NAME_FROM_FILE은 GCPWasmPlugin 구성 파일에 정의한 특정 버전 이름입니다.

게이트웨이의 트래픽 확장 문제 해결

이 섹션에서는 게이트웨이에서 트래픽 확장 프로그램을 구성하는 데 도움이 되는 문제 해결 팁을 제공합니다.

게이트웨이를 찾을 수 없음

다음 오류는 GCPTrafficExtension, GCPRoutingExtension 또는 GCPEdgeExtension 리소스의 targetRefs 필드에 지정된 게이트웨이 리소스가 존재하지 않음을 나타냅니다.

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"

이 문제를 해결하려면 GCPTrafficExtension 또는 GCPRoutingExtension 리소스의 targetRefs 필드에 지정된 게이트웨이 리소스가 지정된 네임스페이스에 있는지 확인합니다.

서비스 또는 서비스 포트를 찾을 수 없음

다음 오류는 GCPTrafficExtension 또는 GCPRoutingExtension 리소스의 backendRef 필드에 지정된 서비스 또는 서비스 포트가 존재하지 않음을 나타냅니다.

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"

이 문제를 해결하려면 GCPTrafficExtension 또는 GCPRoutingExtension 리소스의 backendRef 필드에 지정된 서비스와 서비스 포트가 지정된 네임스페이스에 있는지 확인합니다.

NEG에 네트워크 엔드포인트 없음

다음 오류는 NEG에 GCPTrafficExtension 또는 GCPRoutingExtension 리소스의 backendRef 필드에 지정된 서비스와 연결된 네트워크 엔드포인트가 없음을 나타냅니다.

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"

이 문제를 해결하려면 GCPTrafficExtension 또는 GCPRoutingExtension 리소스의 backendRef 필드에 지정된 서비스에 네트워크 엔드포인트가 있는지 확인합니다.

요청을 보낼 때 답장이 없거나 오류가 포함된 답장이 전송됨

요청을 보낸 경우 답장을 받지 못하거나 오류가 포함된 답장을 받으면 콜아웃 서비스가 올바르게 작동하지 않는 것일 수 있습니다.

이 문제를 해결하려면 콜아웃 서비스의 로그에서 오류를 확인합니다.

JSON 페이로드의 오류 코드 404

다음 오류는 콜아웃 서비스를 찾을 수 없거나 요청에 응답하지 않음을 나타냅니다.

{
  "error": {
    "code": 404,
    "message": "Requested entity was not found.",
    "status": "NOT_FOUND"
  }
}

이 문제를 해결하려면 콜아웃 서비스가 실행 중이고 올바른 포트에서 리슨 중이며 서비스가 GCPTrafficExtension 또는 GCPRoutingExtension 리소스에 올바르게 구성되어 있는지 확인합니다.

JSON 페이로드의 오류 코드 500

다음 오류는 콜아웃 서비스에 내부 서버 오류가 발생했음을 나타냅니다.

{
  "error": {
    "code": 500,
    "message": "Internal server error.",
    "status": "INTERNAL"
  }
}

이 문제를 해결하려면 콜아웃 서비스 로그를 확인하여 내부 서버 오류 원인을 파악합니다.

GCPWasmPlugin이 존재하지 않음

다음 오류는 GCPTrafficExtension 또는 GCPEdgeExtension의 GCPWasmPlugin 리소스가 프로젝트에 없음을 나타냅니다.

Status:
  Ancestors:
    Ancestor Ref:
      Group:      gateway.networking.k8s.io
      Kind:       Gateway
      Name:       external-http
      Namespace:  default
    Conditions:
      Last Transition Time:  2025-03-06T16:27:57Z
      Message:
      Reason:                Accepted
      Status:                True
      Type:                  Accepted
      Last Transition Time:  2025-03-06T16:27:57Z
      Message:               error cause: invalid-wasm-plugin: GCPWasmPlugin default/my-wasm-plugin in GCPTrafficExtension default/my-gateway-plugin-extension does not exist
      Reason:                GCPWasmPluginNotFound
      Status:                False
      Type:                  ResolvedRefs
    Controller Name:         networking.gke.io/gateway

이 문제를 해결하려면 Cloud de Confiance 프로젝트에서 해당 GCPWasmPlugin을 만들거나 기존 GCPWasmPlugin으로 확장 프로그램을 연결합니다.

다음 단계