Skip to main content

Service Mesh with Istio on E2E Kubernetes

1. What is a Service Mesh?

A Service Mesh manages service-to-service communication in a microservices architecture.

It provides:

  • Security – mTLS, authentication, authorization
  • Traffic Management – routing, retries, failover, canary
  • Observability – metrics, logs, tracing
  • Resiliency – circuit breaking, rate limiting

Istio implements this by automatically injecting Envoy sidecar proxies into application pods.

How Istio Works: Control Plane and Data Plane

Control Plane (The Brain)

The control plane is Istio's "brain." It sets all rules for traffic, security, and monitoring. The control plane tells proxies how to manage traffic between services.

Data Plane (The Worker)

The data plane is the "worker" that does the job. It has proxies (small helpers) next to each service. These proxies make sure traffic flows as it should, based on the rules the control plane sets up.

  • Proxies — Small tools next to each service. They manage traffic, secure communication, and collect information about how well services are working.

How Proxies Work: Sidecar vs. Ambient Mode

  • Sidecar Mode — Each service has its own proxy attached to it. This is the more common setup, giving a lot of control but adds a little extra load on each service.
  • Ambient Mode — One proxy on each server manages traffic for all services. This reduces the extra load but has slightly fewer features.

Why Use Istio?

  • Security — Istio encrypts communication, adding strong protection.
  • Efficiency — It keeps traffic balanced, so no single service is overloaded.
  • Easy Monitoring — Istio collects data, showing you how well services are working without needing extra code.

2. Why Istio on E2E Kubernetes?

E2E Kubernetes provides cluster infrastructure and networking. Istio adds production-grade control and visibility.

Without Istio:

  • No automatic encryption between services
  • No traffic control or canary support
  • No service-level observability

With Istio:

  • Automatic mTLS encryption between all services
  • Fine-grained traffic policies (retries, timeouts, circuit breaking)
  • Real-time service graph, metrics, and distributed tracing

3. Prerequisites

Ensure the following are ready:

  • Running E2E Kubernetes cluster
  • At least 2 worker nodes
  • LoadBalancer support enabled (LB IP reserved and attached)
  • A registered domain
  • Tools installed:
    • kubectl
    • helm
    • curl

Verify cluster access:

kubectl get nodes

All nodes must be Ready.

4. Step 1 – Install Istio

Download Istio

curl -L https://istio.io/downloadIstio | sh -
cd istio-*
export PATH=$PWD/bin:$PATH

Install Istio (demo profile)

istioctl install --set profile=demo -y

Verify:

kubectl get pods -n istio-system

5. Step 2 – Enable Sidecar Injection

kubectl label namespace default istio-injection=enabled

All new pods will automatically get an Envoy sidecar.

6. Step 3 – Deploy Sample Application (Bookinfo)

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

Verify:

kubectl get pods

Each pod must show:

READY  2/2

The 2/2 confirms both the application container and the Envoy sidecar are running.

7. Step 4 – Ensure Istio Ingress Gateway Is Public

kubectl get svc istio-ingressgateway -n istio-system

Note the EXTERNAL-IP.

Note: To assign an LB IP, at least one reserved IP must be attached to the cluster from the E2E Dashboard. See Kubernetes Services — Assigning an External IP.

8. Step 5 – Domain Mapping (DNS)

Create an A record in your DNS provider:

istio.yourdomain.com → <Istio Ingress EXTERNAL-IP>

Verify DNS:

nslookup istio.yourdomain.com

9. Step 6 – Create Istio Gateway (HTTP)

gateway.yaml

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "istio.yourdomain.com"

Apply:

kubectl apply -f gateway.yaml
kubectl get gateway

10. Step 7 – Create VirtualService

virtual-service.yaml

apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "istio.yourdomain.com"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
route:
- destination:
host: productpage
port:
number: 9080

Apply:

kubectl apply -f virtual-service.yaml
kubectl get virtualservice

11. Step 8 – Test HTTP Access

Open in a browser:

http://istio.yourdomain.com/productpage

12. Step 9 – Enable mTLS

peer-auth.yaml

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

Apply:

kubectl apply -f peer-auth.yaml
kubectl get peerauthentication

Test Without Istio Sidecar

Create a pod without a sidecar:

kubectl run curl-plain \
--image=curlimages/curl \
--restart=Never \
-- curl http://productpage:9080

Check logs:

kubectl logs curl-plain

Traffic will fail, proving mTLS enforcement. Pods without an Istio sidecar cannot communicate with mTLS-protected services.

13. Step 10 – Install cert-manager

kubectl create namespace cert-manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--set crds.enabled=true

Verify:

kubectl get pods -n cert-manager

14. Step 11 – Create ClusterIssuer (Let's Encrypt)

cluster-issuer.yaml

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: your-email@yourdomain.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: istio

Apply:

kubectl apply -f cluster-issuer.yaml
kubectl get clusterissuer

15. Step 12 – Request SSL Certificate

cert.yaml

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: bookinfo-cert
namespace: istio-system
spec:
secretName: bookinfo-cert
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- istio.yourdomain.com

Apply:

kubectl apply -f cert.yaml

Verify:

kubectl describe certificate bookinfo-cert -n istio-system

16. Step 13 – Enable HTTPS on Istio Gateway

Update gateway.yaml to add HTTPS listener:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "istio.yourdomain.com"
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: bookinfo-cert
hosts:
- "istio.yourdomain.com"

Apply:

kubectl apply -f gateway.yaml
kubectl get gateway

17. Step 14 – Access Application Over HTTPS

Open in a browser:

https://istio.yourdomain.com/productpage

18. Observability Stack (Metrics, Tracing, Service Graph)

Install Istio Add-ons

Istio add-ons include:

  • Prometheus — metrics collection
  • Grafana — dashboards
  • Kiali — service mesh visualization
  • Jaeger — distributed tracing

Run:

kubectl apply -f samples/addons

Wait until Kiali is ready:

kubectl rollout status deployment/kiali -n istio-system

Verify all add-ons:

kubectl get pods -n istio-system

Expose Dashboards Using LoadBalancer

Expose each observability component externally.

Expose Kiali (Service Mesh Graph)

kubectl patch svc kiali -n istio-system \
-p '{"spec": {"type": "LoadBalancer"}}'

Expose Grafana (Metrics Dashboard)

kubectl patch svc grafana -n istio-system \
-p '{"spec": {"type": "LoadBalancer"}}'

Expose Prometheus (Metrics Backend)

kubectl patch svc prometheus -n istio-system \
-p '{"spec": {"type": "LoadBalancer"}}'

Expose Jaeger (Distributed Tracing)

kubectl patch svc tracing -n istio-system \
-p '{"spec": {"type": "LoadBalancer"}}'

Access Observability Dashboards

Get external IPs:

kubectl get svc -n istio-system

Access URLs:

ToolURLPurpose
Kialihttp://<IP>:20001Service-to-service traffic graph
Grafanahttp://<IP>:3000Latency, error rate, throughput
Prometheushttp://<IP>:9090Raw metrics
Jaegerhttp://<IP>:16686End-to-end request tracing

19. Traffic Management

Traffic management allows safe deployments without downtime.

What Traffic Management Controls

Istio controls east–west traffic (service to service):

  • Traffic splitting (canary)
  • Retries
  • Timeouts
  • Circuit breaking
  • Fault injection

Canary Deployment Example

Goal:

  • 80% traffic → old version (v1)
  • 20% traffic → new version (v2)

Create DestinationRule

Defines service versions (subsets).

destination-rule.yaml

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2

Apply:

kubectl apply -f destination-rule.yaml
kubectl get destinationrule

Create VirtualService (Traffic Split)

reviews-canary.yaml

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

Apply:

kubectl apply -f reviews-canary.yaml

Verify Traffic Split

Open the application:

https://istio.yourdomain.com/productpage

Refresh multiple times. You will see:

  • ~80% of requests served by reviews-v1 (no stars)
  • ~20% of requests served by reviews-v2 (black stars)

Explore the Kiali Graph

  1. Navigate to Traffic Graph in the Kiali dashboard
  2. Select your namespace from the Namespace dropdown
  3. Observe traffic flowing to:
    • reviews-v1 (~80%)
    • reviews-v2 (~20%)

This confirms canary deployment is working.

Conclusion

This guide demonstrates a complete, end-to-end implementation of Istio Service Mesh on E2E Kubernetes, covering installation, security, traffic management, observability, and resilience.

By integrating Istio at the platform level, the Kubernetes environment gains:

  • Secure service-to-service communication (mTLS)
  • Advanced traffic control such as canary deployments and retries
  • Deep observability through metrics, tracing, and service graphs — without requiring application code changes

The implementation enables zero-downtime deployments, safe progressive rollouts, and strong security boundaries, making the platform production-ready.

Reference: https://istio.io/latest/docs/