ingress-nginx 错误连接被拒绝
ingress-nginx Errors connection refused
我正在尝试从服务访问我的 ingress-nginx 服务,但它拒绝连接。这是我的入口
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: ticketing.dev
http:
paths:
- path: /api/users/?(.*)
backend:
serviceName: auth-srv
servicePort: 3000
- path: /api/tickets/?(.*)
backend:
serviceName: tickets-srv
servicePort: 3000
- path: /?(.*)
backend:
serviceName: client-srv
servicePort: 3000
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: LoadBalancer
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: http
port: 443
protocol: TCP
targetPort: https
❯ kubectl get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx LoadBalancer 10.101.124.218 10.101.124.218 80:30634/TCP,443:30179/TCP 15m
ingress-nginx 在命名空间 ingress-nginx 上 运行。
因此 http://ingress-nginx.ingress-nginx.svc.cluster.local
应该可以访问它。但是当我访问它时,它显示 connection refused 10.101.124.218:80
。我可以从外部访问入口,即从 ingress
ip.
我正在使用 minikube 并使用 运行 minikube addons enable ingress
的入口。是的,我 运行 minikube tunnel
的隧道
我测试了您的环境并发现了相同的行为,外部访问但内部连接被拒绝,我就是这样解决的:
- Minikube Ingress Addon 在
kube-system
命名空间中部署控制器。如果您尝试在新创建的命名空间中部署服务,它将无法到达 kube-system
命名空间中的部署。
- 很容易混合这些概念,因为默认
nginx-ingress
部署使用命名空间 ingress-nginx
,就像您尝试的那样。
我发现的另一个问题是,您的服务没有将所有选择器分配给控制器部署。
使部署工作的最简单方法是 运行 kubectl expose
在 nginx 控制器上:
kubectl expose deployment ingress-nginx-controller --target-port=80 --type=NodePort -n kube-system
- 使用此命令创建 nginx-ingress-controller 服务,所有通信都正常工作,包括外部和内部。
复制:
- 对于这个例子,我只使用了两个入口后端,以避免在我的解释中重复太多。
- 使用 minikube 1.11.0
- 启用
ingress
和 metallb
插件。
- 部署了两个hello应用:
v1
和v2
,都pods监听端口8080
并暴露为节点端口如下:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello1-svc NodePort 10.110.211.119 <none> 8080:31243/TCP 95m
hello2-svc NodePort 10.96.9.66 <none> 8080:31316/TCP 93m
- 这是入口文件,就像你的一样,只是更改了后端服务名称和端口以匹配我部署的:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: ticketing.dev
http:
paths:
- path: /api/users/?(.*)
backend:
serviceName: hello1-svc
servicePort: 8080
- path: /?(.*)
backend:
serviceName: hello2-svc
servicePort: 8080
- 现在我将创建公开控制器部署的
nginx-ingress
服务,这样所有标签和设置都将被继承:
$ kubectl expose deployment ingress-nginx-controller --target-port=80 --type=NodeP
ort -n kube-system
service/ingress-nginx-controller exposed
- 现在我们部署入口对象:
$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/ingress-service created
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-service <none> ticketing.dev 172.17.0.4 80 56s
$ minikube ip
172.17.0.4
- 从外部测试入口:
$ tail -n 1 /etc/hosts
172.17.0.4 ticketing.dev
$ curl http://ticketing.dev/?foo
Hello, world!
Version: 2.0.0
Hostname: hello2-67bbbf98bb-s78c4
$ curl http://ticketing.dev/api/users/?foo
Hello, world!
Version: 1.0.0
Hostname: hello-576585fb5f-67ph5
- 然后我部署了一个
alpine
pod来测试集群内部的访问:
$ kubectl run --generator=run-pod/v1 -it alpine --image=alpine -- /bin/sh
/ # nslookup ingress-nginx-controller.kube-system.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: ingress-nginx-controller.kube-system.svc.cluster.local
Address: 10.98.167.112
/ # apk update
/ # apk add curl
/ # curl -H "Host: ticketing.dev" ingress-nginx-controller.kube-system.svc.cluster.local/?foo
Hello, world!
Version: 2.0.0
Hostname: hello2-67bbbf98bb-s78c4
/ # curl -H "Host: ticketing.dev" ingress-nginx-controller.kube-system.svc.cluster.local/api/users/?foo
Hello, world!
Version: 1.0.0
Hostname: hello-576585fb5f-67ph5
如您所见,所有请求都已完成。
注:
正如 @suren 指出的那样,在 curling ingress 时,我必须使用 -H
指定主机
服务名称需要是完整的 FQDN,因为我们正在处理托管在另一个命名空间中的服务,使用格式 <SVC_NAME>.<NAMESPACE>.svc.cluster.local
.
在您的 JS 应用程序中,您必须传递 Host
参数才能到达入口。
如果您有任何问题,请在评论中告诉我。
我正在尝试从服务访问我的 ingress-nginx 服务,但它拒绝连接。这是我的入口
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: ticketing.dev
http:
paths:
- path: /api/users/?(.*)
backend:
serviceName: auth-srv
servicePort: 3000
- path: /api/tickets/?(.*)
backend:
serviceName: tickets-srv
servicePort: 3000
- path: /?(.*)
backend:
serviceName: client-srv
servicePort: 3000
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
externalTrafficPolicy: Local
type: LoadBalancer
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: http
port: 443
protocol: TCP
targetPort: https
❯ kubectl get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx LoadBalancer 10.101.124.218 10.101.124.218 80:30634/TCP,443:30179/TCP 15m
ingress-nginx 在命名空间 ingress-nginx 上 运行。
因此 http://ingress-nginx.ingress-nginx.svc.cluster.local
应该可以访问它。但是当我访问它时,它显示 connection refused 10.101.124.218:80
。我可以从外部访问入口,即从 ingress
ip.
我正在使用 minikube 并使用 运行 minikube addons enable ingress
的入口。是的,我 运行 minikube tunnel
我测试了您的环境并发现了相同的行为,外部访问但内部连接被拒绝,我就是这样解决的:
- Minikube Ingress Addon 在
kube-system
命名空间中部署控制器。如果您尝试在新创建的命名空间中部署服务,它将无法到达kube-system
命名空间中的部署。 - 很容易混合这些概念,因为默认
nginx-ingress
部署使用命名空间ingress-nginx
,就像您尝试的那样。 我发现的另一个问题是,您的服务没有将所有选择器分配给控制器部署。
使部署工作的最简单方法是 运行
kubectl expose
在 nginx 控制器上:
kubectl expose deployment ingress-nginx-controller --target-port=80 --type=NodePort -n kube-system
- 使用此命令创建 nginx-ingress-controller 服务,所有通信都正常工作,包括外部和内部。
复制:
- 对于这个例子,我只使用了两个入口后端,以避免在我的解释中重复太多。
- 使用 minikube 1.11.0
- 启用
ingress
和metallb
插件。 - 部署了两个hello应用:
v1
和v2
,都pods监听端口8080
并暴露为节点端口如下:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello1-svc NodePort 10.110.211.119 <none> 8080:31243/TCP 95m
hello2-svc NodePort 10.96.9.66 <none> 8080:31316/TCP 93m
- 这是入口文件,就像你的一样,只是更改了后端服务名称和端口以匹配我部署的:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-service
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: ticketing.dev
http:
paths:
- path: /api/users/?(.*)
backend:
serviceName: hello1-svc
servicePort: 8080
- path: /?(.*)
backend:
serviceName: hello2-svc
servicePort: 8080
- 现在我将创建公开控制器部署的
nginx-ingress
服务,这样所有标签和设置都将被继承:
$ kubectl expose deployment ingress-nginx-controller --target-port=80 --type=NodeP
ort -n kube-system
service/ingress-nginx-controller exposed
- 现在我们部署入口对象:
$ kubectl apply -f ingress.yaml
ingress.networking.k8s.io/ingress-service created
$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-service <none> ticketing.dev 172.17.0.4 80 56s
$ minikube ip
172.17.0.4
- 从外部测试入口:
$ tail -n 1 /etc/hosts
172.17.0.4 ticketing.dev
$ curl http://ticketing.dev/?foo
Hello, world!
Version: 2.0.0
Hostname: hello2-67bbbf98bb-s78c4
$ curl http://ticketing.dev/api/users/?foo
Hello, world!
Version: 1.0.0
Hostname: hello-576585fb5f-67ph5
- 然后我部署了一个
alpine
pod来测试集群内部的访问:
$ kubectl run --generator=run-pod/v1 -it alpine --image=alpine -- /bin/sh
/ # nslookup ingress-nginx-controller.kube-system.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: ingress-nginx-controller.kube-system.svc.cluster.local
Address: 10.98.167.112
/ # apk update
/ # apk add curl
/ # curl -H "Host: ticketing.dev" ingress-nginx-controller.kube-system.svc.cluster.local/?foo
Hello, world!
Version: 2.0.0
Hostname: hello2-67bbbf98bb-s78c4
/ # curl -H "Host: ticketing.dev" ingress-nginx-controller.kube-system.svc.cluster.local/api/users/?foo
Hello, world!
Version: 1.0.0
Hostname: hello-576585fb5f-67ph5
如您所见,所有请求都已完成。
注:
正如 @suren 指出的那样,在 curling ingress 时,我必须使用 -H
指定主机
服务名称需要是完整的 FQDN,因为我们正在处理托管在另一个命名空间中的服务,使用格式
<SVC_NAME>.<NAMESPACE>.svc.cluster.local
.在您的 JS 应用程序中,您必须传递
Host
参数才能到达入口。
如果您有任何问题,请在评论中告诉我。