# Proxy Template

When out-of-the-box Kuma's capabilities aren't enough, you can use ProxyTemplate policy to configure low-level Envoy resources directly.

Technically, it means that you can provide definitions of Listeners, Clusters, ClusterLoadAssignments and RouteConfigurations that will either complement or replace those resources that Kuma generates automatically.

Internally, Kuma assumes that configuration of every dataplane (Envoy) is defined by one of ProxyTemplate policies.

If you don't specify one manually, the implicit default ProxyTemplate policy will be used, i.e.

type: ProxyTemplate
mesh: <any>
name: <implicit default template>

# `selectors` define a subset of `Dataplanes`
# this `ProxyTemplate` should apply to
selectors:
  # selector matches tags either on an `inbound` or
  # on a `gateway` interface of a `Dataplane`
  - match:
      # since every interface of a `Dataplane` is required
      # to have `service` tag, the following selector
      # will match every `Dataplane` in the `Mesh`
      service: '*'

# `conf` defines the desired dataplane (Envoy) configuration
conf:
  # `imports` let you reuse dataplane configuration that Kuma
  # can generate automatically and add a few tweaks on top of it
  imports:
    # `default-proxy` is a reference name for the default
    # dataplane configuration generated by Kuma
    - default-proxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

In order to customize configuartion of a particular Dataplane (or a group of Dataplanes), you will need to provide a custom ProxyTemplate policy with proper values for selectors and conf, e.g.

type: ProxyTemplate
mesh: default
name: my-custom-template

# `selectors` define a subset of `Dataplanes`
# this `ProxyTemplate` should apply to
selectors:
  # selector matches tags either on an `inbound` or
  # on a `gateway` interface of a `Dataplane`
  - match:
      # the following selector will match a very specific
      # subset of `Dataplanes` in the `Mesh`
      service: backend
      role:    api

# `conf` defines the desired dataplane (Envoy) configuration
conf:
  # `imports` let you reuse dataplane configuration that Kuma
  # can generate automatically and add a few tweaks on top of it
  imports:
    # `default-proxy` is a reference name for the default
    # dataplane configuration generated by Kuma
    - default-proxy

  # `resources` define a list of raw Envoy resources
  # that will either complement or replace auto-generated ones
  resources:
    - name: localhost:9901
      version: v1
      # `resource` is a raw Envoy resource
      # provided either in YAML or in JSON format
      resource: |
        '@type': type.googleapis.com/envoy.api.v2.Cluster
        connectTimeout: 5s
        name: localhost:9901
        ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

Notice that:

  1. selectors allow you to limit the scope of Dataplanes this ProxyTemplate should apply to
  2. imports allow you to reuse configuration that Kuma can generate automatically and add a few tweaks on top of it
  3. resources allow you to provide raw Envoy resources that will either complement or replace auto-generated ones

To clarify, the above ProxyTemplate will match either of the following 2 Dataplanes.

  • A regular Dataplane (one with an inbound interface):

    type: Dataplane
    mesh: default
    name: backend-01
    networking:
      address: 192.168.0.1
      inbound:
      - port: 80
        servicePort: 8080
        tags:
          service:  backend    # Notice that both tags from the ProxyTemplate selector - `service` and `role` - must match
          role:     api
          version:  v1.2.3
          protocol: http
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  • A gateway Dataplane (one with a gateway interface):

    type: Dataplane
    mesh: default
    name: gateway
    networking:
      address: 10.0.0.1
      gateway:
        tags:
          service:  backend    # Notice that both tags from the ProxyTemplate selector - `service` and `role` - must match
          role:     api
          env:      production
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

In the current release, the only available canned configuration that can be used inside imports section is called default-proxy.

In future releases, more of these will be available and you will be able to define profiles to re-use them across the infrastructure.

At runtime, whenever the Kuma Control Plane needs to generate configuration for a given Dataplane, it will proceed as follows:

  • First, it will search for all ProxyTemplates that have been defined in the Mesh a given Dataplane belongs to
  • Next, it will select only those ProxyTemplates whose selectors match either an inbound or a gateway interface of a given Dataplane
  • Next, every matching ProxyTemplate will be ranked
  • Then, ProxyTemplate with the highest rank will be used to generate configuration for that dataplane (Envoy)
  • If a ProxyTemplate defines imports, their resources will be generated first
  • If a ProxyTemplate defines resources, they will be copied "as is" and replace auto-generated resources of the same name

By defining resources in a ProxyTemplate you can:

  • add new resources in addition to those auto-generated from imports
  • replace resources auto-generated from imports by giving yours the same names

At the moment, it's not possible to patch or delete resources auto-generated from imports.

On Universal:

type: ProxyTemplate
mesh: default
name: my-custom-template
selectors:
  - match:
      service: backend
conf:
  imports:
    - default-proxy
  resources:
    - name: localhost:9901
      version: v1
      resource: |
        '@type': type.googleapis.com/envoy.api.v2.Cluster
        ...
    - name: inbound:0.0.0.0:4040
      version: v1
      resource: |
        '@type': type.googleapis.com/envoy.api.v2.Listener
        ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

On Kubernetes:

apiVersion: kuma.io/v1alpha1
kind: ProxyTemplate
metadata:
  namespace: default
  name: my-custom-template
mesh: default
spec:
  selectors:
    - match:
        service: backend
  conf:
    imports:
      - default-proxy
    resources:
      - name: localhost:9901
        version: v1
        resource: |
          '@type': type.googleapis.com/envoy.api.v2.Cluster
          ...
      - name: inbound:0.0.0.0:4040
        version: v1
        resource: |
          '@type': type.googleapis.com/envoy.api.v2.Listener
          ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

As a practical example, lets take a look at a ProxyTemplate policy that will configure matching Dataplanes to proxy requests to internal Envoy Admin API in addition to their default behaviour:

type: ProxyTemplate
mesh: default
name: my-custom-template
# `selectors` define a subset of `Dataplanes`
# this `ProxyTemplate` should apply to
selectors:
  - match:
      # the following selector will match a very specific
      # subset of `Dataplanes` in the `Mesh`
      service: backend
conf:
  # `imports` let you reuse dataplane configuration that Kuma
  # can generate automatically and add a few tweaks on top of it
  imports:
    - default-proxy
  # `resources` define a list of raw Envoy resources
  # that will either complement or replace auto-generated ones
  resources:
    - name: localhost:9901
      version: v1
      resource: |
        '@type': type.googleapis.com/envoy.api.v2.Cluster
        connectTimeout: 5s
        name: localhost:9901
        loadAssignment:
          clusterName: localhost:9901
          endpoints:
          - lbEndpoints:
            - endpoint:
                address:
                  socketAddress:
                    address: 127.0.0.1
                    # port the Envoy Admin API will be available on
                    # can be configured via `--admin-port` option
                    # of `kuma-dp`
                    portValue: 9901
        type: STATIC
    - name: inbound:0.0.0.0:4040
      version: v1
      resource: |
        '@type': type.googleapis.com/envoy.api.v2.Listener
        name: inbound:0.0.0.0:4040
        address:
          socket_address:
            address: 0.0.0.0
            port_value: 4040
        filter_chains:
        - filters:
          - name: envoy.http_connection_manager
            config:
              route_config:
                virtual_hosts:
                - routes:
                  - match:
                      # only proxy requests to the `/stats` endpoint
                      # of the Envoy Admin API
                      prefix: /stats
                    route:
                      cluster: localhost:9901
                  domains:
                  - '*'
                  name: envoy_admin
              codec_type: AUTO
              http_filters:
                name: envoy.router
              stat_prefix: envoy_stats
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66