An infrastructure layer that allows you to manage communication between the microservices of your application is a service mesh. As more developers work with microservices, by consolidating common management and administrative tasks in a distributed setup, service meshes have developed to make the job easier and more effective.
To know more about Istio, you can read this article on Istio service mesh to understand the basic terminology, In this tutorial, will explain how to install and configure Istio. Let's get started.
Installing Istio
Get the latest Istio release:
1curl -L https://istio.io/downloadIstio | sh -Extract the archive and export the bin directory in the environment path.
This will also install istioctl, a command-line tool to manage Istio service mesh.
Configuration Profiles
Istio provides various built-in configuration profiles, a set of pre-defined configs related to data and control plane. We can customize the configs according to our needs.
For testing locally or trying it ou, you can use a demo profile. For dev and other environments, we will be using the default configuration profile.
1istioctl install --set profile=demoCustomizing configs
Run:
1istioctl profile dump defaultto see the various configurations. We can change those flag using istioctl commands and --set flag.
For development purpose, we can enabled/changes following flags:
1istioctl install --set addonComponents.kiali.enabled=true \
2--set components.telemetry.enabled=true \
3--set components.citadel.enabled=true \
4--set values.global.proxy.privileged=true \
5--set addonComponents.tracing.enabled=true \
6--set values.pilot.traceSampling=100.0 \
7--set values.global.proxy.tracer=datadogThe path value of --set flag is the YAML path, which you can see in the profile dump command.
While changing any config, make sure to pass all the previous flags with the new ones. For example, if first time, you enabled istioctl install --set addonComponents.kiali.enabled=true and now let’s say, you want to enable citadel, then you have to pass both flags like this: istioctl install --set addonComponents.kiali.enabled=true --set components.telemetry.enabled=true. Failing to add any previously enabled variable will revert the config to its default values. One way to store the dump in a file and do istioctl apply or use helm charts for Istio.
Sidecar injection
For Istio to work properly, a sidecar Envoy proxy needs to be enabled for the services. By default, the Istio control plane will not enable any sidecar to any services. To enable sidecar, we have to add labels at the namespace level.
1kubectl label namespace dsl-test istio-injection=enabledYou need to have this label even if you do not want to add a sidecar to all your services.
You need to restart the pods.
For services, which do not require sidecar, we need to add the following annotation in the deployment template:
1## Pod Annotations
2podAnnotations:
3 sidecar.istio.io/inject: "false"Configuring Services
For demonstration, we will take two demo services demo-1 and demo-2, and configure both services with Istio, and will try to call demo-2 service from demo-1. Make sure there is an env variable in demo-1, which we will configure with demo-2 internal DNS url. The programming language for the two services does not matter here.
A service configuration requires a VirtualService, DestinationRule, PeerAuthentication, and optionally a Gateway configuration.
Gateway
1apiVersion: networking.istio.io/v1alpha3
2kind: Gateway
3metadata:
4 name: demo-1
5spec:
6 selector:
7 istio: ingressgateway
8 servers:
9 - port:
10 number: 80
11 name: http
12 protocol: HTTP
13 - hosts:
14 - "demo-1.example.com"Gateway is used when we want to access the services from the public network.
Here we are using the default gateway provided by the Istio. We can also create multiple gateways and assign the proper name here.
The above gateway configuration enables both HTTP and HTTPS communication. In the case of HTTPS, we have to supply the secret containing the CA certs and key.
1spec:
2 servers:
3 - port:
4 number: 443
5 name: http
6 protocol: HTTP
7 tls:
8 mode: SIMPLE
9 credentialName: div4-dev-certs
10 hosts:
11 - "demo-1.example.com"We can apply the same gateway for demo-2. We just have to update the hosts and metadata name. Since we will demo-2 internally from demo-1, there is no need for an external gateway for demo-2 here.
VirtualServices
1---
2apiVersion: networking.istio.io/v1alpha3
3kind: VirtualService
4metadata:
5 name: demo-1
6spec:
7 hosts:
8 - "demo-1.test.svc.cluster.local"
9 - "demo-1.example.com"
10 gateways:
11 - demo-1
12 http:
13 - route:
14 - destination:
15 host: demo-1.test.svc.cluster.local
16 port:
17 number: 80spec.hosts: Specifies the URL which the caller of the service will use. Here, dsl-es.pbdp.svc.cluster.local will be used by the services calling internally. The endpoint demo-1.example.com will be exposed publicly, and it should match the spec.servers.hosts value in Gateway config.
spec.gateways: In order for the gateways configured above to reach the service, we need to define the gateway metadata name here.
http.route.destination.host: This value should be the actual service FQDN.
DestinationRule
After the virtualservice decides the destination hosts, DestinationRule defines the configuration on the actual service. DestinationRule is optional and is needed only in case we want to override the default behavior.
1---
2apiVersion: networking.istio.io/v1alpha3
3kind: DestinationRule
4metadata:
5 name: demo-1
6spec:
7 host: "demo-1.test.svc.cluster.local"
8 trafficPolicy:
9 loadBalancer:
10 simple: ROUND_ROBIN
11 tls:
12 mode: ISTIO_MUTUALspec.host: specifies service FQDN
spec.trafficPolicy: Specifies policy on the traffic. Here we can specify load balancing algorithms, TLS mode, circuit breaking policies.
spec.trafficPolicy.tls.mode: ISTIO_MUTUAL mode is a TLS mode where we will use the certificates generated by the Istio.
A configuration like circuit breakers, outlier detection comes under the Destination Rule.
PeerAuthentication
This configuration defines how the other services will connect.
1---
2apiVersion: security.istio.io/v1beta1
3kind: PeerAuthentication
4metadata:
5 name: demo-1
6spec:
7 selector:
8 matchLabels:
9 app: demo-1
10 mtls:
11 mode: STRICTspec.selector.matchLabels.app: Specify the deployment label on which this configuration will be applied.
spec.mtls.mode: TLS mode. STRICT being the connection will always be mutual tls.
PeerAuthentication can be applied to a whole namespace. This is useful when all the services in the namespace are part of the mesh.
Apply the same configuration for virutalservice, destination, and peerauthentication by replacing demo-1 with demo-2 assuming both services are in the same namespace.
1kubectl apply -f <file>.yaml -n testAccess the objects:
1kubectl get virtualservices -n pbdp
2kubectl get gateways -n pbdp
3kubectl get destinationrule -n pbdp
4kubectl get peerauthentication -n pbdpNow update the env for demo-2 with demo-2.test.svc.cluster.local in demo-1 service.

