I have two ports on node.js, 4000 and 5050, open for normal api and web socket (require session affinity for web socket) respectively.
Below is my mcs.yaml
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: terraback-mcs
namespace: terraback
labels:
version: v1
spec:
template:
spec:
selector:
app: terraback
ports:
- name: web
protocol: TCP
port: 8080
targetPort: 4000
mci.yaml
apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
name: terraback-ingress
namespace: terraback
labels:
version: v1
spec:
template:
spec:
backend:
serviceName: terraback-mcs
servicePort: 8080
deployment.yaml
# 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
# Replace $LOCATION with your Artifact Registry location (e.g., us-west1).
# Replace $GCLOUD_PROJECT with your project ID.
image: us-east1-docker.pkg.dev/terraback-v2/terraback-repo/terraback-instance:latest
# This app listens on port 8080 for web traffic by default.
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: PORT
value: "8080"
---
How should I make changes to allow additional port 5050?
I have tried the method from Zer0, with the modification of mci from validation error for multiingress yaml file for GKE and it works.
CodePudding user response:
You need to create an additional port in your terraback-mcs
service. This will serve the web socket connections. The following changes will be required:
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: terraback-mcs
namespace: terraback
labels:
version: v1
spec:
template:
spec:
selector:
app: terraback
ports:
- name: web
protocol: TCP
port: 8080
targetPort: 4000
- name: web-socket
protocol: TCP
port: 8081
targetPort: 5050
You will then need to add an additional backend to your MultiClusterIngress
. This can be done as follows:
apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
name: terraback-ingress
namespace: terraback
labels:
version: v1
spec:
template:
spec:
backend:
serviceName: terraback-mcs
servicePort: 8080 # <==== This gets routed to service port 8080->4000
rules:
- host: web.socket.hostname #<==== adjust this as needed
backend:
serviceName: terraback-mcs
servicePort: 8081 # <=== This gets routed to servicePort 8081 => 5050
This Ingress
will route incoming requests to the provided host
if there is a match. Otherwise, the connection will be forwarded to the default
host, which will be your API service.
I hope this gives you an idea of how to configure multiple ports with MultiClusterService
and MultiClusterIngress
objects. I'm unsure what is the point of the terraback-instance
deployment. I don't believe this is your Node.JS application, since it neither exposes port 5050
nor port 4000
. It it is your application indeed, then you need to expose both ports, correctly as:
ports:
- name: api-port
containerPort: 4000
- name: web-socket-port
containerPort: 5050
Summary
The traffic flow will be like this:
- All incoming traffic on the hostname
web.socket.hostname
will be rerouted by the ingress to the service with port8081
. This, will be routed by the service, to the container port5050
. - All the incoming traffic other than the hostname above, will be rerouted by the Ingress to the Service on port
8080
. This, will be routed by the service, to the container port4000
.
Understand that Ingress objects process the incoming traffic on the basis of a host
and path
matching. And forward to backend services on certain ports based on the result of this match. In the current configuration, the ingress rule is defining a default backend only, because of which all the traffic coming in, will be forwarded to the same backend service configured.
Once you make these changes, the ingress will separate traffic based on the host
and forward the traffic to the appropriate service backend.
Hope this helps.