Kubernetes Ingress 路由 HTTP 与 Kestrel

问题描述

我是 k8s 的新手,正在慢慢学习。我已经构建了一个在 .net 5 上运行并仅使用 HTTPS(以前版本使用 http)的 web api,我在 docker compose 中构建了图像,并且一切都在本地使用默认的 aspnetapp.pfx 证书按预期工作。我正在努力解决的是,我的入口路由似乎提前终止了连接。

我为 kestrel 创建了一个 cert pfx 以使用 a.b.com 的 CN 名称运行,这是来自在文档中创建机密所需的 crt 和密钥文件。但根据我的理解,Kestrel 需要一个 pfx 才能运行(直接开箱即用)。

以下是我的入口、服务和部署片段以及日志中的条目: 我相信我的问题是在日志中它显示为“http”请求,但它应该是 https

日志:

2021/02/24 09:44:11 [error] 3231#3231: *44168360 upstream prematurely closed connection while reading response header from upstream,client: 127.0.0.1,server: _,request: "GET /dayofweek/api/1/dayofweek/action HTTP/2.0",upstream: "http://<podip>/api/1/dayofweek/action",host: "<clusterip>:<nodePort>"

入口:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: dayofweek-ingress-path
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    #kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  rules:
  - host: a.b.com
  -  http:
      paths:
      - backend:
          service:
            name: dayofweek-svc
            port:
              number: 9057
        path: /dayofweek/?(.*)
        pathType: Prefix

服务 + 部署

apiVersion: v1
kind: Service
metadata:
  name: dayofweek-svc
  labels:
    run: dayofweek-svc
spec:
  ports:
  - port: 9057
    targetPort: 3441
    protocol: TCP
    name: https
  selector:
    app: dayofweek
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: dayofweek
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dayofweek
  template:
    metadata:
      labels:
        app: dayofweek
    spec:
      volumes:
      - name: cert-volume
        persistentVolumeClaim:
          claimName: persistentcerts-claim
      containers:
      - name: dayofweek
        image: ...omitted
        ports:
        - containerPort: 3441
        env:
          - name: DOTNET_ENVIRONMENT
            value: Development
          - name: Culture
            value: en-US #English by default
          - name: ASPNETCORE_Kestrel__Certificates__Default__Path
            value: /https/aspnetapp.pfx
          - name: ASPNETCORE_Kestrel__Certificates__Default__Password
            value: password
        volumeMounts:
        - mountPath: /https
          name: cert-volume

我按照此处的指南进行操作:https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/

而且我似乎已经启动并运行了它,但是出于某种原因,当我不确定是否通过添加入口的“-host”元素使其过于复杂时。

任何帮助将不胜感激!

解决方法

服务和部署看起来正确,但我可以看到一些入口问题。

当使用基于 ssl-passthrough 路径的路由不起作用时,您可以跳过它。

此外,您的配置中有一个错字:

- host: a.b.com
-  http:    # <- HERE

不应该有第二个破折号。

它应该是这样的:

spec:
  rules:
  - host: a.b.com
    http:
      paths:

此外,看看 nginx ingres 文档对 ssl-passthrough 的看法:

SSL 直通

--enable-ssl-passthrough 标志启用 SSL 直通功能,默认禁用。这是必需的 在 Ingress 对象中启用直通后端

警告

这个功能是通过拦截所有流量来实现的 配置 HTTPS 端口(默认值:443)并将其移交给本地 TCP代理。这完全绕过了 NGINX 并引入了一个 不可忽视的性能损失。

SSL Passthrough 利用 SNI 并从 TLS 协商,需要兼容的客户端。连接后 已被 TLS 侦听器接受,由控制器处理 本身并在后端和客户端之间来回传输。

如果没有与请求的主机名匹配的主机名,则请求 在配置的直通代理端口上交给 NGINX (默认:442),将请求代理到默认后端。


还有this in docs

SSL 直通

nginx.ingress.kubernetes.io/ssl-passthrough 指示控制器 将 TLS 连接直接发送到后端而不是让 NGINX 解密通信。另请参阅用户指南中的 TLS/HTTPS。

**注意 默认情况下禁用 SSL Passthrough,需要启动 带有 --enable-ssl-passthrough 标志的控制器。

注意

因为 SSL Passthrough 适用于 OSI 模型 (TCP) 的第 4 层,并且 不在第 7 层 (HTTP) 上,使用 SSL Passthrough 会使所有 在 Ingress 对象上设置的其他注释。


因此,根据文档,为了使其正常工作,您需要先启用 ssl-passthrough 功能。完成此操作后,您可以使用 ssl-passthrough 注释,但这会使所有其他注释无效,并且基于路径的路由将停止工作。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...