Nginx Ingress 仅在将 nodeport 添加到主机名时才起作用。如何在没有节点端口的情况下使其工作?
Nginx Ingress works only if nodeport is added to the host name. How to make it work without nodeport?
我正在云 Kubernetes 集群上尝试一个简单的微服务应用程序。这是入口 yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-nginx-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
spec:
defaultBackend:
service:
name: auth-svc
port:
number: 5000
rules:
- host: "somehostname.xyz"
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: auth-svc
port:
number: 5000
问题:
当我使用此 URL 时,我能够访问身份验证服务:http://somehostname.xyz:31840
。但是,如果我使用 http://somehostname.xyz
,我会收到 “无法访问此站点 somehostname.xyz 拒绝连接。” 错误。
auth 服务也向其他服务发送 GET 请求,如果我使用:
,我可以看到这些服务的响应
http://somehostname.xyz:31840/go
或 http://somehostname.xyz:31840/express
。但同样,这些仅在使用节点端口 31840
时有效。
我的问题:
一般是什么原因导致这样的问题,我在哪里可以访问服务
使用主机名和节点端口,但如果不提供
节点端口?
有没有一种方法可以用不同的方式测试它,找出它在哪里
问题是?
是Ingress还是Auth命名空间的问题?这是个问题吗
使用 Flask 中的主机名?是不是Ingress的问题
控制器?我该如何调试?
这些是 kubectl get all
和其他命令的结果。
NAME READY STATUS RESTARTS
pod/auth-flask-58ccd5c94c-g257t 1/1 Running 0
pod/ingress-nginx-nginx-ingress-6677d54459-gtr42 1/1 Running 0
NAME TYPE EXTERNAL-IP PORT(S)
service/auth-svc ClusterIP <none> 5000/TCP
service/ingress-nginx-nginx-ingress LoadBalancer 172.xxx.xx.130 80:31840/TCP,443:30550/TCP
NAME READY UP-TO-DATE AVAILABLE
deployment.apps/auth-flask 1/1 1 1
deployment.apps/ingress-nginx-nginx-ingress 1/1 1 1
NAME DESIRED CURRENT READY
replicaset.apps/auth-flask-58ccd5c94c 1 1 1
replicaset.apps/ingress-nginx-nginx-ingress-6677d54459 1 1 1
NAME CLASS HOSTS ADDRESS PORTS
ingress-nginx-nginx-ingress <none> somehostname.xyz 172.xxx.xx.130 80
描述入口也很正常。
kubectl describe ingress ingress-nginx-nginx-ingress
Name: ingress-nginx-nginx-ingress
Namespace: default
Address: 172.xxx.xx.130
Default backend: auth-svc:5000 (10.x.xx.xxx:5000)
Rules:
Host Path Backends
---- ---- --------
somehostname.xyz
/ auth-svc:5000 (10.x.xx.xxx:5000)
Annotations: kubernetes.io/ingress.class: nginx
这是授权码
import requests
from flask import Flask
app = Flask(__name__)
@app.route('/')
def indexPage():
return ' <!DOCTYPE html><html><head><meta charset="UTF-8" />\
<title>Microservice</title></head> \
<body><div style="text-align: center;">Welcome to the Auth page</div></body></html>'
@app.route('/go')
def getGoJson():
return requests.get('http://analytics-svc:8082/info').content
@app.route('/express')
def getNodeResponse():
return requests.get('http://node-svc:8085/express').content
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0")
和 Auth 的 Dockerfile:
FROM python:3.8-slim-buster
WORKDIR /usr/src/app
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_ENV=development
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
docker部分-compose yaml for auth:
version: "3.3"
services:
auth:
build: ./auth/
image: nav9/auth-flask:v1
ports:
- "5000:5000"
Auth 的 Kubernetes 清单:
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-flask
spec:
selector:
matchLabels:
any-name: auth-flask
template:
metadata:
labels:
any-name: auth-flask
spec:
containers:
- name: auth-name
image: nav9/auth-flask:v1
imagePullPolicy: Always
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: auth-svc
spec:
# type: ClusterIP
ports:
- targetPort: 5000
port: 5000
selector:
any-name: auth-flask
What typically causes such a problem, where I can access the service using the hostname and nodeport, but it won't work without supplying the nodeport?
如果 URL 在使用 nodeport 时有效,而不是在没有 nodeport 的情况下有效,那么这意味着入口未针对您想要执行的操作进行正确配置。
Is there a method to test this in a different way to figure out where the problem is?
故障排除步骤是:
- 第一步是确定错误是来自入口还是来自您的后端服务。
在你的情况下,错误 This site can’t be reached somehostname.xyz refused to connect
,听起来像是 Ingress 找到了要映射到的服务并使用端口 5000 连接到它,但连接被拒绝或没有任何东西在端口 5000 上监听服务。
- 接下来我会查看 auth-svc 日志以查看该请求是否进入了系统以及它被拒绝的原因。
我的猜测是身份验证服务正在侦听端口 31840
,但您的入口表示根据配置连接到端口 5000
。
您可以尝试添加一个从 80 到 31840 的端口映射作为 hack/test 以查看是否会出现不同的错误。
类似于:
spec:
rules:
- host: "somehostname.xyz"
http:
paths:
- path: "/"
backend:
service:
port:
number: 31840
我只包含了正确显示缩进所需的部分。
所以另一种测试方法是创建额外的 URLs 映射到不同的端口,例如:
/try1 => auth-svc:5000
/try2 => auth-svc:31840
/try3 => auth-svc:443
我没有玩过的另一部分可能是个问题,因为您正在使用 http,而我不知道有任何使用 http 的身份验证服务,因此只需尝试使用 http 连接到需要 https 的应用程序将获得拒绝连接或出现奇怪错误的连接,因此这可能与您看到的 problem/error 有关。
希望这能给您一些尝试的想法。
解决方案分为三个部分:
使用kubectl get all
找出运行入口服务:
NAME TYPE EXTERNAL-IP PORT(S)
service/ingress-nginx-nginx-ingress LoadBalancer 172.xxx.xx.130 80:31840/TCP,443:30550/TCP
复制服务的 EXTERNAL-IP(在本例中为 172.xxx.xx.130)。
为云集群添加名为*.somehostname.xyz
的DNS A记录,并使用IP地址172.xxx.xx.130
.
通过浏览器访问主机名时,请确保使用 http
而不是 https
。
我正在云 Kubernetes 集群上尝试一个简单的微服务应用程序。这是入口 yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-nginx-nginx-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: nginx
spec:
defaultBackend:
service:
name: auth-svc
port:
number: 5000
rules:
- host: "somehostname.xyz"
http:
paths:
- path: "/"
pathType: Prefix
backend:
service:
name: auth-svc
port:
number: 5000
问题:
当我使用此 URL 时,我能够访问身份验证服务:http://somehostname.xyz:31840
。但是,如果我使用 http://somehostname.xyz
,我会收到 “无法访问此站点 somehostname.xyz 拒绝连接。” 错误。
auth 服务也向其他服务发送 GET 请求,如果我使用:
,我可以看到这些服务的响应
http://somehostname.xyz:31840/go
或 http://somehostname.xyz:31840/express
。但同样,这些仅在使用节点端口 31840
时有效。
我的问题:
一般是什么原因导致这样的问题,我在哪里可以访问服务 使用主机名和节点端口,但如果不提供 节点端口?
有没有一种方法可以用不同的方式测试它,找出它在哪里 问题是?
是Ingress还是Auth命名空间的问题?这是个问题吗 使用 Flask 中的主机名?是不是Ingress的问题 控制器?我该如何调试?
这些是 kubectl get all
和其他命令的结果。
NAME READY STATUS RESTARTS
pod/auth-flask-58ccd5c94c-g257t 1/1 Running 0
pod/ingress-nginx-nginx-ingress-6677d54459-gtr42 1/1 Running 0
NAME TYPE EXTERNAL-IP PORT(S)
service/auth-svc ClusterIP <none> 5000/TCP
service/ingress-nginx-nginx-ingress LoadBalancer 172.xxx.xx.130 80:31840/TCP,443:30550/TCP
NAME READY UP-TO-DATE AVAILABLE
deployment.apps/auth-flask 1/1 1 1
deployment.apps/ingress-nginx-nginx-ingress 1/1 1 1
NAME DESIRED CURRENT READY
replicaset.apps/auth-flask-58ccd5c94c 1 1 1
replicaset.apps/ingress-nginx-nginx-ingress-6677d54459 1 1 1
NAME CLASS HOSTS ADDRESS PORTS
ingress-nginx-nginx-ingress <none> somehostname.xyz 172.xxx.xx.130 80
描述入口也很正常。
kubectl describe ingress ingress-nginx-nginx-ingress
Name: ingress-nginx-nginx-ingress
Namespace: default
Address: 172.xxx.xx.130
Default backend: auth-svc:5000 (10.x.xx.xxx:5000)
Rules:
Host Path Backends
---- ---- --------
somehostname.xyz
/ auth-svc:5000 (10.x.xx.xxx:5000)
Annotations: kubernetes.io/ingress.class: nginx
这是授权码
import requests
from flask import Flask
app = Flask(__name__)
@app.route('/')
def indexPage():
return ' <!DOCTYPE html><html><head><meta charset="UTF-8" />\
<title>Microservice</title></head> \
<body><div style="text-align: center;">Welcome to the Auth page</div></body></html>'
@app.route('/go')
def getGoJson():
return requests.get('http://analytics-svc:8082/info').content
@app.route('/express')
def getNodeResponse():
return requests.get('http://node-svc:8085/express').content
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0")
和 Auth 的 Dockerfile:
FROM python:3.8-slim-buster
WORKDIR /usr/src/app
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_ENV=development
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
docker部分-compose yaml for auth:
version: "3.3"
services:
auth:
build: ./auth/
image: nav9/auth-flask:v1
ports:
- "5000:5000"
Auth 的 Kubernetes 清单:
apiVersion: apps/v1
kind: Deployment
metadata:
name: auth-flask
spec:
selector:
matchLabels:
any-name: auth-flask
template:
metadata:
labels:
any-name: auth-flask
spec:
containers:
- name: auth-name
image: nav9/auth-flask:v1
imagePullPolicy: Always
ports:
- containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
name: auth-svc
spec:
# type: ClusterIP
ports:
- targetPort: 5000
port: 5000
selector:
any-name: auth-flask
What typically causes such a problem, where I can access the service using the hostname and nodeport, but it won't work without supplying the nodeport?
如果 URL 在使用 nodeport 时有效,而不是在没有 nodeport 的情况下有效,那么这意味着入口未针对您想要执行的操作进行正确配置。
Is there a method to test this in a different way to figure out where the problem is?
故障排除步骤是:
- 第一步是确定错误是来自入口还是来自您的后端服务。
在你的情况下,错误 This site can’t be reached somehostname.xyz refused to connect
,听起来像是 Ingress 找到了要映射到的服务并使用端口 5000 连接到它,但连接被拒绝或没有任何东西在端口 5000 上监听服务。
- 接下来我会查看 auth-svc 日志以查看该请求是否进入了系统以及它被拒绝的原因。
我的猜测是身份验证服务正在侦听端口 31840
,但您的入口表示根据配置连接到端口 5000
。
您可以尝试添加一个从 80 到 31840 的端口映射作为 hack/test 以查看是否会出现不同的错误。
类似于:
spec:
rules:
- host: "somehostname.xyz"
http:
paths:
- path: "/"
backend:
service:
port:
number: 31840
我只包含了正确显示缩进所需的部分。 所以另一种测试方法是创建额外的 URLs 映射到不同的端口,例如:
/try1 => auth-svc:5000
/try2 => auth-svc:31840
/try3 => auth-svc:443
我没有玩过的另一部分可能是个问题,因为您正在使用 http,而我不知道有任何使用 http 的身份验证服务,因此只需尝试使用 http 连接到需要 https 的应用程序将获得拒绝连接或出现奇怪错误的连接,因此这可能与您看到的 problem/error 有关。
希望这能给您一些尝试的想法。
解决方案分为三个部分:
使用
kubectl get all
找出运行入口服务:NAME TYPE EXTERNAL-IP PORT(S) service/ingress-nginx-nginx-ingress LoadBalancer 172.xxx.xx.130 80:31840/TCP,443:30550/TCP
复制服务的 EXTERNAL-IP(在本例中为 172.xxx.xx.130)。
为云集群添加名为
*.somehostname.xyz
的DNS A记录,并使用IP地址172.xxx.xx.130
.通过浏览器访问主机名时,请确保使用
http
而不是https
。