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:
kubectlhelmcurl
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:
| Tool | URL | Purpose |
|---|---|---|
| Kiali | http://<IP>:20001 | Service-to-service traffic graph |
| Grafana | http://<IP>:3000 | Latency, error rate, throughput |
| Prometheus | http://<IP>:9090 | Raw metrics |
| Jaeger | http://<IP>:16686 | End-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
- Navigate to Traffic Graph in the Kiali dashboard
- Select your namespace from the Namespace dropdown
- 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/