Mesh HTTP Route

This policy uses new policy matching algorithm. It’s recommended to migrate from TrafficRoute. See “Interactions with TrafficRoute” section for more information.

The MeshHTTPRoute policy allows altering and redirecting HTTP requests depending on where the request is coming from and where it’s going to.

TargetRef support matrix

targetRefAllowed kinds
targetRef.kindMesh, MeshSubset
to[].targetRef.kindMeshService
targetRefAllowed kinds
targetRef.kindMesh, MeshGateway, MeshGateway with listener tags
to[].targetRef.kindMesh
targetRefAllowed kinds
targetRef.kindMesh, MeshSubset
to[].targetRef.kindMeshService

If you don’t understand this table you should read matching docs.

Configuration

Unlike others outbound policies MeshHTTPRoute doesn’t contain default directly in the to array. The default section is nested inside rules, so the policy structure looks like this:

  1. spec:
  2. to:
  3. - targetRef: {...}
  4. rules:
  5. - matches: [...] # various ways to match an HTTP request (path, method, query)
  6. default: # configuration applied for the matched HTTP request
  7. filters: [...]
  8. backendRefs: [...]

Remember to tag your Service ports with appProtocol: http to use them in a MeshHTTPRoute!

Gateways

In order to route HTTP traffic for a MeshGateway, you need to target the MeshGateway in spec.targetRef and set spec.to[].targetRef.kind: Mesh.

Interactions with MeshTCPRoute

MeshHTTPRoute takes priority over MeshTCPRoute when a proxy is targeted by both and the matching MeshTCPRoute is ignored.

Interactions with TrafficRoute

MeshHTTPRoute takes priority over TrafficRoute when a proxy is targeted by both policies.

All legacy policies like Retry, TrafficLog, Timeout etc. only match on routes defined by TrafficRoute. All new recommended policies like MeshRetry, MeshAccessLog, MeshTimeout etc. match on routes defined by MeshHTTPRoute and TrafficRoute.

If you don’t use legacy policies, it’s recommended to remove any existing TrafficRoute. Otherwise, it’s recommended to migrate to new policies and then removing TrafficRoute.

Examples

Traffic split

We can use MeshHTTPRoute to split an HTTP traffic between different MeshServices implementing A/B testing or canary deployments. If we want to split traffic between v1 and v2 versions of the same service, first we have to create MeshServices backend-v1 and backend-v2 that select backend application instances according to the version.

  1. apiVersion: kuma.io/v1alpha1
  2. kind: MeshHTTPRoute
  3. metadata:
  4. name: http-split
  5. namespace: kuma-demo
  6. labels:
  7. kuma.io/mesh: default
  8. spec:
  9. targetRef:
  10. kind: MeshSubset
  11. tags:
  12. app: frontend
  13. to:
  14. - targetRef:
  15. kind: MeshService
  16. name: backend_kuma-demo_svc_3001
  17. rules:
  18. - matches:
  19. - path:
  20. type: PathPrefix
  21. value: "/"
  22. default:
  23. backendRefs:
  24. - kind: MeshServiceSubset
  25. name: backend_kuma-demo_svc_3001
  26. weight: 90
  27. tags:
  28. version: v1
  29. - kind: MeshServiceSubset
  30. name: backend_kuma-demo_svc_3001
  31. weight: 10
  32. tags:
  33. version: v2
  1. apiVersion: kuma.io/v1alpha1
  2. kind: MeshHTTPRoute
  3. metadata:
  4. name: http-split
  5. namespace: kuma-demo
  6. labels:
  7. kuma.io/mesh: default
  8. spec:
  9. targetRef:
  10. kind: MeshSubset
  11. tags:
  12. app: frontend
  13. to:
  14. - targetRef:
  15. kind: MeshService
  16. name: backend
  17. namespace: kuma-demo
  18. sectionName: http
  19. rules:
  20. - matches:
  21. - path:
  22. type: PathPrefix
  23. value: "/"
  24. default:
  25. backendRefs:
  26. - kind: MeshService
  27. name: backend-v1
  28. namespace: kuma-demo
  29. port: 3001
  30. weight: 90
  31. - kind: MeshService
  32. name: backend-v2
  33. namespace: kuma-demo
  34. port: 3001
  35. weight: 10

I am using MeshService

  1. type: MeshHTTPRoute
  2. name: http-split
  3. mesh: default
  4. spec:
  5. targetRef:
  6. kind: MeshSubset
  7. tags:
  8. app: frontend
  9. to:
  10. - targetRef:
  11. kind: MeshService
  12. name: backend
  13. rules:
  14. - matches:
  15. - path:
  16. type: PathPrefix
  17. value: "/"
  18. default:
  19. backendRefs:
  20. - kind: MeshServiceSubset
  21. name: backend
  22. weight: 90
  23. tags:
  24. version: v1
  25. - kind: MeshServiceSubset
  26. name: backend
  27. weight: 10
  28. tags:
  29. version: v2
  1. type: MeshHTTPRoute
  2. name: http-split
  3. mesh: default
  4. spec:
  5. targetRef:
  6. kind: MeshSubset
  7. tags:
  8. app: frontend
  9. to:
  10. - targetRef:
  11. kind: MeshService
  12. name: backend
  13. sectionName: http
  14. rules:
  15. - matches:
  16. - path:
  17. type: PathPrefix
  18. value: "/"
  19. default:
  20. backendRefs:
  21. - kind: MeshService
  22. name: backend-v1
  23. port: 3001
  24. weight: 90
  25. - kind: MeshService
  26. name: backend-v2
  27. port: 3001
  28. weight: 10

Traffic modifications

We can use MeshHTTPRoute to modify outgoing requests, by setting new path or changing request and response headers.

Here is an example of a MeshHTTPRoute that adds x-custom-header with value xyz when frontend tries to consume backend.

  1. apiVersion: kuma.io/v1alpha1
  2. kind: MeshHTTPRoute
  3. metadata:
  4. name: http-route-1
  5. namespace: kuma-demo
  6. labels:
  7. kuma.io/mesh: default
  8. spec:
  9. targetRef:
  10. kind: MeshSubset
  11. tags:
  12. app: frontend
  13. to:
  14. - targetRef:
  15. kind: MeshService
  16. name: backend_kuma-demo_svc_3001
  17. rules:
  18. - matches:
  19. - path:
  20. type: Exact
  21. value: "/"
  22. default:
  23. filters:
  24. - type: RequestHeaderModifier
  25. requestHeaderModifier:
  26. set:
  27. - name: x-custom-header
  28. value: xyz
  1. apiVersion: kuma.io/v1alpha1
  2. kind: MeshHTTPRoute
  3. metadata:
  4. name: http-route-1
  5. namespace: kuma-demo
  6. labels:
  7. kuma.io/mesh: default
  8. spec:
  9. targetRef:
  10. kind: MeshSubset
  11. tags:
  12. app: frontend
  13. to:
  14. - targetRef:
  15. kind: MeshService
  16. name: backend
  17. namespace: kuma-demo
  18. sectionName: http
  19. rules:
  20. - matches:
  21. - path:
  22. type: Exact
  23. value: "/"
  24. default:
  25. filters:
  26. - type: RequestHeaderModifier
  27. requestHeaderModifier:
  28. set:
  29. - name: x-custom-header
  30. value: xyz

I am using MeshService

  1. type: MeshHTTPRoute
  2. name: http-route-1
  3. mesh: default
  4. spec:
  5. targetRef:
  6. kind: MeshSubset
  7. tags:
  8. app: frontend
  9. to:
  10. - targetRef:
  11. kind: MeshService
  12. name: backend
  13. rules:
  14. - matches:
  15. - path:
  16. type: Exact
  17. value: "/"
  18. default:
  19. filters:
  20. - type: RequestHeaderModifier
  21. requestHeaderModifier:
  22. set:
  23. - name: x-custom-header
  24. value: xyz
  1. type: MeshHTTPRoute
  2. name: http-route-1
  3. mesh: default
  4. spec:
  5. targetRef:
  6. kind: MeshSubset
  7. tags:
  8. app: frontend
  9. to:
  10. - targetRef:
  11. kind: MeshService
  12. name: backend
  13. sectionName: http
  14. rules:
  15. - matches:
  16. - path:
  17. type: Exact
  18. value: "/"
  19. default:
  20. filters:
  21. - type: RequestHeaderModifier
  22. requestHeaderModifier:
  23. set:
  24. - name: x-custom-header
  25. value: xyz

Traffic mirror

MeshHTTPRoute can mirror a fraction of requests to another service. This can be useful when testing a new version of the app with the production payload without interrupting real users.

  1. apiVersion: kuma.io/v1alpha1
  2. kind: MeshHTTPRoute
  3. metadata:
  4. name: http-route-1
  5. namespace: kuma-demo
  6. labels:
  7. kuma.io/mesh: default
  8. spec:
  9. targetRef:
  10. kind: MeshSubset
  11. tags:
  12. app: frontend
  13. to:
  14. - targetRef:
  15. kind: MeshService
  16. name: backend_kuma-demo_svc_3001
  17. rules:
  18. - matches:
  19. - headers:
  20. - type: Exact
  21. name: mirror-this-request
  22. value: 'true'
  23. default:
  24. filters:
  25. - type: RequestMirror
  26. requestMirror:
  27. percentage: 30
  28. backendRef:
  29. kind: MeshServiceSubset
  30. name: backend_kuma-demo_svc_3001
  31. tags:
  32. version: v1-experimental
  33. backendRefs:
  34. - kind: MeshService
  35. name: backend_kuma-demo_svc_3001
  1. apiVersion: kuma.io/v1alpha1
  2. kind: MeshHTTPRoute
  3. metadata:
  4. name: http-route-1
  5. namespace: kuma-demo
  6. labels:
  7. kuma.io/mesh: default
  8. spec:
  9. targetRef:
  10. kind: MeshSubset
  11. tags:
  12. app: frontend
  13. to:
  14. - targetRef:
  15. kind: MeshService
  16. name: backend
  17. namespace: kuma-demo
  18. sectionName: http
  19. rules:
  20. - matches:
  21. - headers:
  22. - type: Exact
  23. name: mirror-this-request
  24. value: 'true'
  25. default:
  26. filters:
  27. - type: RequestMirror
  28. requestMirror:
  29. percentage: 30
  30. backendRef:
  31. kind: MeshService
  32. name: backend-v1-experimental
  33. namespace: kuma-demo
  34. port: 3001
  35. backendRefs:
  36. - kind: MeshService
  37. name: backend
  38. namespace: kuma-demo
  39. port: 3001

I am using MeshService

  1. type: MeshHTTPRoute
  2. name: http-route-1
  3. mesh: default
  4. spec:
  5. targetRef:
  6. kind: MeshSubset
  7. tags:
  8. app: frontend
  9. to:
  10. - targetRef:
  11. kind: MeshService
  12. name: backend
  13. rules:
  14. - matches:
  15. - headers:
  16. - type: Exact
  17. name: mirror-this-request
  18. value: 'true'
  19. default:
  20. filters:
  21. - type: RequestMirror
  22. requestMirror:
  23. percentage: 30
  24. backendRef:
  25. kind: MeshServiceSubset
  26. name: backend
  27. tags:
  28. version: v1-experimental
  29. backendRefs:
  30. - kind: MeshService
  31. name: backend
  1. type: MeshHTTPRoute
  2. name: http-route-1
  3. mesh: default
  4. spec:
  5. targetRef:
  6. kind: MeshSubset
  7. tags:
  8. app: frontend
  9. to:
  10. - targetRef:
  11. kind: MeshService
  12. name: backend
  13. sectionName: http
  14. rules:
  15. - matches:
  16. - headers:
  17. - type: Exact
  18. name: mirror-this-request
  19. value: 'true'
  20. default:
  21. filters:
  22. - type: RequestMirror
  23. requestMirror:
  24. percentage: 30
  25. backendRef:
  26. kind: MeshService
  27. name: backend-v1-experimental
  28. port: 3001
  29. backendRefs:
  30. - kind: MeshService
  31. name: backend
  32. port: 3001

Merging

When several MeshHTTPRoute policies target the same data plane proxy they’re merged. Similar to the new policies the merging order is determined by the top level targetRef. The difference is in spec.to[].rules. Kuma treats rules as a key-value map where matches is a key and default is a value. For example MeshHTTPRoute policies:

  1. # MeshHTTPRoute-1
  2. rules:
  3. - matches: # key-1
  4. - path:
  5. type: Exact
  6. name: /orders
  7. method: GET
  8. default: CONF_1 # value
  9. - matches: # key-2
  10. - path:
  11. type: Exact
  12. name: /payments
  13. method: POST
  14. default: CONF_2 # value
  15. ---
  16. # MeshHTTPRoute-2
  17. rules:
  18. - matches: # key-3
  19. - path:
  20. type: Exact
  21. name: /orders
  22. method: GET
  23. default: CONF_3 # value
  24. - matches: # key-4
  25. - path:
  26. type: Exact
  27. name: /payments
  28. method: POST
  29. default: CONF_4 # value

merged in the following list of rules:

  1. rules:
  2. - matches:
  3. - path:
  4. type: Exact
  5. name: /orders
  6. method: GET
  7. default: merge(CONF_1, CONF_3) # because 'key-1' == 'key-3'
  8. - matches:
  9. - path:
  10. type: Exact
  11. name: /payments
  12. method: POST
  13. default: merge(CONF_2, CONF_4) # because 'key-2' == 'key-4'

All policy options

Matches

  • path - (optional) - HTTP path to match the request on
    • type - one of Exact, PathPrefix, RegularExpression
    • value - actual value that’s going to be matched depending on the type
  • method - (optional) - HTTP2 method, available values are CONNECT, DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, TRACE
  • queryParams - (optional) - list of HTTP URL query parameters. Multiple matches are combined together such that all listed matches must succeed
    • type - one of Exact or RegularExpression
    • name - name of the query parameter
    • value - actual value that’s going to be matched depending on the type

Default conf

  • filters - (optional) - a list of modifications applied to the matched request
    • type - available values are RequestHeaderModifier, ResponseHeaderModifier, RequestRedirect, URLRewrite.
    • requestHeaderModifier - HeaderModifier, must be set if the type is RequestHeaderModifier.
    • responseHeaderModifier - HeaderModifier, must be set if the type is ResponseHeaderModifier.
    • requestRedirect - must be set if the type is RequestRedirect
      • scheme - one of http or http2
      • hostname - is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 1 notable exception that numeric IP addresses are not allowed.
      • port - is the port to be used in the value of the Location header in the response. When empty, port (if specified) of the request is used.
      • statusCode - is the HTTP status code to be used in response. Available values are 301, 302, 303, 307, 308.
    • urlRewrite - must be set if the type is URLRewrite
      • hostname - (optional) - is the fully qualified domain name of a network host. This matches the RFC 1123 definition of a hostname with 1 notable exception that numeric IP addresses are not allowed.
      • path - (optional)
        • type - one of ReplaceFullPath, ReplacePrefixMatch
        • replaceFullPath - must be set if the type is ReplaceFullPath
        • replacePrefixMatch - must be set if the type is ReplacePrefixMatch
    • requestMirror - must be set if the type is RequestMirror
      • percentage - percentage of requests to mirror. If not specified, all requests to the target cluster will be mirrored.
      • backendRef - BackendRef, destination to mirror request to
  • backendRefs - BackendRef (optional), list of destinations to redirect requests to

Header modification

  • set - (optional) - list of headers to set. Overrides value if the header exists.
    • name - header’s name
    • value - header’s value
  • add - (optional) - list of headers to add. Appends value if the header exists.
    • name - header’s name
    • value - header’s value
  • remove - (optional) - list of headers’ names to remove

Backends

  • kind - one of MeshService, MeshServiceSubset, MeshExtenalService
  • name - service name
  • tags - service tags, must be specified if the kind is MeshServiceSubset
  • weight - when a request matches the route, the choice of an upstream cluster is determined by its weight. Total weight is a sum of all weights in backendRefs list.