How to Use Kubernetes with Istio for Service Mesh

Updated: January 30, 2024 By: Guest Contributor Post a comment

Introduction

Kubernetes is an open source platform designed to automate deploying, scaling, and operating application containers. But as applications grow to span multiple containers deployed across multiple servers, operating them becomes more complex. To manage this complexity, Kubernetes offers powerful abstractions such as Pods, Services, and Deployments. A service mesh is a dedicated infrastructure layer for handling service-to-service communication. Istio, a service mesh, provides an easy way to create a network of deployed services with load balancing, service-to-service authentication, monitoring, and more, without any changes in service code.

In this tutorial, we’ll walk through the basics of getting Istio up and running on Kubernetes, and then move on to some more advanced features. By the end of this guide, you’ll understand how to deploy your applications to a Kubernetes cluster and use Istio to enhance their operations.

Prerequisites

  • You should have a Kubernetes cluster running.
  • kubectl tool installed and configured to communicate with your cluster.
  • Basic understanding of Kubernetes concepts like pod, deployment, service, etc.

Installation of Istio

curl -L https://istio.io/downloadIstio | sh -
export PATH="\$PATH:\$PWD/istio-1.7.3/bin"
istioctl install --set profile=default -y

The `istioctl` command line tool is used to install Istio in your cluster. After the installation, verify that Istio has been successfully deployed:

kubectl get svc -n istio-system
kubectl get pods -n istio-system

Deploying Your Application

Let’s start by deploying a simple application. Use the following code to create a deployment and a service.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-world
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello-world
  template:
    metadata:
      labels:
        app: hello-world
    spec:
      containers:
      - name: hello-world
        image: 'k8s.gcr.io/echoserver:1.4'
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: hello-world
spec:
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: hello-world

Apply the configuration with kubectl:

kubectl apply -f hello-world.yaml

Enabling Istio Injection

To let Istio manage your services, injection of Istio sidecars in your service pods is necessary. Label your namespace to automatically inject them with the following command:

kubectl label namespace default istio-injection=enabled

When you create new pods, they will now have the Istio sidecar injected.

Accessing Your Services

Istio has installed an ingress gateway in your cluster. You can use it to access your services. For this tutorial, we’ll create an Istio Gateway and VirtualService to route external traffic to our service.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: hello-world-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80      
      name: http   
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-world
spec:
  hosts:
  - "*"
  gateways:
  - hello-world-gateway
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: hello-world
        port:
          number: 80

Once applied, your service will be accessible through the Istio Ingress gateway.

Observability With Istio

Istio provides powerful tools for monitoring your services. Let’s check how to enable Kiali dashboard for observing service mesh:

istioctl dashboard kiali

Additionally, you can install Grafana for sophisticated monitoring:

istioctl install --set addonComponents.grafana.enabled=true

This will enable the Grafana dashboard for monitoring your service mesh.

Advanced Traffic Management

Istio allows you to manipulate the traffic flow between services. Below is an example of a Traffic Shifting rule:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hello-world
spec:
  hosts:
  - "hello-world"
  http:
  - route:
    - destination:
        host: hello-world-v1
      weight: 80
    - destination:
        host: hello-world-v2
      weight: 20

This configuration will send 80% of the traffic to version 1 of the hello-world service and 20% to version 2.

Security With Istio

Istio enhances the security of your clusters by enabling mutual TLS between services. To enforce mTLS, use the following Policy and DestinationRule:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default"
spec:
  mtls:
    mode: STRICT

And for DestinationRule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: default
spec:
  host: "*.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

This will enforce mTLS for all services in the current namespace.

Clean-Up

If you need to remove Istio from your cluster, you can use the following command:

istioctl manifest generate --set profile=default | kubectl delete --ignore-not-found=true -f -
kubectl label namespace default istio-injection-

Conclusion

Throughout this tutorial, we have demonstrated how to effectively use Istio on top of Kubernetes to create a robust service mesh for your microservices. We’ve seen how Istio adds valuable features like traffic management, security, and observability to Kubernetes, making it easier to maintain complex applications.