Search code examples
amazon-web-serviceskuberneteshaproxy-ingress

haproxy-ingress always sends 404


I have a haproxy-ingress (v0.13.5, default helm setup) in an aws hosted kubernetes cluster (v1.21.2-eks-06eac09) and a single service/deployment. The service is up and running and can be called via curl successfully and the haproxy stats page shows a green backend with the correct ip. Everything looks good to me, but if I call the url I get the default 404 backend unless I configure a default backend with the same service. This brings me to the conclusion that there must be some problem with the host or path mapping, right?. Is there an error in my configuration or is the problem somewhere else?

This is my ingress resource:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-service
  namespace: my-service
  annotations:
    haproxy-ingress.github.io/affinity: "cookie"
    haproxy-ingress.github.io/backend-server-naming: "pod"
    haproxy-ingress.github.io/secure-backends: "true"
    haproxy-ingress.github.io/session-cookie-dynamic: "true"
    haproxy-ingress.github.io/session-cookie-keywords: "indirect nocache httponly maxidle 900"
    haproxy-ingress.github.io/session-cookie-preserve: "true"
    haproxy-ingress.github.io/session-cookie-same-site: "true"
    haproxy-ingress.github.io/slots-min-free: "0"
    haproxy-ingress.github.io/ssl-redirect: "false"
    haproxy-ingress.github.io/strict-host: "true"
spec:
  ingressClassName: haproxy-ingress
  tls:
    - secretName: my-service-tls
  rules:
    - http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: my-service
                port:
                  number: 443
      host: my-service.dev.aws.company.local
#  defaultBackend:
#    service:
#      name: my-service
#      port:
#        number: 443

The ingressclass:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: haproxy-ingress
spec:
  controller: haproxy-ingress.github.io/controller

helm installation command:

helm install haproxy-ingress haproxy-ingress/haproxy-ingress --create-namespace --namespace ingress-controller --set controller.service.type=ClusterIP --version 0.13.5

The generated backend from haproxy.conf

backend my-service_my-service_https
    mode http
    balance roundrobin
    acl https-request ssl_fc
    http-request set-header X-Original-Forwarded-For %[hdr(x-forwarded-for)] if { hdr(x-forwarded-for) -m found }
    http-request del-header x-forwarded-for
    option forwardfor
    cookie INGRESSCOOKIE insert preserve attr SameSite=None secure indirect nocache httponly maxidle 900 dynamic
    dynamic-cookie-key "Ingress"
    http-response set-header Strict-Transport-Security "max-age=15768000" if https-request
    server my-service-0 10.19.25.214:443 weight 1 ssl no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets verify none check inter 2s

generated frontend from haproxy.conf

frontend _front_https
    mode http
    bind :443 ssl alpn h2,http/1.1 crt-list /etc/haproxy/maps/_front_bind_crt.list ca-ignore-err all crt-ignore-err all
    option httplog
    http-request set-var(req.path) path
    http-request set-var(req.host) hdr(host),field(1,:),lower
    http-request set-var(req.base) var(req.host),concat(\#,req.path)
    http-request set-var(req.hostbackend) var(req.base),map_dir(/etc/haproxy/maps/_front_https_host__prefix.map)
    http-request set-header X-Forwarded-Proto https
    http-request del-header X-SSL-Client-CN
    http-request del-header X-SSL-Client-DN
    http-request del-header X-SSL-Client-SHA1
    http-request del-header X-SSL-Client-Cert
    use_backend %[var(req.hostbackend)] if { var(req.hostbackend) -m found }
    use_backend %[var(req.defaultbackend)]
    default_backend _error404

generated maps/_front_https_host__prefix.map

my-service.dev.aws.company.local#/ my-service_my-service_https

Solution

  • I found the problem! The hosts section in my tls definition was missing. This way no /etc/haproxy/maps_front_https_host__begin.map was generated and no there was no mapping configuration in my generated frontend section (http-request set-var(req.hostbackend) var(req.base),lower,map_beg(/etc/haproxy/maps/_front_https_host__begin.map)).

    my fully working ingress is now looking like this (I moved the annotations to a configmap):

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-service
      namespace: my-service
    spec:
      ingressClassName: haproxy-ingress
      tls:
        - secretName: my-service-tls
          hosts:
           - my-service.dev.aws.company.local
      rules:
        - http:
            paths:
              - pathType: Prefix
                path: /
                backend:
                  service:
                    name: my-service
                    port:
                      number: 443
          host: my-service.dev.aws.company.local