Istio Service Mesh
Deploy Istio service mesh with traffic management, mutual TLS, and observability.
Time: ~20 minutes Difficulty: Advanced
Resource Requirements: Istio needs additional resources. Ensure minikube has at least 4 CPUs and 8GB RAM. Clean up other demos first with
task clean:all.
What You Will Learn
Section titled “What You Will Learn”- Istio service mesh architecture and components
- Automatic sidecar injection for pods
- Traffic splitting with weighted routing
- Mutual TLS (mTLS) between services
- Istio Gateway for ingress traffic
- DestinationRules and VirtualServices for traffic management
- Observability with istioctl proxy-status
Prerequisites
Section titled “Prerequisites”Install Istio using istioctl:
# Download Istio (if not already installed)curl -L https://istio.io/downloadIstio | sh -cd istio-*export PATH=$PWD/bin:$PATH
# Install Istio with demo profileistioctl install --set profile=demo -yVerify the installation:
kubectl get pods -n istio-systemYou should see istiod and istio-ingressgateway running.
Deploy
Section titled “Deploy”Navigate to the demo directory:
cd demos/istio-service-meshCreate the namespace with automatic sidecar injection enabled:
kubectl apply -f manifests/namespace.yamlDeploy the frontend and backend services:
kubectl apply -f manifests/deployment-frontend.yamlkubectl apply -f manifests/deployment-backend-v1.yamlkubectl apply -f manifests/deployment-backend-v2.yamlkubectl apply -f manifests/service-frontend.yamlkubectl apply -f manifests/service-backend.yamlWait for pods to be ready with sidecars injected:
kubectl get pods -n istio-demoEach pod should show 2/2 containers (application + Envoy sidecar).
Apply Istio traffic management rules:
kubectl apply -f manifests/destination-rule.yamlkubectl apply -f manifests/virtual-service.yamlkubectl apply -f manifests/gateway.yamlVerify
Section titled “Verify”Check that Istio sidecars are injected:
kubectl get pods -n istio-demo -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}'You should see each pod has two containers: the application and istio-proxy.
Verify mutual TLS is enabled:
istioctl proxy-statusAll proxies should show SYNCED status.
Check mTLS configuration:
istioctl authn tls-check -n istio-demo backend-v1-<pod-id>.istio-demoGet the ingress gateway URL:
export INGRESS_HOST=$(minikube ip)export INGRESS_PORT=$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORTecho "http://$GATEWAY_URL"Test the frontend:
curl http://$GATEWAY_URLTest Traffic Splitting
Section titled “Test Traffic Splitting”The VirtualService routes 80% of traffic to backend v1 and 20% to backend v2. Test this from inside the frontend pod:
# Get frontend pod nameexport FRONTEND_POD=$(kubectl get pod -n istio-demo -l app=frontend -o jsonpath='{.items[0].metadata.name}')
# Send 10 requests and observe the distributionfor i in {1..10}; do kubectl exec -n istio-demo $FRONTEND_POD -c nginx -- curl -s http://backend/headers | grep X-Forwarded-HostdoneTo see which backend version handled the request, check the pod logs:
kubectl logs -n istio-demo -l app=backend,version=v1 -c httpbin --tail=5kubectl logs -n istio-demo -l app=backend,version=v2 -c httpbin --tail=5What is Happening
Section titled “What is Happening”manifests/ namespace.yaml # istio-demo namespace with istio-injection: enabled deployment-frontend.yaml # nginx frontend (1 replica) deployment-backend-v1.yaml # httpbin backend v1 (1 replica) deployment-backend-v2.yaml # httpbin backend v2 (1 replica) service-frontend.yaml # ClusterIP service for frontend service-backend.yaml # ClusterIP service for backend (selects both v1 and v2) destination-rule.yaml # Defines subsets v1 and v2, enables mTLS virtual-service.yaml # Routes 80% to v1, 20% to v2 gateway.yaml # Istio Gateway + VirtualService for external accessHow Istio works:
- The
istio-injection: enabledlabel on the namespace tells Istio to automatically inject an Envoy sidecar into every pod. - The sidecar intercepts all inbound and outbound traffic to the pod.
- DestinationRule defines traffic policies (like mTLS) and subsets based on pod labels (version: v1, version: v2).
- VirtualService routes traffic to specific subsets with weight-based routing (80/20 split).
- Gateway exposes services to external traffic via the istio-ingressgateway.
- All service-to-service communication is encrypted with mutual TLS by default.
Traffic flow:
External → Gateway → frontend (Envoy sidecar) → backend Service ↓ VirtualService routes to subsets ↓ ↓ v1 (80%) v2 (20%)Experiment
Section titled “Experiment”-
Shift all traffic to v2:
Terminal window kubectl patch virtualservice backend -n istio-demo --type=merge -p '{"spec": {"http": [{"route": [{"destination": {"host": "backend","subset": "v2"}}]}]}}' -
Inject a 5-second delay for 50% of requests to v1:
Terminal window kubectl apply -f - <<EOFapiVersion: networking.istio.io/v1beta1kind: VirtualServicemetadata:name: backendnamespace: istio-demospec:hosts:- backendhttp:- fault:delay:percentage:value: 50.0fixedDelay: 5sroute:- destination:host: backendsubset: v1EOF -
Test circuit breaking by setting connection limits:
Terminal window kubectl patch destinationrule backend -n istio-demo --type=merge -p '{"spec": {"trafficPolicy": {"connectionPool": {"tcp": {"maxConnections": 1},"http": {"http1MaxPendingRequests": 1,"maxRequestsPerConnection": 1}},"outlierDetection": {"consecutiveErrors": 1,"interval": "1s","baseEjectionTime": "3m","maxEjectionPercent": 100}}}}' -
View Envoy configuration for a pod:
Terminal window istioctl proxy-config routes $FRONTEND_POD -n istio-demo -
Enable access logs to see traffic details:
Terminal window kubectl exec -n istio-demo $FRONTEND_POD -c istio-proxy -- \curl -X POST http://localhost:15000/logging?level=debugkubectl logs -n istio-demo $FRONTEND_POD -c istio-proxy --tail=20
Cleanup
Section titled “Cleanup”Delete the demo namespace:
kubectl delete namespace istio-demoOptionally, uninstall Istio:
istioctl uninstall --purge -ykubectl delete namespace istio-systemFurther Reading
Section titled “Further Reading”See docs/deep-dive.md for a detailed explanation of Istio architecture, control plane vs data plane, Envoy proxies, traffic management patterns, security policies, observability integration with Prometheus and Grafana, and production best practices.
Next Step
Section titled “Next Step”Explore policy enforcement with Kyverno to learn about admission control and policy-as-code.