Extender waypoints con scripts Lua

Istio permite extender los waypoint proxies usando scripts Lua inline a través de la API TrafficExtension. En modo ambient, los recursos TrafficExtension deben adjuntarse a un waypoint proxy usando targetRefs.

Antes de comenzar

  1. Configura Istio siguiendo la guía de inicio rápido en modo ambient.

  2. Despliega la aplicación de ejemplo Bookinfo.

  3. Agrega el namespace default a la mesh ambient.

  4. Despliega la aplicación de ejemplo curl como fuente de prueba:

    Zip
    $ kubectl apply -f @samples/curl/curl.yaml@

En un gateway

Obtén el nombre del gateway:

$ kubectl get gateway
NAME               CLASS            ADDRESS                                            PROGRAMMED   AGE
bookinfo-gateway   istio            bookinfo-gateway-istio.default.svc.cluster.local   True         42m

Crea un TrafficExtension apuntando al bookinfo-gateway con un filtro Lua de paridad. El filtro lee el header de solicitud x-number y agrega el header de respuesta x-parity indicando si el valor es odd (impar) o even (par). El valor se almacena en metadatos dinámicos durante el procesamiento de la solicitud para que esté disponible al escribir el header de respuesta:

$ 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
EOF

Verificar el tráfico a través del 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: even

En un waypoint, para todos los servicios de un namespace

Desplegar un waypoint proxy

Sigue las instrucciones de despliegue de waypoint para desplegar un waypoint proxy en el namespace de bookinfo:

$ istioctl waypoint apply --enroll-namespace --wait

Verifica que el tráfico llega al servicio:

$ kubectl exec deploy/curl -- curl -s -w "%{http_code}" -o /dev/null http://productpage:9080/productpage
200

Obtén el nombre del gateway del waypoint:

$ 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         21h

Crea un TrafficExtension apuntando al 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
EOF

Verificar el tráfico a través del 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: odd

En un waypoint, para un servicio específico

Elimina el filtro a nivel de namespace y reemplázalo con uno que apunte únicamente al servicio reviews:

$ kubectl delete trafficextension parity-at-waypoint

Crea un TrafficExtension apuntando directamente al servicio reviews para que el filtro se aplique únicamente al tráfico destinado a ese servicio:

$ 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
EOF

Verificar el tráfico apuntando al servicio

$ kubectl exec deploy/curl -- curl -s -o /dev/null -D - -H "x-number: 3" http://reviews:9080/reviews/1 | grep x-parity
x-parity: odd

Limpieza

  1. Elimina los recursos TrafficExtension:

    $ kubectl delete trafficextension parity-at-gateway parity-for-reviews
  2. Sigue la guía de desinstalación del modo ambient para eliminar Istio y las aplicaciones de prueba de ejemplo.

¿Fue útil esta información?
¿Tienes alguna sugerencia para mejorar?

¡Gracias por tus comentarios!