Istio Deep Dive — Why It Flows That Way
Find What Is Wrong Before You Deploy
Goal
Most Istio configuration does not work even when its syntax is correct. Because it is a structure in which names point to one another, if just one side's name changes, it quietly breaks.
This lab finds such things before deployment, without a cluster.
The difference between the two tools
| What it looks at | What it catches | |
|---|---|---|
istioctl validate |
The syntax of one file | Typos, unknown fields |
istioctl analyze |
References between resources | Missing subsets and gateways, host conflicts |
Kubernetes catches neither. Unknown fields in the CRD schema are quietly dropped, so kubectl apply succeeds and only the traffic does not flow.
How to use them
istioctl validate -f vs.yaml
istioctl analyze --use-kube=false vs.yaml dr.yaml
echo $? # 0 이면 깨끗, 79 면 문제 있음
--use-kube=false means it looks only at files and not at the cluster.
Steps
- A typo →
01-validate.txt - A broken reference →
02-analyze.txt - Fix it so it passes →
vs.yaml,dr.yaml - A host conflict →
04-conflict.txt - A missing gateway →
05-gateway.txt - Sidecar injection →
06-inject.txt - What analyze cannot catch →
07-blind.txt - Wrap-up →
08-notes.md
Notes
In step 7, the correct answer is that no problem shows up. The purpose is to see the limits of static analysis for yourself.
Catch a typo
Create a VirtualService with a wrong field name, catch it with istioctl validate, and leave the result in 01-validate.txt.
Try writing rout: instead of route: under http:. istioctl validate -f x.yaml tells you unknown field "rout". Kubernetes does not catch this — unknown fields in the CRD schema are quietly dropped, so apply succeeds and only the traffic does not flow.
The schema is right but the behavior is wrong
Create only a VirtualService that sends to subset: v1 (without a DestinationRule), have istioctl analyze catch it, and leave the result in 02-analyze.txt.
istioctl analyze --use-kube=false vs.yaml. You get IST0101 Referenced host+subset in destinationrule not found. validate passes but analyze catches it — the former looks at syntax and the latter at reference relationships. This is the number one cause of "I put in the configuration but get a 503" in Istio.
Fix it so it passes
Add a DestinationRule that defines the subset so that istioctl analyze finishes with exit code 0. Name the files vs.yaml and dr.yaml.
The host of the DestinationRule must be the same as the destination.host of the VirtualService, and subsets[].name must be the same as destination.subset. To check: istioctl analyze --use-kube=false vs.yaml dr.yaml; echo $? — it must be 0 (79 if there is a problem).
When two resources grab the same host
Create one more VirtualService that points to the same host to cause a conflict, and leave the result in 04-conflict.txt.
You get IST0109 — "define the same host ... which can lead to undefined behavior". It is not defined which one wins. This happens when a team splits into two and each creates its own VirtualService. The fix is to merge them into one.
When it points to a gateway that does not exist
Create a VirtualService that references a gateway that does not exist, and leave the result in 05-gateway.txt. Two kinds of diagnostics must appear.
gateways: [nope-gw]. You get IST0101 Referenced gateway not found together with IST0132 (the host is not on the gateway). Leave both.
How a sidecar actually comes to exist
Inject a sidecar into one Deployment and leave the container list after injection in 06-inject.txt.
There is no real istiod in this Pod, so you pass the configuration as files. All three must be there — if you give only two, istioctl goes out to the cluster to look for the remaining one.
istioctl kube-inject -f dep.yaml \
--injectConfigFile /opt/istio/inject-config.yaml \
--meshConfigFile /opt/istio/mesh-config.yaml \
--valuesFile /opt/istio/values-config.yaml
An istio-proxy container and an istio-init init container are added. istio-init is the one that modifies iptables so that all traffic passes through the proxy.
What analyze cannot catch
Set a PeerAuthentication to STRICT and the DestinationRule of the same service to tls.mode: DISABLE, run istioctl analyze, and leave in 07-blind.txt the fact that no problem shows up. Also write one line on why that is dangerous.
analyze says it is clean, but in reality the server demands mTLS while the client connects in plain text, so everything fails. It means static analysis is not all-powerful — there are things you cannot know from files alone and have to look at together with the cluster state. That is why in practice you run istioctl analyze attached to the cluster (the --use-kube default).
Summarize three things
At least three lines in 08-notes.md: the difference between validate and analyze, why a same-host conflict is dangerous, and one thing static analysis cannot catch.
The body must contain 참조, 충돌 and mTLS (the Korean words for "reference" and "conflict", plus mTLS).