Azure Kubernetes Nginx Ingress: How do I properly route to an API service and an Nginx web server with HTTPS and avoid 502?

12/9/2020

I have 2 services, one serves up a rest API and the other serves up static content via nginx web server. I can retrieve the static content from the pod running an nginx web server via the ingress controller using https provided that I don't use the following annotation within the ingress yaml

nginx.ingress.kubernetes.io/backend-protocol: HTTPS

However, the backend API service no longer works. If I add that annotation back, the backend service URL https://fqdn/restservices/engine-rest/v1/api works but the front end https://fqdn/ web server throws a 502.

Ingress

Ingress
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress
  namespace: namespace-abc
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
  rules:
    - http:
        paths:
          - path: /restservices/engine-rest/v1
            backend:
              serviceName: a
              servicePort: 8080
          - path: /
            backend:
              serviceName: b
              servicePort: 8011

Service API

kind: Service
apiVersion: v1
metadata:
  name: a
  namespace:  namespace-abc
  
  labels:
    app: a
    version: 1
spec:
  ports:
    - name: https
      protocol: TCP
      port: 80
      targetPort: 8080
      nodePort: 31019
  selector:
    app: a
    version: 1
  clusterIP: <cluster ip>
  type: LoadBalancer
  sessionAffinity: ClientIP
  externalTrafficPolicy: Cluster
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800

Service UI

kind: Service
apiVersion: v1
metadata:
  name: b
  namespace: namespace-abc
  labels:
    app: b
    version: 1
  annotations:
spec:
  ports:
    - name: http
      protocol: TCP
      port: 8011
      targetPort: 8011
      nodePort: 32620
  selector:
    app: b
    version: 1
  clusterIP: <cluster ip>
  type: LoadBalancer
  sessionAffinity: None
  externalTrafficPolicy: Cluster
-- Jay Steven Hamilton
kubernetes
nginx-ingress

1 Answer

12/9/2020

If your problem is that adding nginx.ingress.kubernetes.io/backend-protocol: HTTPS makes service-A work but fails service-B, and removing it makes service-A fail but works for service-B, then the solution is to create two different Ingress objects so they can be annotated independently

---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress-a
  namespace: namespace-abc
  annotations:
    nginx.ingress.kubernetes.io/backend-protocol: HTTPS
spec:
  rules:
    - http:
        paths:
          - path: /restservices/engine-rest/v1
            backend:
              serviceName: a
              servicePort: 8080
---
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: ingress-b
  namespace: namespace-abc
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: b
              servicePort: 8011
-- mdaniel
Source: StackOverflow