簡體   English   中英

kubernetes nginx 入口 controller 返回 404

[英]kubernetes nginx ingress controller return 404

按照本 指南,我在本地 kubernetes 服務器上創建了一個入口 controller,唯一的區別是它是作為 NodePort 創建的。

我已經完成了一些測試部署,具有相應的服務並且一切正常,這里是文件

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

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

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

服務1:

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

服務2:

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

服務3:

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

這是入口 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

當我在myServer:myPort/test1/test2上執行 GET 時,一切正常,在/geo上我得到以下答案

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

為什么?? 如果我創建一個 pod,並且從 pod 內部,我在geojson-example上執行 curl 它可以工作,但是從外部,我得到一個 404(我認為是 nginx 入口控制器)

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

我能做些什么?

就文檔而言:此注釋的形式nginx.ingress.kubernetes.io/default-backend: <svc name>以指定自定義默認后端。 <svc name>是對應用此注釋的同一命名空間內的服務的引用。 此注釋覆蓋全局默認后端。

當 Ingress 規則中的服務沒有活動端點時,該服務將處理響應。

您不能將相同的服務用作默認后端,也不能用於路徑。 當你這樣做時,路徑/geo變得無效。 正如我們所知,默認后端僅服務於非活動端點。 現在,如果您告訴您希望geojson-example在路徑中再次作為默認后端(對於非活動端點),如果您告訴將geojson-example用於有效路徑/geo那么它變得無效,因為您在這里創建了死鎖類型的情況。

你實際上不需要給這個nginx.ingress.kubernetes.io/default-backend注釋。

您的入口應該如下所示,沒有默認注釋,或者您可以使用注釋,但在這種情況下,您需要從路徑中的任何有效路徑中刪除geojson-example ,或者需要為路徑/geo使用其他服務。 您可以使用的選項如下:

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

或者:

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

或者:

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

這適用於您的默認后端。 您將 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

因此,如果您希望 geojson-example 服務作為默認后端,那么您不需要 /geo 路徑規范。 然后你的清單文件將是:

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

或者,如果您希望 geojson-example 作為入口有效路徑,則必須刪除默認后端注釋。 然后你的清單文件將是:

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