JS 404 error if deploy web application with K8s ingress

4/14/2021

I'm trying the official example Example: Deploying PHP Guestbook application with MongoDB.

Everything is good, but when I deploy a ingress for it, I can see next in chrome network debug (Here, 31083 is the nodeport):

Request URL: http://10.192.244.109:31083/gb 200 OK
Request URL: http://10.192.244.109:31083/controllers.js 404 Not Found

ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gb-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /gb
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

ingress-nginx: (Use the one here)

apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-3.27.0
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 0.45.0
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: NodePort
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

The source code of K8s guestbook index page which I get from chrome:

<html ng-app="guestbook">
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <title>Guestbook</title>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
    <script src="controllers.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.js"></script>
  </head>
  <body ng-controller="guestbookCtrl">
    <div style="width: 50%; margin-left: 20px">
      <h2>Guestbook</h2>
    <form>
    <fieldset>
    <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br>
    <button type="button" class="btn btn-primary" ng-click="controller.onguestbook()">Submit</button>
    </fieldset>
    </form>
    <div>
      <div ng-repeat="msg in messages track by $index">
        {{msg}}
      </div>
    </div>
    </div>
  </body>
</html>

I know my ingress just specify /gb prefix, so http://10.192.244.109:31083/controllers.js can't route to correct service, but how can I make it work?

I think about maybe could add another ingress rule for js rewrite, but what if I have more than one application? Any suggestion?

-- atline
kubernetes
kubernetes-ingress
nginx-ingress

1 Answer

4/14/2021

You should be able to do this with the correct rewrite-rule and path pattern:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: gb-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
  - http:
      paths:
      - path: /gb(/|$)(.*)
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

This will rewrite your requests in the following way:

-- chresse
Source: StackOverflow