-
Notifications
You must be signed in to change notification settings - Fork 67
RHIDP-15905: Document HTTP/2 enablement options for RHDH installations #2548
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
Open
jmagak
wants to merge
1
commit into
redhat-developer:release-2.1
Choose a base branch
from
jmagak:RHIDP-15905-Document-HTTP-2-enablement-options-for-RHDH-installations
base: release-2.1
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
...configure_configuring-rhdh/assembly-enable-http2-to-reduce-page-load-times.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| :_mod-docs-content-type: ASSEMBLY | ||
| ifdef::context[:parent-context: {context}] | ||
|
|
||
| [id="enable-http2-to-reduce-page-load-times_{context}"] | ||
| = Enable HTTP/2 to reduce page load times | ||
|
|
||
| :previouscontext: {context} | ||
| :context: enable-http2-to-reduce-page-load-times | ||
|
|
||
| [role="_abstract"] | ||
| You can enable HTTP/2 for {product} to reduce front-end load times when your environment supports TLS certificates that browsers trust. | ||
|
|
||
| include::../modules/configure_configuring-rhdh/con-http2-and-the-frontend-connection-bottleneck.adoc[leveloffset=+1] | ||
|
|
||
| include::../modules/configure_configuring-rhdh/ref-http2-tls-requirements-and-connection-coalescing-caveats.adoc[leveloffset=+1] | ||
|
|
||
| include::../modules/configure_configuring-rhdh/proc-enable-http2-by-using-a-reverse-proxy-with-helm.adoc[leveloffset=+1] | ||
|
|
||
| include::../modules/configure_configuring-rhdh/proc-enable-http2-by-using-a-reverse-proxy-with-the-operator.adoc[leveloffset=+1] | ||
|
|
||
| include::../modules/configure_configuring-rhdh/proc-request-cluster-wide-http2-on-openshift.adoc[leveloffset=+1] | ||
|
|
||
| :context: {previouscontext} | ||
| :!previouscontext: | ||
|
|
||
| ifdef::parent-context[:context: {parent-context}] | ||
| ifndef::parent-context[:!context:] |
15 changes: 15 additions & 0 deletions
15
...onfigure_configuring-rhdh/con-http2-and-the-frontend-connection-bottleneck.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| :_mod-docs-content-type: CONCEPT | ||
|
|
||
| [id="http2-and-the-frontend-connection-bottleneck_{context}"] | ||
| = HTTP/2 and the front-end connection bottleneck | ||
|
|
||
| [role="_abstract"] | ||
| You can use HTTP/2 to eliminate the six-connection bottleneck that slows page loads in plugin-heavy {product-very-short} deployments by multiplexing browser requests over a single connection. | ||
|
|
||
| {product-very-short} does not enable HTTP/2 by default because it requires valid TLS certificates that browsers trust. | ||
|
|
||
| Browsers limit HTTP/1.1 to six concurrent connections per origin. | ||
| In plugin-heavy {product-very-short} deployments, the browser must download many JavaScript assets before the page becomes interactive. | ||
| With HTTP/1.1, these downloads queue across the six-connection limit, which can result in page load times of 20 to 30 seconds. | ||
|
|
||
| The benefit is greatest during the initial page load, when the browser fetches all plugin assets at once. |
276 changes: 276 additions & 0 deletions
276
...gure_configuring-rhdh/proc-enable-http2-by-using-a-reverse-proxy-with-helm.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,276 @@ | ||
| :_mod-docs-content-type: PROCEDURE | ||
|
|
||
| [id="enable-http2-by-using-a-reverse-proxy-with-helm_{context}"] | ||
| = Enable HTTP/2 by using a reverse proxy with Helm | ||
|
|
||
| [role="_abstract"] | ||
| To enable HTTP/2 for a Helm-based {product-very-short} installation, deploy a reverse proxy in front of {product-very-short}, expose it through a passthrough route, and point {product-very-short} at the reverse proxy URL. | ||
| The reverse proxy terminates TLS and negotiates HTTP/2 with browsers. | ||
|
|
||
| .Prerequisites | ||
|
|
||
| * You installed {product-very-short} on {ocp-short} by using the {product-very-short} Helm chart. | ||
| * You installed the `oc`, `helm`, and `openssl` command-line tools. | ||
| * You have a TLS certificate and key for the reverse proxy hostname. For production, use a certificate that a certificate authority (CA) that browsers trust has signed. | ||
| * You have a Red Hat supported reverse proxy image, such as the Red Hat Hardened Images Caddy image. | ||
|
|
||
| .Procedure | ||
|
|
||
| . Set environment variables for your installation, where `<your_rhdh_namespace>` is the namespace of your {product-very-short} installation and `<your_helm_release_name>` is your Helm release name: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ export NAMESPACE=<your_rhdh_namespace> | ||
| $ export RELEASE=<your_helm_release_name> | ||
| $ oc project "$NAMESPACE" | ||
| ---- | ||
|
|
||
| . Get the cluster application domain: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ export ROUTER_BASE=$(oc get ingress.config.openshift.io/cluster -o jsonpath='{.spec.domain}') | ||
| ---- | ||
|
|
||
| . Choose a hostname for the reverse proxy. The hostname must be different from your existing {product-very-short} route hostname: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ export CADDY_HOST="rhdh-h2-${NAMESPACE}.${ROUTER_BASE}" | ||
| ---- | ||
|
|
||
| . Create a TLS secret from your certificate and key, where `<path_to_tls_crt>` and `<path_to_tls_key>` are the paths to your certificate and key files: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc create secret tls tls-certs \ | ||
| --cert=<path_to_tls_crt> \ | ||
| --key=<path_to_tls_key> \ | ||
| -n "$NAMESPACE" | ||
| ---- | ||
| + | ||
| [NOTE] | ||
| ==== | ||
| The TLS secret must be in the same namespace as the reverse proxy workload. | ||
| ==== | ||
|
|
||
| . Create a `caddy.yaml` file that defines the reverse proxy `Deployment`, `ConfigMap`, and `Service`: | ||
| + | ||
| [source,yaml] | ||
| ---- | ||
| apiVersion: apps/v1 | ||
| kind: Deployment | ||
| metadata: | ||
| name: caddy-fronting-proxy | ||
| spec: | ||
| replicas: 1 | ||
| selector: | ||
| matchLabels: | ||
| app: caddy-fronting-proxy | ||
| template: | ||
| metadata: | ||
| labels: | ||
| app: caddy-fronting-proxy | ||
| spec: | ||
| volumes: | ||
| - name: caddy-config | ||
| configMap: | ||
| name: caddy-reverse-proxy | ||
| defaultMode: 420 | ||
| - name: certs | ||
| secret: | ||
| secretName: tls-certs | ||
| serviceAccountName: default | ||
| containers: | ||
| - name: caddy-reverse-proxy | ||
| resources: | ||
| requests: | ||
| memory: "2Gi" | ||
| cpu: "500m" | ||
| limits: | ||
| memory: "3Gi" | ||
| cpu: "1" | ||
| command: | ||
| - caddy | ||
| - run | ||
| - '--config' | ||
| - /etc/caddy/Caddyfile | ||
| ports: | ||
| - containerPort: 8080 | ||
| protocol: TCP | ||
| name: proxy | ||
| imagePullPolicy: Always | ||
| env: | ||
| - name: CADDY_ROUTE_HOSTNAME | ||
| value: "rhdh-h2-<namespace>.apps.<cluster_domain>" | ||
| - name: DEVELOPER_HUB_SERVICE_HOST | ||
| value: "http://<release>.<namespace>.svc.cluster.local:7007" | ||
| volumeMounts: | ||
| - name: caddy-config | ||
| mountPath: /etc/caddy/Caddyfile | ||
| subPath: Caddyfile | ||
| readOnly: true | ||
| - name: certs | ||
| mountPath: /opt/app-root/certs | ||
| readOnly: true | ||
| image: registry.access.redhat.com/hi/caddy:2 | ||
| --- | ||
| apiVersion: v1 | ||
| kind: ConfigMap | ||
| metadata: | ||
| name: caddy-reverse-proxy | ||
| data: | ||
| Caddyfile: | | ||
| { | ||
| auto_https disable_redirects | ||
| } | ||
|
|
||
| https://{$CADDY_ROUTE_HOSTNAME}:8080 { | ||
| tls /opt/app-root/certs/tls.crt /opt/app-root/certs/tls.key | ||
|
|
||
| @scalprum_chunks { | ||
| path /api/scalprum/*/static/*.js | ||
| } | ||
|
|
||
| header @scalprum_chunks { | ||
| # Cache for 1 year (immutable because the hash changes on new builds) | ||
| >Cache-Control "public, max-age=31536000, immutable" | ||
| } | ||
|
|
||
| reverse_proxy { | ||
| to {$DEVELOPER_HUB_SERVICE_HOST} | ||
| transport http { | ||
| versions 1.1 | ||
| } | ||
| } | ||
| } | ||
| --- | ||
| apiVersion: v1 | ||
| kind: Service | ||
| metadata: | ||
| name: caddy-fronting-proxy | ||
| labels: | ||
| app: caddy-fronting-proxy | ||
| spec: | ||
| type: ClusterIP | ||
| ports: | ||
| - name: caddy-fronting-proxy | ||
| port: 443 | ||
| targetPort: 8080 | ||
| selector: | ||
| app: caddy-fronting-proxy | ||
| ---- | ||
| where: | ||
|
|
||
| `CADDY_ROUTE_HOSTNAME`:: The reverse proxy hostname, which is the value of `$CADDY_HOST`. | ||
| `DEVELOPER_HUB_SERVICE_HOST`:: The internal {product-very-short} service URL, in the format `http://<release>.<namespace>.svc.cluster.local:7007`. | ||
| `image`:: A Red Hat supported reverse proxy image, such as the Red Hat Hardened Images Caddy image. | ||
|
|
||
| . Apply the manifest and wait for the rollout to complete: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc apply -f caddy.yaml -n "$NAMESPACE" | ||
| $ oc rollout status deployment/caddy-fronting-proxy -n "$NAMESPACE" --timeout=5m | ||
| ---- | ||
|
|
||
| . Create an `allow-caddy-ingress.yaml` file that defines a network policy to allow the reverse proxy to reach the {product-very-short} backend, where `<release>` is your Helm release name: | ||
| + | ||
| [source,yaml] | ||
| ---- | ||
| apiVersion: networking.k8s.io/v1 | ||
| kind: NetworkPolicy | ||
| metadata: | ||
| name: allow-caddy-ingress | ||
| spec: | ||
| podSelector: | ||
| matchLabels: | ||
| app.kubernetes.io/instance: <release> | ||
| app.kubernetes.io/component: backstage | ||
| policyTypes: | ||
| - Ingress | ||
| ingress: | ||
| - from: | ||
| - podSelector: | ||
| matchLabels: | ||
| app: caddy-fronting-proxy | ||
| ports: | ||
| - port: 7007 | ||
| protocol: TCP | ||
| ---- | ||
|
|
||
| . Apply the network policy and verify that it is created: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc apply -f allow-caddy-ingress.yaml -n "$NAMESPACE" | ||
| $ oc get networkpolicy allow-caddy-ingress -n "$NAMESPACE" | ||
| ---- | ||
|
|
||
| . Create a passthrough route to expose the reverse proxy externally: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ oc create route passthrough rhdh-caddy-proxy \ | ||
| --service=caddy-fronting-proxy \ | ||
| --port=caddy-fronting-proxy \ | ||
| --hostname="$CADDY_HOST" \ | ||
| -n "$NAMESPACE" | ||
| ---- | ||
| + | ||
| [NOTE] | ||
| ==== | ||
| Always set the hostname explicitly. If you do not set the hostname, {ocp-short} generates a hostname that does not match your certificate or reverse proxy configuration. | ||
| ==== | ||
|
|
||
| . Create a `helm-values-caddy.yaml` file that points {product-very-short} at the reverse proxy URL and disables the default route, where `<router_base>` is the same value as your existing installation and `<caddy_host>` is the value of `$CADDY_HOST`: | ||
| + | ||
| [source,yaml] | ||
| ---- | ||
| openshift: | ||
| clusterRouterBase: "<router_base>" | ||
| route: | ||
| enabled: false | ||
| appConfig: | ||
| app: | ||
| baseUrl: "https://<caddy_host>" | ||
| backend: | ||
| baseUrl: "https://<caddy_host>" | ||
| cors: | ||
| origin: "https://<caddy_host>" | ||
| ---- | ||
|
|
||
| . Upgrade your Helm release to apply the change. Include the values files that you normally use, followed by the new values file, where `<your_chart_version>` is your chart version and `<your_existing_values.yaml>` is your existing values file: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ helm upgrade "$RELEASE" redhat-developer/redhat-developer-hub \ | ||
| --version <your_chart_version> \ | ||
| -n "$NAMESPACE" \ | ||
| -f <your_existing_values.yaml> \ | ||
| -f helm-values-caddy.yaml | ||
| ---- | ||
|
|
||
| .Verification | ||
|
|
||
| . Confirm that the reverse proxy negotiates HTTP/2: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ openssl s_client -connect "${CADDY_HOST}:443" -servername "$CADDY_HOST" -alpn h2,http/1.1 </dev/null 2>&1 | grep -iE 'ALPN|Protocol:' | ||
| ---- | ||
| + | ||
| If HTTP/2 is active, the output includes `h2`. | ||
|
|
||
| . Confirm that {product-very-short} serves HTTP/2: | ||
| + | ||
| [source,terminal] | ||
| ---- | ||
| $ curl --http2 -sk -o /dev/null -w "http_version=%{http_version}\n" "https://${CADDY_HOST}/" | ||
| ---- | ||
| + | ||
| If HTTP/2 is active, the output is `http_version=2`. | ||
|
|
||
| .Additional resources | ||
|
|
||
| * xref:http2-tls-requirements-and-connection-coalescing-caveats_{context}[HTTP/2 TLS requirements and connection coalescing caveats] | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.