Home > Blockchain >  Ingress only routes traffic to one route
Ingress only routes traffic to one route

Time:10-27

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:

  1. 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
  1. 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
  1. 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

  • Related