Angular black page behind nginx and kubernetes

5/17/2020

I am trying to deploy my microservice application on Kubernetes using minikube. I have an angular front service and two backend services and I used this configuration to lunch deployment and services

apiVersion: apps/v1
kind: Deployment
metadata:
  name: searchservice
  labels:
    app: searchservice
spec:
  selector:
    matchLabels:
      app: searchservice
  template:
    metadata:
      labels:
        app: searchservice
    spec:
      containers:
      - name: searchservice
        image: ayoubdali/searchservice:0.1.9-SNAPSHOT
        ports:
        - containerPort: 8070
---
apiVersion: v1
kind: Service
metadata:
  name: searchservice
spec:
  type: NodePort
  selector:
    app: searchservice
  ports:
  - protocol: TCP
   # Port accessible inside cluster
    port: 8070
   # Port to forward to inside the pod
    targetPort: 8070
    nodePort: 31000

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: searchappfront
  labels:
    app: searchappfront
spec:
  selector:
    matchLabels:
      app: searchappfront
  template:
    metadata:
      labels:
        app: searchappfront
    spec:
      containers:
      - name: searchappfront
        image: ayoubdali/searchappfront:0.6.5
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: searchappfront
spec:
  type: NodePort
  selector:
    app: searchappfront
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: subscriberservice
  labels:
    app: subscriberservice
spec:
  selector:
    matchLabels:
      app: subscriberservice
  template:
    metadata:
      labels:
        app: subscriberservice
    spec:
      containers:
      - name: subscriberservice
        image: ayoubdali/subscriber-service:0.1.0-SNAPSHOT 
        ports:
        - containerPort: 8090
---
apiVersion: v1
kind: Service
metadata:
  name: subscriberservice
spec:
  type: NodePort
  selector:
    app: subscriberservice
  ports:
  - protocol: TCP
    port: 8090
    #targetPort: 80
    nodePort: 31102

and this configuration for the ingress service

 apiVersion: networking.k8s.io/v1beta1 # for versions before 1.14 use extensions/v1beta1
 kind: Ingress
 metadata:
   name: ingress
   annotations:
     nginx.ingress.kubernetes.io/rewrite-target: /$1
 spec:
   rules:
   - host: app.info
     http:
       paths:
       - path: /
         backend:
           serviceName: searchappfront
           servicePort: 80
       - path: /api
         backend:
           serviceName: subscriberservice
           servicePort: 8090    

But when I open app.info/ I got a blank page with javascript error like

Failed to load module script: The server responded with a non-JavaScript MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

I tried deploying the application using docker compose and it works fine.

-- daliDV
angular
kubernetes
minikube
nginx-ingress

1 Answer

5/18/2020

When you enable rewrite-target it will create a capture group and send it to the appropriate service.

If you set the capture group to $1, everything after the root / will be discarted and the request is forwarded to root path.

  • In order to forward the full request, remove the rewrite-target line, your Ingress should be like this:
apiVersion: networking.k8s.io/v1beta1
 kind: Ingress
 metadata:
   name: ingress
   annotations:
     kubernetes.io/ingress.class: nginx
 spec:
   rules:
   - host: app.info
     http:
       paths:
       - path: /
         backend:
           serviceName: searchappfront
           servicePort: 80
       - path: /api
         backend:
           serviceName: subscriberservice
           servicePort: 8090    

Example:

  • I've deployed two echo-apps that echoes the requests, I've suppressed the output to show the path and the pod handling it on the background).

    • echo1-app is simulating searchappfront
    • echo2-app is simulating subscriberservice
  • This is the ingress I'm using:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: echo-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: app.info
      http:
        paths:
          - path: /
            backend:
              serviceName: echo1-svc
              servicePort: 80
          - path: /api
            backend:
              serviceName: echo2-svc
              servicePort: 80
  • Now let's test the commands:
$ kubectl get ingress
NAME           HOSTS      ADDRESS        PORTS   AGE
echo-ingress   app.info   35.188.7.149   80      73m

$ kubectl get pods
NAME                            READY   STATUS    RESTARTS   AGE
echo1-deploy-764d5df7cf-2wx4m   1/1     Running   0          74m
echo2-deploy-7bcb8f8d5f-xlknt   1/1     Running   0          74m

$ tail -n 1 /etc/hosts
35.188.7.149 app.info

$ curl app.info
{"path": "/",
  "os": {"hostname": "echo1-deploy-764d5df7cf-2wx4m"}}

$ curl app.info/foo/bar
{"path": "/foo/bar",
  "os": {"hostname": "echo1-deploy-764d5df7cf-2wx4m"}}

$ curl app.info/api
{"path": "/api",
  "os": {"hostname": "echo2-deploy-7bcb8f8d5f-xlknt"}}

$ curl app.info/api/foo
{"path": "/api/foo",
  "os": {"hostname": "echo2-deploy-7bcb8f8d5f-xlknt"}}

$ curl app.info/api/foo/bar
{"path": "/api/foo/bar",
  "os": {"hostname": "echo2-deploy-7bcb8f8d5f-xlknt"}}

To summarize:

  • Requests to app.info/ will be delivered to echo1-app as /
  • Requests to app.info/foo/bar will be delivered to echo1-app as /foo/bar
  • Requests to app.info/api will be delivered to echo2-app as /api
  • Requests to app.info/api/foo/bar will be delivered to echo2-app as /api/foo/bar

Considerations about your environment:

  • I understand you are using NodePort to test the access, but if you wish to close that access, you can set the services as ClusterIP since it will be Ingress job to handle the incoming traffic.

  • Nodeport port range by default is 30000-32767.

    • searchappfront has it set to 80, which will be ignored and the correct port will be attributed.

If you have any question let me know in the comments.

-- willrof
Source: StackOverflow