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 확장을 사용하려면 다음 단계를 완료합니다:
service-defaults또는proxy-defaults를 통해 EnvoyExtensions를 구성합니다.- 구성 항목을 적용합니다.
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
}
}
]