This is an automated email from the ASF dual-hosted git repository.

aicam pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git


The following commit(s) were added to refs/heads/main by this push:
     new 99348fb660 refactor(helm): unify ingress and envoy proxy as a single 
gateway (#4191)
99348fb660 is described below

commit 99348fb6604717e670695280ff5f37bf529a1433
Author: ali risheh <[email protected]>
AuthorDate: Tue Feb 10 14:08:44 2026 -0800

    refactor(helm): unify ingress and envoy proxy as a single gateway (#4191)
    
    <!--
    Thanks for sending a pull request (PR)! Here are some tips for you:
    1. If this is your first time, please read our contributor guidelines:
    [Contributing to
    Texera](https://github.com/apache/texera/blob/main/CONTRIBUTING.md)
      2. Ensure you have added or run the appropriate tests for your PR
      3. If the PR is work in progress, mark it a draft on GitHub.
      4. Please write your PR title to summarize what this PR proposes, we
        are following Conventional Commits style for PR titles as well.
      5. Be sure to keep the PR description updated to reflect all changes.
    -->
    
    ### What changes were proposed in this PR?
    <!--
    Please clarify what changes you are proposing. The purpose of this
    section
    is to outline the changes. Here are some tips for you:
      1. If you propose a new API, clarify the use case for a new API.
      2. If you fix a bug, you can clarify why it is a bug.
      3. If it is a refactoring, clarify what has been changed.
      3. It would be helpful to include a before-and-after comparison using
         screenshots or GIFs.
      4. Please consider writing useful notes for better and faster reviews.
    -->
    
    This PR consolidates the cluster networking architecture by replacing
    multiple disparate ingress/proxy solutions with a single, unified
    **Envoy Gateway** using the Kubernetes Gateway API.
    
    **Previously:**
    - **Texera Ingress**: Handled by `ingress-nginx` controller (separate
    Helm dependency).
    - **MinIO Ingress**: Configured separately, often requiring its own
    ingress status or port exposure.
    - **CU Envoy**: A standalone, manually maintained Envoy deployment was
    used to proxy traffic to Computing Units (CUs).
    
    **Now (with Envoy Gateway):**
    - **Unified Gateway**: A single `Gateway` resource (`texera-gateway`)
    manages traffic for Texera Webserver, MinIO, and Computing Units.
    - **Gateway API**: Uses standard `HTTPRoute` resources to define routing
    rules (prefix matching, rewrites) instead of proprietary Ingress
    annotations or custom config.
    - **SSL/TLS Automation**: Integrated `cert-manager` with Envoy Gateway
    to automatically provision and renew Let's Encrypt certificates for both
    the main Texera domain and the MinIO subdomain.
    
    **New Kubernetes Resources**:
    
    * `bin/k8s/templates/gateway.yaml`: Defines the `Gateway` resource,
    configuring listeners for HTTP, HTTPS, and MinIO. Handles TLS
    termination using Let's Encrypt via cert-manager.
    
    *   `bin/k8s/templates/routes.yaml`: Defines `HTTPRoute` resources.
    * **Static Routes**: Standard path-based routing for Texera services
    (Webserver, API, etc.).
    * **Dynamic Routes**: Captures regex paths for Computing Units and
    delegates them to the dynamic backend.
    
    * `bin/k8s/templates/backend.yaml`: Defines a `Backend` resource of type
    `DynamicResolver`. This allows Envoy to route to targets defined
    dynamically (e.g., by the ExtAuth service modifying headers) rather than
    static Kubernetes services.
    
    * `bin/k8s/templates/security-policy.yaml`: Defines the `SecurityPolicy`
    that attaches to the dynamic routes. It configures the External
    Authorization filter to point to the `access-control-service`.
    
    * `bin/k8s/templates/eg-config-hook.yaml`: A **Helm Hook**
    (pre-install/pre-upgrade) that automatically patches the Envoy Gateway
    configuration to enable necessary features (`enableBackend`,
    `enableEnvoyPatchPolicy`) which are disabled by default. It ensures the
    environment is correctly configured without manual intervention.
    
    ### Any related issues, documentation, discussions?
    <!--
    Please use this section to link other resources if not mentioned
    already.
    1. If this PR fixes an issue, please include `Fixes #1234`, `Resolves
    #1234`
    or `Closes #1234`. If it is only related, simply mention the issue
    number.
      2. If there is design documentation, please add the link.
      3. If there is a discussion in the mailing list, please add the link.
    -->
    Closes #4190
    
    ### How was this PR tested?
    <!--
    If tests were added, say they were added here. Or simply mention that if
    the PR
    is tested with existing test cases. Make sure to include/update test
    cases that
    check the changes thoroughly including negative and positive cases if
    possible.
    If it was tested in a way different from regular unit tests, please
    clarify how
    you tested step by step, ideally copy and paste-able, so that other
    reviewers can
    test and check, and descendants can verify in the future. If tests were
    not added,
    please describe why they were not added and/or why it was difficult to
    add.
    -->
    
    Tested on the production RKE2 cluster:
    
    We tested on http and https on both production server and local
    environment.
    
    ### Was this PR authored or co-authored using generative AI tooling?
    <!--
    If generative AI tooling has been used in the process of authoring this
    PR,
    please include the phrase: 'Generated-by: ' followed by the name of the
    tool
    and its version. If no, write 'No'.
    Please refer to the [ASF Generative Tooling
    Guidance](https://www.apache.org/legal/generative-tooling.html) for
    details.
    -->
    Generated-by: Antigravity
---
 .../service/resource/AccessControlResource.scala   |  11 +-
 bin/k8s/Chart.yaml                                 |  10 +-
 .../access-control-service-deployment.yaml         |   4 +
 bin/k8s/templates/envoy-config.yaml                | 147 ---------------------
 bin/k8s/templates/envoy-deployment.yaml            |  49 -------
 .../{envoy-service.yaml => gateway-backend.yaml}   |  18 +--
 bin/k8s/templates/gateway-routes.yaml              | 142 ++++++++++++++++++++
 ...y-service.yaml => gateway-security-policy.yaml} |  33 +++--
 bin/k8s/templates/gateway.yaml                     |  81 ++++++++++++
 bin/k8s/templates/ingress.yaml                     |  53 --------
 bin/k8s/templates/minio-ingress.yaml               |  65 ---------
 bin/k8s/values.yaml                                | 126 +++++-------------
 common/config/src/main/resources/kubernetes.conf   |   5 +-
 .../apache/texera/config/KubernetesConfig.scala    |   1 +
 14 files changed, 304 insertions(+), 441 deletions(-)

diff --git 
a/access-control-service/src/main/scala/org/apache/texera/service/resource/AccessControlResource.scala
 
b/access-control-service/src/main/scala/org/apache/texera/service/resource/AccessControlResource.scala
index 1f2e2bc11f..0cd52f4919 100644
--- 
a/access-control-service/src/main/scala/org/apache/texera/service/resource/AccessControlResource.scala
+++ 
b/access-control-service/src/main/scala/org/apache/texera/service/resource/AccessControlResource.scala
@@ -26,7 +26,7 @@ import jakarta.ws.rs.{Consumes, GET, POST, Path, Produces}
 import org.apache.texera.auth.JwtParser.parseToken
 import org.apache.texera.auth.SessionUser
 import org.apache.texera.auth.util.{ComputingUnitAccess, HeaderField}
-import org.apache.texera.config.{GuiConfig, LLMConfig}
+import org.apache.texera.config.{GuiConfig, KubernetesConfig, LLMConfig}
 import org.apache.texera.dao.jooq.generated.enums.PrivilegeEnum
 
 import java.net.URLDecoder
@@ -121,12 +121,21 @@ object AccessControlResource extends LazyLogging {
         return Response.status(Response.Status.FORBIDDEN).build()
     }
 
+    // Dynamic Routing Logic
+    val workflowComputingUnitPoolName = KubernetesConfig.computeUnitPoolName
+    val workflowComputingUnitPoolNamespace = 
KubernetesConfig.computeUnitPoolNamespace
+    val workflowComputingUnitPoolPort = KubernetesConfig.computeUnitPortNumber
+
+    val targetHost =
+      
s"computing-unit-$cuidInt.$workflowComputingUnitPoolName-svc.$workflowComputingUnitPoolNamespace.svc.cluster.local:$workflowComputingUnitPoolPort"
+
     Response
       .ok()
       .header(HeaderField.UserComputingUnitAccess, cuAccess.toString)
       .header(HeaderField.UserId, userSession.get().getUid.toString)
       .header(HeaderField.UserName, userSession.get().getName)
       .header(HeaderField.UserEmail, userSession.get().getEmail)
+      .header("Host", targetHost) // Envoy ExtAuth: Rewrite Host
       .build()
   }
 
diff --git a/bin/k8s/Chart.yaml b/bin/k8s/Chart.yaml
index ee57a2b842..1e6dcfbef8 100644
--- a/bin/k8s/Chart.yaml
+++ b/bin/k8s/Chart.yaml
@@ -42,11 +42,6 @@ appVersion: "1.16.0"
 
 
 dependencies:
-  - name: ingress-nginx
-    version: 4.11.3
-    repository: https://kubernetes.github.io/ingress-nginx
-    condition: ingress-nginx.enabled
-
   - name: postgresql
     version: 16.5.6
     repository: https://charts.bitnami.com/bitnami
@@ -59,6 +54,11 @@ dependencies:
     version: 1.4.5
     repository: https://charts.lakefs.io
 
+  - name: gateway-helm
+    version: 1.6.3
+    repository: oci://docker.io/envoyproxy
+    alias: envoy-gateway
+
   - name: metrics-server
     version: 3.12.2
     repository: https://kubernetes-sigs.github.io/metrics-server/
diff --git a/bin/k8s/templates/access-control-service-deployment.yaml 
b/bin/k8s/templates/access-control-service-deployment.yaml
index a332c65bd3..9da05bfd26 100644
--- a/bin/k8s/templates/access-control-service-deployment.yaml
+++ b/bin/k8s/templates/access-control-service-deployment.yaml
@@ -46,6 +46,10 @@ spec:
                 secretKeyRef:
                   name: {{ .Release.Name }}-postgresql
                   key: postgres-password
+            - name: KUBERNETES_COMPUTE_UNIT_POOL_NAME
+              value: {{ .Values.workflowComputingUnitPool.name }}
+            - name: KUBERNETES_COMPUTE_UNIT_POOL_NAMESPACE
+              value: {{ .Values.workflowComputingUnitPool.namespace }}
           livenessProbe:
             httpGet:
               path: /api/healthcheck
diff --git a/bin/k8s/templates/envoy-config.yaml 
b/bin/k8s/templates/envoy-config.yaml
deleted file mode 100644
index 2ba17e63f8..0000000000
--- a/bin/k8s/templates/envoy-config.yaml
+++ /dev/null
@@ -1,147 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-apiVersion: v1
-kind: ConfigMap
-metadata:
-  name: envoy-config
-  namespace: {{ .Release.Namespace }}
-data:
-  envoy.yaml: |
-    static_resources:
-      listeners:
-        - name: listener_0
-          address:
-            socket_address:
-              address: 0.0.0.0
-              port_value: 10000
-          filter_chains:
-            - filters:
-                - name: envoy.filters.network.http_connection_manager
-                  typed_config:
-                    "@type": 
type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
-                    stat_prefix: ingress_http
-                    upgrade_configs:
-                      - upgrade_type: websocket
-                    route_config:
-                      name: local_route
-                      virtual_hosts:
-                        - name: local_service
-                          domains: ["*"]
-                          routes:
-                            - match:
-                                prefix: "/wsapi"
-                              route:
-                                cluster: dynamic_service
-                                prefix_rewrite: "/wsapi"
-                                timeout: "0s" # disables timeout
-                            - match:
-                                safe_regex:
-                                  google_re2: {}
-                                  regex: "^/api/executions/\\d+/stats/\\d+$"
-                              route:
-                                cluster: dynamic_service
-                                timeout: "0s"
-                            - match:
-                                prefix: "/api/executions/result/export"
-                              route:
-                                cluster: dynamic_service
-                                prefix_rewrite: "/api/executions/result/export"
-                                timeout: "0s"
-                    http_filters:
-                      - name: envoy.filters.http.ext_authz
-                        typed_config:
-                          "@type": 
type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
-                          with_request_body:
-                            # Max allowed by Envoy (uint32): 4,294,967,295 
bytes (~4 GiB)
-                            max_request_bytes: 4294967295
-                            allow_partial_message: true     # forward partial 
body if larger than limit
-                          http_service:
-                            server_uri:
-                              uri: http://{{ .Release.Name }}-{{ 
.Values.accessControlService.name }}-svc.{{ .Release.Namespace 
}}.svc.cluster.local
-                              cluster: access_control_service_cluster
-                              timeout: 5s
-                            path_prefix: /api/auth
-                            authorization_request:
-                              allowed_headers:
-                                patterns:
-                                  - exact: "authorization"
-                                  - exact: "x-envoy-original-path"
-                            authorization_response:
-                              allowed_upstream_headers:
-                                patterns:
-                                  - exact: "x-user-cu-access"
-                                  - exact: "x-user-id"
-                                  - exact: "x-user-name"
-                                  - exact: "x-user-email"
-                          failure_mode_allow: false
-                      - name: envoy.filters.http.lua
-                        typed_config:
-                          "@type": 
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
-                          inline_code: |
-                            function envoy_on_request(request_handle)
-                                local uri = 
request_handle:headers():get(":path")
-                                local cuid = string.match(uri, "cuid=(%d+)")
-                                if cuid then
-                                  local new_host = "computing-unit-" .. cuid 
.. ".{{ .Values.workflowComputingUnitPool.name }}-svc.{{ 
.Values.workflowComputingUnitPool.namespace }}.svc.cluster.local:{{ 
.Values.workflowComputingUnitPool.service.port }}"
-                                  
request_handle:headers():replace(":authority", new_host)
-                                end
-                              end
-                      - name: envoy.filters.http.dynamic_forward_proxy
-                        typed_config:
-                          "@type": 
type.googleapis.com/envoy.extensions.filters.http.dynamic_forward_proxy.v3.FilterConfig
-                          dns_cache_config:
-                            name: dynamic_dns_cache
-                            dns_lookup_family: V4_ONLY
-                            dns_refresh_rate: 1s
-                      - name: envoy.filters.http.router
-                        typed_config:
-                          "@type": 
type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
-
-                    access_log:
-                      - name: envoy.access_loggers.stdout
-                        typed_config:
-                          "@type": 
type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
-                          log_format:
-                            text_format_source:
-                              inline_string: "[%START_TIME%] \"%REQ(:METHOD)% 
%REQ(X-ENVOY-ORIGINAL-PATH?PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% 
%BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% 
\"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" 
\"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\" 
AuthHeaders[user-id:\"%REQ(X-USER-ID)%\" email:\"%REQ(X-USER-EMAIL)%\" 
cu-access:\"%REQ(X-USER-CU-ACCESS)%\"]\n"
-
-      clusters:
-        - name: dynamic_service
-          connect_timeout: 0.25s
-          lb_policy: CLUSTER_PROVIDED
-          cluster_type:
-            name: envoy.clusters.dynamic_forward_proxy
-            typed_config:
-              "@type": 
type.googleapis.com/envoy.extensions.clusters.dynamic_forward_proxy.v3.ClusterConfig
-              dns_cache_config:
-                name: dynamic_dns_cache
-                dns_lookup_family: V4_ONLY
-                dns_refresh_rate: 1s
-        - name: access_control_service_cluster # The Access Control Service 
authorize requests and add user info headers
-          connect_timeout: 0.25s
-          type: LOGICAL_DNS
-          lb_policy: round_robin
-          load_assignment:
-            cluster_name: access_control_service_cluster
-            endpoints:
-              - lb_endpoints:
-                  - endpoint:
-                      address:
-                        socket_address:
-                          address: {{ .Release.Name }}-{{ 
.Values.accessControlService.name }}-svc.{{ .Release.Namespace 
}}.svc.cluster.local.
-                          port_value: {{ 
.Values.accessControlService.service.port }}
diff --git a/bin/k8s/templates/envoy-deployment.yaml 
b/bin/k8s/templates/envoy-deployment.yaml
deleted file mode 100644
index 0e0522ee49..0000000000
--- a/bin/k8s/templates/envoy-deployment.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-apiVersion: apps/v1
-kind: Deployment
-metadata:
-  name: {{ .Release.Name }}-envoy-deployment
-  namespace: {{ .Release.Namespace }}
-spec:
-  replicas: {{ .Values.envoy.replicas | default 1 }}
-  selector:
-    matchLabels:
-      app: envoy
-  template:
-    metadata:
-      labels:
-        app: envoy
-    spec:
-      containers:
-        - name: envoy
-          image: "{{ .Values.envoy.image.repository }}:{{ 
.Values.envoy.image.tag }}"
-          ports:
-            - containerPort: {{ .Values.envoy.port}}
-          volumeMounts:
-            - name: envoy-config
-              mountPath: /etc/envoy
-              readOnly: true
-          args:
-            - "-c"
-            - "/etc/envoy/envoy.yaml"  # Specify the path to the configuration 
file
-            - "--log-level debug"  # Set level of logging
-      volumes:
-        - name: envoy-config
-          configMap:
-            name: envoy-config  # Reference the ConfigMap created earlier
\ No newline at end of file
diff --git a/bin/k8s/templates/envoy-service.yaml 
b/bin/k8s/templates/gateway-backend.yaml
similarity index 65%
copy from bin/k8s/templates/envoy-service.yaml
copy to bin/k8s/templates/gateway-backend.yaml
index b936a7702b..2db3cdc3ae 100644
--- a/bin/k8s/templates/envoy-service.yaml
+++ b/bin/k8s/templates/gateway-backend.yaml
@@ -15,20 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 
-apiVersion: v1
-kind: Service
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: Backend
 metadata:
-  name: envoy-svc
+  name: {{ .Release.Name }}-dynamic-backend
   namespace: {{ .Release.Namespace }}
 spec:
-  type: {{ .Values.envoy.service.type }}
-  selector:
-    app: envoy
-  ports:
-    - protocol: TCP
-      port: {{ .Values.envoy.service.port }}
-      targetPort: {{ .Values.envoy.service.port }}
-      # if service type is set to NodePort, include nodePort attribute
-      {{- if eq .Values.envoy.service.type "NodePort" }}
-      nodePort: {{ .Values.envoy.service.nodePort }}
-      {{- end }}
\ No newline at end of file
+  type: DynamicResolver
diff --git a/bin/k8s/templates/gateway-routes.yaml 
b/bin/k8s/templates/gateway-routes.yaml
new file mode 100644
index 0000000000..55dc40f581
--- /dev/null
+++ b/bin/k8s/templates/gateway-routes.yaml
@@ -0,0 +1,142 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: {{ .Release.Name }}-static-routes
+  namespace: {{ .Release.Namespace }}
+spec:
+  parentRefs:
+    - name: {{ .Release.Name }}-gateway
+  {{- if and .Values.gatewayConfig .Values.gatewayConfig.hostname }}
+  hostnames:
+    - {{ .Values.gatewayConfig.hostname }}
+  {{- end }}
+  rules:
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /api/computing-unit
+      backendRefs:
+        - name: workflow-computing-unit-manager-svc
+          port: 8888
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /api/compile
+      backendRefs:
+        - name: workflow-compiling-service-svc
+          port: 9090
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /api/dataset
+        - path:
+            type: PathPrefix
+            value: /api/access/dataset
+      backendRefs:
+        - name: file-service-svc
+          port: 9092
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /api/access/computing-unit
+      backendRefs:
+        - name: workflow-computing-unit-manager-svc
+          port: 8888
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /api/config
+      backendRefs:
+        - name: config-service-svc
+          port: 9094
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /rtc
+      backendRefs:
+        - name: y-websocket-server-svc
+          port: 1234
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /python-language-server
+      backendRefs:
+        - name: python-language-server-svc
+          port: 3000
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /api
+        - path:
+            type: PathPrefix
+            value: /
+      backendRefs:
+        - name: webserver-svc
+          port: 8080
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: {{ .Release.Name }}-dynamic-routes
+  namespace: {{ .Release.Namespace }}
+spec:
+  parentRefs:
+    - name: {{ .Release.Name }}-gateway
+  {{- if and .Values.gatewayConfig .Values.gatewayConfig.hostname }}
+  hostnames:
+    - {{ .Values.gatewayConfig.hostname }}
+  {{- end }}
+  rules:
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /wsapi
+        - path:
+            type: RegularExpression
+            value: "^/api/executions/\\d+/stats/\\d+$"
+        - path:
+            type: PathPrefix
+            value: /api/executions/result/export
+      backendRefs:
+        - group: gateway.envoyproxy.io
+          kind: Backend
+          name: texera-dynamic-backend
+---
+# MinIO Route
+{{- if .Values.minio.gateway.enabled }}
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: texera-minio-route
+  namespace: {{ .Release.Namespace }}
+spec:
+  parentRefs:
+    - name: {{ .Release.Name }}-gateway
+  hostnames:
+    - {{ .Values.minio.gateway.hostname }}
+  rules:
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /
+      backendRefs:
+        - name: {{ .Release.Name }}-minio
+          port: 9000
+{{- end }}
diff --git a/bin/k8s/templates/envoy-service.yaml 
b/bin/k8s/templates/gateway-security-policy.yaml
similarity index 60%
rename from bin/k8s/templates/envoy-service.yaml
rename to bin/k8s/templates/gateway-security-policy.yaml
index b936a7702b..ad2f5684e5 100644
--- a/bin/k8s/templates/envoy-service.yaml
+++ b/bin/k8s/templates/gateway-security-policy.yaml
@@ -15,20 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-apiVersion: v1
-kind: Service
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
 metadata:
-  name: envoy-svc
+  name: {{ .Release.Name }}-ext-auth
   namespace: {{ .Release.Namespace }}
 spec:
-  type: {{ .Values.envoy.service.type }}
-  selector:
-    app: envoy
-  ports:
-    - protocol: TCP
-      port: {{ .Values.envoy.service.port }}
-      targetPort: {{ .Values.envoy.service.port }}
-      # if service type is set to NodePort, include nodePort attribute
-      {{- if eq .Values.envoy.service.type "NodePort" }}
-      nodePort: {{ .Values.envoy.service.nodePort }}
-      {{- end }}
\ No newline at end of file
+  targetRefs:
+    - group: gateway.networking.k8s.io
+      kind: HTTPRoute
+      name: {{ .Release.Name }}-dynamic-routes
+  extAuth:
+    http:
+      backendRefs:
+        - name: {{ .Release.Name }}-{{ .Values.accessControlService.name }}-svc
+          port: {{ .Values.accessControlService.service.port }}
+      path: /api/auth
+      headersToBackend:
+        - x-user-cu-access
+        - x-user-id
+        - x-user-name
+        - x-user-email
+        - Host
diff --git a/bin/k8s/templates/gateway.yaml b/bin/k8s/templates/gateway.yaml
new file mode 100644
index 0000000000..868439a673
--- /dev/null
+++ b/bin/k8s/templates/gateway.yaml
@@ -0,0 +1,81 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+apiVersion: gateway.networking.k8s.io/v1
+kind: GatewayClass
+metadata:
+  name: eg
+spec:
+  controllerName: gateway.envoyproxy.io/gatewayclass-controller
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: {{ .Release.Name }}-gateway
+  annotations:
+    {{- if and .Values.gatewayConfig .Values.gatewayConfig.issuer }}
+    {{- if eq (default "Issuer" .Values.gatewayConfig.issuerKind) 
"ClusterIssuer" }}
+    cert-manager.io/cluster-issuer: {{ .Values.gatewayConfig.issuer }}
+    {{- else }}
+    cert-manager.io/issuer: {{ .Values.gatewayConfig.issuer }}
+    {{- end }}
+    {{- end }}
+spec:
+  gatewayClassName: eg
+  listeners:
+    - name: http
+      protocol: HTTP
+      port: 80
+      {{- if and .Values.gatewayConfig .Values.gatewayConfig.hostname }}
+      hostname: {{ .Values.gatewayConfig.hostname }}
+      {{- end }}
+      allowedRoutes:
+        namespaces:
+          from: Same
+    - name: https
+      protocol: HTTPS
+      port: 443
+      {{- if and .Values.gatewayConfig .Values.gatewayConfig.hostname }}
+      hostname: {{ .Values.gatewayConfig.hostname }}
+      {{- end }}
+      allowedRoutes:
+        namespaces:
+          from: Same
+      tls:
+        mode: Terminate
+        certificateRefs:
+          - name: {{ (index .Values "gatewayConfig" "tlsSecretName") | default 
(printf "%s-cert" .Release.Name) }}
+    {{- if .Values.minio.gateway.enabled }}
+    - name: minio-http
+      protocol: HTTP
+      port: 80
+      hostname: {{ .Values.minio.gateway.hostname }}
+      allowedRoutes:
+        namespaces:
+          from: Same
+    - name: minio-https
+      protocol: HTTPS
+      port: 443
+      hostname: {{ .Values.minio.gateway.hostname }}
+      allowedRoutes:
+        namespaces:
+          from: Same
+      tls:
+        mode: Terminate
+        certificateRefs:
+          - name: {{ .Values.minio.gateway.tlsSecretName | default (printf 
"%s-minio-tls" .Release.Name) }}
+    {{- end }}
diff --git a/bin/k8s/templates/ingress.yaml b/bin/k8s/templates/ingress.yaml
deleted file mode 100644
index 43c5bd3fc1..0000000000
--- a/bin/k8s/templates/ingress.yaml
+++ /dev/null
@@ -1,53 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-{{- if .Values.ingressPaths.enabled }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: {{ .Release.Name }}-ingress
-  namespace: {{ .Release.Namespace }}
-  annotations:
-    nginx.ingress.kubernetes.io/use-regex: "true"
-    {{- if or .Values.ingressPaths.tlsSecretName .Values.ingressPaths.issuer }}
-    nginx.ingress.kubernetes.io/ssl-redirect: {{ or 
.Values.ingressPaths.tlsSecretName .Values.ingressPaths.issuer | quote}}
-    {{- end }}
-    {{- if .Values.ingressPaths.issuer }}
-    cert-manager.io/issuer: {{ .Values.ingressPaths.issuer }}
-    {{- end }}
-spec:
-  ingressClassName: {{ .Values.ingressPaths.ingressClassName }}
-  {{- if or .Values.ingressPaths.tlsSecretName .Values.ingressPaths.issuer }}
-  tls:
-    - hosts:
-        - {{ .Values.ingressPaths.hostname }}
-      secretName: {{ .Values.ingressPaths.tlsSecretName | default (printf 
"%s-tls" .Release.Name) }}
-  {{- end }}
-  rules:
-    - host: {{ .Values.ingressPaths.hostname }}
-      http:
-        paths:
-          {{- range .Values.ingressPaths.paths }}
-          - path: {{ .path }}
-            pathType: {{ .pathType | default "Prefix" }}
-            backend:
-              service:
-                name: {{ .serviceName }}
-                port:
-                  number: {{ .servicePort }}
-          {{- end }}
-{{- end }}
\ No newline at end of file
diff --git a/bin/k8s/templates/minio-ingress.yaml 
b/bin/k8s/templates/minio-ingress.yaml
deleted file mode 100644
index 24bfab2cd7..0000000000
--- a/bin/k8s/templates/minio-ingress.yaml
+++ /dev/null
@@ -1,65 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-{{- if .Values.minio.customIngress.enabled }}
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: texera-minio-api-ingress
-  namespace: {{ .Release.Namespace }}
-  annotations:
-    kubernetes.io/ingress.class: {{ 
.Values.minio.customIngress.ingressClassName }}
-    {{- if .Values.minio.customIngress.issuer }}
-    cert-manager.io/issuer: {{ .Values.minio.customIngress.issuer }}
-    {{- end }}
-    nginx.ingress.kubernetes.io/enable-cors: "true"
-    nginx.ingress.kubernetes.io/cors-allow-origin: "{{ 
.Values.minio.customIngress.texeraHostname }}"
-    nginx.ingress.kubernetes.io/cors-allow-methods: "GET, PUT, POST, DELETE, 
OPTIONS"
-    nginx.ingress.kubernetes.io/cors-allow-headers: "*"
-    nginx.ingress.kubernetes.io/cors-expose-headers: "ETag, 
x-amz-meta-custom-header"
-    nginx.ingress.kubernetes.io/cors-max-age: "86400"
-    nginx.ingress.kubernetes.io/proxy-body-size: "0"
-    nginx.ingress.kubernetes.io/proxy-buffering: "off"
-    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
-    nginx.ingress.kubernetes.io/proxy-request-buffering: "off"
-    nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
-    nginx.ingress.kubernetes.io/use-regex: "true"
-    nginx.ingress.kubernetes.io/x-forwarded-proto: "https"
-    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
-    {{- if or .Values.ingressPaths.tlsSecretName .Values.ingressPaths.issuer }}
-    nginx.ingress.kubernetes.io/ssl-redirect: "true"
-    {{- end }}
-spec:
-  ingressClassName: {{ .Values.minio.customIngress.ingressClassName }}
-  {{- if or .Values.ingressPaths.tlsSecretName .Values.ingressPaths.issuer }}
-  tls:
-    - hosts:
-        - {{ .Values.minio.customIngress.minioHostname }}
-      secretName: {{ .Values.ingressPaths.tlsSecretName | default (printf 
"%s-minio-tls" .Release.Name) }}
-  {{- end }}
-  rules:
-    - host: {{ .Values.minio.customIngress.minioHostname }}
-      http:
-        paths:
-          - path: /
-            pathType: Prefix
-            backend:
-              service:
-                name: {{ .Release.Name }}-minio
-                port:
-                  number: 9000
-{{- end }}
diff --git a/bin/k8s/values.yaml b/bin/k8s/values.yaml
index 11594422d3..ee0de26e20 100644
--- a/bin/k8s/values.yaml
+++ b/bin/k8s/values.yaml
@@ -52,7 +52,6 @@ postgresql:
       size: 10Gi
       storageClass: local-path
       existingClaim: "postgresql-data-pvc"
-
     initdb:
       scriptsConfigMap: "postgresql-init-script"
 
@@ -61,12 +60,10 @@ minio:
   image:
     repository: bitnamilegacy/minio
     tag: 2025.3.12-debian-12-r0
-  customIngress:
+  gateway:
     enabled: false
-    ingressClassName: "" # e.g., "nginx"
-    texeraHostname: "" # the url for the texera WITH http or https, e.g., 
"https://texera.example.com";
-    minioHostname: "" # the url for the minio
-    issuer: "" # e.g., "letsencrypt-prod"
+    hostname: "" # the url for the minio, e.g. "minio.example.com"
+    tlsSecretName: "" # e.g. "minio-tls-secret"
   auth:
     rootUser: texera_minio
     rootPassword: password
@@ -168,19 +165,6 @@ accessControlService:
     type: ClusterIP
     port: 9096
 
-# Configs of the envoy proxy, used to routerequests to the computing units
-envoy:
-  replicas: 1
-  image:
-    repository: envoyproxy/envoy
-    tag: v1.31-latest
-  port:
-    10000
-  debug: false
-  service:
-    type: ClusterIP
-    port: 10000
-
 # headless service for the access of computing units
 workflowComputingUnitPool:
   createNamespaces: true
@@ -254,29 +238,6 @@ texeraEnvVars:
   - name: USER_SYS_DOMAIN
     value: ""
 
-# Ingress dependency configs
-ingress-nginx:
-  enabled: true # set to true if nginx is not installed, should be false in 
production
-  controller:
-    replicaCount: 1
-    service:
-      type: NodePort
-      nodePorts:
-        http: 30080
-    ingressClassResource:
-      name: nginx
-      enabled: true
-    resources:
-      limits:
-        cpu: 100m
-        memory: 128Mi
-      requests:
-        cpu: 100m
-        memory: 128Mi
-  rbac:
-    create: true
-
-
 yWebsocketServer:
   name: y-websocket-server
   replicaCount: 1
@@ -310,54 +271,35 @@ metrics-server:
     create: true
   priorityClassName: system-cluster-critical
 
-# Custom Ingress resource configs
-ingressPaths:
-  enabled: true
-  ingressClassName: nginx  # Set to "alb" when deploying on AWS
+gatewayConfig:
+  # Routes are available at bin/k8s/templates/gateway-routes.yaml
+
+  # The hostname for the Gateway listener (HTTP/HTTPS).
+  # e.g., "texera.example.com"
   hostname: ""
-  # Optional TLS secret (manually created)
-  tlsSecretName: ""  # e.g., "texera-tls"
-  # Optional Issuer name for cert-manager
-  issuer: ""  # e.g., "letsencrypt-prod"
-  paths:
-    - path: /api/computing-unit
-      serviceName: workflow-computing-unit-manager-svc
-      servicePort: 8888
-    - path: /api/compile
-      serviceName: workflow-compiling-service-svc
-      servicePort: 9090
-    - path: /api/dataset
-      serviceName: file-service-svc
-      servicePort: 9092
-    - path: /api/access/dataset
-      serviceName: file-service-svc
-      servicePort: 9092
-    - path: /api/access/computing-unit
-      serviceName: workflow-computing-unit-manager-svc
-      servicePort: 8888
-    - path: /api/config
-      serviceName: config-service-svc
-      servicePort: 9094
-    - path: /wsapi/workflow-websocket
-      serviceName: envoy-svc
-      servicePort: 10000
-    - path: /api/executions/*/stats/*
-      pathType: ImplementationSpecific
-      serviceName: envoy-svc
-      servicePort: 10000
-    - path: /api/executions/result/export/*
-      pathType: ImplementationSpecific
-      serviceName: envoy-svc
-      servicePort: 10000
-    - path: /api
-      serviceName: webserver-svc
-      servicePort: 8080
-    - path: /rtc
-      serviceName: y-websocket-server-svc
-      servicePort: 1234
-    - path: /python-language-server
-      serviceName: python-language-server-svc
-      servicePort: 3000
-    - path: /
-      serviceName: webserver-svc
-      servicePort: 8080
+
+  # The name of the cert-manager Issuer or ClusterIssuer to use for obtaining 
certificates.
+  # This requires cert-manager to be installed in the cluster.
+  # You can find available ClusterIssuers with: `kubectl get clusterissuers`
+  # You can find available Issuers with: `kubectl get issuers -A`
+  # e.g., "letsencrypt-prod"
+  issuer: ""
+
+  # The Kind of the issuer specified above. Can be "Issuer" or "ClusterIssuer".
+  # If you found it via `kubectl get clusterissuers`, use "ClusterIssuer".
+  # If you found it via `kubectl get issuers`, use "Issuer".
+  # defaults to "Issuer" if not specified.
+  issuerKind: "Issuer"
+
+  # The name of the Secret where the signed certificate should be stored.
+  # If empty, it defaults to "{{ .Release.Name }}-cert".
+  # e.g., "texera-tls"
+  tlsSecretName: ""
+
+# Envoy Gateway Configuration
+envoy-gateway:
+  config:
+    envoyGateway:
+      extensionApis:
+        enableBackend: true
+        enableEnvoyPatchPolicy: true
diff --git a/common/config/src/main/resources/kubernetes.conf 
b/common/config/src/main/resources/kubernetes.conf
index f40fe55ea2..e85924e570 100644
--- a/common/config/src/main/resources/kubernetes.conf
+++ b/common/config/src/main/resources/kubernetes.conf
@@ -20,7 +20,10 @@ kubernetes {
   enabled = false
   enabled = ${?KUBERNETES_COMPUTING_UNIT_ENABLED}
 
-  compute-unit-pool-namespace = "workflow-computing-unit-pool"
+  compute-unit-pool-name = "texera-workflow-computing-unit"
+  compute-unit-pool-name = ${?KUBERNETES_COMPUTE_UNIT_POOL_NAME}
+
+  compute-unit-pool-namespace = "texera-workflow-computing-unit-pool"
   compute-unit-pool-namespace = ${?KUBERNETES_COMPUTE_UNIT_POOL_NAMESPACE}
 
   compute-unit-service-name = "workflow-computing-unit-svc"
diff --git 
a/common/config/src/main/scala/org/apache/texera/config/KubernetesConfig.scala 
b/common/config/src/main/scala/org/apache/texera/config/KubernetesConfig.scala
index 7f8763e894..7f9a730fe8 100644
--- 
a/common/config/src/main/scala/org/apache/texera/config/KubernetesConfig.scala
+++ 
b/common/config/src/main/scala/org/apache/texera/config/KubernetesConfig.scala
@@ -28,6 +28,7 @@ object KubernetesConfig {
 
   // Access the Kubernetes settings with environment variable fallback
   val computeUnitServiceName: String = 
conf.getString("kubernetes.compute-unit-service-name")
+  val computeUnitPoolName: String = 
conf.getString("kubernetes.compute-unit-pool-name")
   val computeUnitPoolNamespace: String = 
conf.getString("kubernetes.compute-unit-pool-namespace")
   val computeUnitImageName: String = conf.getString("kubernetes.image-name")
   val computingUnitImagePullPolicy: String = 
conf.getString("kubernetes.image-pull-policy")


Reply via email to