# Cheat sheet — Istio & the Service Mesh

Dense revision sheet. `istioctl` + interview one-liners at the bottom. (Istio **1.18.5** here.)

---

## The architecture in one picture
```
        CONTROL PLANE                         DATA PLANE
   ┌──────────────────┐        ┌────────────────────────────────┐
   │      istiod       │  push  │  Pod: [ app ]──[ Envoy sidecar ]│
   │  discovery + CA + │───────►│  Pod: [ app ]──[ Envoy sidecar ]│
   │  config → Envoy   │ config │       all traffic via Envoy     │
   └──────────────────┘        └────────────────────────────────┘
```
- **Data plane** = Envoy sidecars (carry traffic, do routing/mTLS/retries/metrics).
- **Control plane** = **istiod** (service discovery, turns CRDs → Envoy config, is the CA).
- You add the mesh **without changing app code**.

## The three traffic resources
| Resource | Governs | Analogy |
|---|---|---|
| **Gateway** | the **edge** — which hosts/ports/TLS enter the mesh | the front door |
| **VirtualService** | **routing** — match a request → send it to a destination | the switchboard |
| **DestinationRule** | policy **after** routing — LB, subsets, pools, outlier | the receiving desk |
Request path: **client → ingress Gateway → VirtualService → (DestinationRule) → Pod**.

## VirtualService (routing)
```yaml
http:
- match: [{ uri: { prefix: /pkg.v1.Service } }]
  route: [{ destination: { host: bob, port: { number: 5050 } } }]
  # optional: rewrite, timeout, retries, fault, mirror, weight, corsPolicy
```
- Route by URI/prefix/exact, header, method → a `destination.host` (+ subset/weight).
- **Weighted routes** = canary. **fault.abort** = inject an error (repo blocks Internal RPCs).

## DestinationRule (post-routing policy)
```yaml
host: bob
trafficPolicy:
  loadBalancer: { simple: ROUND_ROBIN }   # or consistentHash for affinity
  connectionPool: {...}                    # limits
  outlierDetection: {...}                  # eject unhealthy pods = circuit breaking
subsets: [{ name: v2, labels: { version: v2 } }]   # what VS routes target
```

## Sidecar injection
- **Automatic**, revision-based: label the namespace `istio.io/rev=<tag>` (repo: `stable`) —
  a mutating webhook adds Envoy to new Pods. (Classic form: `istio-injection=enabled`.)
- Opt-out a Pod: annotation `sidecar.istio.io/inject: "false"`.

## Security (the concepts)
- **mTLS** — sidecars encrypt + mutually authenticate; set by **PeerAuthentication**
  (STRICT / PERMISSIVE / DISABLE). Identity = **SPIFFE** `spiffe://<td>/ns/<ns>/sa/<sa>` from
  the Pod's ServiceAccount; **istiod is the CA**.
- **AuthorizationPolicy** — who (identity) may call what (path/method). mTLS proves *who*; authz
  decides *allowed*.
- **RequestAuthentication** — validate end-user JWTs (origin auth).

## Observability
- Every Envoy emits standard metrics: **`istio_requests_total`** (counter),
  `istio_request_duration_*`, sizes → Prometheus. Covers most golden signals, no app code.
- **Kiali** = mesh graph + config health; **Jaeger** = traces (Course 6).

## EnvoyFilter — the escape hatch
Patch raw Envoy config when the high-level CRDs can't (headers, Lua, rate-limit, custom filters).
Powerful but **version-fragile** — use sparingly.

---

## This repo (anchors) — *reframed by the survey*
| Thing | Where / note |
|---|---|
| VS/DR/CORS factory | `libs/util/templates/_hosts.tpl` (macros, not a VS chart) |
| VirtualService (api) | `_hosts.tpl:96` → gateway `istio-system/<env>-<vendor>-gateway` |
| Route tables | `backend/bob/values.yaml` (`apiHttp:41`, `webHttp:168`) — **no timeout/retries set** |
| Internal-RPC edge block | `bob/values.yaml:42-46` (`fault.abort` 403 @100%) |
| DestinationRule | `_hosts.tpl:68`; tom's `destinationrule.yaml` |
| tom session affinity | `tom/values.yaml:67-70` (`consistentHash` on `x-chat-userhash`) |
| Ingress Gateway | `platforms/gateway/templates/gateway.yaml` (**SIMPLE** TLS at edge) |
| EnvoyFilter (Lua) | `_app_envoyfilter_salesforce.tpl` (Salesforce token swap) + hasura |
| Injection | revision-based `istio.io/rev`; tuning `_workload_metadata.tpl:16-17` |
| **mTLS** | **OFF** — `istiod-values.yaml:13` `enableAutoMtls: false`, no PeerAuthentication |
| **AuthorizationPolicy** | **none in backend** — auth is in-app; only platform/monitoring uses it |
| istio_requests_total → KEDA | `_keda.tpl:146-154` |
| gandalf | a **test harness**, `inject: "false"` — NOT the ingress gateway |
| Istio version | 1.18.5 |

## istioctl survival kit
```
istioctl analyze -n <ns>                  # validate mesh config
istioctl proxy-status                     # are sidecars in sync with istiod?
istioctl proxy-config routes <pod> -n <ns>   # the live Envoy routes (from your VS)
istioctl proxy-config cluster/listener <pod>  # what Envoy actually sees
istioctl x describe pod <pod> -n <ns>     # is it in the mesh? which policies apply?
```

## Interview one-liners
- **What is a service mesh?** *"An infra layer that handles service-to-service comms — routing,
  security, telemetry — via Envoy sidecars, without changing app code. Control plane = istiod,
  data plane = the sidecars."*
- **Gateway vs VirtualService vs DestinationRule?** *"Gateway = the edge door (hosts/TLS);
  VirtualService = routing rules; DestinationRule = post-routing policy + subsets."*
- **How does injection work?** *"A namespace label (`istio.io/rev` / `istio-injection`) makes a
  webhook add the Envoy sidecar to new Pods."*
- **How does Istio do mTLS?** *"Sidecars mutually authenticate with istiod-issued SPIFFE certs;
  PeerAuthentication sets STRICT/PERMISSIVE. (Note: this repo has it off — routing + edge TLS +
  telemetry mesh, not zero-trust.)"*
- **Where does `istio_requests_total` come from?** *"Every Envoy sidecar emits it; Prometheus
  scrapes it. Here it also drives KEDA autoscaling."*
- **What's an EnvoyFilter for?** *"The low-level escape hatch to patch Envoy directly — we use
  Lua filters for Salesforce token exchange. Version-fragile, use sparingly."*
