In microservices architecture, a Service Mesh is a set of components that act as an intermediary to intercept and redirect traffic between your services. This is useful in many scenarios from access authorization to support for canary releases, blue/green deployments and more.
Istio is a service mesh that’s gaining a lot of traction in the Kubernetes community. Istio works by adding a Sidecar container to each one of your Kubernetes Pods, allowing it to act as a gatekeeper to your application container’s traffic.
Deploying Istio to a cluster can be done by adding and configuring its sidecar to all the pods of your application. Doing this manually is not a good idea: possible human error, forgetting to add the sidecar to new services and repetitive configuration are the obvious issues that come to mind.
Currently, there are 2 official ways for adding Istio to your application:
- Using Admission Controllers
- Using Istio command line
Admission Controllers
Admission Controllers are a Kubernetes component that intercepts cluster’s API calls and modifies them before they are applied to the cluster. This means you can write an Admission Controller to intercept any pod creation call and add the Istio sidecar to it. This is a seamless solution but is also opaque to the end user and can usually cause confusion if you’re not aware of the Admission Controllers that are installed on your cluster and how they are configured and behave.
Istio Command Line
Istio command line tool allows manual injection of the sidecars into your Kubernetes manifest files. It does that by reading the application manifest, finding the relevant services and deployments and adding itself to each one of them. While this is a more transparent way to apply changes to a configuration file, it requires installing Istio command line on your build servers and integrating it with your CI/CD pipeline and is not flexible.
Using Alterant to add Istio
Alterant is an open source project by Cloud 66 which lets you write and run custom Javascript code to modify Kubernetes configuration files. In principle, this is similar to the Istio command line approach in transparency but gives you full control of how, where and when to apply the injection code. Let’s look at the example below:
Assume the following is your application manifest file:
apiVersion: v1
kind: Service
metadata:
name: sleep
labels:
app: sleep
spec:
ports:
- port: 80
name: http
selector:
app: sleep
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
spec:
containers:
- name: sleep
image: pstauffer/curl
command: ["/bin/sleep", "3650d"]
imagePullPolicy: IfNotPresent
To add an Istio sidecar to this, we need to iterate through all of our deployments in the manifest (only 1 here) and add the following Istio sidecar template to it. We will also need to tell Istio the name of the service that’s sitting in front of this deployment.
containers:
- name: istio-proxy
image: istio.io/proxy:0.5.0
args:
- proxy
- sidecar
- --configPath
- /etc/istio/proxy
- --binaryPath
- /usr/local/bin/envoy
- --serviceCluster
- NAME
NAME
should be replaced with the name of the service.
To achieve this, we can apply the following Alterant modifier script:
istioSidecar = YamlReader("istio.yml");
// go through all items
$$.forEach($ => {
sidecar = istioSidecar;
// if you find a service, then look for it's deployment
if ($.kind == "Service") {
// we have a service. look for it's deployment
selectors = $.spec.selector;
deployment = findDeploymentForService($$, selectors);
// find the service name and add it as the last arg of istio container config
name = $.metadata.name;
sidecar.args.push(name);
// add the side car to the deployment
var containers = deployment.spec.template.spec.containers;
if (containers.length == 1) {
containers.push(sidecar);
}
$$.replace(deployment);
}
});
What’s happened?
This script loads a base sidecar template to apply to the pods (like the Istio sidecar template shown above).
The script then iterates through all parts of the manifest ($$.forEach
) and find any Service
. For each Service
it then uses the selector
attribute to find the Deployment
behind the service and adds the sidecar loaded from istio.yml
to it.
In the script, you see some helper methods that Alterant supports to make it easier to use it with Kubernetes manifest files.
Conclusion
Alternat is a powerful, flexible and transparent way to modify Kubernetes configuration files and using it to modify your application and using it to add Istio to your application would making changes transparent and flexible.