Open-Source Wikis

/

Istio

/

Systems

/

Mesh config

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| push

Directory 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 + profiles

Key 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 annotation

Resolution 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 MeshConfig via PushContext.Mesh. A change triggers a full push with Reason: MeshUpdate.
  • The CA watches for MeshConfig.trustDomainAliases changes.
  • Pilot-agent reads MeshConfig once at startup (the version mounted into its pod) plus the per-pod ProxyConfig overrides. 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: 15443

It 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 IstioOperator is 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 MeshConfig proto in istio/api, bump the dep, plumb through the watcher. The operator IstioOperator proto picks it up automatically.
  • New runtime knob that doesn't belong in MeshConfig (e.g. an experimental optimization) → register in pilot/pkg/features/pilot.go with env.Register.
  • New ProxyConfig field → same proto change, then plumb through pkg/kube/inject/ (for bootstrap) and pilot/pkg/model/context.go (for runtime).
  • New mesh-config source → implement mesh.Watcher. The two existing implementations in meshwatcher/ and kubemesh/ 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

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Mesh config – Istio wiki | Factory