Install and configure Istio service mesh for Kubernetes with security policies and observability

Intermediate 45 min Apr 01, 2026
Ubuntu 24.04 Ubuntu 22.04 Debian 12 AlmaLinux 9 Rocky Linux 9 Fedora 41

Learn to deploy Istio service mesh on Kubernetes with mTLS security, traffic management, and comprehensive observability using Kiali and Jaeger for production microservices.

Prerequisites

  • Kubernetes cluster with kubectl access
  • At least 4GB RAM and 2 CPUs available
  • Administrative privileges on the cluster
  • Internet connectivity for downloading Istio components

What this solves

Istio service mesh provides traffic management, security, and observability for microservices without changing application code. It uses Envoy sidecars to handle service-to-service communication, automatic mTLS encryption, and distributed tracing. This tutorial shows you how to install Istio on an existing Kubernetes cluster and configure it for production use with security policies and monitoring tools.

Prerequisites

You need a running Kubernetes cluster with at least 4GB RAM and 2 CPUs available. The cluster should have kubectl configured and administrative access. We'll assume you already have a properly configured Kubernetes cluster running.

Step-by-step installation

Download and install Istio CLI

Start by downloading the latest Istio release and installing the istioctl command-line tool.

curl -L https://istio.io/downloadIstio | sh -
cd istio-*
sudo cp bin/istioctl /usr/local/bin/
istioctl version

Install Istio control plane

Install Istio with the demo profile which includes all core components plus observability tools.

istioctl install --set values.defaultRevision=default -y
kubectl get pods -n istio-system

Enable automatic sidecar injection

Label namespaces to automatically inject Envoy sidecars into new pods deployed in those namespaces.

kubectl label namespace default istio-injection=enabled
kubectl get namespace -L istio-injection

Install observability addons

Deploy Kiali, Jaeger, and Prometheus for service mesh observability and monitoring.

kubectl apply -f samples/addons/kiali.yaml
kubectl apply -f samples/addons/jaeger.yaml
kubectl apply -f samples/addons/prometheus.yaml
kubectl apply -f samples/addons/grafana.yaml

Wait for addon deployment

Verify that all observability components are running before proceeding.

kubectl rollout status deployment/kiali -n istio-system
kubectl rollout status deployment/jaeger -n istio-system
kubectl get pods -n istio-system

Deploy sample application

Deploy Bookinfo sample application

Install the Bookinfo application to demonstrate Istio features and test the service mesh functionality.

kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl get services
kubectl get pods

Create Istio Gateway

Configure an Istio Gateway to expose the application to external traffic through the ingress gateway.

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080

Apply gateway configuration

Deploy the gateway and virtual service to make the application accessible.

kubectl apply -f /tmp/bookinfo-gateway.yaml
kubectl get gateway
kubectl get virtualservice

Configure traffic management

Create destination rules

Define destination rules to specify traffic policies and service subsets for load balancing.

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: productpage
spec:
  host: productpage
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3

Apply destination rules

Deploy the destination rules to configure traffic distribution and load balancing policies.

kubectl apply -f /tmp/destination-rules.yaml
kubectl get destinationrules

Configure traffic splitting

Create a virtual service to split traffic between different versions of the reviews service.

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50
    - destination:
        host: reviews
        subset: v3
      weight: 50

Apply traffic splitting

Deploy the virtual service to implement canary deployment and traffic routing rules.

kubectl apply -f /tmp/traffic-split.yaml
kubectl get virtualservices

Implement security policies

Enable strict mTLS

Configure a PeerAuthentication policy to enforce mutual TLS for all services in the default namespace.

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

Apply mTLS policy

Deploy the peer authentication policy to enable automatic mutual TLS encryption between services.

kubectl apply -f /tmp/mtls-policy.yaml
kubectl get peerauthentication

Create authorization policy

Define authorization rules to control which services can communicate with each other.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: productpage-viewer
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"]
  - to:
    - operation:
        methods: ["GET"]
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: reviews-viewer
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
  - to:
    - operation:
        methods: ["GET"]

Apply authorization policies

Deploy the authorization policies to implement zero-trust security between microservices.

kubectl apply -f /tmp/authz-policy.yaml
kubectl get authorizationpolicies

Set up observability

Access Kiali dashboard

Set up port forwarding to access the Kiali service mesh dashboard for traffic visualization.

kubectl port-forward svc/kiali -n istio-system 20001:20001 --address=0.0.0.0 &
echo "Kiali available at http://localhost:20001"

Access Jaeger tracing

Set up port forwarding to access Jaeger for distributed tracing and request flow analysis.

kubectl port-forward svc/jaeger -n istio-system 16686:16686 --address=0.0.0.0 &
echo "Jaeger available at http://localhost:16686"

Generate sample traffic

Create traffic to populate the observability dashboards with meaningful data.

export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

for i in $(seq 1 100); do
  curl -s "http://${GATEWAY_URL}/productpage" > /dev/null
  sleep 0.1
done

Configure production settings

Set resource limits

Configure resource requests and limits for Istio components to ensure stable operation.

apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
  name: production-config
spec:
  values:
    pilot:
      resources:
        requests:
          cpu: 100m
          memory: 128Mi
        limits:
          cpu: 500m
          memory: 512Mi
    global:
      proxy:
        resources:
          requests:
            cpu: 10m
            memory: 64Mi
          limits:
            cpu: 100m
            memory: 128Mi
  components:
    ingressGateways:
    - name: istio-ingressgateway
      k8s:
        resources:
          requests:
            cpu: 100m
            memory: 128Mi
          limits:
            cpu: 2000m
            memory: 1024Mi

Apply production configuration

Update the Istio installation with production-ready resource configurations.

istioctl install -f /tmp/istio-production.yaml -y
kubectl get pods -n istio-system

Enable telemetry v2

Configure enhanced telemetry collection for better observability and monitoring metrics.

apiVersion: telemetry.istio.io/v1alpha1
kind: Telemetry
metadata:
  name: default
  namespace: istio-system
spec:
  metrics:
  - providers:
    - name: prometheus
  - overrides:
    - match:
        metric: ALL_METRICS
      tagOverrides:
        destination_service_name:
          value: "%{destination_service_name | 'unknown'}"
        source_app:
          value: "%{source_app | 'unknown'}"
  accessLogging:
  - providers:
    - name: otel

Apply telemetry configuration

Deploy the telemetry configuration to enhance metrics collection and logging.

kubectl apply -f /tmp/telemetry-config.yaml
kubectl get telemetry -n istio-system

Verify your setup

istioctl proxy-status
kubectl get pods -n istio-system
istioctl analyze
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o ".*"
istioctl proxy-config cluster $(kubectl get pod -l app=productpage -o jsonpath='{.items[0].metadata.name}') --fqdn productpage.default.svc.cluster.local
Note: The istioctl analyze command checks for potential issues in your Istio configuration and provides recommendations for fixes.

Common issues

SymptomCauseFix
Sidecar not injectedNamespace not labeledkubectl label namespace default istio-injection=enabled
Service unreachableMissing virtual serviceCreate VirtualService for the service
mTLS connection failureMixed TLS modesEnsure consistent PeerAuthentication policies
High memory usageDefault proxy resourcesSet appropriate resource limits in IstioOperator
Gateway not workingPort mismatchVerify Gateway port matches service port
Kiali shows no dataNo traffic generatedGenerate traffic with curl or load testing tools
Authorization deniedStrict authorization policyCheck AuthorizationPolicy rules and service accounts
Warning: Enabling strict mTLS mode will break communication with services outside the mesh. Plan your migration carefully and consider using PERMISSIVE mode during transition periods.

Next steps

Automated install script

Run this to automate the entire setup

#istio #service-mesh #kubernetes-networking #mtls #microservices-security

Need help?

Don't want to manage this yourself?

We handle infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.

Talk to an engineer