외부 처리(External Processing) 확장 구성 참조

외부 처리(External Processing) 확장 구성 참조 (External Processing Extension Configuration Reference)

Enterprise

이 기능은 Consul Enterprise가 필요해요. 추가 정보는 enterprise feature matrix를 참고해요.

이 주제는 Envoy 프록시가 요청 및 응답 데이터를 외부 처리 서비스로 보내도록 구성하는 외부 처리(ext-proc) Envoy 확장을 구성하는 방법을 설명해요. 사용 정보는 Delegate request and response processing to an external service를 참고해요.

외부 처리 확장은 API gateway 및 사이드카 프록시에 적용돼요. connect-proxy의 인바운드 또는 아웃바운드 리스너, 또는 api-gateway의 인바운드 리스너에 연결할 수 있어요.

출처: 문서

본문

이 주제는 요청 및 응답 데이터를 외부 처리 서비스로 보내도록 Envoy 프록시를 구성하는 외부 처리 Envoy 확장을 구성하는 방법을 설명해요.

구성 모델 (Configuration model)

다음 목록은 외부 처리 구성의 필드 계층, 데이터 유형 및 요구 사항을 보여줘요. 프록시 기본값 또는 서비스 기본값 구성 항목의 EnvoyExtensions.Arguments 필드 안에 구성을 배치해요. 추가 정보는 다음 문서를 참고해요:

기본값을 포함한 추가 세부 정보를 보려면 속성 이름을 선택해요.

Enterprise

        * [`Partition`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-grpcservice-target-service): string |

Enterprise

        * [`Port`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-grpcservice-target-service): string
      * [`URI`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-grpcservice-target-uri): string
      * [`Timeout`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-grpcservice-target-timeout): string | `5s`
    * [`Authority`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-grpcservice-authority): string
  * [`HttpService`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice): map
    * [`Target`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target): map | required
      * [`Service`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-service): map
        * [`Name`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-service): string
        * [`Namespace`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-service): string |

Enterprise

        * [`Partition`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-service): string |

Enterprise

        * [`Port`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-service): string
      * [`URI`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-uri): string
      * [`Timeout`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-target-timeout): string | `5s`
    * [`Path`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-httpservice-path): string | `/`
  * [`StatPrefix`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-statprefix): string
  * [`FailureModeAllow`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-failuremodeallow): boolean | `false`
  * [`RouteCacheAction`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-routecacheaction): string | `DEFAULT` | gRPC 전용
  * [`MessageTimeout`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-messagetimeout): string
  * [`Processing`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing): map
    * [`Request`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-request): map
      * [`HeadersMode`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-request): string | `SEND`
      * [`BodyMode`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-request): string | `SKIP`
      * [`TrailersMode`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-request): string | `SKIP`
      * [`MaxBodyBytes`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-request): number
    * [`Response`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-response): map
      * [`HeadersMode`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-response): string | `SKIP`
      * [`BodyMode`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-response): string | `SKIP`
      * [`TrailersMode`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-response): string | `SKIP`
      * [`MaxBodyBytes`](/consul/docs/reference/proxy/extensions/ext-proc#arguments-config-processing-response): number

전체 구성 (Complete configuration)

각 필드가 정의되면 ext-proc 구성은 다음 형식을 가져요.

Name = "builtin/ext-proc"
Arguments = {
   ProxyType    = "api-gateway"
   ListenerType = "inbound"
   InsertOptions = {
      Location   = "<location in the filter chain>"
      FilterName = "<filter relative to the location>"
   }
   Config = {
      GrpcService = {
         Target = {
            Service = {
               Name      = "<processing service to send gRPC requests to>"
               Namespace = "<namespace containing the processing service>"
               Partition = "<partition containing the processing service>"
               Port      = "<named port of a multi-port processing service>"
            }
            URI     = "<URI of the processing service>"
            Timeout = "5s"
         }
         Authority = "<authority header to send in the gRPC request>"
      }
      HttpService = {
         Target = {
            Service = {
               Name      = "<processing service to send HTTP requests to>"
               Namespace = "<namespace containing the processing service>"
               Partition = "<partition containing the processing service>"
               Port      = "<named port of a multi-port processing service>"
            }
            URI     = "<URI of the processing service>"
            Timeout = "5s"
         }
         Path = "/<processing-request-path>"
      }
      StatPrefix       = "<prefix that uniquely identifies this instance>"
      FailureModeAllow = false
      RouteCacheAction = "DEFAULT" // gRPC only
      MessageTimeout   = "<maximum duration to wait for a processor response>"
      Processing = {
         Request = {
            HeadersMode  = "SEND"
            BodyMode     = "SKIP"
            TrailersMode = "SKIP"
            MaxBodyBytes = <max bytes buffered when BodyMode buffers the body>
         }
         Response = {
            HeadersMode  = "SKIP"
            BodyMode     = "SKIP"
            TrailersMode = "SKIP"
            MaxBodyBytes = <max bytes buffered when BodyMode buffers the body>
         }
      }
   }
}

사양 (Specification)

이 섹션은 외부 처리 확장에 대해 구성할 수 있는 필드를 설명해요.

Name

확장의 이름을 지정해요. builtin/ext-proc로 설정해야 해요.

값 (Values)
  • 기본값: None
  • 이 필드는 필수예요.
  • 데이터 유형: builtin/ext-proc로 설정된 문자열 값.

Arguments

확장에 대한 전역 구성을 포함해요.

값 (Values)
  • 기본값: None
  • 이 필드는 필수예요.
  • 데이터 유형: Map

Arguments.ProxyType

이 확장이 적용되는 Envoy 프록시 유형을 지정해요. 확장은 이 유형과 일치하는 프록시에만 적용되며 다른 모든 프록시 유형에는 무시돼요.

값 (Values)
  • 기본값: api-gateway
  • 이 필드는 필수예요.
  • 데이터 유형은 다음 문자열 값 중 하나:
    • api-gateway — API gateway 프록시에 확장을 적용해요. 확장은 항상 인바운드 리스너에 연결돼요.
    • connect-proxy — 사이드카(서비스 메시) 프록시에 확장을 적용해요. 확장은 ListenerType 필드로 제어되는 인바운드 또는 아웃바운드 리스너 중 하나에 연결할 수 있어요.

Arguments.ListenerType

확장이 적용되는 리스너 유형을 지정해요.

값 동작
inbound Consul은 메시의 다른 서비스가 프록시에 연결된 서비스로 보내는 요청에 대해 외부 처리를 활성화해요.
outbound Consul은 연결된 프록시가 메시의 다른 서비스로 보내는 요청에 대해 외부 처리를 활성화해요.
any Consul은 인바운드 및 아웃바운드 리스너 모두에서 외부 처리를 활성화해요.

ProxyType이 api-gateway로 설정된 경우 Consul은 이 값과 관계없이 항상 인바운드 리스너에 확장을 적용해요.

값 (Values)
  • 기본값: inbound
  • 데이터 유형은 다음 문자열 값 중 하나:

Arguments.InsertOptions

Envoy 필터 체인에서 외부 처리 필터의 삽입 지점을 정의하기 위한 옵션을 지정해요. 기본적으로 Consul은 envoy.filters.http.router 필터 앞에 외부 처리 필터를 삽입해요.

값 (Values)
  • 기본값: None
  • 데이터 유형: Map

Arguments.InsertOptions.Location

Envoy 필터 체인에서 외부 처리 필터의 삽입 지점을 지정해요. 다음 문자열 값 중 하나를 지정할 수 있어요:

  • First: FilterName 필드에 지정된 필터와 관계없이 필터를 필터 체인의 첫 번째 필터로 삽입해요.
  • BeforeLast: FilterName 필드에 지정된 필터와 관계없이 필터를 체인의 마지막 필터 앞에 삽입해요. 이렇게 하면 다른 모든 필터 뒤, 종단(terminal) 필터 바로 앞에 필터가 삽입될 수 있어요.
  • AfterFirstMatch: FilterName 필드 값과 일치하는 이름을 가진 체인의 첫 번째 필터 뒤에 필터를 삽입해요.
  • AfterLastMatch: FilterName 필드 값과 일치하는 이름을 가진 체인의 마지막 필터 뒤에 필터를 삽입해요.
  • BeforeFirstMatch (기본값) : FilterName 필드 값과 일치하는 이름을 가진 체인의 첫 번째 필터 앞에 필터를 삽입해요.
  • BeforeLastMatch: FilterName 필드 값과 일치하는 이름을 가진 체인의 마지막 필터 앞에 필터를 삽입해요.
값 (Values)
  • 기본값: BeforeFirstMatch
  • 데이터 유형: String

Arguments.InsertOptions.FilterName

외부 처리 필터를 삽입할 때 일치시킬 체인의 기존 필터 이름을 지정해요. 필터 이름을 지정하면 체인의 다른 필터 위치를 기준으로 삽입 지점을 구성할 수 있어요.

값 (Values)
  • 기본값: envoy.filters.http.router
  • 데이터 유형: String

Arguments.Config

확장에 대한 구성 설정을 포함해요. GrpcService 또는 HttpService 설정 중 하나를 구성하되 둘 다는 안 돼요.

값 (Values)
  • 기본값: None
  • 이 필드는 필수예요.
  • 데이터 유형: Map

Arguments.Config.GrpcService

gRPC 프로세서에 대한 외부 처리 구성을 지정해요. GrpcService 또는 HttpService 설정을 구성하되 둘 다는 안 돼요.

gRPC 프로세서는 양방향 gRPC 스트림을 통해 Envoy와 통신하며 요청 및 응답 헤더, 본문, 트레일러 처리를 포함한 전체 외부 처리 수명 주기를 지원해요.

값 (Values)
  • 기본값: None
  • GrpcService 또는 HttpService 구성 중 하나가 필요해요.
  • 데이터 유형: Map

Arguments.Config.GrpcService.Target

Envoy가 gRPC 처리 요청을 보내는 서비스를 지정해요. Target 필드는 다음 필드를 포함할 수 있어요:

값 (Values)
  • 기본값: None
  • 이 필드는 필수예요.
  • 데이터 유형: Map

Arguments.Config.GrpcService.Target.Service

업스트림 외부 처리 서비스를 지정해요. Envoy가 서비스 메시 내의 서비스에 처리 요청을 보낼 때 이 필드를 구성해요. 확장을 connect-proxy에 연결할 때 서비스는 필터가 적용되는 서비스의 업스트림으로 구성되어야 해요.

Service 필드 또는 URI 필드를 구성하되 둘 다는 안 돼요.

값 (Values)
  • 기본값: None
  • 이 필드 또는 URI가 필요해요.
  • 데이터 유형: Map

다음 표는 Service 필드의 매개변수 구성 방법을 설명해요:

매개변수 설명 데이터 유형 기본값
Name 업스트림 서비스의 이름을 지정해요. String None
Namespace Enterprise 업스트림 서비스가 속한 Consul 네임스페이스를 지정해요. String default
Partition Enterprise 업스트림 서비스가 속한 Consul admin partition을 지정해요. String default
Port 업스트림 서비스가 여러 포트를 노출할 때 대상으로 지정할 포트의 이름을 지정해요. String None

Arguments.Config.GrpcService.Target.URI

외부 처리 서비스의 URI를 지정해요. 처리 서비스에 명시적 URI를 제공해야 할 때(예: 처리 서비스가 같은 호스트나 pod에서 실행될 때) 이 필드를 구성해요. 설정되면 이 필드의 값은 localhost:<port>, 127.0.0.1:<port> 또는 ::1:<port> 중 하나여야 해요.

URI 필드 또는 Service 필드를 구성하되 둘 다는 안 돼요.

값 (Values)
  • 기본값: None
  • 이 필드 또는 Service가 필요해요.
  • 데이터 유형: String

Arguments.Config.GrpcService.Target.Timeout

Envoy가 처리 서비스에 대한 연결을 설정할 때까지 기다리는 최대 기간을 지정해요.

값 (Values)
  • 기본값: 5s
  • 데이터 유형: String

Arguments.Config.GrpcService.Authority

gRPC 요청에서 보낼 authority 헤더를 지정해요. 이 필드가 설정되지 않으면 Consul은 authority 헤더를 클러스터 이름으로 설정해요.

값 (Values)
  • 기본값: 클러스터 이름
  • 데이터 유형: String

Arguments.Config.HttpService

HTTP 프로세서에 대한 외부 처리 구성을 지정해요. HttpService 또는 GrpcService 설정을 구성하되 둘 다는 안 돼요.

HTTP 프로세서는 HTTP side stream을 통해 Envoy와 통신해요. 요청 헤더 처리만 지원해요.

값 (Values)
  • 기본값: None
  • HttpService 또는 GrpcService 구성 중 하나가 필요해요.
  • 데이터 유형: Map

Arguments.Config.HttpService.Target

Envoy가 HTTP 처리 요청을 보내는 서비스를 지정해요. Target 필드는 다음 필드를 포함할 수 있어요:

값 (Values)
  • 기본값: None
  • 이 필드는 필수예요.
  • 데이터 유형: Map

Arguments.Config.HttpService.Target.Service

업스트림 외부 처리 서비스를 지정해요. Envoy가 서비스 메시 내의 서비스에 처리 요청을 보낼 때 이 필드를 구성해요. 확장을 connect-proxy에 연결할 때 서비스는 필터가 적용되는 서비스의 업스트림으로 구성되어야 해요.

Service 필드 또는 URI 필드를 구성하되 둘 다는 안 돼요.

값 (Values)
  • 기본값: None
  • 이 필드 또는 URI가 필요해요.
  • 데이터 유형: Map

다음 표는 Service 필드의 매개변수 구성 방법을 설명해요:

매개변수 설명 데이터 유형 기본값
Name 업스트림 서비스의 이름을 지정해요. String None
Namespace Enterprise 업스트림 서비스가 속한 Consul 네임스페이스를 지정해요. String default
Partition Enterprise 업스트림 서비스가 속한 Consul admin partition을 지정해요. String default
Port 업스트림 서비스가 여러 포트를 노출할 때 대상으로 지정할 포트의 이름을 지정해요. String None

Arguments.Config.HttpService.Target.URI

외부 처리 서비스의 URI를 지정해요. 처리 서비스에 명시적 URI를 제공해야 할 때(예: 처리 서비스가 같은 호스트나 pod에서 실행될 때) 이 필드를 구성해요. 설정되면 이 필드의 값은 localhost:<port>, 127.0.0.1:<port> 또는 ::1:<port> 중 하나여야 해요.

URI 필드 또는 Service 필드를 구성하되 둘 다는 안 돼요.

값 (Values)
  • 기본값: None
  • 이 필드 또는 Service가 필요해요.
  • 데이터 유형: String

Arguments.Config.HttpService.Target.Timeout

Envoy가 처리 서비스에 대한 연결을 설정할 때까지 기다리는 최대 기간을 지정해요.

값 (Values)
  • 기본값: 5s
  • 데이터 유형: String

Arguments.Config.HttpService.Path

Envoy가 외부 처리 서비스에 처리 요청을 보내는 HTTP 경로를 지정해요. 선행 슬래시(/)를 포함해야 해요. 처리 루프를 피하기 위해 Consul은 이 경로와 일치하는 경로에서 외부 처리를 비활성화해요.

값 (Values)
  • 기본값: /
  • 데이터 유형: String

Arguments.Config.StatPrefix

이 외부 처리 인스턴스를 고유하게 식별하는 접두사를 지정해요. Consul은 접두사를 사용해 envoy.filters.http.ext_proc/<StatPrefix> 형식의 고유한 Envoy 필터 이름을 파생하고 필터가 내보내는 통계를 네임스페이스화해요. 접두사를 생략하면 Consul은 접미사 없는 필터 이름 envoy.filters.http.ext_proc를 사용해요.

같은 필터 체인에서 두 개 이상의 외부 처리 인스턴스를 구성할 때 각 인스턴스에 고유한 StatPrefix를 설정해야 해요.

값 (Values)
  • 기본값: None
  • 데이터 유형: String

Arguments.Config.FailureModeAllow

외부 처리 서비스에 도달할 수 없거나 오류를 반환할 때 Envoy가 요청을 처리하는 방법을 제어해요. false로 설정하면 Envoy는 요청을 거부해요. true로 설정하면 Envoy는 요청을 계속 진행하도록 허용해요.

값 (Values)
  • 기본값: false
  • 데이터 유형: Boolean

Arguments.Config.RouteCacheAction

처리 서비스가 응답 헤더를 반환한 후 Envoy가 경로 캐시를 처리하는 방법을 제어해요. 이 필드는 gRPC 프로세서에만 적용돼요. 다음 문자열 값 중 하나를 지정할 수 있어요:

  • DEFAULT: 처리 서비스가 라우팅에 영향을 주는 헤더를 수정할 때 Envoy는 경로 캐시를 지워요.
  • CLEAR: Envoy는 항상 경로 캐시를 지워 처리 서비스가 만든 헤더 변경이 라우팅 결정에 영향을 주도록 해요.
  • RETAIN: Envoy는 경로 캐시를 유지하고 라우팅에 영향을 줄 헤더 변경을 무시해요.
값 (Values)
  • 기본값: DEFAULT
  • 데이터 유형: String

Arguments.Config.MessageTimeout

각 메시지에 대해 Envoy가 처리 서비스의 응답을 기다리는 최대 기간을 지정해요. 200ms 같은 기간 문자열로 값을 지정해요. 이 필드를 생략하면 Envoy는 타임아웃 없음이라는 내장 기본값을 적용해요. 자세한 내용은 Envoy message_timeout 문서를 참고해요.

값 (Values)
  • 기본값: 타임아웃 없음(Envoy 내장 기본값)
  • 데이터 유형: String

Arguments.Config.Processing

Envoy가 처리 서비스로 보내는 요청 및 응답 수명 주기의 단계를 지정해요. 이 필드를 생략하면 Envoy는 요청 헤더만 보내요(Request.HeadersMode = SEND 설정과 동일).

값 (Values)
  • 기본값: 요청 헤더만 보냄(Request.HeadersMode = SEND; 다른 모든 단계는 건너뜀)
  • 데이터 유형: Map

Arguments.Config.Processing.Request

Envoy가 요청 방향에 적용하는 처리 모드를 지정해요.

값 (Values)
  • 기본값: None
  • 데이터 유형: Map

다음 표는 Request 필드에서 구성할 수 있는 매개변수를 설명해요:

매개변수 설명 데이터 유형 기본값
HeadersMode Envoy가 요청 헤더를 처리 서비스로 보내는지 제어해요. SEND 또는 SKIP로 설정해요. String SEND
BodyMode Envoy가 요청 본문을 처리 서비스로 보내는지와 방법을 제어해요. SKIP, BUFFERED, BUFFERED_PARTIAL 또는 STREAMED로 설정해요. String SKIP
TrailersMode Envoy가 요청 트레일러를 처리 서비스로 보내는지 제어해요. SEND 또는 SKIP로 설정해요. String SKIP
MaxBodyBytes BodyMode가 BUFFERED 또는 BUFFERED_PARTIAL일 때 Envoy가 버퍼링하는 최대 본문 바이트 수를 지정해요. Integer None

Arguments.Config.Processing.Response

Envoy가 응답 방향에 적용하는 처리 모드를 지정해요.

값 (Values)
  • 기본값: None
  • 데이터 유형: Map

다음 표는 Response 필드에서 구성할 수 있는 매개변수를 설명해요:

매개변수 설명 데이터 유형 기본값
HeadersMode Envoy가 응답 헤더를 처리 서비스로 보내는지 제어해요. SEND 또는 SKIP로 설정해요. String SKIP
BodyMode Envoy가 응답 본문을 처리 서비스로 보내는지와 방법을 제어해요. SKIP, BUFFERED, BUFFERED_PARTIAL 또는 STREAMED로 설정해요. String SKIP
TrailersMode Envoy가 응답 트레일러를 처리 서비스로 보내는지 제어해요. SEND 또는 SKIP로 설정해요. String SKIP
MaxBodyBytes BodyMode가 BUFFERED 또는 BUFFERED_PARTIAL일 때 Envoy가 버퍼링하는 최대 본문 바이트 수를 지정해요. Integer None

예시 (Examples)

다음 예시는 특정 사용 사례에 대한 일반적인 구성 패턴을 보여줘요.

gRPC 서비스로 게이트웨이 요청 처리 (Process gateway requests with a gRPC service)

다음 서비스 기본값 구성 항목은 api-gateway의 인바운드 리스너에 ext-proc 확장을 연결해요. 구성은 게이트웨이가 gRPC로 ext-proc 서비스에 요청을 보내고 경로 캐시를 지워 헤더 변경이 라우팅에 영향을 주도록 지시해요.

HCL (api-gateway-ext-proc-service-defaults.hcl):

Kind     = "service-defaults"
Name     = "api-gateway"
Protocol = "http"
EnvoyExtensions = [
  {
    Name = "builtin/ext-proc"
    Arguments = {
      ProxyType    = "api-gateway"
      ListenerType = "inbound"
      Config = {
        StatPrefix       = "route-decider"
        RouteCacheAction = "CLEAR"
        GrpcService = {
          Target = {
            Service = {
              Name = "ext-proc"
            }
          }
        }
      }
    }
  }
]

JSON (api-gateway-ext-proc-service-defaults.json):

{
  "Kind": "service-defaults",
  "Name": "api-gateway",
  "Protocol": "http",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-proc",
    "Arguments": {
      "ProxyType": "api-gateway",
      "ListenerType": "inbound",
      "Config": {
        "StatPrefix": "route-decider",
        "RouteCacheAction": "CLEAR",
        "GrpcService": {
          "Target": {
            "Service": {
              "Name": "ext-proc"
            }
          }
        }
      }
    }
  }]
}

YAML (api-gateway-ext-proc-service-defaults.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: api-gateway
spec:
  protocol: http
  envoyExtensions:
    - name: builtin/ext-proc
      arguments:
        proxyType: api-gateway
        listenerType: inbound
        config:
          statPrefix: route-decider
          routeCacheAction: CLEAR
          grpcService:
            target:
              service:
                name: ext-proc

gRPC 서비스로 사이드카 요청 처리 (Process sidecar requests with a gRPC service)

다음 서비스 기본값 구성 항목은 service-e 사이드카 프록시의 인바운드 리스너에 ext-proc 확장을 연결해요. 다른 메시 서비스가 service-e에 요청을 보내면 프록시는 gRPC로 ext-proc-connect-proxy 서비스에 요청을 보내요.

HCL (service-e-ext-proc-service-defaults.hcl):

Kind     = "service-defaults"
Name     = "service-e"
Protocol = "http"
EnvoyExtensions = [
  {
    Name = "builtin/ext-proc"
    Arguments = {
      ProxyType    = "connect-proxy"
      ListenerType = "inbound"
      Config = {
        RouteCacheAction = "CLEAR"
        GrpcService = {
          Target = {
            Service = {
              Name = "ext-proc-connect-proxy"
            }
          }
        }
      }
    }
  }
]

JSON (service-e-ext-proc-service-defaults.json):

{
  "Kind": "service-defaults",
  "Name": "service-e",
  "Protocol": "http",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-proc",
    "Arguments": {
      "ProxyType": "connect-proxy",
      "ListenerType": "inbound",
      "Config": {
        "RouteCacheAction": "CLEAR",
        "GrpcService": {
          "Target": {
            "Service": {
              "Name": "ext-proc-connect-proxy"
            }
          }
        }
      }
    }
  }]
}

YAML (service-e-ext-proc-service-defaults.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: service-e
spec:
  protocol: http
  envoyExtensions:
    - name: builtin/ext-proc
      arguments:
        proxyType: connect-proxy
        listenerType: inbound
        config:
          routeCacheAction: CLEAR
          grpcService:
            target:
              service:
                name: ext-proc-connect-proxy

로컬 HTTP 서비스로 사이드카 요청 처리 (Process sidecar requests with a local HTTP service)

다음 서비스 기본값 구성 항목은 service-e1 사이드카 프록시의 인바운드 리스너에 ext-proc 확장을 연결해요. 처리 서비스는 같은 pod의 사이드카로 실행되므로 확장은 메시 서비스 대신 로컬 URI를 대상으로 해요.

HCL (service-e1-ext-proc-service-defaults.hcl):

Kind     = "service-defaults"
Name     = "service-e1"
Protocol = "http"
EnvoyExtensions = [
  {
    Name = "builtin/ext-proc"
    Arguments = {
      ProxyType    = "connect-proxy"
      ListenerType = "inbound"
      Config = {
        RouteCacheAction = "CLEAR"
        HttpService = {
          Target = {
            URI = "127.0.0.1:9000"
          }
          Path = "/decide"
        }
      }
    }
  }
]

JSON (service-e1-ext-proc-service-defaults.json):

{
  "Kind": "service-defaults",
  "Name": "service-e1",
  "Protocol": "http",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-proc",
    "Arguments": {
      "ProxyType": "connect-proxy",
      "ListenerType": "inbound",
      "Config": {
        "RouteCacheAction": "CLEAR",
        "HttpService": {
          "Target": {
            "URI": "127.0.0.1:9000"
          },
          "Path": "/decide"
        }
      }
    }
  }]
}

YAML (service-e1-ext-proc-service-defaults.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: service-e1
spec:
  protocol: http
  envoyExtensions:
    - name: builtin/ext-proc
      arguments:
        proxyType: connect-proxy
        listenerType: inbound
        config:
          routeCacheAction: CLEAR
          httpService:
            target:
              uri: "127.0.0.1:9000"
            path: /decide

ext-proc 헤더 기반 ServiceRouter로 트래픽 라우팅 (Route traffic with a ServiceRouter based on ext-proc headers)

다음 예시는 헤더 기반 라우팅을 수행하기 위해 ext-proc 확장을 ServiceRouter와 함께 사용하는 방법을 보여줘요. ext-proc 서비스는 요청 처리 중에 사용자 지정 헤더를 주입하고, ServiceRouter는 해당 헤더를 사용해 트래픽을 서로 다른 업스트림 서비스로 전달해요.

이 패턴에서 service-c는 아웃바운드 리스너에서 ext-proc를 실행하므로 헤더가 요청이 사이드카를 떠나기 전에 주입돼요. 그런 다음 service-d2의 ServiceRouter가 헤더 값을 일치시켜 올바른 대상을 선택해요.

다음 구성은 service-c 사이드카 프록시의 아웃바운드 리스너에 ext-proc 확장을 연결해요. service-c가 service-d2에 요청을 보내면 사이드카는 먼저 요청을 ext-proc-grpc로 전달하고, 요청이 라우팅되기 전에 x-cell 헤더를 주입해요.

HCL (service-c-ext-proc-service-defaults.hcl):

Kind     = "service-defaults"
Name     = "service-c"
Protocol = "http"
EnvoyExtensions = [
  {
    Name     = "builtin/ext-proc"
    Required = true
    Arguments = {
      ProxyType    = "connect-proxy"
      ListenerType = "outbound"
      Config = {
        GrpcService = {
          Target = {
            Service = {
              Name = "ext-proc-grpc"
            }
          }
        }
      }
    }
  }
]

JSON (service-c-ext-proc-service-defaults.json):

{
  "Kind": "service-defaults",
  "Name": "service-c",
  "Protocol": "http",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-proc",
    "Required": true,
    "Arguments": {
      "ProxyType": "connect-proxy",
      "ListenerType": "outbound",
      "Config": {
        "GrpcService": {
          "Target": {
            "Service": {
              "Name": "ext-proc-grpc"
            }
          }
        }
      }
    }
  }]
}

YAML (service-c-ext-proc-service-defaults.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: service-c
spec:
  protocol: http
  envoyExtensions:
    - name: builtin/ext-proc
      required: true
      arguments:
        proxyType: connect-proxy
        listenerType: outbound
        config:
          grpcService:
            target:
              service:
                name: ext-proc-grpc

service-d2에 대한 다음 구성은 x-cell 헤더 값을 기반으로 트래픽을 라우팅해요. x-cell: C가 있는 요청은 service-d1로 전달되고, x-cell: D가 있는 요청은 service-d2로 전달돼요.

HCL (service-d2-service-router.hcl):

Kind = "service-router"
Name = "service-d2"
Routes = [
  {
    Match = {
      HTTP = {
        Header = [
          {
            Name  = "x-cell"
            Exact = "C"
          }
        ]
      }
    }
    Destination = {
      Service = "service-d1"
    }
  },
  {
    Match = {
      HTTP = {
        Header = [
          {
            Name  = "x-cell"
            Exact = "D"
          }
        ]
      }
    }
    Destination = {
      Service = "service-d2"
    }
  }
]

JSON (service-d2-service-router.json):

{
  "Kind": "service-router",
  "Name": "service-d2",
  "Routes": [
    {
      "Match": {
        "HTTP": {
          "Header": [
            {
              "Name": "x-cell",
              "Exact": "C"
            }
          ]
        }
      },
      "Destination": {
        "Service": "service-d1"
      }
    },
    {
      "Match": {
        "HTTP": {
          "Header": [
            {
              "Name": "x-cell",
              "Exact": "D"
            }
          ]
        }
      },
      "Destination": {
        "Service": "service-d2"
      }
    }
  ]
}

YAML (service-d2-service-router.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceRouter
metadata:
  name: service-d2
spec:
  routes:
    - match:
        http:
          header:
            - name: x-cell
              exact: C
      destination:
        service: service-d1
    - match:
        http:
          header:
            - name: x-cell
              exact: D
      destination:
        service: service-d2

ext-proc와 명명된 서비스 포트로 API gateway 트래픽 라우팅 (Route API gateway traffic with ext-proc and a named service port)

다음 예시는 처리 서비스에 명시적 포트로 도달해야 할 때 API gateway에 ext-proc을 연결하는 방법을 보여줘요. connect-proxy 사이드카와 달리 API gateway Envoy는 업스트림 서비스에 대한 아웃바운드 클러스터를 미리 구축하지 않아요. Consul이 올바른 xDS 클러스터 주소를 구성할 수 있도록 Port 필드를 설정해야 해요. 포트가 없으면 Consul은 필터를 자동으로 건너뛰고 트래픽은 헤더 주입 없이 통과해요.

다음 구성은 api-gateway의 인바운드 리스너에 ext-proc 확장을 연결하고 RouteCacheAction: CLEAR를 사용해 처리 서비스가 주입한 모든 헤더가 라우팅 결정에 영향을 주도록 해요.

HCL (api-gateway-named-port-ext-proc-service-defaults.hcl):

Kind     = "service-defaults"
Name     = "api-gateway"
Protocol = "http"
EnvoyExtensions = [
  {
    Name     = "builtin/ext-proc"
    Required = true
    Arguments = {
      ProxyType    = "api-gateway"
      ListenerType = "inbound"
      Config = {
        RouteCacheAction = "CLEAR"
        GrpcService = {
          Target = {
            Service = {
              Name = "ext-proc-grpc"
              Port = "50051"
            }
          }
        }
      }
    }
  }
]

JSON (api-gateway-named-port-ext-proc-service-defaults.json):

{
  "Kind": "service-defaults",
  "Name": "api-gateway",
  "Protocol": "http",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-proc",
    "Required": true,
    "Arguments": {
      "ProxyType": "api-gateway",
      "ListenerType": "inbound",
      "Config": {
        "RouteCacheAction": "CLEAR",
        "GrpcService": {
          "Target": {
            "Service": {
              "Name": "ext-proc-grpc",
              "Port": "50051"
            }
          }
        }
      }
    }
  }]
}

YAML (api-gateway-named-port-ext-proc-service-defaults.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: api-gateway
spec:
  protocol: http
  envoyExtensions:
    - name: builtin/ext-proc
      required: true
      arguments:
        proxyType: api-gateway
        listenerType: inbound
        config:
          routeCacheAction: CLEAR
          grpcService:
            target:
              service:
                name: ext-proc-grpc
                port: "50051"

요청 및 응답 본문 처리 (Process request and response bodies)

다음 서비스 기본값 구성 항목은 요청 헤더와 버퍼링된 요청 본문, 그리고 응답 헤더를 처리 서비스로 보내는 ext-proc 확장을 연결해요.

HCL (api-gateway-body-processor-ext-proc-service-defaults.hcl):

Kind     = "service-defaults"
Name     = "api-gateway"
Protocol = "http"
EnvoyExtensions = [
  {
    Name = "builtin/ext-proc"
    Arguments = {
      ProxyType    = "api-gateway"
      ListenerType = "inbound"
      Config = {
        StatPrefix = "body-processor"
        GrpcService = {
          Target = {
            Service = {
              Name = "ext-proc"
            }
          }
        }
        Processing = {
          Request = {
            HeadersMode  = "SEND"
            BodyMode     = "BUFFERED"
            MaxBodyBytes = 8192
          }
          Response = {
            HeadersMode = "SEND"
          }
        }
      }
    }
  }
]

JSON (api-gateway-body-processor-ext-proc-service-defaults.json):

{
  "Kind": "service-defaults",
  "Name": "api-gateway",
  "Protocol": "http",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-proc",
    "Arguments": {
      "ProxyType": "api-gateway",
      "ListenerType": "inbound",
      "Config": {
        "StatPrefix": "body-processor",
        "GrpcService": {
          "Target": {
            "Service": {
              "Name": "ext-proc"
            }
          }
        },
        "Processing": {
          "Request": {
            "HeadersMode": "SEND",
            "BodyMode": "BUFFERED",
            "MaxBodyBytes": 8192
          },
          "Response": {
            "HeadersMode": "SEND"
          }
        }
      }
    }
  }]
}

YAML (api-gateway-body-processor-ext-proc-service-defaults.yaml):

apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: api-gateway
spec:
  protocol: http
  envoyExtensions:
    - name: builtin/ext-proc
      arguments:
        proxyType: api-gateway
        listenerType: inbound
        config:
          statPrefix: body-processor
          grpcService:
            target:
              service:
                name: ext-proc
          processing:
            request:
              headersMode: SEND
              bodyMode: BUFFERED
              maxBodyBytes: 8192
            response:
              headersMode: SEND

더 알아보기 (Learn more)