【问题标题】:Using HTTP/2 with nginx Ingress on GKE在 GKE 上使用 HTTP/2 和 nginx Ingress
【发布时间】:2021-07-31 21:53:51
【问题描述】:

我们已经在 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

我的入口文件:

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 建立的

您好,感谢您的回复。但我已将 ingress 更改为使用 cert-manager 和 LetEncrypt,下面是更新后的 Ingress。

入口

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"
  
  

【问题讨论】:

    标签: google-kubernetes-engine nginx-ingress


    【解决方案1】:

    编辑


    在进一步复制后,我注意到在问题中NGINX Ingress controllers 之间存在不匹配。

    有 2 个名称相似的 Ingress 控制器:

    这是 2 个不同的产品,此处解释了不同之处:

    由于这个Configmap键:

    • use-http2: "true"

    我错误地认为我们在谈论 nginx,实际上它是 nginx-inc em>(我错过了$ helm repo add的链接)。此字段特定于 nginx,不适用于 nginx-inc

    我已经设法找到一种方法来通过 nginx-inc 启用 HTTP/2 支持。变化:

    • 来自:use-http2: "true"
    • 至:http2: "true"

    更多解释可以在这里找到:



    以下部分更多地是在GKEIngress 上支持HTTP/2 的一般方法。

    附注!

    即使在YAML 清单中没有tls 部分,由于Fake Ingress Controller certificate,也可以使用HTTPS


    正如以下 github 问题中所指出的:

    aldbf 于 2019 年 3 月 28 日发表评论


    NGINX 不支持在明文(非 TLS)端口上同时支持 HTTP/1.x 和 HTTP/2。 这就是为什么它只在使用 HTTPS 时才有效的原因。

    -- Github.com: Kubernetes: Ingress nginx: Issue: HTTP2 support

    如启用HTTP/2 所述,您需要在Ingress 资源中配置tls 部分(证书)。

    您可以在此处找到帮助您完成该过程的文档:


    我在GKE 版本1.20.5-gke.2000Helm 部分)上使用了您的设置,这就是我发现的。

    使用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-ingressConfigmap 的修改部分添加整个答案:

    data:
      use-http2: "true"
    

    使用-http2

    安全连接中启用或禁用 HTTP/2 支持。

    -- 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


    其他资源:

    【讨论】:

    • 感谢您的回复,我已经编辑了问题以包含新的 Ingress,它适用于 HTTPS,但仍然只有 http/1.1。
    • @Humberto 你能告诉我你用什么软件来检查HTTP 版本吗?另外,您能否详细介绍一下您的GKE 版本?
    • 升级到最新的发布频道,但仍然没有成功。我已经用完整的配置文件编辑了这个问题。谢谢
    • @Humberto,请看一下现在更新的答案。
    • 这正是问题所在,没有注意到不同的版本。
    猜你喜欢
    • 2020-05-19
    • 2021-11-05
    • 2019-06-16
    • 2019-01-13
    • 2019-12-18
    • 2021-08-12
    • 2020-05-27
    • 1970-01-01
    • 2021-02-01
    相关资源
    最近更新 更多