Kubernetes Nginx Controller/Ingress Bad Gateway (502)

967 Views Asked by At

My goal is to route traffic to a frontend (web-frontend) and backend (public-api) service using nginx controller and two ingress rules. public-api works over https, but web-frontend does not and returns 502 Bad Gateway. Each service has its own ingress to allow separate url rewrites. I am using the aws nginx controller (https://kubernetes.github.io/ingress-nginx/deploy/#aws).

public-api is listening on 8000 and no port is exposed in its dockerfile. In web-frontends dockerfile several ports have been exposed for good measure (80, 443, 8080).

I don't understand why public-api is working when its ingress configuration is nearly identical to web-frontend. Both routes worked before adding tls certificate management.

Thanks for the help!

Basic networking:

public-api ingress /v1/ -> public-api:443 -> NodePort Service ->8000 -> Deployment listening on 8000.
web-frontend ingress / -> public-api:443 -> NodePort Service -> 8080 -> Deployment listening on 8080.

Ingress Describe:

public-api:

Name:             public-api-rule
Namespace:        default
Address:          localhost
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  staging-certificate terminates <domain>
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  staging.grouphouse.io
                         /v([0-9])/(.*)   public-api:443 (10.1.3.158:8000)
Annotations:             cert-manager.io/cluster-issuer: letsencrypt-staging
                         external-dns.alpha.kubernetes.io/hostname: <domain>
                         kubernetes.io/ingress.class: nginx
                         nginx.ingress.kubernetes.io/rewrite-target: /v$1/$2
                         nginx.ingress.kubernetes.io/use-regex: true

web-frontend:

Name:             web-frontend-rule
Namespace:        default
Address:          localhost
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
  staging-certificate terminates <domain>
Rules:
  Host                   Path  Backends
  ----                   ----  --------
  staging.grouphouse.io
                         /(.*)   web-frontend:443 (10.1.3.163:8080)
Annotations:             cert-manager.io/cluster-issuer: letsencrypt-staging
                         external-dns.alpha.kubernetes.io/hostname: <domain>
                         kubernetes.io/ingress.class: nginx
                         nginx.ingress.kubernetes.io/rewrite-target: /$1
                         nginx.ingress.kubernetes.io/use-regex: true

YAMLs:

public-api:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: public-api-rule
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
    nginx.ingress.kubernetes.io/rewrite-target: /v$1/$2
    nginx.ingress.kubernetes.io/use-regex: "true"
    external-dns.alpha.kubernetes.io/hostname: {{ .Values.domain }}
spec:
  tls:
    - hosts:
        - {{ .Values.domain }}
      secretName: staging-certificate
  rules:
    - host: {{ .Values.domain }}
      http:
        paths:
          - path: /v([0-9])/(.*)
            pathType: Prefix
            backend:
              service:
                name: public-api
                port:
                  number: 443
apiVersion: v1
kind: Service
metadata:
  name: public-api
spec:
  type: NodePort
  selector:
    app: public-api
  ports:
    - port: 443
      protocol: TCP
      targetPort: 8000
apiVersion: apps/v1
kind: Deployment
metadata:
  name: public-api
  labels:
    app: public-api
spec:
  selector:
    matchLabels:
      app: public-api
  template:
    metadata:
      labels:
        app: public-api
    spec:
      containers:
        - name: public-api
          image: <image> 
          imagePullPolicy: Always
          ports:
            - containerPort: 8000

web-frontend:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-frontend-rule
  annotations:
    kubernetes.io/ingress.class: "nginx"
    cert-manager.io/cluster-issuer: "letsencrypt-staging"
    external-dns.alpha.kubernetes.io/hostname: {{ .Values.domain }}
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/use-regex: "true"
spec:
  tls:
    - hosts:
        - {{ .Values.domain }}
      secretName: staging-certificate
  rules:
    - host: {{ .Values.domain }}
      http:
        paths:
          - path: /(.*)
            pathType: Prefix
            backend:
              service:
                name: web-frontend
                port:
                  number: 443
apiVersion: v1
kind: Service
metadata:
  name:  web-frontend
spec:
  type: NodePort
  selector:
      app: web-frontend
  ports:
    - port: 443
      protocol: TCP
      targetPort: 8080
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-frontend
  labels:
    app: web-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-frontend
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 0
      maxSurge: 1
  template:
    metadata:
      labels:
        app: web-frontend
    spec:
      containers:
        - name: web-frontend
          image: <image> 
          imagePullPolicy: Always
          ports:
            - name: web-frontend
              containerPort: 8080
0

There are 0 best solutions below