Question

Migrating Heroku Angular app to DO Kubernetes

Posted April 6, 2021 693 views
NginxKubernetesAngular

At present I am running an Angular client app and a Nodejs/Express API on Heroku, and a MongoDB on MongoDB Inc. I have decided to migrate my project to Kubernetes, and selected DigitalOcean (mainly because they’re neither Google nor Amazon).

I have successfully migrated the API to a kubernetes deployment. Following an excellent DO tutorial, I was able to connect the deployment to my domain name through Nginx Ingress and secure it with Cert-Manager. This was the tutorial I followed:
https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nginx-ingress-on-digitalocean-kubernetes-using-helm

I am now working to migrate the Angular client to a k8s deployment and could use advice on troubleshooting. I experienced problems containerizing the app with docker and resolved those by switching the package manager from npm to yarn. The container now successfully runs in a pod (status is ‘running’), and I’ve connected it to my ingress controller. When I try to connect, however, I get the 502 Bad Gateway error. I suspect I’m routing the port incorrectly. Angular apps default to port 4200, and I redirect those to port 80, just as with the tutorial, above.

Here are my yaml files for the deployment and for Ingress. There are four DNS routes. hw1 and hw2 are from the tutorial and are working fine. api is my API and is working fine. I have not included those yaml files. The DNS route for pvg does not work. It points to the “markwilx” deployment. I welcome any suggestion for proceeding with troubleshooting.

Thanks in advance,
Mark

Deployment:

---
apiVersion: v1
kind: Service
metadata:
  name: markwilx
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 4200
  selector:
    app: markwilx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: markwilx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: markwilx
  template:
    metadata:
      labels:
        app: markwilx
    spec:
      containers:
      - name: nginx
        image: registry.digitalocean.com/XXXXXXXX/markwilx:0.3.1
        ports:
        - containerPort: 4200
          protocol: TCP

Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: hello-kubernetes-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - hw1.XXXXXXXXX.org    # This is working
    - hw2.XXXXXXXXX.org    # This is working
    - api.XXXXXXXXX.org    # This is working
    - pvg.XXXXXXXXX.org    # This is NOT working
    secretName: hello-kubernetes-tls
  rules:
  - host: "hw1.XXXXXXXXX.org"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-first
            port:
              number: 80
  - host: "hw2.XXXXXXXXX.org"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-kubernetes-second
            port:
              number: 80
  - host: "api.XXXXXXXXX.org"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: mwx-api
            port:
              number: 80
  - host: "pvg.XXXXXXXXX.org"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: markwilx
            port:
              number: 80
3 comments
  • Update:

    I followed this most excellent Kubernetes debugging flow chart and determined that the pod and service are running correctly and that Ingress is not.
    https://learnk8s.io/troubleshooting-deployments

    Examining ingress with the describe command, I discovered that the default backend could not be found. As pvg does not rely on the backend, I decided not to pursue that error for now.

    Examining the logs for the Ingress pod, I discovered that the service markwilx does not have an active endpoint. Researching this, I found this post, which reports the same problem. His workaround did not solve the problem in my system.

  • Update:

    To ensure there were no configurations in my own Angular code that is causing this problem, I created a basic, default app per the instruction on the Angular website:
    https://angular.io/guide/setup-local

    This basic Angular client will operate on my desktop machine (ng serve), in a Kubernetes pod (kubectl port-forward [pod] 8080:4200) and in a Kubernetes service (kubectl port-forward service/[service] 8080:80). However, I continue to get the 502 Bad Gateway error when attempting to connect to the application from the Internet through Ingress.

    Examining the ingress logs (kubectl logs -n ingress-nginx ingress-nginx) I note the following error message:

    2021/04/11 19:11:54 [error] 423#423: *979014 connect() failed (111: Connection refused) while connecting to upstream, client: XXX.XXX.XXX.XXX, server: pvg.XXXXXXXXX.org, request: "GET / HTTP/2.0", upstream: "http://XX.XXX.X.XXX:4200/", host: "pvg.XXXXXXXXX.org"
    

    It seems that when Ingress attempts to connect an Internet request to an Angular pod, the connection is refused. The closest hint I’ve identified as to the source of this problem is here:
    https://www.digitalocean.com/community/questions/nginx-111-connection-refused-errors
    A number of people are reporting the 111 connection refused error for various reasons: folder permissions, proxy settings, and firewalls. I do not believe my problems are related to this.

    I’ll continue investigating. I will continue posting updates and would appreciate any insights that others may have.

  • Update: As I have not yet received any community assistance with this problem, I want to disclaim that I have also asked this question on StackOverflow. When I receive an answer on either site, I will reference them together. This is the StackOverflow URL:
    https://stackoverflow.com/questions/67054836/502-bad-gateway-error-with-angular-app-in-kubernetes

Submit an answer

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!