Transparent proxy allows users to reach other services in the service mesh while ensuring that inbound and outbound traffic for services in the mesh are directed through the sidecar proxy. Traffic is secured and only reaches intended destinations since the proxy can enforce security and policy like TLS and Service Intentions.
Previously, service mesh users would need to explicitly define upstreams for a service as a local listener on the sidecar proxy, and dial the local listener to reach the appropriate upstream. Users would also have to set intentions to allow specific services to talk to one another. Transparent proxying reduces this duplication, by determining upstreams implicitly from Service Intentions. Explicit upstreams are still supported in the proxy service registration on VMs and via the annotation in Kubernetes.
To support transparent proxying, Consul's CLI now has a command
consul connect redirect-traffic to redirect traffic through an inbound and
outbound listener on the sidecar. Consul also watches Service Intentions and configures the Envoy proxy with the appropriate
upstream IPs. If the default ACL policy is "allow", then Service Intentions are not required. In Consul on Kubernetes,
the traffic redirection command is automatically set up via an init container.
- To use transparent proxy on Kubernetes, Consul-helm >=
0.32.0and Consul-k8s >=
0.26.0are required in addition to Consul >=
- If the default policy for ACLs is "deny", then Service Intentions should be set up to allow intended services to connect to each other. Otherwise, all Connect services can talk to all other services.
The Kubernetes integration takes care of registering Kubernetes services with Consul, injecting a sidecar proxy, and enabling traffic redirection.
»Upgrading to Transparent Proxy
When upgrading from older versions (i.e Consul-k8s <
0.26.0 or Consul-helm <
0.32.0) to Consul-k8s >=
0.26.0 and Consul-helm >=
0.32.0, please make sure to follow the upgrade steps here.
»Enabling Transparent Proxy
Transparent proxy can be enabled in Kubernetes on the whole cluster via the Helm value:
connectInject: transparentProxy: defaultEnabled: true
It can also be enabled on a per namespace basis by setting the label
consul.hashicorp.com/transparent-proxy=true on the
Kubernetes namespace. This will override the Helm value
connectInject.transparentProxy.defaultEnabled and define the
default behavior of Pods in the namespace. For example:
kubectl label namespaces my-app "consul.hashicorp.com/transparent-proxy=true"
It can also be enabled on a per service basis via the annotation
consul.hashicorp.com/transparent-proxy=true on the
Pod for each service, which will override both the Helm value and the namespace label:
apiVersion: v1kind: Servicemetadata: name: static-serverspec: selector: app: static-server ports: - protocol: TCP port: 80 targetPort: 8080---apiVersion: v1kind: ServiceAccountmetadata: name: static-server---apiVersion: apps/v1kind: Deploymentmetadata: name: static-serverspec: replicas: 1 selector: matchLabels: app: static-server template: metadata: name: static-server labels: app: static-server annotations: 'consul.hashicorp.com/connect-inject': 'true' 'consul.hashicorp.com/transparent-proxy': 'true' spec: containers: - name: static-server image: hashicorp/http-echo:latest args: - -text="hello world" - -listen=:8080 ports: - containerPort: 8080 name: http serviceAccountName: static-server
»Kubernetes HTTP Health Probes Configuration
Traffic redirection interferes with Kubernetes HTTP health
probes since the
probes expect that kubelet can directly reach the application container on the probe's endpoint, but that traffic will
be redirected through the sidecar proxy, causing errors because kubelet itself is not encrypting that traffic using a
mesh proxy. For this reason, Consul allows you to (overwrite Kubernetes HTTP health probes)[/docs/k8s/connect/health] to point to the proxy instead.
This can be done using the Helm value
or the Pod annotation
»Traffic Redirection Configuration
Pods with transparent proxy enabled will have an init container injected that sets up traffic redirection for all inbound and outbound traffic through the sidecar proxies. This will include all traffic by default, with the ability to configure exceptions on a per-Pod basis. The following Pod annotations allow you to exclude certain traffic from redirection to the sidecar proxies:
- Traffic can only be transparently proxied when the address dialed corresponds to the address of a service in the
transparent proxy's datacenter. Cross-datacenter transparent proxying is only possible using
service-resolver configuration entries that resolve to remote datacenters.
Services can also dial explicit upstreams in other datacenters without transparent proxy, for example, by adding an
annotation such as
"consul.hashicorp.com/connect-service-upstreams": "my-service:1234:dc2"to reach an upstream service called
my-servicein the datacenter
- In the deployment configuration where a single Consul datacenter spans multiple Kubernetes clusters, services in one Kubernetes cluster must explicitly dial a service in another Kubernetes cluster using the consul.hashicorp.com/connect-service-upstreams annotation. An example would be
"consul.hashicorp.com/connect-service-upstreams": "my-service:1234", where
my-serviceis the service that exists in another Kubernetes cluster and is exposed on port
1234. Although Transparent Proxy is enabled, KubeDNS is not utilized when communicating between services existing on separate Kubernetes clusters.
- When dialing headless services the request will be proxied using a plain TCP proxy with a 5s connection timeout. Currently the upstream's protocol and connection timeout are not considered.
»Using Transparent Proxy
In Kubernetes, services can reach other services via their KubeDNS address or via Pod IPs, and that traffic will be transparently sent through the proxy. Connect services in Kubernetes are required to have a Kubernetes service selecting the Pods.
Note: In order to use KubeDNS, the Kubernetes service name will need to match the Consul service name. This will be the
case by default, unless the service Pods have the annotation
consul.hashicorp.com/connect-service overriding the
Consul service name.
Transparent proxy is enabled by default in Consul-helm >=
0.32.0. The Helm value used to enable/disable transparent
proxy for all applications in a Kubernetes cluster is
Each Pod for the service will be configured with iptables rules to direct all inbound and outbound traffic through an
inbound and outbound listener on the sidecar proxy. The proxy will be configured to know how to route traffic to the
appropriate upstream services based on Service
Intentions. This means Connect services no longer
need to use the
consul.hashicorp.com/connect-service-upstreams annotation to configure upstreams explicitly. Once the
Service Intentions are set, they can simply address the upstream services using KubeDNS.
As of Consul-k8s >=
0.26.0 and Consul-helm >=
0.32.0, a Kubernetes service that selects application pods is required
for Connect applications, i.e:
apiVersion: v1kind: Servicemetadata: name: sample-app namespace: defaultspec: selector: app: sample-app ports: - protocol: TCP port: 80
In the example above, if another service wants to reach
sample-app via transparent proxying,
it can dial
If ACLs with default "deny" policy are enabled, it also needs a
ServiceIntention allowing it to talk to
For services that are not addressed using a virtual cluster IP, the upstream service must be configured using the DialedDirectly option.
Individual instance addresses can then be discovered using DNS, and dialed through the transparent proxy. When this mode is enabled on the upstream, connect certificates will be presented for mTLS and intentions will be enforced at the destination.
Note that when dialing individual instances HTTP routing rules configured with config entries will not be considered. The transparent proxy acts as a TCP proxy to the original destination IP address.