Introduction to Service Mesh Interface
Service Mesh Interface (SMI) is a Kubernetes-native specification under active development. It’s defining a standard set of Kubernetes Custom Resource Definitions (CRDs) and APIs for service meshes. The SMI development process is open, relying on community participation, and the specification itself is publicly available under an Apache 2.0 license.
As stated on the SMI website, “the goal of the SMI API is to provide a common, portable set of service mesh APIs which a Kubernetes user can use in a provider agnostic manner. In this way people can define applications that use service mesh technology without tightly binding to any specific implementation.” SMI doesn’t include a service mesh implementation; it’s solely a specification that service mesh implementations can use.
Without a standard like SMI, every service mesh technology would have completely different APIs. That would make things more complicated and time-consuming for developers and for platform and DevOps teams. Instead of using SMI APIs, developers would have to write their own code to provide equivalent functionality. Integration with other technologies and tools would take more effort, as would changing which service mesh technology an app uses.
Here, we’ll take a closer look at four SMI APIs that help to manage, secure, and observe service-to-service traffic within a cluster:
- Traffic Specs
- Traffic Split
- Traffic Access Control
- Traffic Metrics
All of these APIs involve service mesh concepts we examine in this piece about resilience, specifically load balancing; we’ll be building on that knowledge and focusing specifically on examples of what these APIs support and how they can be used.
Note that adoption of the SMI APIs by service mesh technologies is ongoing. Also, SMI itself is rapidly evolving, with updates being made all the time. For the foreseeable future, it is likely that at any given time, common service mesh technologies will offer different degrees of support for each of the SMI APIs.
Traffic Specs API
The Traffic Specs API allows you to define routes that an app can use. This is hard to explain without an example, so let’s look at one to show what that means.
This example illustrates how a resource named
m-routes
HTTPRouteGroup
/metrics
By itself,
HTTPRouteGroup
m-routes
kind: HTTPRouteGroup
metadata:
name: m-routes
spec:
matches:
- name: metrics
pathRegex: "/metrics"
methods:
- GET
Traffic Split API
The Traffic Split API allows you to implement traffic splitting and traffic shifting methods like A/B testing, blue-green deployment, and canary deployment.
Here’s an example of defining a
TrafficSplit
backends
e8-widget-svc-current
e8-widget-svc-patch
weight
kind: TrafficSplit
metadata:
name: e8-feature-test
namespace: e8app
spec:
service: e8-widget-svc
backends:
- service: e8-widget-svc-current
weight: 75
- service: e8-widget-svc-patch
weight: 25
Over time, to continue the canary deployment, you would update the weights: for example, you might next set these to 50 and 50. If that goes well, then the next step might be 25 and 75, with 0 and 100 being the last step.
To use
TrafficSplit
For a blue-green deployment with
TrafficSplit
If you want to do a traffic split with three or more services, you would simply list each of the services under
backends
kind: TrafficSplit
metadata:
name: e8-feature-test
namespace: e8app
spec:
service: e8-render-svc
backends:
- service: e8-render-svc-baseline
weight: 50
- service: e8-render-svc-feature1
weight: 25
- service: e8-render-svc-feature2
weight: 25
Traffic Access Control API
The Traffic Access Control API allows you to set access control policies for pod-to-pod (service proxy to service proxy) communications based on service proxy identity. When you use this API, by default all traffic is denied. You have to explicitly grant permission for any types of traffic you want to allow.
Here’s an example of defining a
TrafficTarget
spec
- , which specifies the pods that may be the sources of the traffic.
sources
- , which specifies the pods that may be the destinations of the traffic.
destination
- , which defines the characteristics the traffic must have in order to be allowed to reach its destination.
rules
In this example, traffic is being allowed from pods with a
prometheus
service-a
rules, which in this case is that the traffic matches the m-routesHTTPRouteGroup
m-routes
/metrics
To recap: in this TrafficTarget example,
- HTTP GET requests with the string “” in their path
/metrics
- that are sent from pods with a service account
prometheus
- and that are going to port 8080 on pods with a service account
service-a
- will be allowed.
kind: TrafficTarget
metadata:
name: path-specific
namespace: default
spec:
destination:
kind: ServiceAccount
name: service-a
namespace: default
port: 8080
rules:
- kind: HTTPRouteGroup
name: m-routes
matches:
- metrics
sources:
- kind: ServiceAccount
name: prometheus
namespace: default
Some of the elements in this example are optional. For example, if you don’t specify a port for the
destination
TrafficTarget
port
TrafficTarget
sources
destination
rules
Traffic Metrics API
The Traffic Metrics API allows you to collect metrics on HTTP traffic and make those metrics available to other tools. Each metric involves a Kubernetes resource, either a lower-level one like a pod or a service, or a higher-level one like a namespace. Each metric is also limited to a particular edge, which is another term for the traffic’s source or destination. Note that an edge can be set as blank, which would match all traffic.
Here’s an example of defining
TrafficMetrics
- , which specifies the source of the traffic to collect the metrics for.
resource
- , which specifies the destination of the traffic to collect the metrics for.
edge
- , which specifies when the definition was created.
timestamp
- , which specifies the time period to be used for calculating the metrics. In this example, 30 seconds is specified, so metrics will be calculated on the past 30 seconds of activity.
window
- , which list the metrics to be collected. In this example, the metrics will include data on response latency and on successful and failed requests.
metrics
kind: TrafficMetrics
# See ObjectReference v1 core for full spec
resource:
name: foo-775b9cbd88-ntxsl
namespace: foobar
kind: Pod
edge:
direction: to
side: client
resource:
name: baz-577db7d977-lsk2q
namespace: foobar
kind: Pod
timestamp: 2019-04-08T22:25:55Z
window: 30s
metrics:
- name: p99_response_latency
unit: seconds
value: 10m
- name: p90_response_latency
unit: seconds
value: 10m
- name: p50_response_latency
unit: seconds
value: 10m
- name: success_count
value: 100
- name: failure_count
value: 100
The Traffic Metrics API is in its early stages at this time, so its support of individual metrics is quite limited.