The Mesh Install Manifest and the Sidecar Dissected
Goal
You check what actually goes into the cluster when you install a mesh, and become able to explain, in terms of structure, how a Pod with an injected sidecar differs from the original Pod.
Why it matters
A good share of mesh adoption failures start from "not knowing what was installed." It looks as if one line of istioctl install finishes the job, but behind it dozens of CRDs, webhook configurations, ConfigMaps, and control plane workloads all go in at once. That is why in practice you look at it first with your own eyes using manifest generate before installing and commit it to a repository. Only then can you see a diff at upgrade time. Injection is the same. Injection is the webhook modifying the spec when a Pod is created, so if you attach only the label and do not trigger a rollout, nothing happens. If you confirm this fact by hand, you can answer the question "I attached the label but it is not in the mesh" in a few seconds.
In this lab environment, a real Envoy does not carry traffic. So grading looks at manifests and static analysis. In exchange, the training of dissecting the injected manifest carries over as it is to real environments.
Steps
- Save the output of
istioctl versionto/root/istio/out/version.txt(it must contain a version number). Then save the pre-install check (istioctl x precheck), including standard error, to/root/istio/out/precheck.txt. - Save the result of
istioctl manifest generateto/root/istio/manifest.yaml. It must containCustomResourceDefinitionandistiod, and there must be at least 10 lines starting withkind:. Then save a count by kind to/root/istio/out/manifest-kinds.txt(CustomResourceDefinitionmust be visible in the tally). - Apply the manifest to the cluster to register the mesh API types. All five of
virtualservices.networking.istio.io,destinationrules.networking.istio.io,gateways.networking.istio.io,peerauthentications.security.istio.io, andauthorizationpolicies.security.istio.iomust exist, and there must be at least 5 CRDs in theistio.iogroup. - Create the namespace
mesh-laband attach the labelistio-injection=enabled. Create the namespacelegacytoo, but do not attach the injection label. And in/root/istio/out/injection-note.txt, write the content "even if you attach the label, existing Pods stay as they are, and the sidecar gets in only when they are recreated by a rollout." - Run
istioctl kube-injecton/opt/lab/fixtures/istio/inject-target.yamland save the result to/root/istio/injected.yaml. The Deployment's containers must include bothpaymentsandistio-proxy, there must be an init container (istio-initoristio-validation), and the Pod template must have thesidecar.istio.io/statusannotation. - Save the result of
istioctl analyze -n mesh-labto/root/istio/out/analyze.txt(Error [must not remain). And in/root/istio/out/analyze-note.txt, write in two lines that analyze inspects configuration statically, before and after applying it, not traffic. - Create
/root/istio/out/sidecar.json. The keys are five:containers(an array of container names, includingistio-proxy),init_containers(an array of at least 1),container_count(the number of containers after injection),proxy_image(it must be exactly the same string as the image of theistio-proxycontainer ininjected.yaml), andinterception(one sentence on how traffic is intercepted — it must contain the wordiptables). - Create
/root/istio/out/mesh-readiness.json. It has three keys:istio_crds(the actual number ofistio.iogroup CRDs in the cluster),injection_namespaces(an array of namespaces that carry the injection label —mesh-labmust be in it andlegacymust not), andanalyze_errors(0). Also save the result ofistioctl validate -f /root/istio/injected.yamlto/root/istio/out/validate.txt.
Notes
- Step 3: with
yq 'select(.kind == "CustomResourceDefinition")' /root/istio/manifest.yaml | kubectl apply -f -you can apply only the CRDs first. However, it is more convenient to apply the whole manifest — because the injection configuration that step 5 uses is in two ConfigMaps inistio-system(istio-sidecar-injectorandistio). Runkubectl create ns istio-systemfirst. - Step 5: there is no real istiod Pod in this environment. So if you just run
kube-inject, it tries to port-forward to istiod and fails. From the ConfigMaps you applied in step 3, extract the injection template (.data.config), the mesh configuration (.data.mesh), and the values (.data.values) into separate files and pass them with--injectConfigFile,--meshConfigFile, and--valuesFile. You must give all three — if you give only two, it goes back to the cluster looking for the remaining one. (The example inistioctl kube-inject --helpshows exactly this method.) - For the CRD count in step 8, do not count by hand; extract it with
kubectl get crd -o json | jq '[.items[] | select(.spec.group | test("istio.io"))] | length'. - The output of
istioctl validatemay be short or empty when it passes. If it is empty, append one result line (such as검증 통과, the Korean phrase for "validation passed") so that the file is not empty. - Common mistake 1: writing step 7's
proxy_imagefrom memory. Always extract it frominjected.yamland put it in. - Common mistake 2: not creating the
legacynamespace at all in step 4. Only with an uninjected control group is the meaning of the label proven.
istioctl version and the pre-install check
Save the output of istioctl version to /root/istio/out/version.txt (it must contain a version number). Then save the pre-install check (istioctl x precheck), including standard error, to /root/istio/out/precheck.txt.
istioctl version prints the client version first. The pre-install check is under an experimental subcommand, and error messages are results too, so save standard error together.
Generate the installation manifest and count its contents
Save the result of istioctl manifest generate to /root/istio/manifest.yaml. It must contain CustomResourceDefinition and istiod, and there must be at least 10 lines starting with kind:. Then save a count by kind to /root/istio/out/manifest-kinds.txt (CustomResourceDefinition must be visible in the tally).
istioctl manifest generate creates nothing in the cluster and only spits out YAML. To see what is there and how many, just count the lines that start with kind:.
Register the mesh API types in the cluster
Apply the manifest to the cluster to register the mesh API types. All five of virtualservices.networking.istio.io, destinationrules.networking.istio.io, gateways.networking.istio.io, peerauthentications.security.istio.io, and authorizationpolicies.security.istio.io must exist, and there must be at least 5 CRDs in the istio.io group.
A type like VirtualService is recognized by kubectl only once it is registered as a CRD. Apply the whole manifest, or pick out and apply only the CustomResourceDefinitions. The Established condition is attached by the API server.
Create the injection target namespace and a control group
Create the namespace mesh-lab and attach the label istio-injection=enabled. Create the namespace legacy too, but do not attach the injection label. And in /root/istio/out/injection-note.txt, write the content "even if you attach the label, existing Pods stay as they are, and the sidecar gets in only when they are recreated by a rollout."
The label name and value must be exact to match the webhook's namespaceSelector. Do not attach the label to the control group. And write in the note when the label takes effect.
Inject a sidecar into the fixture workload
Run istioctl kube-inject on /opt/lab/fixtures/istio/inject-target.yaml and save the result to /root/istio/injected.yaml. The Deployment's containers must include both payments and istio-proxy, there must be an init container (istio-init or istio-validation), and the Pod template must have the sidecar.istio.io/status annotation.
istioctl kube-inject takes a file as input and prints the injected manifest. The original container must not disappear, and it is normal for one init container to be added.
Analyze the configuration statically
Save the result of istioctl analyze -n mesh-lab to /root/istio/out/analyze.txt (Error [ must not remain). And in /root/istio/out/analyze-note.txt, write in two lines that analyze inspects configuration statically, before and after applying it, not traffic.
analyze reads the configuration resources in the cluster and finds places where they are inconsistent with each other. The key point is that it does not send traffic, and no Error may remain in the result.
Dissect the injection result as JSON
Create /root/istio/out/sidecar.json. The keys are five: containers (an array of container names, including istio-proxy), init_containers (an array of at least 1), container_count (the number of containers after injection), proxy_image (it must be exactly the same string as the image of the istio-proxy container in injected.yaml), and interception (one sentence on how traffic is intercepted — it must contain the word iptables).
Do not count by eye; extract the values from the injected file and write them. If an image string differs by even one character, it differs from the real value.
Build a mesh readiness summary
Create /root/istio/out/mesh-readiness.json. It has three keys: istio_crds (the actual number of istio.io group CRDs in the cluster), injection_namespaces (an array of namespaces that carry the injection label — mesh-lab must be in it and legacy must not), and analyze_errors (0). Also save the result of istioctl validate -f /root/istio/injected.yaml to /root/istio/out/validate.txt.
Gather what you made in the earlier steps into one file. Fill in the numbers by recounting from the cluster, and a namespace that is not injected must not be in the list.