5

We have a number of services behind an API gateway which is itself behind ingress-nginx. We're trying to use HTTP/2 to speed up data transfer to the front-end but all of our connections are still being done with HTTP/1.1.

The connection from client to nginx is over HTTPS, but nginx communicates with our API gateway using HTTP, and the gateway also uses HTTP to communicate with the backend services.

Do we need to use HTTPS from end-to-end to get HTTP/2 to work? If so, what's the best way to set this up re: using certificates? If not, what could be causing the connection to drop to HTTP/1.1?

We are using ingress-nginx version 0.21.0, which has nginx 1.15.6 and OpenSSL 1.1.1, which should be sufficient to support TLS 1.3/ALPN/HTTP2. Our nginx-configuration configmap has use-http2 set to true and I can see that the pod's /etc/nginx.conf has a listen ... http2; line.


Edit 10/05/2019:

Further to the comments of @Barry Pollard and @Rico, I've found out that AWS Elastic Load Balancer, which sits in front of our ingress-nginx controller, doesn't support HTTP/2. I've cut nginx out of the stack and our API Gateway is being provisioned its own Network Load Balancer. However, we're still on HTTP/1.1. It looks like ASP.Net Core 2.2's HTTP server Kestrel uses HTTP/2 by default, so I'm not sure why the connection is still dropping to 1.1.

Chris Swinchatt
  • 1,081
  • 2
  • 9
  • 18
  • 1
    No you don’t need HTTPS all the way through. Is it a publicly available endpoint? Can you run it through https://www.ssllabs.com/ssltest/ and confirm ALPN I set to “Yes h2 http/1.1” and also what TLS version and cipher is used by Chrome 70 for example? – Barry Pollard May 09 '19 at 16:14
  • That says TLS 1.3 & ALPN are not supported. I think ELB is the cause. – Chris Swinchatt May 10 '19 at 08:31
  • Were you able to get this working? I am running into the same issue with nginx ingress dropping the connection to Http 1.1 – Jatinshravan Jun 25 '21 at 05:24

1 Answers1

1

Like @BarryPollard said you shouldn't need HTTP/2 end to end to establish HTTP/2 connections on your browser.

It sounds like whatever you are using for a client is dropping to HTTP/1.1, make sure you try with one of the following:

  • Chrome 51
  • Firefox 53
  • Edge 12
  • Internet Explorer 11
  • Opera 38

You didn't specify what architecture is fronting your nginx. Is it connected directly to the internet? or it's going through cloud load balancer? CDN? You can also test with Wireshark as described here.

Rico
  • 58,485
  • 12
  • 111
  • 141
  • 1
    NGINX is behind Elastic Load Balancer. – Chris Swinchatt May 10 '19 at 08:20
  • 1
    For clients I have tried Chrome 73, Firefox 66, IE 11 and Edge 12 and all are saying HTTP/1.1. I'll have a look at configuring ELB, I hadn't considered it. – Chris Swinchatt May 10 '19 at 08:31
  • You need to check what that ELB is configured as. I believe traditional ELBs don't support HTTP/2 – Rico May 11 '19 at 17:18
  • I'm working on getting it configured as a network/application load balancer, but Kubernetes automatically provisions a classic. – Chris Swinchatt May 13 '19 at 07:17
  • You can use an annotation to provision an NLB: https://aws.amazon.com/blogs/opensource/network-load-balancer-support-in-kubernetes-1-9/ . – Rico May 13 '19 at 14:14
  • Right, it's now provisioning an NLB, but it configures it with TCP on port 443 instead of TLS, and setting the `service.beta.kubernetes.io/aws-load-balancer-backend-protocol` annotation to `https` or `ssl` (with the `service.beta.kubernetes.io/aws-load-balancer-ssl-cert` annotation set correctly) makes no difference. If I manually configure the NLB listener with TLS and choose the cert, I get an HTTPS connection, but still no HTTP/2. I have registered a subdomain so that our cert is valid with no luck, still HTTP/1.1. – Chris Swinchatt May 15 '19 at 09:55
  • 2
    The NLB doesn't terminate SSL since it's only layer 4, you will have to terminate SSL on your ingress or nginx (where you configure http2) – Rico May 15 '19 at 15:13