简体   繁体   English

kubernetes nginx 入口 controller 返回 404

[英]kubernetes nginx ingress controller return 404

Following this guide , I created an ingress controller on my local kubernetes server, the only difference is that it is created as a NodePort.按照本 指南,我在本地 kubernetes 服务器上创建了一个入口 controller,唯一的区别是它是作为 NodePort 创建的。

I have done some test deployments, with respective services and everything works, here the file我已经完成了一些测试部署,具有相应的服务并且一切正常,这里是文件

Deploy1:部署1:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: helloworld1
spec:
  selector:
    matchLabels:
      app: helloworld1
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld1
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080

Deploy2:部署2:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: helloworld2
spec:
  selector:
    matchLabels:
      app: helloworld2
  replicas: 1
  template:
    metadata:
      labels:
        app: helloworld2
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:2.0
        ports:
        - containerPort: 8080

Deploy3:部署3:

apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: geojson-example
spec:
  selector:
    matchLabels:
      app: geojson-example
  replicas: 1
  template:
    metadata:
      labels:
        app: geojson-example
    spec:
      containers:
        - name: geojson-container
          image: "nmex87/geojsonexample:latest"
          ports:
            - containerPort: 8080

Service1:服务1:

apiVersion: v1
kind: Service
metadata:
  name: helloworld1
spec:
#  type: NodePort
  ports:
  - port: 8080
  selector:
    app: helloworld1

Service2:服务2:

apiVersion: v1
kind: Service
metadata:
  name: helloworld2
spec:
#  type: NodePort
  ports:
  - port: 8080
  selector:
    app: helloworld2

Service3:服务3:

apiVersion: v1
kind: Service
metadata:
  name: geojson-example
spec:
  ports:
    - port: 8080
  selector:
    app: geojson-example

This is the ingress controller:这是入口 controller:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/default-backend: geojson-example
spec:
  rules:
    - http:
        paths:
          - path: /geo
            pathType: Prefix
            backend:
              service:
                name: geojson-example
                port:
                  number: 8080
          - path: /test1
            pathType: Prefix
            backend:
              service:
                name: helloworld1
                port:
                  number: 8080
          - path: /test2
            pathType: Prefix
            backend:
              service:
                name: helloworld2
                port:
                  number: 8080

When I do a GET on myServer:myPort/test1 or /test2 everything works, on /geo i get the following answer当我在myServer:myPort/test1/test2上执行 GET 时,一切正常,在/geo上我得到以下答案

{
    "timestamp": "2021-03-09T17:02:36.606+00:00",
    "status": 404,
    "error": "Not Found",
    "message": "",
    "path": "/geo"
}

Why??为什么?? if I create a pod, and from inside the pod, i do a curl on geojson-example it works, but from the external, i obtain a 404 (i think by nginx ingress controller)如果我创建一个 pod,并且从 pod 内部,我在geojson-example上执行 curl 它可以工作,但是从外部,我得到一个 404(我认为是 nginx 入口控制器)

This is the log of nginx pod:这是 nginx pod 的日志:

x.x.x.x - - [09/Mar/2021:17:02:21 +0000] "GET /test1 HTTP/1.1" 200 68 "-" "PostmanRuntime/7.26.8" 234 0.006 [default-helloworld1-8080] [] 192.168.168.92:8080 68 0.008 200 

x.x.x.x - - [09/Mar/2021:17:02:36 +0000] "GET /geo HTTP/1.1" 404 116 "-" "PostmanRuntime/7.26.8" 232 0.013 [default-geojson-example-8080] [] 192.168.168.109:8080 116 0.012 404 

What can I do?我能做些什么?

As far the doc: This annotation is of the form nginx.ingress.kubernetes.io/default-backend: <svc name> to specify a custom default backend.就文档而言:此注释的形式nginx.ingress.kubernetes.io/default-backend: <svc name>以指定自定义默认后端。 This <svc name> is a reference to a service inside of the same namespace in which you are applying this annotation.<svc name>是对应用此注释的同一命名空间内的服务的引用。 This annotation overrides the global default backend.此注释覆盖全局默认后端。

This service will be handle the response when the service in the Ingress rule does not have active endpoints.当 Ingress 规则中的服务没有活动端点时,该服务将处理响应。

You cannot use same service as default backend and also for a path.您不能将相同的服务用作默认后端,也不能用于路径。 When you do this the path /geo became invalid.当你这样做时,路径/geo变得无效。 As we know default backend serves only the inactive endpoints.正如我们所知,默认后端仅服务于非活动端点。 Now If you tell that you want geojson-example as default backend(for inactive endpoints) again in the paths if you tell that use geojson-example for a valid path /geo then it became invalid as you are creating a deadlock type situation here.现在,如果您告诉您希望geojson-example在路径中再次作为默认后端(对于非活动端点),如果您告诉将geojson-example用于有效路径/geo那么它变得无效,因为您在这里创建了死锁类型的情况。

You actually do not need to give this nginx.ingress.kubernetes.io/default-backend annotation.你实际上不需要给这个nginx.ingress.kubernetes.io/default-backend注释。

Your ingress should be like below without the default annotation, or you can use the annotation but in that case you need to remove geojson-example from using for any valid path in the paths, or need to use another service for the path /geo .您的入口应该如下所示,没有默认注释,或者您可以使用注释,但在这种情况下,您需要从路径中的任何有效路径中删除geojson-example ,或者需要为路径/geo使用其他服务。 Options that you can use are given below:您可以使用的选项如下:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - http:
        paths:
          - path: /geo
            pathType: Prefix
            backend:
              service:
                name: geojson-example
                port:
                  number: 8080
          - path: /test1
            pathType: Prefix
            backend:
              service:
                name: helloworld1
                port:
                  number: 8080
          - path: /test2
            pathType: Prefix
            backend:
              service:
                name: helloworld2
                port:
                  number: 8080

Or:或者:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/default-backend: geojson-example
spec:
  rules:
    - http:
        paths:
          - path: /geo
            pathType: Prefix
            backend:
              service:
                name: <any_other_service>    # here use another service except `geojson-example`
                port:
                  number: 8080
          - path: /test1
            pathType: Prefix
            backend:
              service:
                name: helloworld1
                port:
                  number: 8080
          - path: /test2
            pathType: Prefix
            backend:
              service:
                name: helloworld2
                port:
                  number: 8080

Or:或者:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/default-backend: geojson-example
spec:
  rules:
    - http:
        paths:
          - path: /test1
            pathType: Prefix
            backend:
              service:
                name: helloworld1
                port:
                  number: 8080
          - path: /test2
            pathType: Prefix
            backend:
              service:
                name: helloworld2
                port:
                  number: 8080

This is for your default backend.这适用于您的默认后端。 You set the geojson-example service as a default backend.您将 geojson-example 服务设置为默认后端。

The default backend is a service which handles all URL paths and hosts the nginx controller doesn't understand (i.e., all the requests that are not mapped with an Ingress).

Basically a default backend exposes two URLs:

/healthz that returns 200
/ that returns 404

So, if you want geojson-example service as a default backend then you don't need /geo path specification.因此,如果您希望 geojson-example 服务作为默认后端,那么您不需要 /geo 路径规范。 Then your manifest file will be:然后你的清单文件将是:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/default-backend: geojson-example
spec:
  rules:
    - http:
        paths:
          - path: /test1
            pathType: Prefix
            backend:
              service:
                name: helloworld1
                port:
                  number: 8080
          - path: /test2
            pathType: Prefix
            backend:
              service:
                name: helloworld2
                port:
                  number: 8080

Or if you want geojson-example as a ingress valid path then you have to remove default backend annotation.或者,如果您希望 geojson-example 作为入口有效路径,则必须删除默认后端注释。 Then your manifest file will be:然后你的清单文件将是:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - http:
        paths:
          - path: /geo
            pathType: Prefix
            backend:
              service:
                name: geojson-example
                port:
                  number: 8080
          - path: /test1
            pathType: Prefix
            backend:
              service:
                name: helloworld1
                port:
                  number: 8080
          - path: /test2
            pathType: Prefix
            backend:
              service:
                name: helloworld2
                port:
                  number: 8080

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

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