Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP2 - configuration #790

Closed
f3l1x opened this issue Oct 31, 2016 · 26 comments
Closed

HTTP2 - configuration #790

f3l1x opened this issue Oct 31, 2016 · 26 comments
Labels
Milestone

Comments

@f3l1x
Copy link

f3l1x commented Oct 31, 2016

Could you please help me to setup up http2? Is there any special configuration for that? This tester (https://tools.keycdn.com/http2-test) told me it's not http2. Thank you for helping me.

@emilevauge
Copy link
Member

You need to enable TLS to get http2 :)

@f3l1x
Copy link
Author

f3l1x commented Nov 1, 2016

I'm using ACME for getting SSL certificates, like this:

[entryPoints]
  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

Does it need any other setting?

@f3l1x
Copy link
Author

f3l1x commented Nov 8, 2016

ping @emilevauge

@trecloux
Copy link
Contributor

trecloux commented Nov 8, 2016

@f3l1x Did you run the test using http or https ?

@f3l1x
Copy link
Author

f3l1x commented Nov 8, 2016

@trecloux Both. Any other tips?

@trecloux
Copy link
Contributor

trecloux commented Nov 8, 2016

@f3l1x can you share your configuration ?

@f3l1x
Copy link
Author

f3l1x commented Nov 8, 2016

defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.http]
  address = ":80"
  compress = true
    [entryPoints.http.redirect]
    entryPoint = "https"

  [entryPoints.https]
  address = ":443"
    [entryPoints.https.tls]

[acme]

email = "email"
storage = "/path/to/acme.json"
entryPoint = "https"

[[acme.domains]]
 main = "redmine.domain.tld"
 sans = ["redmine.domain.tld"]

[file]

[backends]
  [backends.redmine]
    [backends.redmine.servers.node1]
      url = "http://{IP}"

[frontends]
  [frontends.redmine]
  backend = "redmine"
  passHostHeader = true
    [frontends.redmine.routes.entry]
    rule = "Host: redmine.domain.tld"

@trecloux
Copy link
Contributor

trecloux commented Nov 9, 2016

Which version of traefik are you using ?

@f3l1x
Copy link
Author

f3l1x commented Nov 9, 2016

@trecloux v1.1.0-rc2.

@trecloux
Copy link
Contributor

trecloux commented Nov 9, 2016

@f3l1x can you please try with v1.0.3
I created a simple test to check HTTP2 : https://github.com/trecloux/traefik-http2-demo
The test is OK with v1.0.3 and not with 1.1.0-rc2 and 1.1.0-rc3

@trecloux
Copy link
Contributor

trecloux commented Nov 9, 2016

@emilevauge I tried to activate http2 logs with GODEBUG=http2debug=2 do you have any tip to activate logs ?

@emilevauge emilevauge added this to the 1.1 milestone Nov 9, 2016
@emilevauge
Copy link
Member

Thanks a lot @trecloux for investigating. I confirm that the issue comes from go 1.7 update:

The server's Serve method now only enables HTTP/2 support if the Server.TLSConfig field is nil or includes "h2" in its TLSConfig.NextProtos.

https://golang.org/doc/go1.7

When setting TLSConfig.NextProtos = []string{"h2"}, I get http2...

@emilevauge
Copy link
Member

Fixed in #814

@f3l1x
Copy link
Author

f3l1x commented Nov 15, 2016

Confirmed: 1.1.0-rc4 works. Good job guys!

@andrewwebber
Copy link

Has anyone testing this with gRPC?

I cannot proxy a gRPC backend and get the following error:
gRPC requires HTTP/2

Framer 0xc4200740d0: read DATA flags=END_STREAM stream=1 len=21 data="gRPC requires HTTP/2\n"

This is because the backend is called with http version 1

When comparing a gRPC client connecting directly to the backend there is the following log difference backend side

gRPC client -> gRPC backend
content-type header: application/grpc, method: POST, proto-major: 2, content-type: application/grpc

gRPC client -> traefik -> gRPC backend
content-type header: application/grpc, method: POST, proto-major: 1, content-type: application/grpc

The following pattern is commonly used to have an http endpoint that supports http V1 and gRPC

func grpcHandlerFunc(rpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		log.Printf("content-type header: %v, method: %v, proto-major: %v, content-type: %s", r.Header.Get("Content-Type"), r.Method, r.ProtoMajor, r.Header.Get("Content-Type"))

		if r.ProtoMajor == 2 && (strings.Contains(r.Header.Get("Content-Type"), "application/grpc") || r.Method == "PRI") {
			log.Printf("handling gRPC request")
			rpcServer.ServeHTTP(w, r)
			return
		}

		log.Printf("handling regular HTTP1.x/2 request")
		otherHandler.ServeHTTP(w, r)
	})
}

This logic works with nghttpx proxy

@johnbelamaric
Copy link

johnbelamaric commented Jan 13, 2017

@andrewwebber I also couldn't get it to work with gRPC. My error was quite different though:

time="2017-01-13T20:37:13Z" level=warning msg="Error forwarding to https://10.222.243.100:8123, err: malformed HTTP response \"\\x00\\x00\\x00\\x04\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x04\\b\\x00\\x00\\x00\\x00\\x00\\x00\\x0e\\xff\\xf1\""

@andrewwebber
Copy link

@johnbelamaric After some frustration I switched to Envoy and now run my gRPC containers on GKE behind Envoy as the load balancer.

@johnbelamaric
Copy link

@andrewwebber Thanks, I'll check that out.

@irfn
Copy link

irfn commented Jan 14, 2017

I am facing a similar issue @andrewwebber @johnbelamaric .
I would prefer traefik if we could get it to work but i guess ill have to check out Envoy now.

@irfn
Copy link

irfn commented Jan 14, 2017

This looks related to possible hardcoding in oxy as reported here vulcand/oxy#52

@irfn
Copy link

irfn commented Jan 14, 2017

I tried the above change however my error remains unchanged.
Error forwarding to https://127.0.0.1:5000, err: EOF
@andrewwebber can you provide a gist of your config if possible?

@andrewwebber
Copy link

@irfn

{
  "listeners": [
    {
      "port": 443,
      "ssl_context": {
        "alpn_protocols": "h2,http/1.1",
        "cert_chain_file": "./keys/api_public_key",
        "private_key_file": "./keys/api_private_key"
      },
      "filters": [
        {
          "type": "read",
          "name": "http_connection_manager",
          "config": {
            "generate_request_id" : false,
            "codec_type": "auto",
            "stat_prefix": "ingress_http",
            "access_log": [{
              "path": "./envoy.txt",
              "filter": {"type": "logical_and", "filters": [
                  {"type": "logical_or", "filters": [
                      {"type": "status_code", "op": ">=", "value": 200},
                      {"type": "status_code", "op": "=", "value": 0},
                      {"type": "duration", "op": ">=", "value": 2000},
                      {"type": "traceable_request"}
                    ]
                  },
                  {"type": "not_healthcheck"}
                ]
              }
            }],
            "route_config": {
              "virtual_hosts": [
                {
                  "name": "ingress_http",
                  "domains": ["*"],
                  "routes": [
                    {
                      "prefix": "/",
                      "cluster": "serviceGrpc"
                    }
                  ]
                }
              ]
            },
            "filters": [
              { "type": "decoder", "name": "buffer",
                "config": {
                  "max_request_bytes": 5242880,
                  "max_request_time_s": 120
                }
              },
              {
                "type": "decoder",
                "name": "router",
                "config": {}
              }
            ]
          }
        }
      ]
    }
  ],
  "admin": {
    "access_log_path": "/dev/null",
    "port": 8001
  },
  "cluster_manager": {
    "clusters": [
      {
        "name": "serviceGrpc",
        "connect_timeout_ms": 250,
        "type": "strict_dns",
        "lb_type": "round_robin",
        "features": "http2",
        "ssl_context": {
          "alpn_protocols": "h2"
        },
        "hosts": [
          {
            "url": "tcp://originsinfo-apiserver-service:1984"
          }
        ]
      }
    ]
  }
}

@emilevauge emilevauge reopened this Jan 14, 2017
@emilevauge emilevauge added the priority/P0 needs hot fix label Jan 14, 2017
@drewwells
Copy link
Contributor

any progress on this? It seems like the solution has been outlined by @andrewwebber very nicely

@timoreimann
Copy link
Contributor

I lost track, sorry. What's the designated solution?

@drewwells
Copy link
Contributor

After digging into this, I didn't find any of the code samples alleviated the problem. It appears to be a std library error thrown while doing the initial... handshake? The http1 hardcoding in oxy isn't executed prior to this error stopping the request. I'll continue looking for when the error happens.

@krancour krancour mentioned this issue Apr 11, 2017
@emilevauge
Copy link
Member

emilevauge commented Apr 19, 2017

To my mind, this is more an issue with GRPC, not http2.
We need more investigation on this, but http2 is working (without GRPC).
I suggest we close this issue and continue to #1419.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

10 participants