Back to Technology

Istio Track Part 1: Install, Sidecar Injection & Traffic Basics

June 6, 2026 Wasil Zafar 38 min read

Install Istio with istioctl, understand Envoy sidecar injection, and learn the fundamentals of traffic management in a Kubernetes service mesh.

Table of Contents

  1. Service Mesh Concepts
  2. Install Istio
  3. Sidecar Injection
  4. Traffic Flow
  5. Gateway & VirtualService Intro
  6. Exercises
  7. Key Takeaways & Next Steps
Istio Track (3 Parts): Part 1: Install & Sidecars (You are here)Part 2: VirtualService & RoutingPart 3: mTLS & AuthorizationPolicy

Service Mesh Concepts

A service mesh is a dedicated infrastructure layer that manages service-to-service communication within a microservices architecture. Istio is the most widely adopted service mesh for Kubernetes, providing traffic management, observability, and security without requiring application code changes.

Data Plane & Control Plane

Istio follows a two-plane architecture:

  • Data Plane — Envoy sidecar proxies deployed alongside each workload pod. They intercept all inbound and outbound traffic, applying policies and collecting telemetry.
  • Control Planeistiod is the single binary that combines Pilot (traffic management), Citadel (certificate authority), and Galley (configuration) into one process.
Key Insight: Envoy proxies form a mesh of intelligent routers. Application code sends normal HTTP/gRPC requests — the sidecar transparently handles retries, circuit breaking, mTLS, and observability.

Install Istio

The recommended installation method uses istioctl, Istio's CLI tool. The demo profile enables all features for learning environments.

# Download and install istioctl
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.0 sh -
cd istio-1.22.0
export PATH=$PWD/bin:$PATH

# Install Istio with the demo profile (includes all components)
istioctl install --set profile=demo -y

# Verify the installation
istioctl verify-install

Verify Installation

After installation, confirm that the control plane pods are running in the istio-system namespace:

# Check Istio system pods
kubectl get pods -n istio-system

# Expected output:
# NAME                                    READY   STATUS    RESTARTS   AGE
# istiod-xxxxxxxxxx-xxxxx                 1/1     Running   0          2m
# istio-ingressgateway-xxxxxxxxxx-xxxxx   1/1     Running   0          2m
# istio-egressgateway-xxxxxxxxxx-xxxxx    1/1     Running   0          2m

# Check Istio version
istioctl version

Label the namespace where you want automatic sidecar injection:

# Enable automatic sidecar injection for the default namespace
kubectl label namespace default istio-injection=enabled

# Verify the label
kubectl get namespace default --show-labels

Sidecar Injection

Istio injects Envoy sidecars into pods using a Kubernetes mutating admission webhook. When a pod is created in a labeled namespace, the webhook automatically adds the istio-proxy container.

Automatic Injection

Any pod deployed to a namespace with the istio-injection=enabled label will automatically receive a sidecar:

# sample-app.yaml — deploy to an injection-enabled namespace
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - name: httpbin
        image: kennethreitz/httpbin:latest
        ports:
        - containerPort: 80
# Deploy and verify sidecar injection (2/2 READY means sidecar present)
kubectl apply -f sample-app.yaml
kubectl get pods -l app=httpbin

# Expected: httpbin-xxxxx   2/2   Running   0   30s
# The "2/2" indicates the app container + istio-proxy sidecar

Manual Injection & Disabling

For namespaces without automatic injection, use istioctl kube-inject. To exclude specific pods, use annotations:

# Manual injection for a single deployment
istioctl kube-inject -f sample-app.yaml | kubectl apply -f -
# Disable sidecar for a specific pod via annotation
apiVersion: v1
kind: Pod
metadata:
  name: skip-sidecar
  annotations:
    sidecar.istio.io/inject: "false"
spec:
  containers:
  - name: app
    image: nginx:latest

Traffic Flow

When Istio injects a sidecar, it also configures iptables rules inside the pod's network namespace to redirect all traffic through the Envoy proxy:

  1. Outbound: App sends a request → iptables redirects to Envoy (port 15001) → Envoy applies routing rules → forwards to destination sidecar
  2. Inbound: Traffic arrives at pod → iptables redirects to Envoy (port 15006) → Envoy applies policies → delivers to app container
Transparency: The application never knows the proxy exists. It connects to service-name:port as usual — Envoy handles mTLS negotiation, load balancing, and telemetry collection transparently.

Gateway & VirtualService Intro

To expose services outside the mesh, Istio uses a Gateway (defines the L4-L6 load balancer) paired with a VirtualService (defines L7 routing rules):

# gateway.yaml — expose HTTP traffic on port 80
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: httpbin-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "httpbin.example.com"
---
# virtualservice.yaml — route traffic to httpbin service
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: httpbin-vs
spec:
  hosts:
  - "httpbin.example.com"
  gateways:
  - httpbin-gateway
  http:
  - match:
    - uri:
        prefix: /status
    - uri:
        prefix: /headers
    route:
    - destination:
        host: httpbin
        port:
          number: 80
# Apply Gateway and VirtualService
kubectl apply -f gateway.yaml

# Get the Istio ingress gateway external IP
export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway \
  -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

# Test the route
curl -H "Host: httpbin.example.com" http://$INGRESS_HOST/status/200

Exercises

Exercise 1: Install Istio using the minimal profile instead of demo. Compare which components are deployed. Then switch to demo profile and observe the difference with kubectl get pods -n istio-system.
Exercise 2: Deploy two services (e.g., sleep and httpbin) in the mesh. Exec into the sleep pod and curl httpbin. Verify with istioctl proxy-status that both sidecars are synchronized with the control plane.
Exercise 3: Create a Gateway and VirtualService that routes /api/v1/* to one service and /api/v2/* to another. Test with curl using the Host header to confirm path-based routing works.

Key Takeaways & Next Steps

  • Istio's architecture separates the data plane (Envoy sidecars) from the control plane (istiod)
  • Installation with istioctl install --set profile=demo gives you a complete setup for learning
  • Sidecar injection is automatic with namespace labels, or manual with istioctl kube-inject
  • Traffic flows transparently through Envoy via iptables redirection
  • Gateway + VirtualService is the pattern for ingress traffic routing

Next in the Series

In Part 2: VirtualService & Advanced Routing, we'll explore canary deployments with traffic splitting, header-based routing, fault injection for chaos testing, and circuit breaking with DestinationRules.