Manage Traffic with Consul Service Mesh
In this tutorial, you will be introduced to Consul service mesh's comprehensive traffic management features. By the end of the tutorial, you will know how you can leverage the features of Consul service mesh to support use cases that are challenging to implement using previous generation networking technologies.
Your desired infrastructure scenarios include multi-region, multi-cloud, and on-prem/cloud hybrid. You want to be able to perform blue/green or even canary rollouts. Your product teams want to be able to rapidly iterate on A/B tests. The demands of the modern enterprise adds to the complexity of your network and generates new security issues. The inefficiencies of traditional networking solutions may have previously made these goals simply unobtainable. Consul's comprehensive traffic shaping features empower you with a modern, flexible toolkit designed to support these exact use cases and more.
Consul service mesh allows you to manage your mesh traffic using three distinct mechanisms.
- Envoy proxies
- L7 service discovery chain
- Gateways
Prerequisites
To try the features in this tutorial, you will need a Kubernetes cluster with Consul service mesh installed. In case you do not have one, and are interested in testing the use cases, you can follow the Deploy Consul Service Mesh on Kubernetes tutorial to install Consul service mesh and a demo application you can experiment with.
Envoy proxy
Consul service mesh on Kubernetes leverages Envoy as the sidecar proxy. Consul configures
Envoy by optionally exposing a gRPC service on the local agent that serves Envoy's
xDS configuration API. Consul configures Envoy sidecars to proxy http/1.1
, http2
,
or gRPC
traffic at L7, and any other TCP-based protocol at L4.
Proxy defaults
Consul's ProxyDefaults
configuration entry provides you with a mechanism to
inject a custom Envoy proxy configuration, thus allowing you to use features of
Envoy that might not yet be exposed by Consul. ProxyDefaults
are used to specify
global settings, thus limiting the amount of configuration you need to apply to each
individual service. For example, the following YAML defines a CRD that sets a global
default protocol for all service proxies to http
.
Review the official documentation
for more details on what you can configure globally using a ProxyDefaults
configuration entry CRD.
Service defaults
ServiceDefaults
configuration entries allows for Envoy proxy configuration at the individual service
level. It is important to note that settings applied using a ServiceDefaults
configuration entry are still global for all instances of a service within the mesh.
The following YAML example shows a CRD that overrides the global protocol set in
the previous ProxyDefaults
example from the preceding section. Once applied,
this CRD will ensure that all instances of the postgres
service use the tcp
protocol.
Review the official documentation
for more details on what you can configure on a per service basis using a ServiceDefaults
configuration entry CRD.
L7 service discovery chain
Consul service mesh offers a flexible and comprehensive set of service discovery and traffic management features at Layer 7. The service discovery process can be thought of as a discovery chain which passes through three distinct stages: routing, splitting, and resolution. Each stage manages a different aspect of the L7 traffic management story and can be configured to work in concert.
Each stage of the discovery pipeline can be dynamically configured by applying CRDs that register Consul configuration entries. Configuration entries are a Consul specific concept. Review the official documentation for an in-depth discussion of configuration entries.
L7 configuration entries can be defined in a way that targets only a subset of a service. For instance, it is possible to define a configuration that only applies to a specific version in scenarios where multiple version of the same service may be deployed. If you don't provide a configuration for a stage of the pipeline for a given service, Consul falls back to its default behavior.
This approach allows you to manage a datacenter's pool of services far beyond simple load balancing based on health or service name resolution. With Consul's service discovery chain, you can implement fine-grained traffic shaping based on a service version, HTTP header, path prefix, query string, and more. Employing canary rollouts, A/B testing, and blue/green deployments are now completely obtainable goals.
Best of all, since all the following configuration entries can now be managed as
CRDs, you can manage your Consul service mesh with a familiar kubectl
based
workflow.
Routing
Routing is the first stage of the L7 traffic management pipeline and allows the
interception of traffic using L7 criteria such as path prefixes or http headers.
To inject user defined routing rules into your service mesh, you must register a
ServiceRouter
configuration entry with the Consul control plane. When a request matching the criteria
specified by a ServiceRouter
configuration entry is made, Consul re-routes the traffic
to a different service or service subset as specified by the configuration entry.
A ServiceRouter
configuration entry may only reference ServiceSplitter
or
ServiceResolver
entries. The following is an example of a ServiceRouter
configuration entry that re-routes traffic that matches on the /coffees
pathPrefix
and re-routes traffic away from the target service to a new, route-specific service,
coffee-service
.
Review the official documentation
for more details on what you can configure using a ServiceRouter
configuration
entry CRD.
Splitting
Splitting is the second stage of the L7 traffic management pipeline. To inject
your own splitting rules into your service mesh, you must register a
ServiceSplitter
config entry with the Consul control plane. A splitter configuration entry allows
you to choose to split incoming requests across different subsets of a single
service (like during staged canary rollouts), or perhaps across different services
(like during a v2 rewrite or other type of codebase migration).
A ServiceSplitter
configuration may only reference other ServiceSplitter
entries
or a ServiceResolver
entry. The following is an example of a ServiceSplitter
configuration entry that splits traffic destined for the coffee-service
service
across two different versions of the service. A configuration entry such as this
can be registered with Consul to perform a controlled rollout of a new service version.
Review the official documentation
for more details on what you can configure using a ServiceSplitter
configuration
entry CRD.
Resolution
Resolution is the final state of the L7 traffic management pipeline. To inject
your own splitting rules into your service mesh, you must register a
ServiceResolver
config entry with the Consul control plane. A resolver configuration entry allows
for a user to define which instances of a service should satisfy discovery requests
for the provided name.
These configuration entries may only reference other ServiceResolver
entries.
Examples of things you can do with resolver configuration entries:
- Control where to send traffic if all instances of
api
service in the current datacenter are unhealthy. - Configure service subsets based on
Service.Meta.version
values. - Send all traffic for
web
that does not specify a service subset to the version1 subset. - Send all traffic for
api
tonew-api
. - Send all traffic for
api
in all datacenters to instances ofapi
indc2
. - Create a "virtual service"
api-dc2
that sends traffic to instances ofapi
indc2
. This can be referenced in upstreams or in other configuration entries.
If no resolver configuration is defined for a service it is assumed 100% of traffic flows to the healthy instances of a service with the same name in the current datacenter/namespace and discovery terminates.
The following is an example of a ServiceResolver
configuration entry that
defines two subsets of a service based on service registration metadata. This
type of configuration entry works in concert with other configuration entries
that reference a serviceSubset
. The ServiceResolver
configuration entry
kind has a powerful filtering mechanism that enables highly flexible service
subset targeting.
Tip
ServiceResolver configuration entries function at L4 (unlike
ServiceRouter
and ServiceSplitter
entries). These can be created for services of
any protocol such as tcp.
Review the official documentation
for more details on what you can configure using a ServiceResolver
configuration
entry CRD.
Virtual services
A virtual service is really just a specialized type of ServiceResolver
that
allows you to route traffic to a service hosted in another datacenter. If you have
mesh gateways enabled, and you have federated your datacenters, you can create a
virtual service by registering aServiceResolver
with the extra datacenter
setting, as illustrated in the following example.
Review the official documentation
for more details on how you can configure a virtual service using a ServiceResolver
configuration entry CRD.
Gateways
Unless your use case is limited to intra-datacenter operations, you will need your services to interoperate with resources outside the mesh, or located in other, federated datacenters. Consul service mesh provides several Gateway resources for securely managing traffic across the WAN.
Mesh gateways
Mesh gateways enable you to secure cross-datacenter communication with mTLS even when that traffic may be sent over the public internet. Mesh gateways support federating datacenters in both the Kubernetes-to-Kubernetes and Kubernetes-to-VM scenarios. The following YAML example illustrates how you can enable Consul mesh gateways at the top level of your Consul Helm values file.
Review the Secure Service Mesh Communication Across Kubernetes Clusters for details on how to configure mesh gateways and federation for your Consul service mesh on Kubernetes.
Ingress gateways
Ingress gateways enable external access to Consul service mesh services running inside Kubernetes. Adding an ingress gateway is a multi-step process that consists of the following steps:
- Adding the ingress gateway to your Helm chart configuration
- Deploying the updated Helm chart
- Registering the gateway with a CRD
- Defining an Intention (if ACLs are enabled)
The following YAML example illustrates how you must define an ingress gateway in your Helm chart configuration.
Once you've defined the ingress gateway in your Helm chart, and deployed the updated configuration, you must still create the ingress gateway resource. The following YAML example illustrates a valid CRD for an ingress gateway configuration entry.
Review the official documentation
for full details on how you can configure an IngressGateway
configuration entry
CRD.
Terminating gateways
Terminating gateways enable internal Consul service mesh services to access services running outside the mesh. Adding a terminating gateway is a multi-step process that consists of the following steps:
- Enabling terminating gateways in your Helm chart configuration
- Deploying the updated Helm chart
- Registering external services with Consul
- Updating the terminating gateway ACL token if ACLs are enabled
- Creating a TerminatingGateway resource to configure the terminating gateway
- Creating a ServiceIntentions resource to allow access from services in the mesh to external service
- Defining upstream annotations for any services that need to talk to the external services
The following YAML example illustrates how you must enable terminating gateways in your Helm chart configuration.
Once you've enabled the terminating gateways in your Helm chart, and deployed the updated configuration, you are able to create terminating gateway resources. While the overall process is beyond the scope of this tutorial, the following YAML example illustrates a valid CRD for an terminating gateway configuration entry.
Review the official documentation
for full details on how you can configure a TerminatingGateway
configuration entry CRD.
Next steps
Congratulations on completing the Getting Started with Consul Service Mesh on Kubernetes collection. We hope you enjoyed this introduction to Consul service mesh on Kubernetes, and that your Day 0 experience has convinced you to adopt Consul service mesh on Kubernetes for Day 1 and beyond. Once you start your production journey, you can refer to our Consul Service Mesh on Kubernetes collection for production best practices for all Kubernetes installation types, and to learn more about cloud-specific configurations for deploying Consul on different cloud providers.
Now that you know the basics, we want to direct you towards more resources to help you continue learning about Consul.
- Deploy Consul on AKS, EKS, or GKE
- Review the reference architecture for Consul on Kubernetes
- Learn how to secure Consul on Kubernetes
- Learn more about how to evaluate Consul's observability features