Skip to content

Commit c4374c1

Browse files
api: add vmID to EnvoyExtensionPolicy Wasm extensions
Envoy Gateway derives the Envoy Wasm `VmConfig.vm_id` from a name that is unique per EnvoyExtensionPolicy Wasm entry, so two policies that configure the exact same Wasm module still start two separate Wasm VMs. That is a safe default, but it makes the memory cost of a module grow linearly with the number of policies that attach it, which is the common shape when policies are managed per service or per route. Add an optional `vmID` field to the Wasm API that is passed through to `VmConfig.vm_id`. Wasm extensions that set the same `vmID` and are backed by the same Wasm code share a single Envoy Wasm VM. Leaving `vmID` unset keeps the current per-extension VM ID, so existing policies are unaffected. Fixes #9565 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Signed-off-by: MohammadMahdi Ahmadi <mm.ahmadi0101@gmail.com>
1 parent 513b511 commit c4374c1

21 files changed

Lines changed: 1144 additions & 9 deletions

File tree

api/v1alpha1/wasm_types.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,28 @@ type Wasm struct {
3838
// Note: RootID must match the root_id parameter used to register the Context in the Wasm code.
3939
RootID *string `json:"rootID,omitempty"`
4040

41+
// VMID is the ID of the Envoy Wasm VM that runs this Wasm extension.
42+
//
43+
// By default, Envoy Gateway assigns each Wasm extension a VM ID that is unique
44+
// to the EnvoyExtensionPolicy it is defined in, so extensions are isolated from
45+
// each other and never share a VM.
46+
//
47+
// Setting VMID opts into sharing: Envoy reuses a single Wasm VM for all the Wasm
48+
// extensions that have the same VMID and the same Wasm code, which saves the memory
49+
// that a separate VM per extension would otherwise consume. This is useful when the
50+
// same Wasm extension is attached to different targets through separate
51+
// EnvoyExtensionPolicies.
52+
//
53+
// Note: Wasm extensions that share a VM also share its global state, and only the
54+
// configuration of the first extension to initialize the VM is used for the VM
55+
// startup. Only set the same VMID on extensions that are backed by the same Wasm
56+
// code and are intended to share a VM.
57+
//
58+
// +optional
59+
// +kubebuilder:validation:MinLength=1
60+
// +kubebuilder:validation:MaxLength=253
61+
VMID *string `json:"vmID,omitempty"`
62+
4163
// Code is the Wasm code for the extension.
4264
Code WasmCodeSource `json:"code"`
4365

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2427,6 +2427,27 @@ spec:
24272427
24282428
Note: RootID must match the root_id parameter used to register the Context in the Wasm code.
24292429
type: string
2430+
vmID:
2431+
description: |-
2432+
VMID is the ID of the Envoy Wasm VM that runs this Wasm extension.
2433+
2434+
By default, Envoy Gateway assigns each Wasm extension a VM ID that is unique
2435+
to the EnvoyExtensionPolicy it is defined in, so extensions are isolated from
2436+
each other and never share a VM.
2437+
2438+
Setting VMID opts into sharing: Envoy reuses a single Wasm VM for all the Wasm
2439+
extensions that have the same VMID and the same Wasm code, which saves the memory
2440+
that a separate VM per extension would otherwise consume. This is useful when the
2441+
same Wasm extension is attached to different targets through separate
2442+
EnvoyExtensionPolicies.
2443+
2444+
Note: Wasm extensions that share a VM also share its global state, and only the
2445+
configuration of the first extension to initialize the VM is used for the VM
2446+
startup. Only set the same VMID on extensions that are backed by the same Wasm
2447+
code and are intended to share a VM.
2448+
maxLength: 253
2449+
minLength: 1
2450+
type: string
24302451
required:
24312452
- code
24322453
type: object

charts/gateway-helm/charts/crds/crds/generated/gateway.envoyproxy.io_envoyextensionpolicies.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,6 +2426,27 @@ spec:
24262426
24272427
Note: RootID must match the root_id parameter used to register the Context in the Wasm code.
24282428
type: string
2429+
vmID:
2430+
description: |-
2431+
VMID is the ID of the Envoy Wasm VM that runs this Wasm extension.
2432+
2433+
By default, Envoy Gateway assigns each Wasm extension a VM ID that is unique
2434+
to the EnvoyExtensionPolicy it is defined in, so extensions are isolated from
2435+
each other and never share a VM.
2436+
2437+
Setting VMID opts into sharing: Envoy reuses a single Wasm VM for all the Wasm
2438+
extensions that have the same VMID and the same Wasm code, which saves the memory
2439+
that a separate VM per extension would otherwise consume. This is useful when the
2440+
same Wasm extension is attached to different targets through separate
2441+
EnvoyExtensionPolicies.
2442+
2443+
Note: Wasm extensions that share a VM also share its global state, and only the
2444+
configuration of the first extension to initialize the VM is used for the VM
2445+
startup. Only set the same VMID on extensions that are backed by the same Wasm
2446+
code and are intended to share a VM.
2447+
maxLength: 253
2448+
minLength: 1
2449+
type: string
24292450
required:
24302451
- code
24312452
type: object

internal/gatewayapi/envoyextensionpolicy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,7 @@ func (t *Translator) buildWasm(
17631763
wasmIR := &ir.Wasm{
17641764
Name: name,
17651765
RootID: config.RootID,
1766+
VMID: config.VMID,
17661767
WasmName: wasmName,
17671768
Config: config.Config,
17681769
FailOpen: failOpen,
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
gateways:
2+
- apiVersion: gateway.networking.k8s.io/v1
3+
kind: Gateway
4+
metadata:
5+
namespace: envoy-gateway
6+
name: gateway-1
7+
spec:
8+
gatewayClassName: envoy-gateway-class
9+
listeners:
10+
- name: http
11+
protocol: HTTP
12+
port: 80
13+
allowedRoutes:
14+
namespaces:
15+
from: All
16+
httpRoutes:
17+
- apiVersion: gateway.networking.k8s.io/v1
18+
kind: HTTPRoute
19+
metadata:
20+
namespace: default
21+
name: httproute-1
22+
spec:
23+
hostnames:
24+
- www.example.com
25+
parentRefs:
26+
- namespace: envoy-gateway
27+
name: gateway-1
28+
sectionName: http
29+
rules:
30+
- matches:
31+
- path:
32+
value: "/foo"
33+
backendRefs:
34+
- name: service-1
35+
port: 8080
36+
- apiVersion: gateway.networking.k8s.io/v1
37+
kind: HTTPRoute
38+
metadata:
39+
namespace: default
40+
name: httproute-2
41+
spec:
42+
hostnames:
43+
- www.example.com
44+
parentRefs:
45+
- namespace: envoy-gateway
46+
name: gateway-1
47+
sectionName: http
48+
rules:
49+
- matches:
50+
- path:
51+
value: "/bar"
52+
backendRefs:
53+
- name: service-1
54+
port: 8080
55+
envoyextensionpolicies:
56+
# The two policies below configure the same Wasm extension for different routes
57+
# and opt into sharing a single Envoy Wasm VM by setting the same vmID.
58+
- apiVersion: gateway.envoyproxy.io/v1alpha1
59+
kind: EnvoyExtensionPolicy
60+
metadata:
61+
namespace: default
62+
name: policy-for-http-route-1
63+
spec:
64+
targetRef:
65+
group: gateway.networking.k8s.io
66+
kind: HTTPRoute
67+
name: httproute-1
68+
wasm:
69+
- name: auth-filter
70+
vmID: shared-auth-filter
71+
code:
72+
type: HTTP
73+
http:
74+
url: https://www.example.com/auth-filter.wasm
75+
sha256: f5173e637a258751276b55f1f9ca6ec3b2f21ea8e6cc34216bba899cac96e9da
76+
- apiVersion: gateway.envoyproxy.io/v1alpha1
77+
kind: EnvoyExtensionPolicy
78+
metadata:
79+
namespace: default
80+
name: policy-for-http-route-2
81+
spec:
82+
targetRef:
83+
group: gateway.networking.k8s.io
84+
kind: HTTPRoute
85+
name: httproute-2
86+
wasm:
87+
- name: auth-filter
88+
vmID: shared-auth-filter
89+
code:
90+
type: HTTP
91+
http:
92+
url: https://www.example.com/auth-filter.wasm
93+
sha256: f5173e637a258751276b55f1f9ca6ec3b2f21ea8e6cc34216bba899cac96e9da

0 commit comments

Comments
 (0)