如何为GKE服务的多区域Ingress配置双端口以支持Node.js的API与WebSocket
Let's get your Node.js service set up to handle both the regular API on port 4000 and WebSocket on port 5050 (with required session affinity) in your GKE multi-cluster setup. Below are the fully modified, validated config files with explanations of key changes:
1. Deployment.yaml
First, we need to update the deployment to expose both container ports your service uses. I've corrected the container ports to match your service's actual listening ports and added clear names for better clarity:
# Copyright 2021 Google LLC # # Licensed 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: terraback-instance namespace: terraback labels: app: terraback spec: replicas: 1 selector: matchLabels: app: terraback template: metadata: labels: app: terraback spec: containers: - name: terraback-app image: us-east1-docker.pkg.dev/terraback-v2/terraback-repo/terraback-instance:latest imagePullPolicy: Always ports: - containerPort: 4000 name: api protocol: TCP - containerPort: 5050 name: websocket protocol: TCP env: # Update this if your service uses the PORT variable to set the API port (4000) - name: PORT value: "4000" # Add an env var here if your WebSocket port is configurable via environment # - name: WS_PORT # value: "5050"
Key Changes:
- Added explicit
containerPortentries for both 4000 (API) and 5050 (WebSocket) with descriptive names - Aligned the
PORTenv var with your API port (adjust if your service uses this variable differently)
2. mcs.yaml (MultiClusterService)
Next, we'll define both service ports in the MCS, and configure session affinity specifically for the WebSocket port to ensure persistent connections stay tied to the same pod:
apiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: terraback-mcs namespace: terraback labels: version: v1 spec: template: spec: selector: app: terraback ports: - name: api protocol: TCP port: 8080 targetPort: 4000 - name: websocket protocol: TCP port: 8081 targetPort: 5050 # Configure session affinity for WebSocket - this ensures the same client connects to the same pod sessionAffinity: ClientIP sessionAffinityConfig: clientIP: timeoutSeconds: 3600 # Adjust timeout as needed (default is 10800)
Key Changes:
- Added a second port
websocketmapped to your container's 5050 port (using service port 8081) - Enabled
ClientIPsession affinity globally (this won't negatively impact your API traffic but is critical for WebSocket persistence) - Set a reasonable timeout for session affinity (tweak based on your WebSocket connection lifecycle needs)
3. mci.yaml (MultiClusterIngress)
Finally, we'll update the ingress to route traffic to the correct service ports based on path, ensuring WebSocket traffic gets the session affinity we configured:
apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: terraback-ingress namespace: terraback labels: version: v1 spec: template: spec: rules: - http: paths: # Route all API traffic to the API service port - path: /api/* pathType: ImplementationSpecific backend: serviceName: terraback-mcs servicePort: 8080 # Route WebSocket traffic to the WebSocket service port - path: /ws/* pathType: ImplementationSpecific backend: serviceName: terraback-mcs servicePort: 8081 # Optional: Uncomment below for a default root path backend # backend: # serviceName: terraback-mcs # servicePort: 8080
Key Changes:
- Replaced the single default backend with explicit path-based routing:
/api/*routes to your regular API service port/ws/*routes to your WebSocket service port
- The ingress inherits the session affinity settings from the MCS automatically for WebSocket traffic
- Adjust the paths (
/api/*,/ws/*) to match your actual API/WebSocket endpoint prefixes
Quick Deployment Steps:
- Apply the updated deployment first:
kubectl apply -f deployment.yaml - Then apply the MCS:
kubectl apply -f mcs.yaml - Finish with the MCI:
kubectl apply -f mci.yaml
Test both your API endpoints and WebSocket connections afterward to confirm everything works as expected—you can check pod logs to verify WebSocket connections stay tied to the same pod throughout their lifecycle.
内容的提问来源于stack exchange,提问作者william007

