Skip to content

Commit 2d3cf32

Browse files
authored
feat: add feature to support envoy as a sidecar to gateway-plugin (#1931)
* feat: add feature to support envoy as a sidecar to gateway-plugin * lint fix * address gemini-code-assist comments Signed-off-by: varungupta <varungup90@gmail.com>
1 parent 839cfd9 commit 2d3cf32

File tree

10 files changed

+234
-6
lines changed

10 files changed

+234
-6
lines changed

dist/chart/templates/_helpers.tpl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,9 @@ Create the name of the metadata service service account
125125
{{- .Values.metadata.serviceAccount.name | default "default" -}}
126126
{{- end -}}
127127
{{- end -}}
128+
129+
{{- define "aibrix.validateValues" -}}
130+
{{- if and .Values.gateway.enable .Values.gateway.envoyAsSideCar -}}
131+
{{- fail "gateway.enable and gateway.envoyAsSideCar are mutually exclusive and cannot both be true." -}}
132+
{{- end -}}
133+
{{- end -}}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Sidecar Envoy configuration:
2+
# - For advanced users who need full control without Envoy Gateway dependencies.
3+
# - Runs Envoy as a sidecar alongside aibrix-gateway for tighter integration, local admin, and simplified networking.
4+
# - No dependency on Envoy Gateway controller or data plane; you manage routes and clusters here.
5+
# - Recommended only if you understand Envoy configuration and operational impacts.
6+
# TODO: make parameters configurable such as ports, timeouts, concurrent streams
7+
{{- if and (not .Values.gateway.enable) (.Values.gateway.envoyAsSideCar) }}
8+
apiVersion: v1
9+
kind: ConfigMap
10+
metadata:
11+
name: {{ include "aibrix.fullname" . }}-envoy-config
12+
namespace: aibrix-system
13+
data:
14+
envoy.yaml: |
15+
admin:
16+
access_log:
17+
- name: envoy.access_loggers.file
18+
typed_config:
19+
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
20+
path: /dev/null
21+
address:
22+
socket_address:
23+
address: 127.0.0.1
24+
port_value: 19000
25+
ipv4_compat: true
26+
27+
static_resources:
28+
listeners:
29+
- name: envoy-gateway-proxy-ready-0.0.0.0-10080
30+
address:
31+
socket_address:
32+
address: '0.0.0.0'
33+
port_value: {{ .Values.gateway.envoySideCar.ports.http | default 10080 }}
34+
protocol: TCP
35+
per_connection_buffer_limit_bytes: 4194304
36+
filter_chains:
37+
- filters:
38+
- name: envoy.filters.network.http_connection_manager
39+
typed_config:
40+
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
41+
stat_prefix: ingress_http
42+
access_log:
43+
- name: envoy.access_loggers.file
44+
typed_config:
45+
"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
46+
path: "/dev/stdout"
47+
log_format:
48+
json_format:
49+
":authority": "%REQ(:AUTHORITY)%"
50+
"bytes_received": "%BYTES_RECEIVED%"
51+
"bytes_sent": "%BYTES_SENT%"
52+
"connection_termination_details": "%CONNECTION_TERMINATION_DETAILS%"
53+
"downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%"
54+
"downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%"
55+
"duration": "%DURATION%"
56+
"method": "%REQ(:METHOD)%"
57+
"protocol": "%PROTOCOL%"
58+
"requested_server_name": "%REQUESTED_SERVER_NAME%"
59+
"response_code": "%RESPONSE_CODE%"
60+
"response_code_details": "%RESPONSE_CODE_DETAILS%"
61+
"response_flags": "%RESPONSE_FLAGS%"
62+
"route_name": "%ROUTE_NAME%"
63+
"start_time": "%START_TIME%"
64+
"upstream_cluster": "%UPSTREAM_CLUSTER%"
65+
"upstream_host": "%UPSTREAM_HOST%"
66+
"upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%"
67+
"upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%"
68+
"user-agent": "%REQ(USER-AGENT)%"
69+
"x-envoy-origin-path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
70+
"x-envoy-upstream-service-time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%"
71+
"x-forwarded-for": "%REQ(X-FORWARDED-FOR)%"
72+
"x-request-id": "%REQ(X-REQUEST-ID)%"
73+
http_filters:
74+
# External Processing Filter
75+
- name: envoy.filters.http.ext_proc
76+
typed_config:
77+
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor
78+
grpc_service:
79+
envoy_grpc:
80+
cluster_name: ext_proc_cluster
81+
timeout: 10s
82+
processing_mode:
83+
request_header_mode: SEND
84+
response_header_mode: SEND
85+
request_body_mode: BUFFERED
86+
response_body_mode: STREAMED
87+
message_timeout: 60s
88+
89+
# Router filter (must be last)
90+
- name: envoy.filters.http.router
91+
typed_config:
92+
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
93+
94+
route_config:
95+
name: local_route
96+
virtual_hosts:
97+
- name: original_route
98+
domains: ["*"]
99+
routes:
100+
- match:
101+
prefix: "/"
102+
headers:
103+
- name: "routing-strategy"
104+
string_match:
105+
safe_regex:
106+
regex: .*
107+
route:
108+
cluster: original_destination_cluster
109+
timeout: 300s # Increase route timeout
110+
111+
112+
clusters:
113+
# External Processor Cluster (Sidecar)
114+
- name: ext_proc_cluster
115+
connect_timeout: 10s
116+
type: STATIC
117+
lb_policy: ROUND_ROBIN
118+
dns_lookup_family: AUTO # Enable dual-stack DNS
119+
upstream_connection_options:
120+
tcp_keepalive:
121+
keepalive_probes: 3
122+
keepalive_time: 30
123+
keepalive_interval: 5
124+
typed_extension_protocol_options:
125+
envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
126+
"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
127+
explicit_http_config:
128+
http2_protocol_options: {}
129+
load_assignment:
130+
cluster_name: ext_proc_cluster
131+
endpoints:
132+
- lb_endpoints:
133+
- endpoint:
134+
address:
135+
socket_address:
136+
address: ::1 # IPv6 localhost
137+
port_value: 50052
138+
- endpoint:
139+
address:
140+
socket_address:
141+
address: "127.0.0.1" # IPv4 localhost fallback
142+
port_value: 50052
143+
144+
- name: original_destination_cluster
145+
type: ORIGINAL_DST
146+
original_dst_lb_config:
147+
use_http_header: true
148+
http_header_name: "target-pod"
149+
connect_timeout: 6s
150+
lb_policy: CLUSTER_PROVIDED
151+
dns_lookup_family: AUTO
152+
upstream_connection_options:
153+
tcp_keepalive:
154+
keepalive_probes: 3
155+
keepalive_time: 30
156+
keepalive_interval: 5
157+
{{- end }}

dist/chart/templates/gateway-instance/gateway.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{- if .Values.gateway.enable }}
1+
{{- if and .Values.gateway.enable (not .Values.gateway.envoyAsSideCar) }}
22
apiVersion: gateway.networking.k8s.io/v1
33
kind: GatewayClass
44
metadata:

dist/chart/templates/gateway-plugin/deployment.yaml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{- if .Values.gateway.enable }}
1+
{{- if or .Values.gateway.enable .Values.gateway.envoyAsSideCar }}
22
{{- $redisHost := default (printf "%s-redis-master" (include "aibrix.fullname" .)) .Values.gatewayPlugin.dependencies.redis.host }}
33
---
44
apiVersion: apps/v1
@@ -100,6 +100,10 @@ spec:
100100
valueFrom:
101101
fieldRef:
102102
fieldPath: metadata.namespace
103+
{{- if and .Values.gateway.envoyAsSideCar (not (hasKey .Values.gatewayPlugin.container.envs "ROUTING_ALGORITHM")) }}
104+
- name: ROUTING_ALGORITHM
105+
value: "random"
106+
{{- end }}
103107
{{- range $key, $val := .Values.gatewayPlugin.container.envs }}
104108
- name: {{ $key }}
105109
value: "{{ $val }}"
@@ -109,5 +113,31 @@ spec:
109113
{{- toYaml .Values.gatewayPlugin.container.probes.liveness | nindent 12 }}
110114
readinessProbe:
111115
{{- toYaml .Values.gatewayPlugin.container.probes.readiness | nindent 12 }}
116+
{{- if .Values.gateway.envoyAsSideCar }}
117+
- name: envoy
118+
image: {{ .Values.gateway.envoyProxy.container.envoy.image }}
119+
command: ["/bin/sh", "-c"]
120+
args:
121+
- |
122+
exec /usr/local/bin/envoy \
123+
-c /etc/envoy/envoy.yaml \
124+
--service-cluster envoy-sidecar \
125+
--log-level warn \
126+
--cpuset-threads \
127+
--drain-strategy immediate \
128+
--drain-time-s 60
129+
volumeMounts:
130+
- name: {{ include "aibrix.fullname" . }}-envoy-config
131+
mountPath: /etc/envoy
132+
{{- end }}
133+
{{- if .Values.gateway.envoyAsSideCar }}
134+
volumes:
135+
- name: {{ include "aibrix.fullname" . }}-envoy-config
136+
configMap:
137+
name: {{ include "aibrix.fullname" . }}-envoy-config
138+
items:
139+
- key: envoy.yaml
140+
path: envoy.yaml
141+
{{- end }}
112142
serviceAccountName: {{ include "aibrix.gatewayPlugin.serviceAccountName" . }}
113143
{{- end }}

dist/chart/templates/gateway-plugin/envoy_extension_policy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# templates/envoy-extension-policy.yaml
2-
{{- if .Values.gateway.enable }}
2+
{{- if and .Values.gateway.enable (not .Values.gateway.envoyAsSideCar) }}
33
apiVersion: gateway.envoyproxy.io/v1alpha1
44
kind: EnvoyExtensionPolicy
55
metadata:

dist/chart/templates/gateway-plugin/httproute.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{- if .Values.gateway.enable }}
1+
{{- if and .Values.gateway.enable (not .Values.gateway.envoyAsSideCar) }}
22
apiVersion: gateway.networking.k8s.io/v1
33
kind: HTTPRoute
44
metadata:

dist/chart/templates/gateway-plugin/rbac.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{- if .Values.gateway.enable }}
1+
{{- if or .Values.gateway.enable .Values.gateway.envoyAsSideCar }}
22
---
33
apiVersion: v1
44
kind: ServiceAccount

dist/chart/templates/gateway-plugin/service.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{{- if .Values.gateway.enable }}
1+
{{- if or .Values.gateway.enable (.Values.gateway.envoyAsSideCar) }}
22
apiVersion: v1
33
kind: Service
44
metadata:
@@ -11,6 +11,11 @@ metadata:
1111
prometheus.io/port: "8080"
1212
prometheus.io/path: "/metrics"
1313
spec:
14+
{{- if .Values.gateway.envoyAsSideCar }}
15+
type: LoadBalancer
16+
{{- else }}
17+
type: {{ .Values.gatewayPlugin.service.type | default "ClusterIP" }}
18+
{{- end }}
1419
selector:
1520
{{- include "aibrix.selectorLabels" . | nindent 4 }}
1621
app.kubernetes.io/component: aibrix-gateway-plugin
@@ -24,4 +29,9 @@ spec:
2429
- name: metrics
2530
port: 8080
2631
targetPort: 8080
32+
{{- if .Values.gateway.envoyAsSideCar }}
33+
- name: envoy-http
34+
port: 10080
35+
targetPort: 10080
36+
{{- end }}
2737
{{- end }}

dist/chart/values.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ gatewayPlugin:
8686
redis:
8787
host: "" # aibrix-redis-master
8888
port: 6379
89+
service:
90+
type: ClusterIP
8991
messageTimeout: "60s"
9092
failOpen: false
9193
extProc:
@@ -133,7 +135,18 @@ gpuOptimizer:
133135
affinity: {}
134136

135137
gateway:
138+
# Mode Selection (mutually exclusive; values must be opposite)
139+
# | gateway.enable | envoyAsSideCar | Notes |
140+
# | -------------- | ------------------- | ----- |
141+
# | true | false | Envoy managed by Envoy Gateway (data plane). Installs Gateway, GatewayClass, EnvoyProxy, and gateway-plugins. |
142+
# | false | true | Envoy runs as a sidecar with aibrix-gateway within your workload (no Gateway data plane). Renders only the sidecar Envoy ConfigMap. |
143+
# | false | false | Disables both. No gateway and no sidecar. Useful when using an external gateway or for CRD-only installs. |
144+
# | true | true | INVALID: Do not enable both. Values must be opposite. |
136145
enable: true
146+
envoyAsSideCar: false
147+
envoySideCar:
148+
ports:
149+
http: 10080
137150
envoyProxy:
138151
replicas: 1
139152
imagePullSecrets: []

dist/chart/vke.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ gpuOptimizer:
102102
affinity: {}
103103

104104
gateway:
105+
# Mode Selection (mutually exclusive; values must be opposite)
106+
# | gateway.enable | envoyAsSideCar | Notes |
107+
# | -------------- | ------------------- | ----- |
108+
# | true | false | Envoy managed by Envoy Gateway (data plane). Installs Gateway, GatewayClass, EnvoyProxy, and gateway-plugins. |
109+
# | false | true | Envoy runs as a sidecar with aibrix-gateway within your workload (no Gateway data plane). Renders only the sidecar Envoy ConfigMap. |
110+
# | false | false | Disables both. No gateway and no sidecar. Useful when using an external gateway or for CRD-only installs. |
111+
# | true | true | INVALID: Do not enable both. Values must be opposite. |
112+
enable: false
113+
envoyAsSideCar: true
114+
envoySideCar:
115+
ports:
116+
http: 10080
105117
envoyProxy:
106118
replicas: 1
107119
imagePullSecrets: []

0 commit comments

Comments
 (0)