在 GKE 上使用 HTTP/2 和 nginx Ingress
Using HTTP/2 with nginx Ingress on GKE
我们已经在GKE 上配置了集群并安装了nginx-ingress。使用我们的入口规则它可以工作,但我不能让它与 HTTP/2 一起工作。我们在 ConfigMap 上设置了数据信息,但它总是回退到 http/1.1。这个确切的设置在 DigitalOcean 上 运行 没问题。谁能提供一些指导?
谢谢
安装 Nginx-Ingress
kubectl create ns ingress-nginx
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
helm install nginx-ingress nginx-stable/nginx-ingress --namespace ingress-nginx
我的 Ingress 文件:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: "mylocalip"
spec:
rules:
- host: test.mydomain.com
http:
paths:
- path: /hello
backend:
serviceName: hello-server
servicePort: 80
- backend:
serviceName: default-server
servicePort: 80
我的ConfigMap数据应用于nginx-ingress-nginx-ingress configmap
data:
use-http2: "true"
编辑(2021 年 5 月 11 日):
我们更改了入口以使用证书,现在我们使用 HTTPS 进行连接。但是,所有连接都是使用 http/1.1
建立的
您好,感谢您的回复。但是我已经将入口更改为使用 cert-manager 和 LetEncrypt,下面是更新后的入口。
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: "myip"
spec:
tls:
- hosts:
- test.mydomain.com
secretName: my-cert
rules:
- host: test.mydomain.com
http:
paths:
- backend:
serviceName: myweb
servicePort: 80
编辑 2 (05/14/2021)
当前版本:1.19.9-gke.1400
使用curl和https://http2.pro/测试(均表示不可用)
同样的设置可以在 DigitalOcean 上使用 k8s。
这是我的安装和配置文件:
安装 INGRESS-NGINX
kubectl create ns ingress-nginx
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
helm install nginx-ingress nginx-stable/nginx-ingress --namespace ingress-nginx --set controller.service.loadBalancerIP=x.x.x.x
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- test.mydomain.com
secretName: my-cert
rules:
- host: test.mydomain.com
http:
paths:
- backend:
serviceName: myweb
servicePort: 80
配置图
apiVersion: v1
kind: ConfigMap
metadata:
namespace: ingress-nginx
name: nginx-ingress-nginx-ingress
data:
proxy-buffering: "false"
ssl-ciphers: EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED
ssl-protocols: TLSv1.2 TLSv1.3
ssl-redirect: "true"
use-forward-headers: "true"
use-http2: "true"
编辑
进一步复制后,我注意到问题中 NGINX Ingress controllers
.
之间存在不匹配
有 2 个名称相似的 Ingress
控制器:
- Github.com: NginxInc: Kubernetes Ingress - 为此我们将其命名为:nginx-inc
- Github.com: Kubernetes: Ingress Nginx - 为此我们将其命名为:nginx
这是 2 种不同的产品,差异在此处解释:
由于这个 Configmap
键:
use-http2: "true"
我错误地认为我们在谈论 nginx 而实际上它是 nginx-inc(我错过了 $ helm repo add
的 link)。此字段特定于 nginx,不适用于 nginx-inc.
我已经设法找到一种方法来启用 HTTP/2
对 nginx-inc 的支持。变化:
- 来自:
use-http2: "true"
- 至:
http2: "true"
更多解释可以在这里找到:
下面的部分是在 GKE
和 Ingress
上支持 HTTP/2
的一般方法。
A side note!
Even without the tls
part in the YAML
manifest it's possible to use HTTPS
due to the Fake Ingress Controller certificate
正如以下 github 问题所指出的:
aledbf commented on 28 Mar 2019
NGINX does not support HTTP/1.x and HTTP/2 at the same time on a cleartext (non-TLS) port.
That's the reason why it works only when HTTPS is used.
-- Github.com: Kubernetes: Ingress nginx: Issue: HTTP2 support
如所述,要启用 HTTP/2
,您需要在 Ingress
资源中配置 tls 部分(证书)。
在这里您可以找到帮助您完成该过程的文档:
我在 GKE
版本 1.20.5-gke.2000
(Helm
部分)上使用了您的设置,这是我发现的。
使用 HTTP
请求查询 Ingress
控制器的外部 IP 将允许您使用 HTTP/1.1
.
在我将证书配置为与 Ingress
资源(和域名)一起使用后,我可以得到表明我正在使用 HTTP/2
:
的响应
您可以使用各种方法检查它,例如 cURL
或在线 HTTP/2
测试站点:
curl -v -k https://DOMAIN.NAME
* Trying IP_ADRESS
* TCP_NODELAY set
* Connected to DOMAIN.NAME ( IP_ADRESS) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
< <-- REDACTED -->
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fa5b300e800)
> GET / HTTP/2
> Host: DOMAIN.NAME
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< <-- REDACTED -->
<
< <-- NGINX WELCOME SITE -->
* Connection #0 to host DOMAIN.NAME left intact
* Closing connection 0
您还可以寻求更多的单行解决方案:
curl -k -sI https://DOMAIN.NAME -o/dev/null -w '%{http_version}\n'
输出应为 2
。更多参考:
此外,在 nginx-ingress
的 Configmap
的修改部分添加到整个答案:
data:
use-http2: "true"
use-http2
Enables or disables HTTP/2 support in secure connections.
-- Kubernetes.github.io: Ingress nginx: User guide: Nginx configuration: Configmap: Use HTTP/2
我也不确定这个注释的用法:
kubernetes.io/ingress.global-static-ip-name: "mylocalip"
因为它仅对 GKE Ingress
的 Ingress
资源有效,而不是 ingress-nginx
。
其他资源:
我们已经在GKE 上配置了集群并安装了nginx-ingress。使用我们的入口规则它可以工作,但我不能让它与 HTTP/2 一起工作。我们在 ConfigMap 上设置了数据信息,但它总是回退到 http/1.1。这个确切的设置在 DigitalOcean 上 运行 没问题。谁能提供一些指导?
谢谢
安装 Nginx-Ingress
kubectl create ns ingress-nginx
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
helm install nginx-ingress nginx-stable/nginx-ingress --namespace ingress-nginx
我的 Ingress 文件:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: "mylocalip"
spec:
rules:
- host: test.mydomain.com
http:
paths:
- path: /hello
backend:
serviceName: hello-server
servicePort: 80
- backend:
serviceName: default-server
servicePort: 80
我的ConfigMap数据应用于nginx-ingress-nginx-ingress configmap
data:
use-http2: "true"
编辑(2021 年 5 月 11 日):
我们更改了入口以使用证书,现在我们使用 HTTPS 进行连接。但是,所有连接都是使用 http/1.1
建立的您好,感谢您的回复。但是我已经将入口更改为使用 cert-manager 和 LetEncrypt,下面是更新后的入口。
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: nginx
kubernetes.io/ingress.global-static-ip-name: "myip"
spec:
tls:
- hosts:
- test.mydomain.com
secretName: my-cert
rules:
- host: test.mydomain.com
http:
paths:
- backend:
serviceName: myweb
servicePort: 80
编辑 2 (05/14/2021)
当前版本:1.19.9-gke.1400 使用curl和https://http2.pro/测试(均表示不可用)
同样的设置可以在 DigitalOcean 上使用 k8s。
这是我的安装和配置文件:
安装 INGRESS-NGINX
kubectl create ns ingress-nginx
helm repo add nginx-stable https://helm.nginx.com/stable
helm repo update
helm install nginx-ingress nginx-stable/nginx-ingress --namespace ingress-nginx --set controller.service.loadBalancerIP=x.x.x.x
入口
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
namespace: mynamespace
annotations:
kubernetes.io/ingress.class: nginx
spec:
tls:
- hosts:
- test.mydomain.com
secretName: my-cert
rules:
- host: test.mydomain.com
http:
paths:
- backend:
serviceName: myweb
servicePort: 80
配置图
apiVersion: v1
kind: ConfigMap
metadata:
namespace: ingress-nginx
name: nginx-ingress-nginx-ingress
data:
proxy-buffering: "false"
ssl-ciphers: EECDH+ECDSA+AESGCM:EECDH+aRSA+AESGCM:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA256:EECDH+ECDSA+SHA384:EECDH+ECDSA+SHA256:EECDH+aRSA+SHA384:EDH+aRSA+AESGCM:EDH+aRSA+SHA256:EDH+aRSA:EECDH:!aNULL:!eNULL:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SEED
ssl-protocols: TLSv1.2 TLSv1.3
ssl-redirect: "true"
use-forward-headers: "true"
use-http2: "true"
编辑
进一步复制后,我注意到问题中 NGINX Ingress controllers
.
有 2 个名称相似的 Ingress
控制器:
- Github.com: NginxInc: Kubernetes Ingress - 为此我们将其命名为:nginx-inc
- Github.com: Kubernetes: Ingress Nginx - 为此我们将其命名为:nginx
这是 2 种不同的产品,差异在此处解释:
由于这个 Configmap
键:
use-http2: "true"
我错误地认为我们在谈论 nginx 而实际上它是 nginx-inc(我错过了 $ helm repo add
的 link)。此字段特定于 nginx,不适用于 nginx-inc.
我已经设法找到一种方法来启用 HTTP/2
对 nginx-inc 的支持。变化:
- 来自:
use-http2: "true"
- 至:
http2: "true"
更多解释可以在这里找到:
下面的部分是在 GKE
和 Ingress
上支持 HTTP/2
的一般方法。
A side note!
Even without the
tls
part in theYAML
manifest it's possible to useHTTPS
due to theFake Ingress Controller certificate
正如以下 github 问题所指出的:
aledbf commented on 28 Mar 2019
NGINX does not support HTTP/1.x and HTTP/2 at the same time on a cleartext (non-TLS) port. That's the reason why it works only when HTTPS is used.
-- Github.com: Kubernetes: Ingress nginx: Issue: HTTP2 support
如所述,要启用 HTTP/2
,您需要在 Ingress
资源中配置 tls 部分(证书)。
在这里您可以找到帮助您完成该过程的文档:
我在 GKE
版本 1.20.5-gke.2000
(Helm
部分)上使用了您的设置,这是我发现的。
使用 HTTP
请求查询 Ingress
控制器的外部 IP 将允许您使用 HTTP/1.1
.
在我将证书配置为与 Ingress
资源(和域名)一起使用后,我可以得到表明我正在使用 HTTP/2
:
您可以使用各种方法检查它,例如 cURL
或在线 HTTP/2
测试站点:
curl -v -k https://DOMAIN.NAME
* Trying IP_ADRESS
* TCP_NODELAY set
* Connected to DOMAIN.NAME ( IP_ADRESS) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
< <-- REDACTED -->
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7fa5b300e800)
> GET / HTTP/2
> Host: DOMAIN.NAME
> User-Agent: curl/7.64.1
> Accept: */*
>
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< <-- REDACTED -->
<
< <-- NGINX WELCOME SITE -->
* Connection #0 to host DOMAIN.NAME left intact
* Closing connection 0
您还可以寻求更多的单行解决方案:
curl -k -sI https://DOMAIN.NAME -o/dev/null -w '%{http_version}\n'
输出应为 2
。更多参考:
此外,在 nginx-ingress
的 Configmap
的修改部分添加到整个答案:
data:
use-http2: "true"
use-http2
Enables or disables HTTP/2 support in secure connections.
-- Kubernetes.github.io: Ingress nginx: User guide: Nginx configuration: Configmap: Use HTTP/2
我也不确定这个注释的用法:
kubernetes.io/ingress.global-static-ip-name: "mylocalip"
因为它仅对 GKE Ingress
的 Ingress
资源有效,而不是 ingress-nginx
。
其他资源: