Transparent Proxy

A transparent proxy is a server that intercepts network traffic going to and from a service without requiring any changes to the application code. In Kuma, it captures this traffic and routes it to the data plane proxy, allowing Mesh policies to be applied.

Kuma uses iptables and also has experimental support for eBPF to make this possible.

For a closer look at how the transparent proxy works in Kuma, visit the Transparent Proxying page in our Service Discovery & Networking documentation.

Kubernetes mode

In Kubernetes mode, the transparent proxy is automatically set up through the kuma-init container or Kuma CNI. By default, it intercepts all incoming and outgoing traffic and routes it through the kuma-dp sidecar container, so no changes to the application code are needed.

Kuma works smoothly with Kubernetes DNS for Services and Pods and provides its own Kuma DNS, which is especially helpful in multi-zone setups for cross-zone service discovery.

In this mode, Kuma requires the transparent proxy to be enabled, so it cannot be turned off.

Adjusting transparent proxy settings in Kubernetes mode

If the default settings don’t meet your needs, see the Customizing Transparent Proxy Configuration in Kubernetes Mode guide. This guide explains different ways to change settings and when to use each one.

For a complete list of transparent proxy settings, including examples and allowed configuration methods for each field, see the Transparent Proxy Configuration Reference.

Universal mode

Using the transparent proxy in Universal mode makes setup easier and enables features that wouldn’t be possible otherwise. Key benefits include:

  • Simplified Dataplane resources: You can skip the networking.outbound section, so you don’t have to list each service your application connects to manually. Here’s an example without outbound entries:

    type: Dataplane
    name: {{ name }}
    networking:
      address: {{ address }}
      inbound:
      - port: {{ port }}
        tags:
          kuma.io/service: demo-client 
      transparentProxying:
        redirectPortInbound: 15006
        redirectPortOutbound: 15001
    
  • Easier service naming: Use the .mesh DNS domain to connect to services, like https://service-1.mesh, without needing localhost and ports from the Dataplane resource.

  • Flexible service naming with VirtualOutbound policy: It lets you:

    • Keep existing DNS names when moving to the service mesh.
    • Assign multiple DNS names to a service for renaming or convenience.
    • Create specific routes, like targeting individual StatefulSet Pods or service versions.
    • Expose multiple inbounds for a service on different ports.
  • Simpler security, tracing, and observability: Transparent proxy makes managing these features easier, with no extra setup required.

Installing transparent proxy in Universal mode

To learn how to integrate the Transparent Proxy with your existing services or to set up a service environment from scratch, follow the Integrating Transparent Proxy into Your Service Environment guide. This guide provides step-by-step instructions for both scenarios.

Adjusting transparent proxy settings in Universal mode

If the default settings don’t meet your needs, see the Customizing Transparent Proxy Configuration in Universal Mode guide. This guide explains different ways to change settings and when to use each one.

For a complete list of transparent proxy settings, including examples and allowed configuration methods for each field, see the Transparent Proxy Configuration Reference.

Reachable Services

When the transparent proxy is enabled, Kuma automatically configures each data plane proxy to connect with every other data plane proxy in the same mesh. This setup ensures broad service-to-service communication but can create issues in large service meshes:

  • Increased Memory Usage: The configuration for each data plane proxy can consume significant memory as the mesh grows.
  • Slower Propagation: Even small configuration changes for one service must be propagated to all data planes, which can be slow and resource-intensive.
  • Excessive Traffic: Frequent updates generate additional traffic between the control plane and data plane proxies, especially when services are added or changed often.

In real-world scenarios, services usually need to communicate only with a few other services rather than all services in the mesh. To address these challenges, Kuma offers the Reachable Services feature, allowing you to define only the services that each proxy should connect to. Specifying reachable services helps reduce memory usage, improves configuration propagation speed, and minimizes unnecessary traffic.

Here’s how to configure reachable services:

Specify the list of reachable services in the kuma.io/transparent-proxying-reachable-services annotation, separating each service with a comma. Your workload configuration could look like this:

apiVersion: apps/v1
kind: Pod
metadata:
  name: demo-client
  annotations:
    kuma.io/transparent-proxying-reachable-services: "redis_kuma-demo_svc_6379,elastic_kuma-demo_svc_9200"
...

You can update your workload manifests manually or use a command like:

kumactl annotate pods example-app \
  "kuma.io/transparent-proxying-reachable-services=redis_kuma-demo_svc_6379,elastic_kuma-demo_svc_9200"

This configuration ensures that example-app only connects to redis_kuma-demo_svc_6379 and elastic_kuma-demo_svc_9200, reducing the overhead associated with managing connections to all services in the mesh.

Reachable Backends

This feature works only when MeshService is enabled.

Reachable Backends provides similar functionality to Reachable Services, but it applies to resources such as MeshService, MeshExternalService, and MeshMultiZoneService.

By default, each data plane proxy tracks all other data planes in the mesh, which can impact performance and use more resources. Configuring reachableBackends allows you to specify only the services your application actually needs to communicate with, improving efficiency.

Unlike Reachable Services, Reachable Backends uses a structured model to define the resources.

Model

  • refs: Lists the resources your application needs to connect with, including:
    • kind: Type of resource. Options include:
      • MeshService
      • MeshExternalService
      • MeshMultiZoneService
    • name: Name of the resource.
    • namespace: (Kubernetes only) Namespace where the resource is located. Required if using namespace.
    • labels: A list of labels to match resources. You can define either labels or name.
    • port: (Optional) Port for the service, used with MeshService and MeshMultiZoneService.
apiVersion: apps/v1
kind: Pod
metadata:
  name: demo-client
  namespace: kuma-demo
  annotations:
    kuma.io/reachable-backends: |
      refs:
      - kind: MeshService
        name: redis
        namespace: kuma-demo
        port: 8080
      - kind: MeshMultiZoneService
        labels:
          kuma.io/display-name: test-server
      - kind: MeshExternalService
        name: mes-http
        namespace: kuma-system
...

Examples

demo-client communicates only with redis on port 6379

apiVersion: apps/v1
kind: Pod
metadata:
  name: demo-client
  namespace: kuma-demo
  annotations:
    kuma.io/reachable-backends: |
      refs:
      - kind: MeshService
        name: redis
        namespace: kuma-demo
        port: 6379
...

demo-client doesn’t need to communicate with any service

apiVersion: apps/v1
kind: Pod
metadata:
  name: demo-client
  namespace: kuma-demo
  annotations:
    kuma.io/reachable-backends: ""
...

demo-app communicates with all MeshServices in the kuma-demo namespace

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
  namespace: kuma-demo
  annotations:
    kuma.io/reachable-backends: |
      refs:
      - kind: MeshService
        labels:
          k8s.kuma.io/namespace: kuma-demo
...

firewalld support

In Kubernetes mode, transparent proxy is automatically set up using the kuma-init container or Kuma CNI. Since the proxy is reinstalled each time your workload restarts, there is no need to persist it. This feature is specifically designed for Universal environments.

The changes made by running kumactl install transparent-proxy will not persist after a reboot. To ensure persistence, you can either add this command to your system’s start-up scripts or leverage firewalld for managing iptables.

If you prefer using firewalld, you can include the --store-firewalld flag when installing the transparent proxy. This will store the iptables rules in /etc/firewalld/direct.xml, ensuring they persist across system reboots. Here’s an example:

kumactl install transparent-proxy --redirect-dns --store-firewalld

Important: Currently, there is no uninstall command for this feature. If needed, you will have to manually clean up the firewalld configuration.

Transparent proxy with eBPF (experimental)

Starting from Kuma 2.0 you can set up transparent proxy to use eBPF instead of iptables.

To use the transparent proxy with eBPF your environment has to use Kernel >= 5.7 and have cgroup2 available

kumactl install control-plane \
  --set "experimental.ebpf.enabled=true" \
  | kubectl apply -f-