§11 istio
Source: examples/11-istio/ · ← Back to examples index
The longest single demo in the tutorial. Installs Istio on a
dedicated minikube profile, sidecar-injects our existing
nginx-custom:v1 Deployment, deploys the Bookinfo sample
app, exercises traffic-routing rules (v1 pinning, 50/50 split)
and verifies that requests actually flow through the configured
versions.
Pre-requisites
This demo assumes you’ve already run:
./scripts/setup-istio.sh
which downloads Istio 1.31.1 to ~/.local/share/istio-1.31.1/,
installs istioctl to ~/.local/bin/, and creates the
~/.local/share/istio-current symlink the demo references for
the Bookinfo manifests.
The demo also expects a minikube profile called istio —
separate from the minikube profile §6-§9 use. If it
doesn’t exist, the demo creates it. The recommended sizing:
minikube start -p istio --driver=docker --container-runtime=containerd \
--kubernetes-version=v1.36.5 --cpus=4 --memory=6144 \
--ports=127.0.0.1:8080:30880,127.0.0.1:20001:30201,127.0.0.1:3000:30300,127.0.0.1:19090:30990,127.0.0.1:16686:31686
These match the §3 settings (Docker Engine, containerd), just on a
bigger profile. The demo creates it with this command through
ensure_profile; the --ports map is ISTIO_PORTS in
scripts/lib/_helpers.sh. Published ports are fixed at profile
creation: if the profile already exists without them, the demo
prints the delete-and-recreate command and stops.
What it tests
Eleven §11 claims:
- The
istiominikube profile starts with sufficient resources for Istio + Bookinfo and publishes its five NodePorts on127.0.0.1 istioctl install --set profile=demoinstalls the control plane + ingressgateway successfully- The
defaultnamespace can be labeled for sidecar injection - A Deployment with the
sidecar.istio.io/inject: "true"annotation produces Pods withREADY 2/2(app + Envoy sidecar) - Bookinfo’s 4 microservices deploy cleanly with sidecars
- The Bookinfo Gateway + VirtualService make productpage
reachable through the ingress gateway at
http://127.0.0.1:8080/productpage(companion Serviceingressgateway-host, nodePort 30880) istioctl analyzereturns clean (no config errors)virtual-service-all-v1.yamlpins 100% of reviews traffic to v1 (the demo confirms by counting v2/v3 indicators in 10 responses — should be 0)virtual-service-reviews-50-v3.yamlproduces roughly 50/50 between v1 and v3 (sampled across 20 requests)- Per-profile minikube image cache is independent from the
minikubeprofile (nginx-custom:v1 must be rebuilt on the istio profile) - Every call is pinned to the
istiocontext, so your current kubectl context is never changed
Running
./demo.sh
Expected duration:
- First run (image build + Istio install + Bookinfo first-pull): 8-12 minutes. Most of it is Bookinfo Pods pulling images (~150 MB total across 4 services × 3 reviews versions)
- Subsequent runs (everything cached): 4-6 minutes
If nginx-custom:v1 isn’t cached on the istio profile, add 2-4
minutes for the §6 Containerfile to build (docker build, then
minikube image load).
What you should see
==> step lines for each phase. Notable checkpoints:
==> deploying nginx-with-sidecar
✓ nginx-istio Pod has nginx + istio-proxy (mesh injection working)
==> applying Bookinfo Gateway + VirtualService
✓ Gateway + VirtualService applied; istioctl analyze clean
==> waiting for productpage on http://127.0.0.1:8080/ (nodePort 30880)
✓ ingress gateway reachable at http://127.0.0.1:8080/
==> curling productpage; expecting the Bookinfo Sample heading
✓ Bookinfo productpage served via ingress + mesh
==> curling productpage 10 times; counting v2/v3 indicators (should be 0)
0 of 10 responses contained 'glyphicon-star' (v2/v3 ratings)
✓ 100% of reviews traffic routed to v1 (no ratings)
==> curling productpage 20 times; expecting roughly 8-12 v3 hits
10 of 20 responses contained 'glyphicon-star' (v3 indicator)
✓ traffic split: 10/20 hit v3
The exact split count varies (it’s a random sample of 20 requests). The demo treats 4-16 of 20 as a soft pass — anything more skewed than that prints a warning but doesn’t fail, since routing rule propagation can lag a few seconds.
Cluster scope
Uses the istio minikube profile (NOT the default profile
that §6-§9 use). Every kubectl, istioctl and minikube call
in the demo targets the istio context or profile explicitly, so
your current kubectl context stays as it was and your minikube
profile is undisturbed; §6-§9 demos continue to work normally
after §11 runs.
Host access
Services this demo needs from the host are NodePorts published at
profile creation, reached on 127.0.0.1. The upstream Services
(istio-ingressgateway, and the Kiali, Grafana, Prometheus and
Jaeger addons) are never patched, since istioctl install or an
addon re-apply would revert the change. Instead
host-access/ holds one companion NodePort Service per
destination, owned by this repo and selecting the same Pods. It
sits outside manifests/ so the demo’s cleanup of the workload
does not remove it.
| Companion (istio-system) | Target | nodePort | Host URL |
|---|---|---|---|
ingressgateway-host |
80 -> 8080 | 30880 | http://127.0.0.1:8080/productpage |
kiali-host |
20001 | 30201 | http://127.0.0.1:20001/kiali |
grafana-host |
3000 | 30300 | http://127.0.0.1:3000/ |
prometheus-host |
19090 | 30990 | http://127.0.0.1:19090/ |
tracing-host |
80 -> 16686 | 31686 | http://127.0.0.1:16686/jaeger/ |
The demo applies ingressgateway-host after the Istio install.
The addon companions are applied together with the addons (see
“Going further”). Selectors were read from the Istio 1.31.1
release’s addon manifests; confirm any of them on a live cluster
with kubectl --context istio get svc -n istio-system <svc> -o
jsonpath='{.spec.selector}'.
Cleanup
The demo’s trap cleanup EXIT handler:
- Deletes Bookinfo’s networking rules
- Deletes Bookinfo’s Deployments and Services
- Deletes our nginx-with-sidecar
Istio itself stays installed on the istio profile, along with
the ingressgateway-host companion Service. The demo
doesn’t istioctl uninstall on every exit — that would mean
every re-run waits 30-60 seconds for the control plane to come
back up. To fully remove Istio:
kubectl --context istio delete -f host-access/ --ignore-not-found
istioctl --context istio uninstall --purge -y
kubectl --context istio delete namespace istio-system
kubectl --context istio label namespace default istio-injection-
# or all of it, including the addons, with:
./cleanup.sh --remove-istio
To stop or delete the istio profile entirely:
minikube stop -p istio # stop, keep state
minikube delete -p istio # delete, free disk
When this fails
-
scripts/setup-istio.shnot run — the demo will tell you if istioctl isn’t in PATH or if the Bookinfo samples aren’t present at~/.local/share/istio-current/samples/bookinfo/. Run setup-istio.sh and try again -
istio profile out of resources — Istio + Bookinfo + sidecars easily peak at 4-5 GB. If the profile was created with less than
--memory=6g, Pods will go OOMKilled or stay Pending. Fix: delete and recreate the profileminikube delete -p istio minikube start -p istio --driver=docker \ --container-runtime=containerd \ --kubernetes-version=v1.36.5 --cpus=4 --memory=6144 \ --ports=127.0.0.1:8080:30880,127.0.0.1:20001:30201,127.0.0.1:3000:30300,127.0.0.1:19090:30990,127.0.0.1:16686:31686 -
Bookinfo Pods stuck pulling images — the
docker.io/istio/*images are larger than our nginx-custom image. Checkkubectl describe podfor image-pull errors -
istioctl analyzereports errors — usually a Gateway or VirtualService misconfiguration. The demo’s failure dump includes the full analyze output -
v3-hit count is way off — could mean the routing rule didn’t propagate to the sidecars (rare; usually resolves within 10s of apply), OR the Bookinfo manifest filename moved in a newer Istio release. The demo falls back to
virtual-service-reviews-jason-v2-v3.yamlif the canonical 50/50 file is missing -
Port 8080, 20001, 3000, 19090 or 16686 already in use on the host —
ensure_profilelists the conflicting host port and stops before creating the profile. Free the port (a stray local server is the usual cause) and re-run -
Demo says the profile does not publish a nodePort — the
istioprofile was created without--ports. Published ports cannot be added to an existing profile; run the printedminikube delete/minikube startcommand -
curl 127.0.0.1:8080fails but the gateway is Ready — the companion selector matched no Pod. The demo prints the Service’s endpoints and the gateway Service’s real selector; fixhost-access/ingressgateway-host.yamlto match -
READY 1/2instead of2/2on Bookinfo Pods — sidecar injection didn’t happen. Verify the namespace label:kubectl get namespace default -L istio-injection
For any of these, paste the failing output back.
Going further on your own
The demo deliberately stops short of:
- Fault injection — try
kubectl --context istio apply -f ~/.local/share/istio-current/samples/bookinfo/networking/virtual-service-ratings-test-delay.yamlfor a 7-second delay on ratings - Observability addons —
kubectl --context istio apply -f ~/.local/share/istio-current/samples/addons/installs Kiali, Prometheus, Grafana, Jaeger (5+ min), thenkubectl --context istio apply -f host-access/adds their NodePort companions. Kiali is then athttp://127.0.0.1:20001/kiali - Production profiles — the demo profile is for tutorials; real deployments use a slimmer profile or a custom IstioOperator
All three are covered briefly in the §11 prose.