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


이 페이지에서는 Google Kubernetes Engine (GKE)에서 서비스 확장 프로그램을 사용하여 Cloud Load Balancing에 맞춤 로직을 추가하는 방법을 설명합니다.

이 페이지는 서비스 확장 프로그램을 사용하여 맞춤 트래픽 관리 로직을 구성해야 하는 GKE ID 및 계정 관리자와 개발자를 대상으로 합니다.

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

개요

GKE는 서비스 확장 프로그램을 사용하여 Cloud Load Balancing에 맞춤 로직을 추가합니다. 확장 프로그램은 Gateway에 연결되고 Service 또는 GoogleAPIServiceName를 참조합니다. GoogleAPIServiceNameGCPTrafficExtensions에서만 지원됩니다.

백엔드 서비스 선택 또는 보안 정책에 영향을 주지 않으면서 요청 및 응답의 HTTP 헤더와 페이로드를 수정하거나 트래픽 라우팅을 제어할 수 있습니다. 고급 트래픽 분할, 맞춤 인증, 요청 로깅과 같은 작업에 서비스 확장 프로그램을 사용할 수 있습니다.

GKE 게이트웨이 컨트롤러는 다음 서비스 확장 프로그램을 지원합니다.

  • GCPRoutingExtension: 이 확장 프로그램은 Cloud Load Balancing에 맞춤 로직을 추가하여 트래픽 라우팅을 제어합니다. 리전 외부 애플리케이션 부하 분산기 및 리전 내부 애플리케이션 부하 분산기에서 지원됩니다.

    `GCPRoutingExtension` 리소스는 게이트웨이에 연결되며 서비스를 참조합니다. 확장 프로그램은 트래픽 라우팅을 제어합니다.
    그림: `GCPRoutingExtension` 이 게이트웨이와 함께 작동하는 방식
  • GCPTrafficExtension: 이 확장 프로그램은 Cloud Load Balancing에 맞춤 로직을 삽입합니다. 확장 프로그램 서비스에서 요청 및 응답의 헤더와 페이로드를 변경할 수 있습니다. GCPTrafficExtension는 백엔드 서비스 선택 또는 백엔드 서비스 보안 정책에 영향을 미치지 않습니다.

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

Google Cloud GatewayClasses와의 서비스 확장 프로그램 호환성

다음 표에서는 Google Cloud 서비스 확장 프로그램과 다양한 GatewayClass의 호환성을 설명합니다.

GatewayClass GCPRoutingExtension GCPTrafficExtension
gke-l7-rilb 지원됨 지원됨
gke-l7-regional-external-managed 지원됨 지원됨
gke-l7-global-external-managed 지원되지 않음 지원됨

시작하기 전에

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

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화하세요. 이전에 gcloud CLI를 설치한 경우 gcloud components update를 실행하여 최신 버전을 가져옵니다.

GKE Gateway Controller 요구사항

제한 및 한도

다음 표에는 GKE의 게이트웨이 서비스 확장 프로그램 구성과 관련된 제한사항이 나와 있습니다.

카테고리 제한 및 한도
부하 분산기 GCPRoutingExtension는 리전 외부 애플리케이션 부하 분산기 및 리전 내부 애플리케이션 부하 분산기 (gke-l7-regional-external-managedgke-l7-rilb 게이트웨이 클래스)에서만 지원되며 gke-l7-global-external-managed 게이트웨이 클래스에서는 지원되지 않습니다.
확장 프로그램 체인 및 사양
  • GCPTrafficExtension의 경우 각 ExtensionChain에 최대 3개의 Extensions가 있을 수 있습니다.
  • GCPRoutingExtension의 경우 각 ExtensionChain는 1개의 Extension로 제한됩니다.
  • GCPTrafficExtensionSpecGCPRoutingExtensionSpec는 각각 최대 5개의 ExtensionChains를 보유할 수 있습니다.
타이밍 및 일치
  • 확장 프로그램 내 스트림의 개별 메시지마다 제한 시간은 10~1,000밀리초여야 합니다. 이 1초 제한은 경로 및 트래픽 확장 프로그램에 적용됩니다.
  • ExtensionChain 내의 각 MatchCondition는 최대 10개의 CELExpressions로 제한됩니다.
  • GCE로 전송되는 결과 MatchCondition 문자열은 512자로 제한됩니다.
  • CELExpression 내의 CELMatcher 문자열은 최대 512자(영문 기준) 길이이며 특정 패턴을 따라야 합니다. CELExpressionBackendRefs 필드는 지원되지 않습니다.
헤더 및 메타데이터
  • ExtensionForwardHeaders 목록에는 최대 50개의 HTTP 헤더 이름을 포함할 수 있습니다.
  • ExtensionMetadata 맵에는 최대 16개의 속성이 있을 수 있습니다.
  • Metadata 맵 내 키는 1~63자(영문 기준)여야 합니다.
  • Metadata 맵 내 값은 1~1,023자(영문 기준)여야 합니다.
이벤트
  • GCPRoutingExtension의 경우 requestBodySendMode가 설정되지 않으면 supportedEvents 목록에 RequestHeaders 이벤트만 포함될 수 있습니다.
  • GCPRoutingExtension의 경우 requestBodySendModeFullDuplexStreamed로 설정되면 supportedEvents 목록에 RequestHeaders, RequestBody, RequestTrailers 이벤트만 포함될 수 있습니다.
GCPTrafficExtension
  • responseBodySendMode 필드는 GCPTrafficExtension에만 지원됩니다.
  • googleAPIServiceName 필드는 GCPTrafficExtension에만 지원됩니다.
googleAPIServiceNamebackendRef 확장 프로그램에서 backendRef를 사용하는 서비스를 참조하는 경우 다음 조건을 충족해야 합니다.
  • HTTP2를 appProtocol로 사용해야 합니다.
  • 확장 프로그램 및 확장 프로그램에서 참조하는 게이트웨이와 동일한 네임스페이스에 있어야 합니다.
  • IAP를 사용할 수 없습니다.
  • Google Cloud Armor 보안 정책 ( GCPBackendPolicyConfigsecurityPolicy 필드)을 사용할 수 없습니다.
  • Cloud CDN을 사용할 수 없습니다.
  • ExtensionbackendRef 또는 googleAPIServiceName 중 하나를 정확히 하나만 설정해야 합니다.
  • backendRef가 설정된 경우 authority를 설정해야 합니다.
  • googleAPIServiceName가 설정된 경우 authority를 설정해야 합니다.
  • backendRef만 사용하여 확장 프로그램의 requestBodySendMode를 구성합니다.
  • backendRef만 사용하여 확장 프로그램의 responseBodySendMode를 구성합니다.

GKE 서비스 확장 프로그램 구성

GKE 서비스 확장 프로그램을 구성하여 트래픽 라우팅을 맞춤설정하고, 요청 또는 응답 페이로드를 수정하고, 외부 서비스와 통합할 수 있습니다. 게이트웨이에는 기본적으로 서비스 확장 프로그램이 없습니다.

GKE 서비스 확장 프로그램을 구성하려면 다음 단계를 따르세요.

  1. 게이트웨이 배포: GKE 서비스 확장 프로그램을 구성하려면 먼저 외부 트래픽을 클러스터로 전달하는 게이트웨이를 배포해야 합니다. 전역 외부 애플리케이션 부하 분산기, 리전 외부 애플리케이션 부하 분산기 또는 리전 내부 애플리케이션 부하 분산기 게이트웨이가 될 수 있습니다.

    게이트웨이 배포에 관한 자세한 내용은 게이트웨이 배포를 참고하세요.

  2. 백엔드 호출 서비스 배포: 커스텀 로직 실행을 위한 백엔드 서비스를 나타내는 Kubernetes 서비스를 만듭니다. 부하 분산기에서 이 서비스를 호출합니다.

  3. 서비스 확장 프로그램 구성: 부하 분산기 유형 및 요구사항에 따라 적절한 서비스 확장 프로그램을 구성합니다.

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

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

백엔드 콜아웃 서비스 배포

콜아웃 서비스는 GKE의 게이트웨이 서비스 확장 프로그램에 대한 맞춤 로직을 구현합니다. 게이트웨이는 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. 배포 및 서비스 리소스를 정의합니다.

    다음을 정의해야 합니다.

    • 배포: 서비스 확장 프로그램의 맞춤 로직이 포함된 애플리케이션 팟을 관리합니다.
    • 서비스: 배포에서 관리하는 애플리케이션 포드를 네트워크 서비스로 노출합니다.
    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:main
              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
                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
      
    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
      

서비스 확장 프로그램 구성

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>
      

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

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

      1. GCPRoutingExtension가 게이트웨이에 바인딩되어 있는지 확인합니다. 이 작업은 몇 분 정도 걸릴 수 있습니다.

        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-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에서 게이트웨이와 기본Google Cloud 리소스 간의 링크를 저장하는 데 사용하는 주석이 표시됩니다. networking.gke.io/lb-route-extensions 주석은 게이트웨이가 GCPRoutingExtension에 바인딩되었음을 확인합니다.

      2. GCPRoutingExtension의 상태가 ReconciliationSucceeded 이유와 함께 Reconciled인지 확인하여 연장 상태를 확인합니다. 이 명령어는 몇 분 정도 걸릴 수 있습니다.

        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:                ReconciliationSucceeded
              Status:                True
              Type:                  Reconciled
            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: ReconciliationSucceeded가 있는 Reconciled 조건이 표시됩니다.

        참 및 이유: ReconciliationSucceeded. 이 정보는 연장이 적용되었음을 확인해 줍니다.

  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를 사용하여 Google Cloud 환경 내에서 고급 트래픽 관리 기능을 사용할 수 있습니다. 전역 외부 애플리케이션 부하 분산기, 리전 외부 애플리케이션 부하 분산기, 리전 내부 애플리케이션 부하 분산기에서 이 확장 프로그램을 구성할 수 있습니다. GCPTrafficExtension를 사용하여 맞춤 요청 및 응답 로직, 정교한 라우팅, 변환, 보안 정책을 구현할 수 있습니다.

  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
      

      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에서 게이트웨이와 기본 Google Cloud 리소스 간의 링크를 저장하는 데 사용하는 주석이 표시됩니다. networking.gke.io/lb-traffic-extensions 주석은 바인딩을 확인합니다.

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

      GCPTrafficExtension의 상태가 Reconciled이고 이유가 ReconciliationSucceeded인지 확인합니다. 이 명령어를 완료하는 데 몇 분이 걸릴 수 있습니다.

      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:    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:                ReconciliationSucceeded
            Status:                True
            Type:                  Reconciled
          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: ReconciliationSucceeded가 있는 Reconciled 조건이 표시됩니다. 이 정보는 연장이 적용되었음을 확인해 줍니다.

  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
      }
      

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

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

게이트웨이를 찾을 수 없음

다음 오류는 GCPTrafficExtension 또는 GCPRoutingExtension 리소스의 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"
  }
}

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

다음 단계