简体   繁体   English

Kubernetes 入口路由 HTTP 与 Kestrel

[英]Kubernetes Ingress Routing HTTP with Kestrel

I'm new to k8s and slowly picking it up.我是k8s的新手,慢慢上手。 I have built out a web api that runs on .net 5 and uses HTTPS (a previous version used http) only, I built the image in docker compose and everything works as expected locally with the default aspnetapp.pfx cert. I have built out a web api that runs on .net 5 and uses HTTPS (a previous version used http) only, I built the image in docker compose and everything works as expected locally with the default aspnetapp.pfx cert. What I am struggling with is that my ingress routing seems to terminaate the connection early.我正在努力解决的是我的入口路由似乎提前终止了连接。

I have created a cert pfx for kestrel to run on with the CN name of abcom this was from the crt and key files that are needed to create secrets in the documentation.我已经为 kestrel 创建了一个 cert pfx 以使用 abcom 的 CN 名称运行,这是来自在文档中创建机密所需的 crt 和密钥文件。 but from my understanding kestrel needs a pfx to run (straight out of the box).但据我了解,红隼需要一个 pfx 才能运行(直接开箱即用)。

Below are my ingress, service and deployment snippets as well as the entries from the logs: I believe that my issue is that in the logs it is showing as a "http" request but it should be https下面是我的入口、服务和部署片段以及日志中的条目:我相信我的问题是在日志中它显示为“http”请求但它应该是 https

Logs:日志:

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

Ingress:入口:

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

Service + Deployment服务+部署

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

I followed through with the guide here: https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/我按照这里的指南进行操作: https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/

And I seem to have it up and running, but for some reason when I'm not sure if I've overcomplicated it by adding in the "-host" element of the ingress.而且我似乎已经启动并运行了它,但是由于某种原因,当我不确定是否通过添加入口的“-host”元素使其过于复杂时。

Any help would be greatly appreciated!任何帮助将不胜感激!

Service and deployment look correct, but I can see some issues with ingress.服务和部署看起来正确,但我可以看到一些与入口有关的问题。

When using ssl-passthrough path based routing doesn't work so you can skip it.当使用基于 ssl-passthrough 路径的路由不起作用时,您可以跳过它。

Also, there is a typo in your config:此外,您的配置中有一个错字:

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

there shouldn't be the second dash.不应该有第二个破折号。

Here is how it should look like:这是它的样子:

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

Additionally, have a look what nginx ingres docs has to say about ssl-passthrough :此外,请查看 nginx ingres 文档对ssl-passthrough 的评价:

SSL Passthrough SSL 直通

The --enable-ssl-passthrough flag enables the SSL Passthrough feature, which is disabled by default. --enable-ssl-passthrough 标志启用 SSL 直通功能,默认情况下禁用。 This is required to enable passthrough backends in Ingress objects .这是在 Ingress 对象中启用直通后端所必需的

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.此功能通过拦截配置的 HTTPS 端口(默认值:443)上的所有流量并将其移交给本地 TCP 代理来实现。 This bypasses NGINX completely and introduces a non-negligible performance penalty.这完全绕过了 NGINX 并引入了不可忽略的性能损失。

SSL Passthrough leverages SNI and reads the virtual domain from the TLS negotiation, which requires compatible clients. SSL Passthrough 利用 SNI 并从 TLS 协商中读取虚拟域,这需要兼容的客户端。 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.在 TLS 侦听器接受连接后,它由 controller 自己处理,并在后端和客户端之间来回传输。

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.如果没有与请求的主机名匹配的主机名,则将请求移交给配置的直通代理端口(默认:442)上的 NGINX,该端口将请求代理到默认后端。


There is also this in docs : 文档中也有这个

SSL Passthrough SSL 直通

nginx.ingress.kubernetes.io/ssl-passthrough instructs the controller to send TLS connections directly to the backend instead of letting NGINX decrypt the communication. 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.另请参阅用户指南中的 TLS/HTTPS。

**Note SSL Passthrough is disabled by default and requires starting the controller with the --enable-ssl-passthrough flag. **注意 SSL 直通默认禁用,需要使用 --enable-ssl-passthrough 标志启动 controller。

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


So, according to the docs, in order for it to work you need to enable ssl-passthrough feature first.因此,根据文档,为了使其工作,您需要先启用 ssl-passthrough 功能。 After this is done, you can use ssl-passthrough annotation but this invalidates all the other annotations and path based routing stops working.完成此操作后,您可以使用 ssl-passthrough 注释,但这会使所有其他注释无效,并且基于路径的路由停止工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM