Lua Envoy 확장

Lua Envoy 확장 (Lua Envoy Extension)

Lua Envoy 확장은 Consul Envoy 프록시에서 HTTP Lua 필터를 활성화해서, 요청·응답이 Consul이 생성한 Envoy 리소스를 통과할 때 Lua 스크립트를 실행할 수 있게 해 줘요. 이 문서에서 EnvoyExtensions 블록 구성과 service-defaults/proxy-defaults 적용 방법, 그리고 다양한 예제를 살펴볼게요.

출처: 문서

본문

Lua Envoy 확장은 Consul Envoy 프록시에서 HTTP Lua 필터를 활성화합니다. 이를 통해 요청·응답이 Consul이 생성한 Envoy 리소스를 통과할 때 Lua 스크립트를 실행할 수 있습니다.

Envoy 필터는 동적 메타데이터(dynamic metadata) 설정·조회를 지원하며, 이를 통해 한 필터가 후속 필터와 상태 정보를 공유할 수 있습니다. 동적 메타데이터를 설정하려면 HTTP Lua 필터를 구성합니다. 사용자는 Lua 스크립트에서 streamInfo:dynamicMetadata()를 호출해 요청의 동적 메타데이터를 가져올 수 있습니다.

구성 사양 (Configuration specifications)

Lua Envoy 확장을 사용하려면 EnvoyExtensions 블록에서 다음 인자를 구성합니다:

| 인자 (Arguments) | 타입 (Type) | 기본값 (Default) | 설명 (Description) | | ListenerType | string | 필수 | 확장이 inbound 또는 outbound 리스너에 적용되는지 지정합니다. | | ProxyType | string | 필수 | 확장이 적용되는 프록시 유형을 결정합니다. 지원되는 값은 connect-proxy와 api-gateway입니다. | | Script | string | 필수 | HTTP Lua 필터가 실행하도록 구성된 Lua 스크립트입니다. |

워크플로 (Workflow)

Lua Envoy 확장을 사용하려면 다음 단계를 완료합니다:

  1. service-defaults 또는 proxy-defaults를 통해 EnvoyExtensions를 구성합니다.
  2. 구성 항목을 적용합니다.

EnvoyExtensions 구성 (Configure EnvoyExtensions)

Envoy 확장을 사용하려면 Envoy 확장이 포함된 proxy-defaults 또는 service-defaults 구성 항목을 구성하고 적용해야 합니다.

  • proxy-defaults에 Envoy 확장을 구성하면 모든 서비스에 적용됩니다.
  • service-defaults에 Envoy 확장을 구성하면 특정 서비스에 적용됩니다.

Consul은 proxy-defaults에 구성된 Envoy 확장을 service-defaults의 확장보다 먼저 적용합니다. 결과적으로 service-defaults의 Envoy 확장 구성이 proxy-defaults의 구성을 재정의(override)할 수 있습니다.

다음 예제는 proxy-defaults를 사용해 모든 서비스에 Lua Envoy 확장을 구성합니다.

HCL

JSON

YAML

lua-envoy-extension-proxy-defaults.hcl:

Kind = "proxy-defaults"
Name = "global"
Config {
  protocol = "http"
}
EnvoyExtensions {
  Name = "builtin/lua"
  Arguments = {
    ProxyType = "connect-proxy"
    Listener  = "inbound"
    Script    = <<-EOF
function envoy_on_request(request_handle)
  meta = request_handle:streamInfo():dynamicMetadata()
  m = meta:get("consul")
  request_handle:headers():add("x-consul-service", m["service"])
  request_handle:headers():add("x-consul-namespace", m["namespace"])
  request_handle:headers():add("x-consul-datacenter", m["datacenter"])
  request_handle:headers():add("x-consul-trust-domain", m["trust-domain"])
end
 EOF
  }
}

lua-envoy-extension-proxy-defaults.json:

{
  "kind": "proxy-defaults",
  "name": "global",
  "protocol": "http",
  "envoy_extensions": [{
    "name": "builtin/lua",
    "arguments": {
      "proxy_type": "connect-proxy",
      "listener": "inbound",
      "script": "function envoy_on_request(request_handle)\nmeta = request_handle:streamInfo():dynamicMetadata()\nm = \nmeta:get(\"consul\")\nrequest_handle:headers():add(\"x-consul-service\", m[\"service\"])\nrequest_handle:headers():add(\"x-consul-namespace\", m[\"namespace\"])\nrequest_handle:headers():add(\"x-consul-datacenter\", m[\"datacenter\"])\nrequest_handle:headers():add(\"x-consul-trust-domain\", m[\"trust-domain\"])\nend"
    }
  }]
}

lua-envoy-extension-proxy-defaults.yaml:

apiVersion: consul.hashicorp.com/v1alpha1
kind: ProxyDefaults
metadata:
  name: global
spec:
  protocol: http
  envoyExtensions:
    - name = "builtin/lua"
      arguments:
        proxyType: "connect-proxy"
        listener: "inbound"
        script: |-
function envoy_on_request(request_handle)
  meta = request_handle:streamInfo():dynamicMetadata()
  m = meta:get("consul")
  request_handle:headers():add("x-consul-service", m["service"])
  request_handle:headers():add("x-consul-namespace", m["namespace"])
  request_handle:headers():add("x-consul-datacenter", m["datacenter"])
  request_handle:headers():add("x-consul-trust-domain", m["trust-domain"])
end

EnvoyExtensions의 전체 매개변수 목록은 service-defaults 및 proxy-defaults 구성 항목 참조 문서를 참조하세요.

경고

EnvoyExtensions를 ProxyDefaults에 적용하면 의도하지 않은 결과가 발생할 수 있습니다. 대부분의 경우 ServiceDefaults로 EnvoyExtensions를 활성화할 것을 권장합니다.

Lua Envoy 확장의 전체 인자 목록은 구성 사양 섹션을 참조하세요.

구성 항목 적용 (Apply the configuration entry)

proxy-defaults 또는 service-defaults 구성 항목을 적용합니다.

HCL

JSON

YAML

$ consul config write lua-envoy-extension-proxy-defaults.hcl
$ consul config write lua-envoy-extension-proxy-defaults.json
$ kubectl apply lua-envoy-extension-proxy-defaults.yaml

예제 (Examples)

다음 예제 구성은 myservice라는 모든 Consul 서비스에 HTTP Lua 필터를 삽입하고 모든 인바운드 요청의 x-consul-service 헤더에 Consul 서비스 이름을 추가하도록 Lua Envoy 확장을 구성합니다. ListenerType은 서비스의 connect 프록시의 인바운드 리스너에만 확장이 적용되도록 합니다.

lua-envoy-extension.hcl:

Kind = "service-defaults"
Name = "myservice"
EnvoyExtensions = [
  {
    Name = "builtin/lua"

    Arguments = {
      ProxyType = "connect-proxy"
      Listener  = "inbound"
      Script    = <<EOF
  function envoy_on_request(request_handle)
    local service = request_handle:streamInfo():dynamicMetadata():get("consul")["service"]
    request_handle:headers():add("x-consul-service", service)
  end
  EOF
    }
  }
]

또는 같은 확장 구성을 proxy-defaults 구성 항목에 적용할 수 있습니다. 그러면 프로кси 기본값 이름에 지정한 한 서비스 대신 모든 서비스에 적용됩니다.

Envoy 확장을 통해 여러 개의 Lua 필터를 지정할 수도 있습니다. 서로를 재정의하지 않습니다.

lua-envoy-extension.hcl:

Kind = "service-defaults"
Name = "myservice"
EnvoyExtensions = [
  {
    Name = "builtin/lua",
    Arguments = {
      ProxyType = "connect-proxy"
      Listener  = "inbound"
      Script    = <<-EOF
function envoy_on_request(request_handle)
  meta = request_handle:streamInfo():dynamicMetadata()
  m = meta:get("consul")
  request_handle:headers():add("x-consul-datacenter", m["datacenter1"])
end
      EOF
    }
  },
  {
    Name = "builtin/lua",
    Arguments = {
      ProxyType = "connect-proxy"
      Listener  = "inbound"
      Script    = <<-EOF
function envoy_on_request(request_handle)
  meta = request_handle:streamInfo():dynamicMetadata()
  m = meta:get("consul")
  request_handle:headers():add("x-consul-datacenter", m["datacenter2"])
end
      EOF
    }
  }
]

다음 예제 구성은 my-api-gateway라는 모든 Consul API 게이트웨이에 HTTP Lua 필터를 삽입하여, 업스트림의 http 요청 상태가 404일 때 응답 본문을 수정하도록 Lua Envoy 확장을 구성합니다.

lua-envoy-extension.hcl:

  Kind = "service-defaults"
  Name = "my-api-gateway"
  EnvoyExtensions = [
  {
    Name = "builtin/lua",
    Arguments = {
      ProxyType = "api-gateway"
      Listener  = "outbound"
      Script    = <<EOF
        function envoy_on_response(response_handle)
          if response_handle:headers():get(":status") == "404" then
            local json = '{"message":"Modified by Lua script","status":"success"}'
            response_handle:body():setBytes(json)
            response_handle:headers():remove("content-length")
            response_handle:headers():replace("content-encoding", "identity")
            response_handle:headers():replace("content-type", "application/json")
          end
        end
      EOF
    }
  }
  ]

더 알아보기 (Learn more)