Skip to content

Instantly share code, notes, and snippets.

@mohashari
Created March 14, 2026 23:31
Show Gist options
  • Select an option

  • Save mohashari/c5571bc2d6f370013f15022fcd460122 to your computer and use it in GitHub Desktop.

Select an option

Save mohashari/c5571bc2d6f370013f15022fcd460122 to your computer and use it in GitHub Desktop.
Service Mesh with Istio: Traffic Control, Security, and Observability
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-v1
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: backend
version: v1
template:
metadata:
labels:
app: backend
version: v1
spec:
containers:
- name: backend
image: your-registry/backend:1.0.0
ports:
- containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-v2
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: backend
version: v2
template:
metadata:
labels:
app: backend
version: v2
spec:
containers:
- name: backend
image: your-registry/backend:2.0.0
ports:
- containerPort: 8080
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: backend
namespace: production
spec:
host: backend
trafficPolicy:
connectionPool:
tcp:
maxConnections: 100
http:
http1MaxPendingRequests: 50
http2MaxRequests: 1000
outlierDetection:
consecutive5xxErrors: 5
interval: 30s
baseEjectionTime: 30s
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: backend
namespace: production
spec:
hosts:
- backend
http:
- route:
- destination:
host: backend
subset: v1
weight: 90
- destination:
host: backend
subset: v2
weight: 10
timeout: 5s
retries:
attempts: 3
perTryTimeout: 2s
retryOn: gateway-error,connect-failure,retriable-4xx
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT
---
# Optionally verify the certificate chain after applying
# Run from a debug pod inside the mesh:
apiVersion: v1
kind: Pod
metadata:
name: curl-debug
namespace: production
annotations:
sidecar.istio.io/inject: "true"
spec:
containers:
- name: curl
image: curlimages/curl:8.6.0
command: ["sleep", "3600"]
# Exec into the debug pod and inspect the TLS handshake
kubectl exec -n production curl-debug -c curl -- \
curl -sv http://backend:8080/health 2>&1 | grep -E "SSL|certificate|issuer"
# Check the effective mTLS configuration for a specific workload
istioctl authn tls-check curl-debug.production backend.production.svc.cluster.local
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: backend-authz
namespace: production
spec:
selector:
matchLabels:
app: backend
action: ALLOW
rules:
- from:
- source:
principals:
- "cluster.local/ns/production/sa/frontend"
to:
- operation:
methods: ["GET"]
paths: ["/api/*"]
- from:
- source:
principals:
- "cluster.local/ns/production/sa/admin-worker"
to:
- operation:
methods: ["GET", "POST", "PUT", "DELETE"]
paths: ["/api/*", "/admin/*"]
package middleware
import (
"net/http"
)
// tracingHeaders are the headers Istio/Envoy uses to correlate distributed traces.
// Your app only needs to forward these — Envoy generates and exports the actual spans.
var tracingHeaders = []string{
"x-request-id",
"x-b3-traceid",
"x-b3-spanid",
"x-b3-parentspanid",
"x-b3-sampled",
"x-b3-flags",
"traceparent", // W3C Trace Context
"tracestate",
}
// PropagateTracing copies upstream trace headers into all outgoing requests.
func PropagateTracing(upstream *http.Request) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
for _, h := range tracingHeaders {
if val := upstream.Header.Get(h); val != "" {
r.Header.Set(h, val)
}
}
next.ServeHTTP(w, r)
})
}
}
# Deploy the sample observability addons (use production-grade installs for real clusters)
kubectl apply -f istio-1.21.0/samples/addons/prometheus.yaml
kubectl apply -f istio-1.21.0/samples/addons/grafana.yaml
kubectl apply -f istio-1.21.0/samples/addons/kiali.yaml
kubectl apply -f istio-1.21.0/samples/addons/jaeger.yaml
# Wait for all addons to become ready
kubectl rollout status deployment/kiali -n istio-system
kubectl rollout status deployment/grafana -n istio-system
# Open the Kiali dashboard in your browser
istioctl dashboard kiali
# Or port-forward manually if istioctl dashboard isn't available
kubectl port-forward -n istio-system svc/kiali 20001:20001
# Download and install Istio 1.21.0
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.21.0 sh -
export PATH="$PWD/istio-1.21.0/bin:$PATH"
# Install using the default profile
istioctl install --set profile=default -y
# Verify control plane components are healthy
istioctl verify-install
# Enable automatic sidecar injection for your workload namespace
kubectl label namespace production istio-injection=enabled
# Confirm the label
kubectl get namespace production --show-labels
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment