使用 Kestrel 的 Kubernetes 入口路由 HTTP

Kubernetes Ingress Routing HTTP with Kestrel

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

我已经为 kestrel 创建了一个证书 pfx 到 运行,CN 名称为 a.b.com,这是来自文档中创建机密所需的 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: /
    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/

而且我似乎已经准备好 运行ning,但出于某种原因,我不确定是否通过添加入口的“-host”元素使它过于复杂。

如有任何帮助,我们将不胜感激!

服务和部署看起来正确,但我发现入口存在一些问题。

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

此外,您的配置中有一个拼写错误:

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

不应该有第二个破折号。

它应该是这样的:

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

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

SSL Passthrough

The --enable-ssl-passthrough flag enables the SSL Passthrough feature, which is disabled by default. This is required to enable passthrough backends in Ingress objects.

Warning

This feature is implemented by intercepting all traffic on the configured HTTPS port (default: 443) and handing it over to a local TCP proxy. This bypasses NGINX completely and introduces a non-negligible performance penalty.

SSL Passthrough leverages SNI and reads the virtual domain from the TLS negotiation, which requires compatible clients. After a connection has been accepted by the TLS listener, it is handled by the controller itself and piped back and forth between the backend and the client.

If there is no hostname matching the requested host name, the request is handed over to NGINX on the configured passthrough proxy port (default: 442), which proxies the request to the default backend.


还有this in docs:

SSL Passthrough

nginx.ingress.kubernetes.io/ssl-passthrough instructs the controller to send TLS connections directly to the backend instead of letting NGINX decrypt the communication. See also TLS/HTTPS in the User guide.

**Note SSL Passthrough is disabled by default and requires starting the controller with the --enable-ssl-passthrough flag.

Attention

Because SSL Passthrough works on layer 4 of the OSI model (TCP) and not on the layer 7 (HTTP), using SSL Passthrough invalidates all the other annotations set on an Ingress object.


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