Master the service mesh fundamentals with this comprehensive, hands-on study guide. Practice every concept with real YAML configurations and istioctl commands.
This comprehensive study guide covers all four domains of the Istio Certified Associate (ICA) exam. Each section provides conceptual explanations, hands-on examples, and exam-focused tips to help you understand not just the "how" but also the "why" behind Istio's service mesh capabilities.
The guide is designed for hands-on learning. All YAML configurations and commands have been verified for Istio 1.28.x. You're encouraged to practice each concept in a real Kubernetes environment as you study.
Practice the concepts in this guide using any Kubernetes environment with Istio installed. Choose the option that works best for you:
| Environment | Options | Best For |
|---|---|---|
| โ๏ธ Cloud Playgrounds | KodeKloud, Killercoda, Play with Kubernetes | Quick practice, no setup required |
| ๐ป Local Clusters | Minikube, kind, k3d, Docker Desktop | Offline practice, full control |
| ๐ข Managed K8s | GKE, EKS, AKS with Istio addon | Production-like experience |
kubectl (Kubernetes CLI), istioctl (Istio CLI, version 1.28.x recommended), and cluster admin access. Most cloud playgrounds come pre-configured with these tools.
The Istio Certified Associate (ICA) exam validates your foundational knowledge of Istio service mesh concepts, architecture, and hands-on operational skills. The exam combines performance-based tasks with multiple-choice questions, meaning you'll need to demonstrate real ability to configure and troubleshoot Istio installations.
| Exam Detail | Information |
|---|---|
| Duration | 2 hours |
| Passing Score | 75% |
| Cost | $250 USD (includes one free retake) |
| Format | Performance-based + Multiple choice |
| Certification Validity | 3 years |
Since Traffic Management represents 35% of your score, invest proportionally more study time there. However, don't neglect Troubleshootingโthose skills are essential across all domains and will help you debug issues in every topic area.
This domain tests your ability to deploy Istio using different methods, customize installations to match requirements, and safely upgrade production meshes without downtime.
Think of istioctl as your primary interface to the Istio control plane. It's more than just an installerโit's a comprehensive diagnostic and management tool that understands Istio's architecture deeply. When you install Istio using istioctl, you're leveraging the IstioOperator API, which provides a declarative way to specify exactly what you want installed and how it should be configured.
The beauty of istioctl's approach is in its installation profiles. Rather than starting from scratch every time, Istio provides pre-configured profiles optimized for different scenarios. The default profile gives you a production-ready starting point with just the control plane (istiod) and an ingress gateway. The demo profile enables nearly everythingโit's designed for learning and evaluation.
If your environment has Istio pre-installed, verify it. Otherwise, you can install Istio using the commands below.
# Verify istioctl is available istioctl version # List all available installation profiles istioctl profile list # View the complete configuration for a profile istioctl profile dump demo # Compare two profiles to understand differences istioctl profile diff default demo # Check current installation status kubectl get pods -n istio-system # Run pre-installation checks istioctl x precheck
| Profile | Use Case | Components Installed |
|---|---|---|
| default | Production starting point | istiod, Ingress Gateway |
| demo | Learning and evaluation | All components, higher trace sampling |
| minimal | Control plane only | istiod only (no gateways) |
| ambient | Sidecar-less mesh | istiod, CNI, ztunnel |
| empty | Base for custom profiles | Nothing (define everything yourself) |
Always run istioctl x precheck before installing or upgrading. This command validates that your cluster meets Istio's requirements and identifies potential issues before they cause problems.
While profiles provide excellent starting points, real-world deployments almost always require customization. The IstioOperator API gives you fine-grained control over every aspect of your installation. You can override individual settings using --set flags directly on the command line, or define a complete IstioOperator manifest for more complex configurations.
apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: namespace: istio-system name: istio-control-plane spec: profile: default # Mesh-wide configuration settings meshConfig: accessLogFile: /dev/stdout accessLogEncoding: JSON enableTracing: true defaultConfig: tracing: sampling: 100.0 holdApplicationUntilProxyStarts: true outboundTrafficPolicy: mode: REGISTRY_ONLY # Component-level configuration components: pilot: enabled: true k8s: resources: requests: cpu: 500m memory: 2Gi ingressGateways: - name: istio-ingressgateway enabled: true
The REGISTRY_ONLY mode restricts outbound traffic to services defined in Istio's service registry. This is more secure but requires ServiceEntry resources for external services. ALLOW_ANY permits traffic to any destination.
Istio's traditional architecture uses the sidecar patternโan Envoy proxy container is injected into every application pod, intercepting all network traffic for that workload. This approach provides comprehensive L4/L7 traffic management but adds resource overhead to every pod in your mesh.
Ambient mode represents Istio's answer to this challenge. Instead of per-pod sidecars, ambient mode uses a shared ztunnel component running on each node that handles L4 security (mTLS) for all pods on that node. For workloads needing L7 features, you deploy waypoint proxies. This architecture can reduce proxy resource usage by up to 90%.
# Enable SIDECAR injection for a namespace kubectl label namespace default istio-injection=enabled # Verify namespace labels kubectl get namespace -L istio-injection # Enable AMBIENT mode for a namespace (alternative) kubectl label namespace default istio.io/dataplane-mode=ambient # Check which mode is enabled kubectl get namespaces -L istio-injection,istio.io/dataplane-mode # Disable injection for specific pod (annotation) # sidecar.istio.io/inject: "false"
Upgrading a service mesh in production requires careful planning. Istio supports canary upgrades which run multiple control plane versions simultaneously, enabling gradual workload migration and safe rollback. Each control plane installation gets a unique revision label, and namespaces are labeled to indicate which revision they should use.
# Step 1: Install new revision alongside existing istioctl install --set revision=1-21-0 # Verify both control planes running kubectl get pods -n istio-system -l app=istiod # Step 2: Migrate namespaces to new revision kubectl label namespace test-ns istio-injection- istio.io/rev=1-21-0 # Step 3: Restart workloads to get new sidecars kubectl rollout restart deployment -n test-ns # Step 4: Verify migration istioctl proxy-status # Step 5: After migrating ALL namespaces, remove old revision istioctl uninstall --revision 1-20-1 -y
After changing namespace labels or revision tags, existing pods still run with their old sidecar version. You must restart pods (using kubectl rollout restart) for them to receive the new sidecar version.
| Concept | Details |
|---|---|
| Sidecar Injection Label | istio-injection=enabled |
| Ambient Mode Label | istio.io/dataplane-mode=ambient |
| Disable Injection (Pod) | sidecar.istio.io/inject: "false" |
| Revision Label | istio.io/rev=<revision> |
| Control Plane Namespace | istio-system |
| Control Plane Component | istiod (Pilot, Citadel, Galley combined) |
| Default Profile Components | istiod + Ingress Gateway |
| Demo Profile | All components + higher trace sampling |
If pods don't get sidecars after labeling namespace: (1) Check namespace label exists, (2) Verify istio-sidecar-injector webhook, (3) Restart pods - existing pods won't automatically get sidecars!
Bookmark these pages for exam preparation and quick reference:
This is the largest domain, and for good reasonโtraffic management is at the heart of what makes a service mesh valuable. You'll learn to control how requests flow through your mesh using Gateways, VirtualServices, and DestinationRules.
Before diving into traffic management, let's deploy the Bookinfo sample application that we'll use throughout this section. This microservices application includes productpage, details, reviews (v1, v2, v3), and ratings servicesโperfect for practicing routing scenarios.
# Ensure sidecar injection is enabled kubectl label namespace default istio-injection=enabled --overwrite # Deploy the Bookinfo application kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/platform/kube/bookinfo.yaml # Wait for all pods to be ready kubectl get pods -w # Deploy the Gateway and VirtualService for external access kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/networking/bookinfo-gateway.yaml # Deploy destination rules (defines subsets) kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/networking/destination-rule-all.yaml # Verify the application kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" \ -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
The Gateway resource is your mesh's front doorโit configures the load balancer that sits at the edge of your service mesh, accepting traffic from outside and directing it inward. Think of it as configuring the "what" of edge traffic: which ports to listen on, which protocols to accept, and which hostnames to serve.
apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: bookinfo-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"
The VirtualService is where the real routing magic happens. While a Gateway just opens the door, the VirtualService decides where each request should go based on its characteristicsโURI paths, HTTP headers, query parameters, or percentage-based weights for canary deployments.
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: # Route user "jason" to reviews v2 (black stars) - match: - headers: end-user: exact: jason route: - destination: host: reviews subset: v2 # Default: Everyone else goes to v1 (no stars) - route: - destination: host: reviews subset: v1
If VirtualService is about routing (which version to send traffic to), DestinationRule is about policy (how to communicate with that version). DestinationRules define traffic policies that apply after routing decisions are madeโload balancing algorithms, connection pooling, outlier detection for circuit breaking, and TLS settings.
apiVersion: networking.istio.io/v1 kind: DestinationRule metadata: name: reviews spec: host: reviews trafficPolicy: loadBalancer: simple: ROUND_ROBIN connectionPool: tcp: maxConnections: 100 http: http1MaxPendingRequests: 100 outlierDetection: consecutive5xxErrors: 5 interval: 10s baseEjectionTime: 30s subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3
Traffic shifting enables safe, gradual rollouts of new service versions. Instead of switching all traffic at once, you can shift 1%, then 5%, then 20%, monitoring metrics at each stage. If problems emerge, simply adjust the weights backโno redeployment required.
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 80 - destination: host: reviews subset: v3 weight: 20
ServiceEntry adds external services to Istio's service registry, enabling traffic management and observability for external API calls. When outboundTrafficPolicy.mode: REGISTRY_ONLY is set, the mesh will block traffic to services not in the registry.
apiVersion: networking.istio.io/v1 kind: ServiceEntry metadata: name: httpbin-ext spec: hosts: - httpbin.org ports: - number: 443 name: https protocol: TLS location: MESH_EXTERNAL resolution: DNS
Istio provides several resilience patternsโtimeouts, retries, circuit breaking, and outlier detectionโthat protect your system from cascading failures without requiring application code changes.
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - route: - destination: host: ratings timeout: 10s retries: attempts: 3 perTryTimeout: 3s retryOn: 5xx,reset,connect-failure
VirtualService: Timeouts, retries, fault injection, routing rules
DestinationRule: Load balancing, connection pools, circuit breaking, TLS settings, subsets
Fault injection lets you simulate failures in a controlled way. Inject delays to test timeout handling, or inject aborts (HTTP errors) to verify error handling. You can target specific users via headers or affect a percentage of all traffic.
apiVersion: networking.istio.io/v1 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - match: - headers: end-user: exact: jason fault: delay: percentage: value: 100 fixedDelay: 7s route: - destination: host: ratings - route: - destination: host: ratings
| Resource | Purpose | Key Fields |
|---|---|---|
| Gateway | Edge load balancer configuration | selector, servers (port, hosts, tls) |
| VirtualService | Routing rules (WHERE to send) | hosts, gateways, http (match, route, timeout, retries, fault) |
| DestinationRule | Traffic policies (HOW to communicate) | host, trafficPolicy, subsets |
| ServiceEntry | Add external services to registry | hosts, ports, location, resolution |
| Sidecar | Limit proxy scope | workloadSelector, egress |
| Load Balancer Mode | Description |
|---|---|
| ROUND_ROBIN | Default, cycles through endpoints |
| LEAST_REQUEST | Routes to endpoint with fewest active requests |
| RANDOM | Random selection |
| PASSTHROUGH | Direct connection to original destination |
A VirtualService routing to a subset requires a DestinationRule that defines that subset. Without it, you'll get "no healthy upstream" errors. Always create the DestinationRule first!
Traffic weights must add up to 100. If using two destinations with weights 80/20, both must be specified. Also remember: weights are specified in VirtualService, subsets are defined in DestinationRule.
Bookmark these pages for exam preparation and quick reference:
Security is foundational to Istio's value proposition. This domain covers authentication (proving identity with mTLS and JWT), authorization (controlling who can access what), and securing edge traffic with TLS.
Mutual TLS (mTLS) is one of Istio's most valuable security features. With mTLS, both the client and server present certificates to prove their identity. Istio manages the certificate lifecycle automaticallyโeach workload gets a SPIFFE identity and short-lived X.509 certificate that's automatically rotated.
| mTLS Mode | Behavior | Use Case |
|---|---|---|
| STRICT | Only accept mTLS connections | Production, security-critical workloads |
| PERMISSIVE | Accept both mTLS and plaintext | Migration, mixed environments |
| DISABLE | Don't use mTLS for this scope | Legacy services that can't use TLS |
# Mesh-wide STRICT mTLS apiVersion: security.istio.io/v1 kind: PeerAuthentication metadata: name: default namespace: istio-system spec: mtls: mode: STRICT
AuthorizationPolicy controls what services can do. It's Istio's access control mechanism, letting you define fine-grained rules about which services can access which endpoints. Evaluation order: CUSTOM โ DENY โ ALLOW โ implicit deny.
# Default deny-all for namespace apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: deny-all namespace: default spec: {} --- # Allow specific access apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: reviews-viewer namespace: default spec: selector: matchLabels: app: reviews action: ALLOW rules: - from: - source: principals: - "cluster.local/ns/default/sa/bookinfo-productpage" to: - operation: methods: - "GET"
RequestAuthentication enables end-user authentication using JSON Web Tokens (JWTs). It validates tokens but doesn't require themโrequests without tokens pass through. To require authentication, combine with an AuthorizationPolicy that checks for the presence of a request principal.
apiVersion: security.istio.io/v1 kind: RequestAuthentication metadata: name: jwt-auth spec: selector: matchLabels: app: httpbin jwtRules: - issuer: "https://accounts.google.com" jwksUri: "https://www.googleapis.com/oauth2/v3/certs" --- # Require valid JWT apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: require-jwt spec: selector: matchLabels: app: httpbin action: ALLOW rules: - from: - source: requestPrincipals: - "*"
The Gateway resource supports three TLS modes: SIMPLE (standard TLS termination), MUTUAL (client certificate required), and PASSTHROUGH (SNI-based routing without termination).
# Create TLS secret for Gateway
kubectl create -n istio-system secret tls bookinfo-credential \
--key=bookinfo.example.com.key \
--cert=bookinfo.example.com.crt
apiVersion: networking.istio.io/v1 kind: Gateway metadata: name: secure-gateway spec: selector: istio: ingressgateway servers: - port: number: 443 name: https protocol: HTTPS hosts: - "bookinfo.example.com" tls: mode: SIMPLE credentialName: bookinfo-credential
| Security Resource | Purpose | Scope Options |
|---|---|---|
| PeerAuthentication | mTLS settings (workload identity) | Mesh โ Namespace โ Workload |
| AuthorizationPolicy | Access control (who can access what) | Mesh โ Namespace โ Workload |
| RequestAuthentication | JWT validation (end-user identity) | Namespace โ Workload |
| AuthorizationPolicy Action | Evaluation Order | Behavior |
|---|---|---|
| CUSTOM | 1st | Delegate to external auth |
| DENY | 2nd | Explicit deny (if matched) |
| ALLOW | 3rd | Explicit allow (if matched) |
| Implicit deny | 4th | Deny if no ALLOW matched (when ALLOW policies exist) |
| Gateway TLS Mode | Client Cert Required? | Use Case |
|---|---|---|
| SIMPLE | No | Standard HTTPS (server cert only) |
| MUTUAL | Yes | mTLS at gateway edge |
| PASSTHROUGH | N/A | SNI routing, TLS handled by backend |
| AUTO_PASSTHROUGH | N/A | SNI routing without VirtualService |
Service Account: cluster.local/ns/{namespace}/sa/{service-account}
JWT Principal: {issuer}/{subject}
SPIFFE ID: spiffe://cluster.local/ns/{namespace}/sa/{service-account}
spec: {} in AuthorizationPolicy = deny all (zero-trust default)
rules: [{}] in AuthorizationPolicy = match all (use with DENY action)
Bookmark these pages for exam preparation and quick reference:
When things go wrong, you need systematic approaches to diagnose issues. This domain covers configuration validation, control plane diagnostics, and data plane debugging.
istioctl analyze is your first line of defense against configuration issues. It validates your Istio resources against known problems and best practices, catching issues before they cause production problems.
# Analyze all namespaces istioctl analyze --all-namespaces # Analyze specific namespace istioctl analyze -n default # Analyze local files without applying istioctl analyze --use-kube=false my-config.yaml # Suppress specific warnings istioctl analyze --suppress "IST0102=Namespace default"
istioctl proxy-status shows whether each sidecar is synchronized with the control plane. All proxies should show "SYNCED" for each configuration type (CDS, LDS, EDS, RDS). A "STALE" status indicates problems.
# Check synchronization status of all proxies istioctl proxy-status # Status meanings: # SYNCED - Proxy acknowledged latest config # NOT SENT - Nothing to send (normal) # STALE - Config sent but not acknowledged (problem!)
| Config Type | Full Name | What It Configures |
|---|---|---|
| CDS | Cluster Discovery | Upstream clusters (services) |
| LDS | Listener Discovery | Ports proxy listens on |
| EDS | Endpoint Discovery | Actual pod IPs |
| RDS | Route Discovery | VirtualService rules |
istioctl proxy-config lets you inspect exactly what configuration a sidecar has receivedโclusters, listeners, routes, endpoints, and secrets. Essential for debugging "why isn't my traffic going where I expect?"
# View upstream clusters istioctl proxy-config clusters productpage-v1-xxx.default # View listeners istioctl proxy-config listeners productpage-v1-xxx.default # View routes istioctl proxy-config routes productpage-v1-xxx.default --name 9080 # View endpoints istioctl proxy-config endpoints productpage-v1-xxx.default # View TLS certificates istioctl proxy-config secret productpage-v1-xxx.default # Get full JSON output istioctl proxy-config routes productpage-v1-xxx.default -o json
When proxies show STALE status or configuration isn't being applied, the control plane (istiod) is often where you should look first.
# Check istiod pod status kubectl get pods -n istio-system -l app=istiod # View istiod logs kubectl logs -n istio-system -l app=istiod --tail=100 # Verify version alignment istioctl version # Describe a workload's Istio config istioctl experimental describe pod productpage-v1-xxx.default # Check sidecar injection status istioctl experimental check-inject -n default deployment/productpage-v1
Add trafficPolicy.tls.mode: ISTIO_MUTUAL to your DestinationRule when using subsets with mesh-wide mTLS.
The proxy can't find a route for the request. Check VirtualService configuration and ensure the destination service exists.
Circuit breaker triggered due to connection pool limits. Review DestinationRule connectionPool settings.
# Install observability addons kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/prometheus.yaml kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/grafana.yaml kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/jaeger.yaml kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/kiali.yaml # Open dashboards istioctl dashboard kiali istioctl dashboard prometheus istioctl dashboard grafana istioctl dashboard jaeger
| proxy-config Type | Shows | Use When |
|---|---|---|
| clusters | Upstream services (CDS) | Service not found, subset issues |
| listeners | Port listeners (LDS) | Port not accessible, traffic not intercepted |
| routes | Routing rules (RDS) | Wrong destination, VirtualService not applied |
| endpoints | Pod IPs (EDS) | No healthy upstream, load balancing issues |
| secret | Certificates | mTLS failures, certificate expiry |
| Response Flag | Meaning | Common Cause |
|---|---|---|
| NR | No Route | VirtualService not matching, missing ServiceEntry |
| UH | No Healthy Upstream | All endpoints failed health checks |
| UF | Upstream Connection Failure | Network issues, pod not running |
| UO | Upstream Overflow | Circuit breaker tripped |
| UC | Upstream Connection Termination | Connection reset by peer |
| UT | Upstream Request Timeout | Request exceeded timeout |
| DC | Downstream Connection Termination | Client disconnected |
| RBAC | RBAC Access Denied | AuthorizationPolicy blocked request |
| Istio Port | Purpose |
|---|---|
| 15000 | Envoy admin interface |
| 15001 | Envoy outbound traffic |
| 15006 | Envoy inbound traffic |
| 15010 | Istiod xDS (plaintext) |
| 15012 | Istiod xDS (mTLS) |
| 15014 | Istiod metrics |
| 15017 | Webhook injection |
| 15020 | Merged Prometheus telemetry |
| 15021 | Health checks |
| 15090 | Envoy Prometheus |
1. istioctl analyze - Check for config errors
2. istioctl proxy-status - Verify all proxies SYNCED
3. istioctl proxy-config - Inspect specific proxy config
4. Check access logs for response flags
5. kubectl logs -l app=istiod -n istio-system - Control plane logs
Bookmark these pages for exam preparation and quick reference:
| Command | Purpose |
|---|---|
| istioctl install --set profile=<name> | Install Istio with profile |
| istioctl analyze -n <ns> | Detect configuration issues |
| istioctl proxy-status | Check proxy sync status |
| istioctl proxy-config clusters <pod> -n <ns> | View upstream clusters (CDS) |
| istioctl proxy-config routes <pod> -n <ns> | View routing config (RDS) |
| istioctl proxy-config listeners <pod> -n <ns> | View port listeners (LDS) |
| istioctl proxy-config endpoints <pod> -n <ns> | View endpoints (EDS) |
| istioctl proxy-config secret <pod> -n <ns> | View certificates |
| istioctl x describe pod <pod> -n <ns> | Describe pod config |
| istioctl x precheck | Pre-upgrade check |
| istioctl dashboard <tool> | Open dashboards (kiali, grafana, jaeger) |
| istioctl kube-inject -f <file> | Manual sidecar injection |
| kubectl label ns <ns> istio-injection=enabled | Enable auto sidecar injection |
| Resource | API Group | Short Name |
|---|---|---|
| Gateway | networking.istio.io/v1 | gw |
| VirtualService | networking.istio.io/v1 | vs |
| DestinationRule | networking.istio.io/v1 | dr |
| ServiceEntry | networking.istio.io/v1 | se |
| Sidecar | networking.istio.io/v1 | - |
| PeerAuthentication | security.istio.io/v1 | pa |
| AuthorizationPolicy | security.istio.io/v1 | ap |
| RequestAuthentication | security.istio.io/v1 | ra |
| EnvoyFilter | networking.istio.io/v1alpha3 | ef |
| WorkloadEntry | networking.istio.io/v1 | we |