Extend waypoints with Lua scripts
Istio provides the ability to extend waypoint proxies using inline Lua scripts
via the TrafficExtension API.
In ambient mode, TrafficExtension resources must be attached to a waypoint proxy using targetRefs.
Before you begin
Set up Istio by following the ambient mode Getting Started guide.
Deploy the Bookinfo sample application.
Deploy the curl sample app as a test source:
$ kubectl apply -f @samples/curl/curl.yaml@
At a gateway
Get the gateway name:
$ kubectl get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
bookinfo-gateway istio bookinfo-gateway-istio.default.svc.cluster.local True 42mCreate a TrafficExtension targeting the bookinfo-gateway with a Lua parity filter. The filter
reads an x-number request header and adds an x-parity response header indicating whether the
value is odd or even. The value is stored in dynamic metadata during request processing so it
is available when writing the response header:
$ kubectl apply -f - <<EOF
apiVersion: extensions.istio.io/v1alpha1
kind: TrafficExtension
metadata:
name: parity-at-gateway
spec:
targetRefs:
- kind: Gateway
group: gateway.networking.k8s.io
name: bookinfo-gateway
phase: STATS
lua:
inlineCode: |
function envoy_on_request(request_handle)
local number = tonumber(request_handle:headers():get("x-number"))
if number == nil then return end
local parity = number % 2 == 0 and "even" or "odd"
request_handle:streamInfo():dynamicMetadata():set(
"envoy.filters.http.lua", "parity", parity)
end
function envoy_on_response(response_handle)
local meta = response_handle:streamInfo():dynamicMetadata():get(
"envoy.filters.http.lua")
if meta == nil then return end
response_handle:headers():add("x-parity", meta["parity"])
end
EOFVerify the traffic via the gateway
$ kubectl exec deploy/curl -- curl -s -o /dev/null -D - -H "x-number: 4" "http://bookinfo-gateway-istio.default.svc.cluster.local/productpage" | grep x-parity
x-parity: evenAt a waypoint, for all services in a namespace
Deploy a waypoint proxy
Follow the waypoint deployment instructions to deploy a waypoint proxy in the bookinfo namespace:
$ istioctl waypoint apply --enroll-namespace --waitVerify traffic reaches the service:
$ kubectl exec deploy/curl -- curl -s -w "%{http_code}" -o /dev/null http://productpage:9080/productpage
200Get the waypoint gateway name:
$ kubectl get gateway
NAME CLASS ADDRESS PROGRAMMED AGE
bookinfo-gateway istio bookinfo-gateway-istio.default.svc.cluster.local True 23h
waypoint istio-waypoint 10.96.202.82 True 21hCreate a TrafficExtension targeting the waypoint:
$ kubectl apply -f - <<EOF
apiVersion: extensions.istio.io/v1alpha1
kind: TrafficExtension
metadata:
name: parity-at-waypoint
spec:
targetRefs:
- kind: Gateway
group: gateway.networking.k8s.io
name: waypoint
phase: STATS
lua:
inlineCode: |
function envoy_on_request(request_handle)
local number = tonumber(request_handle:headers():get("x-number"))
if number == nil then return end
local parity = number % 2 == 0 and "even" or "odd"
request_handle:streamInfo():dynamicMetadata():set(
"envoy.filters.http.lua", "parity", parity)
end
function envoy_on_response(response_handle)
local meta = response_handle:streamInfo():dynamicMetadata():get(
"envoy.filters.http.lua")
if meta == nil then return end
response_handle:headers():add("x-parity", meta["parity"])
end
EOFVerify the traffic via the waypoint proxy
$ kubectl exec deploy/curl -- curl -s -o /dev/null -D - -H "x-number: 7" http://productpage:9080/productpage | grep x-parity
x-parity: oddAt a waypoint, for a specific service
Remove the namespace-wide filter and replace it with one that targets only the reviews service:
$ kubectl delete trafficextension parity-at-waypointCreate a TrafficExtension targeting the reviews service directly so that the filter applies
only to traffic destined for that service:
$ kubectl apply -f - <<EOF
apiVersion: extensions.istio.io/v1alpha1
kind: TrafficExtension
metadata:
name: parity-for-reviews
spec:
targetRefs:
- kind: Service
group: ""
name: reviews
match:
- mode: SERVER
phase: STATS
lua:
inlineCode: |
function envoy_on_request(request_handle)
local number = tonumber(request_handle:headers():get("x-number"))
if number == nil then return end
local parity = number % 2 == 0 and "even" or "odd"
request_handle:streamInfo():dynamicMetadata():set(
"envoy.filters.http.lua", "parity", parity)
end
function envoy_on_response(response_handle)
local meta = response_handle:streamInfo():dynamicMetadata():get(
"envoy.filters.http.lua")
if meta == nil then return end
response_handle:headers():add("x-parity", meta["parity"])
end
EOFVerify the traffic targeting the service
$ kubectl exec deploy/curl -- curl -s -o /dev/null -D - -H "x-number: 3" http://reviews:9080/reviews/1 | grep x-parity
x-parity: oddCleanup
Remove
TrafficExtensionresources:$ kubectl delete trafficextension parity-at-gateway parity-for-reviewsFollow the ambient mode uninstall guide to remove Istio and sample test applications.