-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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 support for the Kibana server #7104
Comments
@elastic/kibana-operations - any idea on what to do with this ? I have added enhancement label. |
works for me, but we're a long ways out, at a minimum we need to upgrade hapi, but our bundling patterns for http1 are anti-patterns for http2. to get the single pipelining benefits we'll need to remove concatenation, inline images, etc. if anyone's stumbled on this we would love to hear more about your use case. i do think we should do it but i don't think the web's quite there yet put this at a high priority. in the interim a proxy local to kibana configured for http2 should be okay. |
@jbudz hi! is there any workaround? |
Hey @Asgoret, no new progress for Kibana yet. A reverse proxy local to Kibana is probably the closest option currently. |
@jbudz already in use in red hat version of EFK, but it don't work. If i disable H2 on cluster router all works fine. |
any progress? |
FYI: We're upgrading to hapi v18 in #80468. That should be one less roadblock in order to support http/2 |
Pinging @elastic/kibana-core (Team:Core) |
In prod mode Kibana loads them only once. on the next visit, they are loaded from the browser cache. |
I took a stab adding http/2 support to Kibana. You can find some necessary changes and page load time benchmarks in this PR #123748 There are a few open questions left:
It doesn't look like a lot of work, we can prioritize the work if we think the page load time is one of Kibana's bottlenecks. |
tl:dr; Moving to http2/3 would be a concrete improvement to Dashboard performance and improve the overall developer experience for teams that work on apps like Dashboard, Discover, Lens, Maps ("Analytics"). bsearch introduces overhead kibana server, and some minimal overhead on the client.bsearch is a work-around to http1 connection limit. This work-around is useful for Dashboards. bsearch collects requests on the client on a debounce-interval (introducing a small delay). On the server, it fans out these individual requests to elasticsearh. It then serializes and concatenates these responses and sends them back as a single payload to the client. In turn, the client deserializes the responses back to the original Elasticsearhc response JSON. The overall mechanism is explain here #166206 bsearch introduces a known overhead:
bsearch degrades the developer experiencebsearch introduces additional mental load:
bsearch blocks incremental progress wrt data formatSwitching to one of the more compact output formats supported by Elasticsearch, like smile or CBOR, would be a small, concrete win to reduce the overall network traffic to Dashboards. Some of these benefits are wasted on the client<->kibana-server connection if bsearch remains as a middleware. We would still need the overhead of the reserialization and concatenation of responses. It would also require additional investment in bsearch, something we likely no longer want to do (see all other reasons) working towards a thin kibana serverThe removal of bsearch is the most concrete contribution we can make for apps like Discover, dashboards, lens, or maps to reduce their load on Kibana Server. anticipating streaming, webgl, and binary formatsin the future, we are likely seeing a move to data formats with higher data density, and which have better characteristics for streaming (such as arrow), to support more advanced chart types (e.g. scatterplots). An intermediate batching layer which re-encodes data does not fit into this model. code and asset loading benefitsWe would also expect a broader improvement wrt code and asset loading, something which would benefit all apps, not just Dashboards. |
Do elasticsearch and kibana's proxy support HTTP2? |
@TinaHeiligers , wrt #7104 (comment)
no. There is some discussion here elastic/elasticsearch#10981 . imho - there's less relevance for the kibana<-->ES connection to be http2, because it's usually (hopefully! ;)) not a browser that connects directly to ES.
I believe yes. To see the benefits in a dashboard, it would be important to ensure that the proxy is http2 as well. |
Correct - the proxy supports http2, and currently requests to kibana are downgraded to http/1.1, which we would stop doing once Kibana supports http2. |
I recently resurrected @mshustov's POC to open my own investigation PR. The outcome is unsurprisingly the same as it was 2 years ago: if booting Kibana with a http2 listener is relatively easy, making sure that everything works fine with it, that our tooling (test tooling mostly) supports it, and that other components of the stack are able to communicate with Kibana when http2 is enabled will be most of the work in that initiative. Things to knowHTTP2 "requires" TLSEven if it's not a requirement in the spec, all browsers will only accept to use HTTP2 against a secure server. There are two main reasons for that:
Note that, as said, this is not a requirement on the spec, and it is possible to perform unsecure http2 communication between two servers (or more commonly, a proxy and its backend), as long as the two components are fine with it and don't need protocol negotiation. ALPN and protocol negotiationALPN (for Application-Layer Protocol Negotiation) is a TLS Basically, in our scenario, this is what will allow to downgrade connections performed against an HTTP2 server to HTTP/1 if the client doesn't support HTTP2. This is very important (not to say mandatory) for the component serving the public traffic, and is why we will absolutely want/need to have TLS configured on Kibana when http2 is enabled (most of the time) Things we will have to doImplement HTTP2 supportObviously the first stage. #183465 is doing most of the work, but we need to polish it and get it merged. I don't think we need a feature branch for it (given http2 will be disabled by default), but we might want to lock the protocol option under dev mode until we're fine releasing it as experimental. Confirm components of the stack are able to communicate with Kibana when HTTP2 is enabledSo in theory, with ALPN (so TLS) enabled and accepting downgrades to HTTP/1.x, nothing would need to be done and everything should work "out of the box" if we enable HTTP2 on the Kibana server. However, we will have to validate that. Components that I can think of (list likely not exhaustive)
Adapt our http clients to use HTTP2So, there are two parts of that: Note that in theory, as long as protocol negociation works, this shouldn't be blocker for an "experimental release" of HTTP2 support, as all those clients should gracefully downgrade to HTTP/1 (but again, we will need to confirm that) Replacing agents that don't support HTTP2 at all
We will have to migrate to another http agent instead (seems like ky may be the way to go today?) We need to also figure out which other(s) clients we might be using across our codebase Enabling http2 on our agents (when http2 is enabled on the server)This was quite of a surprise to me, but most (all non-browser?) agents are not supporting ALPN (or at least don't have http2 enabled out of the box). Meaning that if you want to use them against an http2 backend, you have to explicitly configure it that way at the agent or request level. For example, this is how it works for const request = require('supertest');
// request level
request(app, { http2: true }).get('/user');
// agent level
request.agent(app, { http2: true }).get('/user') Note that performing a request with http2 disabled on the client-side against an HTTP2 server accepting downgrading via ALPN works, but it doesn't the other way (http2-enabled client against a plain HTTP1 TLS client), so we can't just always enable http2, and will have to do it only when the server is supporting it. For test tooling, this implies some work, but is relatively straightforward, given we know we're testing directly against the Kibana server without middlewares or proxies. For our production usages of clients (e.g. our production usage of axios), it may be trickier, given having http2 enabled on the server !== http2 available for the browser (depending on the custom infra), so we might need to think a bit of how exactly we want to manage that. But again, with protocol downgrade, this should be doable as a follow-up enhancement. Adapting our internal toolingDev modeDo we want to enable http2 by default for dev mode? If so, we need to change the CLI script accordingly, to at least add the TLS dev certificate to the config. Dev serverIf we want to support HTTP2 with "virtual" base-path on dev-mode, we will have to adapt the base path proxy to accept http2 connection and proxy http2 connection. It may require to fully change on implementation kibana/packages/kbn-cli-dev-mode/src/base_path_proxy_server.ts Lines 131 to 137 in d893a06
FTR test runner / test configurationThis is a big one. The first question to ask is what the strategy should be regarding http2 enablement for our functional test suites.
I personally feel the last one would be our best option, but we need to get to a consensus. Then the second part is changing our FTR configuration accordingly. As explained previously, there are two major things impacting this protocol switch for FTR tests:
E.g. for supertest, we should be able to globally enable http2 at the agent level at the provider's level: kibana/test/api_integration/services/supertest.ts Lines 16 to 20 in d2feac0
Adapting our APIsConfig validationShould we have the config fail validation if http2 is enabled without TLS? should we just log a warning? Expose the protocol information internallyWe already have a kibana/packages/core/http/core-http-server/src/http_contract.ts Lines 395 to 404 in 364ee52
We will want to add the information of the protocol (http1 / http2) to this structure. More important, given we will support protocol fallback, we probably want / need to be able to expose this information at the request level. The info is available on the raw requests ( Perform performance testing to compare behavior between the two protocolsIn theory, enabling http2 should only be beneficial. However, we ideally need to confirm that and put numbers on it. ConclusionThis is likely not an exhaustive list - I will edit/update it when needed. |
## Summary Related to #7104 Update supertest, superagent, and the corresponding type package, to their latest version. (of course, types had some signature changes and we're massively using supertest in all our FTR suites so the whole Kibana multiverse has to review it) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary Related to #7104 Adapted from #183465 For `http2` support, we will have to change the way we configure the HAPI server to manually provide the listener instead of passing down the options for HAPI to create it. This PR prepares that work, by creating the `http` or `https` (`tls`) listener and passing it when creating the HAPI server instead of just passing the `tls` options. **Note:** no integration tests were added, because we already have the right coverage for both tls and non-tls mode, so any change of behavior introduced by the PR should be detectable by them.
## Summary Part of #7104 Add support for `http2` to the Kibana server. `http2` can be enabled by setting `server.protocol: http2` in the Kibana config file. *Note: by default, enabling `http2` requires a valid `h2c` configuration, meaning that it can only run over HTTPS with TLS1.2+* ```yaml ## kibana.yaml server.protocol: http2 server.ssl.enabled: true server.ssl.key: path/to/key server.ssl.certificate: path/my/cerf ``` ## What is this PR doing ### Add HTTP2 support for the Kibana server #### - Plug http2 to the Kibana server Even if HAPI was never officially updated to really support HTTP2, node's `http`/`https`/`http2` modules are compatible enough to be able to just instantiate an http2 server/listener and provide it to HAPI "as a plain https listener". There were some tweaks to do (mostly silencing a few warnings that HAPI was causing by sending http2-illegal headers such as `Connection`), but overall, it went smoothly. #### - Add config validation By default, Kibana will require a valid `h2c` configuration to accept enabling `http2`. It means that TLS must be enabled and that TLS1.2+ should at least be in the list of supported SSL protocols (`server.ssl.supportedProtocols`). Note that default value of this setting includes TLS1.2 and 1.3. #### - Add escape hatch to run `h2` without `h2c` In some situations, it may be required to enable http2 without a valid `h2c` configuration. Kibana supports it, by setting `server.http2.allowUnsecure` to `true`. (*Note, however, that if http2 is enabled without TLS, ALPN protocol negotiation won't work, meaning that most http2 agents/clients will fail connecting unless they're explictly configured to use http2.*) ### Add documentation about this new feature #### - Update the user-facing doc about this new `server.protocol` setting Update the user-facing Kibana settings documentation to include this `http.protocol` setting (and refer to `server.http2.allowUnsecure`) **Note: this setting, and this feature, are considered as experimental** ### Adapt our dev tooling to support running Kibana with http2 enabled #### - Add a `--http2` flag to the dev CLI Enabling this flag will add the proper configuration settings to run Kibana with `http2` enabled in an (almost) valid `h2c` configutation. *Note: when using this flag, even if listening on the same port, the Kibana server will be accessible over https, meaning that you need to use https in your browser to access it. Aka `http://localhost:5601` won't work, you need to use `https://localhost:5601`. Also, we're using the self-signed dev certificates, meaning that you must go though the scary warning of your browser* #### - Implement an http2-compatible base-path proxy The current base path proxy is based on `hapi` and `hapi/h2o2`. I tried for a bunch hours trying to hack around to make it work with http2 proxying, but ultimately gave up and implemented a new version from scratch. Note that with some additional efforts, this new http2 basepath proxy could probably fully replace the existing one and be used for both http1 and http2 traffic, but it's an optimization / refactoring that did not feel required for this PR. ### Adapt the FTR to run suites against http2 #### - Add support to run FTR test suite against an h2c-enabled Kibana Note that with ALPN, clients using http1 should be (and are) able to communicate with http2 Kibana, given h2c/alpn allows protocol negitiation. So adapting our FTR tooling was not really about making it work with http2 (which worked out of the box), but making it work with **the self signed certifcates we use for https on dev mode** Note that I'm not a big fan of what I had to do, however, realistically this was the only possible approach if we want to run arbitrary test suites with TLS/HTTP2 enabled without massively changing our FTR setup. Operations and QA, feel free to chime in there, as this is your territory. #### - Change some FTR test suites to run against an HTTP2-enabled server I added a quick `configureHTTP2` helper function to take any "final" FTR suite config and mutate it to enable `http2`. I then enabled it on a few suites locally, to make sure the suites were passing correctly. I kept two suites running with http2 enabled: - the `console` oss functional tests - the `home` oss functional tests We could possibly enable it for more, but we need to figure out what kind of strategy we want on that matter (see below) ## What is this pull request NOT doing #### - Making sure everything works when HTTP2 is enabled I navigated the applications quite a bit, and did not see anything broken, however I obviously wasn't able to do a full coverage. Also, the self-signed certificate was a huge pain to detect issues really caused by http2 compared to issues because the local setup isn't valid `h2c`. In theory though (famous last words) anything not doing http/1.1 specific hacks such as bfetch should work fine with http2, given that even if using non-http2 clients, ALPN should just allow to fallback to http/1.x (this part was tested) #### - Enabling HTTP2 by default PR isn't doing it for obvious reasons. #### - Enabling HTTP2 for all FTR suites First of all, it's not that easy, because it requires adapting various parts of the config (and even some var env...), and we don't have any proper way to override config "at the end". For instance, if you add the http2 config on a top level config (e.g. the oss functional one that is reuse by the whole world - learned the hard way), it won't work because higher-level configs redefined (and override) the `browser` part of the config, loosing the settings added to run the browser in insecure mode. Secondly, I'm not sure we really need to run that many suites with http2 enabled. I learned working on that PR that we only have like one suite where https is enabled for the Kibana server, and I feel like it could be fine to have the same for http2. In theory it's just a protocol change, unless parts of our apps (e.g. bfetch) are doing things that are specific to http/1.1, switching to http2 should be an implementation detail. But I'd love to get @elastic/kibana-operations and @elastic/appex-qa opinion on that one, given they have more expertise than I do on that area. - Running performances tests We should absolutely run perf testing between http/1.1 over https and http/2, to make sure that it goes into the right directly (at least in term of user perceived speed), but I did not do it in the scope of this PR (and @dmlemeshko is on PTO so... 😅) ## Release Note Add support for `http2` to the Kibana server. `http2` can be enabled by setting `server.protocol: http2` in the Kibana config file. Note: by default, enabling `http2` requires a valid `h2c` configuration, meaning that it can only run over HTTPS with TLS1.2+ Please refer to the Kibana config documentation for more details. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
#183465 was just merged, bringing HTTP2 capabilities to the Kibana server. The feature is flagged as experimental, but will be available in Kibana The next two major tasks are:
In the meantime, I updated the issue with a "follow-ups" task list. At the moment, we have two items:
|
thanks @pgayvallet, fantastic news. yes, we will follow up. Our next step is to validate some of the improvements we are expecting (#183096), and looking at how we can phase the removal of bsearch for stateful (possibly tied into with 9.0 release). cc @lukasolson @vadimkibana @davismcphee @kertal |
Configuring F5 Load balancer in front of tribe nodes for HA for Kibana. Would be nice for the Kibana server to support http2.
Tasks
Follow-ups
The text was updated successfully, but these errors were encountered: