kubernetes nginx 入口控制器 return 404
kubernetes nginx ingress controller return 404
按照这个 guide,我在本地 kubernetes 服务器上创建了一个入口控制器,唯一的区别是它是作为 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
这是入口控制器:
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 上卷曲它有效,但从外部,我获得 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
我能做什么?
这是您的默认后端。您将 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
就文档而言:此注释的形式为 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
按照这个 guide,我在本地 kubernetes 服务器上创建了一个入口控制器,唯一的区别是它是作为 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
这是入口控制器:
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 上卷曲它有效,但从外部,我获得 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
我能做什么?
这是您的默认后端。您将 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
就文档而言:此注释的形式为 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