Accessing external services with Istio
Almost every blog post or lecture explaining how Istio service meshes route traffic takes the time to go over how sidecar containers capture outgoing traffic - how that traffic is routed to another service with another sidecar. However, in the real world, a large amount of network traffic passes through the boundaries of the service mesh itself. That traffic might be from a public facing app that receives traffic from the internet, an internal service that needs to connect to a legacy application running outside the mesh, or a workload that consumes an external, third party API.
In this post, we'll take a look at the different methods by which a workload inside an Istio mesh can access external services. We'll be following the structure of our earlier posts about Istio and Backyards (now Cisco Service Mesh Manager). These cover Istio's basics first, then go into detail about how Backyards (now Cisco Service Mesh Manager) can help configure and visualize the features we discuss.
Istio uses sidecars to manage outbound traffic origination from an Istio-enabled pod. Previously, we wrote an in-depth post about reducing sidecar resource consumption. This time we are going to explore something a little different, accessing external services from the mesh. If you're a regular reader of this blog, you might have already guessed that we'll be talking about another Istio custom resource: ServiceEntry. But let's not get ahead of ourselves. A workload on an Istio mesh can access external services in three different ways:
- Allow sidecar to passthrough traffic for undiscovered services.
- Restrict access to services that are configured in Istio's registry; an external service can be added to this registry through ServiceEntries.
- Completely bypass the sidecar (can only be configured for a specific IP address range).
While the third option might seem tempting and it may be a viable option for a high performance application, we discourage it for use with regular workloads. According, we're not going to discuss that option in this blog post, only the first two.
A default Istio installation usually comes with this set up. Istio's outbound traffic policy mode is set to ALLOW_ANY. In this mode, all trafic originating from the cluster to any external service is permitted. This eases application development as well as the migration of existing applications to the mesh.
REGISTRY_ONLY outbound traffic policy mode is the complete opposite of Passthrough. All unknown traffic to external services that originates from inside the cluster is blocked. From a security and operations point of view, it is critical to restrict external traffic to known services only. This mitigates a significant security vulnerability, preventing applications from attempting to communicate with services they should not be allowed to. Since all external traffic is blocked in this mode, known external services need to be defined and monitored. In the next section, we'll talk about how Istio accomplishes this.
Backyards is able to display traffic to external services from
Passthroughclusters – which are not part of your platform – by capturing augmented metrics.
ServiceEntry custom resource
ServiceEntry is a way of extending Istio's service registry, so that existing auto-discovered services can access other services whether they are undiscovered internal services or services completely external to the mesh (e.g., web APIs).
The following example describes an external API accessed by internal applications over HTTP using DNS for hostname resolution.
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: httpbin.org namespace: backyards-demo spec: hosts: - httpbin.org - www.httpbin.org ports: - number: 80 name: http protocol: HTTP exportTo: - "." resolution: DNS location: MESH_EXTERNAL
Let's break this down a little.
|hosts||DNS name. Can have a wildcard prefix.|
|ports.protocol||One of the following: HTTP, HTTPS, HTTP2, GRPC, MONGO, TCP or TLS.|
|exportTo||By default "*" is used, which means this entry is exposed to every namespace. "." restricts it to the current namespace only. The exportTo value is restricted to these two for now.|
|resolution||Service discovery mode for the hosts.|
|location||From the perspective of the mesh this service should be considered internal or external.|
Note, not all fields are shown here. You can find the full specifications here.
While we're going to stick to this simple example, you should bear in mind that a ServiceEntry can be used in a variety of more advantageous ways. You can use ServiceEntry to span an Istio mesh over multiple clusters or use it for locality aware failure domain-based routing.
Try it out!
Create a cluster
For this demo we'll need a Kubernetes cluster.
For this example, I created a Kubernetes cluster on AWS, using Banzai Cloud's lightweight, CNCF-certified Kubernetes distribution, PKE, via the Pipeline platform. If you'd like to do likewise, go ahead and create your cluster on any of the several cloud providers we support or on-premise, using Pipeline (for free).
The easiest way of installing Backyards (now Cisco Service Mesh Manager), and a demo application on a brand new cluster, is to use the Backyards CLI.
Register for an evaluation version
and run the following command to install the CLI tool
KUBECONFIG must be set for your cluster):
This command first installs Istio with our open-source Istio operator, then installs Backyards (now Cisco Service Mesh Manager) itself as well as a demo application for demonstration purposes. After the installation of each component has finished, the Backyards UI will automatically open and start to send traffic to the demo application. By issuing this one simple command you can watch as Backyards starts a brand new production ready Istio cluster in just a few minutes! Give it a try!
Allow sidecar to passthrough traffic for undiscovered services
This method is much easier. All it requires is that you change the default policy for outbound traffic to passthrough.
$ backyards istio outbound-traffic-policy allowed
Calling external service from a notification's deployment
First, we modify the deployed demo application.
$ kubectl -n backyards-demo set env deployment/notifications-v1 'REQUESTS=http://httpbin.org/get#1' deployment.extensions/notifications-v1 env updated
The Backyards UI will show passthrough traffic to httpbin.org.
The Backyards UI should open automatically if you execute
backyards install -a --run-demo, but, as an alternative, you can always open it with
Restrict outbound traffic explicitly to the known endpoints
$ backyards istio outbound-traffic-policy restricted
If this policy succeeds, it will prevent calls to httpbin.org.
Create a service entry for an external service
The following command creates an external service endpoint for httpbin.org, a simple HTTP Request & Response Service.
$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: httpbin.org namespace: backyards-demo spec: hosts: - httpbin.org - www.httpbin.org ports: - number: 80 name: http protocol: HTTP resolution: DNS location: MESH_EXTERNAL EOF
So far, we've restricted external traffic only to a known service. Hostname based matching for the new entry will allow traffic to flow to the external service. This can be observed taking place on the Backyards UI.
Since the httpbin.org service is now known to Istio, we can do the all of our usual nifty things with it.
To remove the demo application, Backyards, and Istio from your cluster, you only need to apply one command, which takes care of removing these components in the correct order:
$ backyards uninstall -a
It is recommended that you make a
services external to the mesh. This way you can improve the
security of your mesh by only allowing calls to external
services, essentially a whitelist. The
Backyards (now Cisco Service Mesh Manager) UI
visualizes traffic to external services and therefore helps
you easily track external connections, allowing you to
determine if they are working properly. In an upcoming
release we'll make it even easier to manage external
services, just like we already do for our other supported
Banzai Cloud’s Backyards (now Cisco Service Mesh Manager) is a multi and hybrid-cloud enabled service mesh platform for constructing modern applications. Built on Kubernetes and our Istio operator, it gives you flexibility, portability, and consistency across on-premise datacenters and cloud environments. Use our simple, yet extremely powerful UI and CLI, and experience automated canary releases, traffic shifting, routing, secure service communication, in-depth observability and more, for yourself.