I have two pods, each with a LoadBalancer svc. Each service's IP address is working.
My first service is:
apiVersion: v1
kind: Service
metadata:
name: hello-world-1
spec:
type: LoadBalancer
selector:
greeting: hello
version: one
ports:
- protocol: TCP
port: 60000
targetPort: 50000
My second service is:
apiVersion: v1
kind: Service
metadata:
name: hello-world-2
spec:
type: LoadBalancer
selector:
greeting: hello
version: two
ports:
- protocol: TCP
port: 5000
targetPort: 5000
My ingress is:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: gce
spec:
defaultBackend:
service:
name: hello-world-1
port:
number: 60000
rules:
- http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: hello-world-1
port:
number: 60000
- path: /v2
pathType: ImplementationSpecific
backend:
service:
name: hello-world-2
port:
number: 5000
Only the first route works this way and when I put
<MY_IP>/v2
in the url bar I get
Cannot GET /v2
How do I configure the ingress so it hits the / route when no subpath is specified and the /v2 route when /v2 is specified?
If I change the first route to
backend:
service:
name: hello-world-2
port:
number: 5000
and get rid of the second one it works.
but if I change the route to /v2 it stops working?
***** EDIT *****
Following this tutorial here ingress tut I tried changing the yaml so the different routes were on different ports and this breaks it. Does anybody know why?
CodePudding user response:
By default, when you create an ingress in your cluster, GKE creates an HTTP(S) load balancer and configures it to route traffic to your application, as stated in the following document [1]. So, you should not be configuring your services as LoadBalancer type, instead you need to configure them as NodePort.
Here, you can follow an example of a complete implementation similar to what you want to accomplish:
- Create a manifest that runs the application container image in the specified port, for each version:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web1
namespace: default
spec:
selector:
matchLabels:
run: web1
template:
metadata:
labels:
run: web1
spec:
containers:
- image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
name: web1
ports:
- containerPort: 8000
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web2
namespace: default
spec:
selector:
matchLabels:
run: web2
template:
metadata:
labels:
run: web2
spec:
containers:
- image: gcr.io/google-samples/hello-app:2.0
imagePullPolicy: IfNotPresent
name: web2
ports:
- containerPort: 9000
protocol: TCP
- Create two services (one for each version) as type NodePort. A very important note at this step, is that the targetPort specified should be the one the application is listening on, in my case both services are pointing to port 8080 since I am using the same application but different versions:
apiVersion: v1
kind: Service
metadata:
name: web1
namespace: default
spec:
ports:
- port: 8000
protocol: TCP
targetPort: 8080
selector:
run: web1
type: NodePort
---
apiVersion: v1
kind: Service
metadata:
name: web2
namespace: default
spec:
ports:
- port: 9000
protocol: TCP
targetPort: 8080
selector:
run: web2
type: NodePort
- Finally, you need to create the ingress with the path rules:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: gce
spec:
defaultBackend:
service:
name: web1
port:
number: 8000
rules:
- http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: web1
port:
number: 8000
- path: /v2
pathType: ImplementationSpecific
backend:
service:
name: web2
port:
number: 9000
If you configured everything correctly, the output of the command kubectl get ingress my-ingress should be something like this:
NAME CLASS HOSTS ADDRESS PORTS AGE
my-ingress <none> * <External IP> 80 149m
And, if your services are pointing to the correct ports, and your applications are listening on those ports, doing a curl to your external ip (curl External IP) should get you to the version one of your application, here is my example output:
Hello, world!
Version: 1.0.0
Hostname: web1-xxxxxxxxxxxxxx
Doing a curl to your external ip /v2 (curl External IP/v2) should get you to the version two of your application:
Hello, world!
Version: 2.0.0
Hostname: web2-xxxxxxxxxxxxxx
[1] https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer