istio/istio
Mesh config
Active contributors: hzxuzhonghu, howardjohn, ramaraochavali, costinm
Purpose
MeshConfig is the single mesh-wide configuration document for an Istio install. It owns settings that don't fit cleanly on any single CR: trust domain, default access log format, default tracing provider, outbound traffic policy, retry budgets, default ingress controller, etc. The companion ProxyConfig (per-pod overrides) and the istio ConfigMap (the on-disk representation) layer on top.
This page covers how those three things plus environment variables come together inside istiod and pilot-agent.
Sources of mesh-wide config
graph TD
cm[istio ConfigMap<br/>data: mesh + meshNetworks] --> watcher[meshwatcher.Watcher]
file[--meshConfig file flag] --> watcher
defaults[mesh.DefaultMeshConfig] --> watcher
iop[IstioOperator.meshConfig] -->|render time| cm
watcher --> mesh[*meshconfig.MeshConfig]
mesh --> push[PushContext.Mesh]
mesh --> bootstrap[Bootstrap rendering]
mesh --> agent[pilot-agent local config]
pcOverride[ProxyConfig CR] -->|merged per proxy| push
pcAnnotation[proxy.istio.io/config annotation] -->|merged per proxy| pushDirectory layout
pkg/config/mesh/
├── mesh.go # ApplyMeshConfigDefaults, ParseMeshConfig
├── watchers.go # The Watcher interface
├── meshwatcher/ # File-based watcher
└── kubemesh/ # ConfigMap-based watcher
pilot/pkg/features/
└── pilot.go # Env-var-gated feature flags (`PILOT_*`, `ISTIOD_*`)
pkg/features/ # Cross-component feature flags
operator/pkg/values/ # Chart-time merge of meshConfig from IstioOperator + profilesKey abstractions
| Symbol | File | Role |
|---|---|---|
meshconfig.MeshConfig |
istio/api/mesh/v1alpha1 (proto) |
The schema |
mesh.Watcher |
pkg/config/mesh/watchers.go |
Interface for live mesh-config delivery |
meshwatcher.NewFileWatcher |
pkg/config/mesh/meshwatcher/ |
File-driven watcher (used in dev/file mode) |
kubemesh.NewConfigMapWatcher |
pkg/config/mesh/kubemesh/ |
ConfigMap-driven watcher (production) |
model.Environment.MeshNetworks |
pilot/pkg/model/network.go |
The MeshNetworks doc |
model.NodeMetadata.ProxyConfig |
pilot/pkg/model/context.go |
Per-proxy resolved ProxyConfig |
env.Var[T] |
pkg/env/var.go |
Typed env-var registration |
Three layers of overrides
mesh-wide (MeshConfig)
↓ merged with (only the meshConfig.defaultConfig field)
default ProxyConfig (the .defaultConfig sub-message)
↓ merged with
per-namespace / per-revision ProxyConfig CRs
↓ merged with
per-pod proxy.istio.io/config annotationResolution happens in pilot/pkg/model/context.go's Proxy.SetWorkloadLabels and friends. The result is the effective ProxyConfig for each proxy. The istioctl experimental describe command shows the merged result for a given pod.
ConfigMap layout
The default istio ConfigMap (rendered by the istio-discovery chart) has two keys:
data:
mesh: |
accessLogFile: ""
defaultConfig:
drainDuration: 45s
meshId: cluster.local
proxyMetadata: {}
tracing:
zipkin:
address: zipkin.istio-system:9411
enableTracing: true
rootNamespace: istio-system
trustDomain: cluster.local
# ...many more fields
meshNetworks: |
networks: {}The watcher (pkg/config/mesh/kubemesh/) registers a callback per istiod subsystem so changes propagate without restarts. Per-subsystem reactions vary:
- xDS sees
MeshConfigviaPushContext.Mesh. A change triggers a full push withReason: MeshUpdate. - The CA watches for
MeshConfig.trustDomainAliaseschanges. - Pilot-agent reads
MeshConfigonce at startup (the version mounted into its pod) plus the per-podProxyConfigoverrides. Live reload is limited.
Environment variables
Many fine-grained behaviors are gated by env vars rather than MeshConfig to allow per-pod overrides via injection. The registry is in pilot/pkg/features/pilot.go (and pkg/features/ for cross-component flags). Each entry uses env.Register:
var EnableLDSCacheRequestForRoutes = env.Register(
"PILOT_ENABLE_LDS_CACHE_REQUEST_FOR_ROUTES",
true,
"If enabled, ...",
).Get()Naming:
PILOT_*— istiod-only knobs.ISTIOD_*— same scope; older convention.PROXY_*— pilot-agent / Envoy bootstrap.XDS_*— xDS-specific.UNSAFE_*— explicitly unsafe / experimental.BOOTSTRAP_*— bootstrap rendering.EXTERNAL_CA,CA_PROVIDER,TRUST_DOMAIN, … — cross-cutting.
CI's envvarlinter (in tools/envvarlinter/) enforces that every flag has a description and a default. The full registry of registered vars is dumped via pilot-discovery discovery --help — search for "Environment variables" in the output, or grep env.Register in the tree.
ProxyConfig CR
The ProxyConfig CR (introduced in 1.13) lets users override defaultConfig per namespace / revision / labels. A per-pod CR scopes tighter than namespace-wide; the most-specific match wins.
The merge happens at injection time (pkg/kube/inject/) and again at xDS time (pilot/pkg/model/context.go). At injection, the result drives bootstrap; at xDS, it drives runtime decisions like proxy concurrency, tracing sampling, and proxyMetadata env vars that downstream code may read.
Mesh networks
MeshNetworks is a parallel document for multi-network topology:
networks:
network1:
endpoints:
- fromRegistry: cluster1
gateways:
- address: 1.2.3.4
port: 15443It tells Istio where the cross-network gateways are so traffic crossing networks can be tunneled through them. The watcher is the same kubemesh / file pair as MeshConfig.
Validation
Mesh config is validated at three points:
- Schema at chart render time (operator API validation).
- Webhook when the
IstioOperatoris applied. - Runtime at istiod startup (
pkg/config/validation/). A bad mesh config fails istiod fast rather than producing surprise xDS output.
Integration points
- Reads from: ConfigMap watch via the kube client; or a file watch (
--meshConfig=...); or compiled defaults if neither is configured. - Pushes to: every subsystem that has registered a callback. The xDS server tags pushes triggered by mesh-config changes with
Reason: MeshUpdate. - Per-pod: bootstrap rendering at injection time; xDS push computation at run time.
Entry points for modification
- New mesh-wide field → add to the
MeshConfigproto inistio/api, bump the dep, plumb through the watcher. The operatorIstioOperatorproto picks it up automatically. - New runtime knob that doesn't belong in
MeshConfig(e.g. an experimental optimization) → register inpilot/pkg/features/pilot.gowithenv.Register. - New
ProxyConfigfield → same proto change, then plumb throughpkg/kube/inject/(for bootstrap) andpilot/pkg/model/context.go(for runtime). - New mesh-config source → implement
mesh.Watcher. The two existing implementations inmeshwatcher/andkubemesh/are the templates.
Key source files
| File | Purpose |
|---|---|
pkg/config/mesh/mesh.go |
Defaults and parsing |
pkg/config/mesh/watchers.go |
The Watcher interface |
pkg/config/mesh/kubemesh/configmap_watcher.go |
ConfigMap-driven watcher |
pkg/config/mesh/meshwatcher/watcher.go |
File-driven watcher |
pilot/pkg/features/pilot.go |
Env-var feature flags |
pkg/env/var.go |
Typed env-var registration |
pilot/pkg/model/context.go |
Per-proxy ProxyConfig merge |
pkg/config/validation/validation.go |
Schema validation |
See also
- overview/getting-started — common env vars.
- reference/configuration — the full reference.
istio/api— the schema source.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.