Ingress 未转发请求 - Docker 桌面 Windows 和 kubernetes
Ingress not forwarding the requests - Docker desktop for Windows and kubernetes
编辑:
我删除了 minikube,在 Docker 桌面中为 Windows 启用了 kubernetes,并手动安装了 ingress-nginx
。
$helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace
Release "ingress-nginx" does not exist. Installing it now.
Error: rendered manifests contain a resource that already exists. Unable to continue with install: ServiceAccount "ingress-nginx" in namespace "ingress-nginx" exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "ingress-nginx"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ingress-nginx"
它给了我一个错误,但我认为这是因为我之前已经这样做了,因为:
$kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.106.222.233 localhost 80:30199/TCP,443:31093/TCP 11m
ingress-nginx-controller-admission ClusterIP 10.106.52.106 <none> 443/TCP 11m
然后再次应用我所有的 yaml 文件,但这次入口没有获得任何地址:
$kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-ingress <none> myapp.com 80 10m
我正在使用 docker 桌面(windows)并通过 minikube 插件启用命令安装了 nginx-ingress 控制器:
$kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-lp4md 0/1 Completed 0 67m
ingress-nginx-admission-patch--1-jdkn7 0/1 Completed 1 67m
ingress-nginx-controller-5f66978484-6mpfh 1/1 Running 0 67m
并应用了我所有的 yaml 文件:
$kubectl get svc --all-namespaces -o wide
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default event-service-svc ClusterIP 10.108.251.79 <none> 80/TCP 16m app=event-service-app
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16m <none>
default mssql-clusterip-srv ClusterIP 10.98.10.22 <none> 1433/TCP 16m app=mssql
default mssql-loadbalancer LoadBalancer 10.109.106.174 <pending> 1433:31430/TCP 16m app=mssql
default user-service-svc ClusterIP 10.111.128.73 <none> 80/TCP 16m app=user-service-app
ingress-nginx ingress-nginx-controller NodePort 10.101.112.245 <none> 80:31583/TCP,443:30735/TCP 68m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.105.169.167 <none> 443/TCP 68m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 72m k8s-app=kube-dns
所有 pods 和服务似乎 运行 正常。检查 pod 日志,所有迁移等都有效,应用程序已启动并且 运行。但是当我尝试发送 HTTP 请求时,出现套接字挂起错误。我检查了所有 pods 的所有日志,找不到任何有用的东西。
$kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-ingress nginx myapp.com localhost 80 74s
这个也有点奇怪,我希望 ADRESS 设置为 IP 而不是本地主机。因此,在 /etc/hosts 中为 myapp.com 添加 127.0.0.1 条目似乎也不太正确。
我的问题是我可能做错了什么?或者我怎样才能追踪我的请求被转发到哪里?
入口-svc.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: myapp.com
http:
paths:
- path: /api/Users
pathType: Prefix
backend:
service:
name: user-service-svc
port:
number: 80
- path: /api/Events
pathType: Prefix
backend:
service:
name: event-service-svc
port:
number: 80
事件-depl.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: event-service-app
labels:
app: event-service-app
spec:
replicas: 1
selector:
matchLabels:
app: event-service-app
template:
metadata:
labels:
app: event-service-app
spec:
containers:
- name: event-service-app
image: ghcr.io/myapp/event-service:master
imagePullPolicy: Always
ports:
- containerPort: 80
imagePullSecrets:
- name: myapp
---
apiVersion: v1
kind: Service
metadata:
name: event-service-svc
spec:
selector:
app: event-service-app
ports:
- protocol: TCP
port: 80
targetPort: 80
复制
我使用 minikube v1.24.0
、Docker 桌面 4.2.0
、引擎 20.10.10
重现了案例
首先,localhost
in ingress 由于逻辑出现,/etc/hosts
中域后面的 IP 地址是什么并不重要,我添加了一个不同的用于测试,但它仍然显示本地主机。只有 metallb
会提供来自设置网络的 IP 地址。
会发生什么
当 minikube 驱动程序为 docker
时,minikube 创建一个大容器 (VM),其中 kubernetes 组件为 运行。这可以通过主机系统中的 运行ning docker ps
命令进行检查:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f087dc669944 gcr.io/k8s-minikube/kicbase:v0.0.28 "/usr/local/bin/entr…" 16 minutes ago Up 16 minutes 127.0.0.1:59762->22/tcp, 127.0.0.1:59758->2376/tcp, 127.0.0.1:59760->5000/tcp, 127.0.0.1:59761->8443/tcp, 127.0.0.1:59759->32443/tcp minikube
然后 minikube ssh
进入这个容器,运行 docker ps
查看所有 kubernetes 容器。
前进。在引入 ingress
之前,已经很清楚即使 NodePort
也不能按预期工作。让我们检查一下。
有两种获取方式minikube VM IP
:
- 运行
minikube IP
kubectl get nodes -o wide
并找到节点的 IP
NodePort
接下来应该发生的是请求应该转到 minikube_IP:Nodeport
而它不起作用。发生这种情况是因为 minikube VM 内的 docker 容器没有暴露在集群之外,这是另一个 docker 容器。
在 minikube
上访问集群内的服务有一个特殊的命令 - minikube service %service_name%
它将创建一个直接隧道到 minikube VM
内的服务(你可以看到它包含service URL
和 NodePort
应该可以工作):
$ minikube service echo
|-----------|------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------|-------------|---------------------------|
| default | echo | 8080 | http://192.168.49.2:32034 |
|-----------|------|-------------|---------------------------|
* Starting tunnel for service echo.
|-----------|------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------|-------------|------------------------|
| default | echo | | http://127.0.0.1:61991 |
|-----------|------|-------------|------------------------|
* Opening service default/echo in default browser...
! Because you are using a Docker driver on windows, the terminal needs to be open to run it
现在可以在主机上使用了:
$ curl http://127.0.0.1:61991/
StatusCode : 200
StatusDescription : OK
添加入口
前进并添加入口。
$ minikube addons enable ingress
$ kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default echo NodePort 10.111.57.237 <none> 8080:32034/TCP 25m
ingress-nginx ingress-nginx-controller NodePort 10.104.52.175 <none> 80:31041/TCP,443:31275/TCP 2m12s
尝试通过点击 minikube_IP:NodePort
获得 ingress
的任何回应,但没有成功:
$ curl 192.168.49.2:31041
curl : Unable to connect to the remote server
At line:1 char:1
+ curl 192.168.49.2:31041
正在尝试使用 minikube service
命令创建隧道:
$ minikube service ingress-nginx-controller -n ingress-nginx
|---------------|--------------------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|---------------|--------------------------|-------------|---------------------------|
| ingress-nginx | ingress-nginx-controller | http/80 | http://192.168.49.2:31041 |
| | | https/443 | http://192.168.49.2:31275 |
|---------------|--------------------------|-------------|---------------------------|
* Starting tunnel for service ingress-nginx-controller.
|---------------|--------------------------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|---------------|--------------------------|-------------|------------------------|
| ingress-nginx | ingress-nginx-controller | | http://127.0.0.1:62234 |
| | | | http://127.0.0.1:62235 |
|---------------|--------------------------|-------------|------------------------|
* Opening service ingress-nginx/ingress-nginx-controller in default browser...
* Opening service ingress-nginx/ingress-nginx-controller in default browser...
! Because you are using a Docker driver on windows, the terminal needs to be open to run it.
并从 ingress-nginx
获取 404
这意味着我们可以向入口发送请求:
$ curl http://127.0.0.1:62234
curl : 404 Not Found
nginx
At line:1 char:1
+ curl http://127.0.0.1:62234
解决方案
上面我解释了会发生什么。以下是如何让它发挥作用的三种解决方案:
- 使用另一个 minikube driver(例如 virtualbox。我使用
hyperv
因为我的笔记本电脑有 windows 10 pro)
minikube ip
将 return 虚拟机的“正常”IP 地址和所有网络功能都可以正常工作。您需要将此 IP 地址添加到 /etc/hosts
中用于入口规则
的域
注意! 即使 localhost
显示在 kubectl get ing ingress
输出中 ADDRESS
.
- 在 Docker 桌面中为 Windows 使用内置的 kubernetes 功能。
您将需要manually install ingress-nginx
and change ingress-nginx-controller
service type from NodePort
to LoadBalancer
so it will be available on localhost
and will be working. Please find
- (仅测试)- 使用端口转发
这与minikube service
命令几乎完全相同。但是有了更多的控制。您还将在端口 80
上打开从主机 VM 端口 80
到 ingress-nginx-controller
服务(最终是 pod)的隧道。 /etc/hosts
应包含 127.0.0.1 test.domain
个实体。
$ kubectl port-forward service/ingress-nginx-controller -n ingress-nginx 80:80
Forwarding from 127.0.0.1:80 -> 80
Forwarding from [::1]:80 -> 80
并测试它是否有效:
$ curl test.domain
StatusCode : 200
StatusDescription : OK
docker 桌面 windows 和入口中的 kubernetes 更新:
在现代 ingress-nginx
版本中 .spec.ingressClassName
应该添加到入口规则中。请参阅 last updates,因此入口规则应如下所示:
apiVersion: networking.k8s.io/v1
kind: Ingress
...
spec:
ingressClassName: nginx # can be checked by kubectl get ingressclass
rules:
- host: myapp.com
http:
...
编辑:
我删除了 minikube,在 Docker 桌面中为 Windows 启用了 kubernetes,并手动安装了 ingress-nginx
。
$helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace
Release "ingress-nginx" does not exist. Installing it now.
Error: rendered manifests contain a resource that already exists. Unable to continue with install: ServiceAccount "ingress-nginx" in namespace "ingress-nginx" exists and cannot be imported into the current release: invalid ownership metadata; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "ingress-nginx"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "ingress-nginx"
它给了我一个错误,但我认为这是因为我之前已经这样做了,因为:
$kubectl get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller LoadBalancer 10.106.222.233 localhost 80:30199/TCP,443:31093/TCP 11m
ingress-nginx-controller-admission ClusterIP 10.106.52.106 <none> 443/TCP 11m
然后再次应用我所有的 yaml 文件,但这次入口没有获得任何地址:
$kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-ingress <none> myapp.com 80 10m
我正在使用 docker 桌面(windows)并通过 minikube 插件启用命令安装了 nginx-ingress 控制器:
$kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-lp4md 0/1 Completed 0 67m
ingress-nginx-admission-patch--1-jdkn7 0/1 Completed 1 67m
ingress-nginx-controller-5f66978484-6mpfh 1/1 Running 0 67m
并应用了我所有的 yaml 文件:
$kubectl get svc --all-namespaces -o wide
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
default event-service-svc ClusterIP 10.108.251.79 <none> 80/TCP 16m app=event-service-app
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16m <none>
default mssql-clusterip-srv ClusterIP 10.98.10.22 <none> 1433/TCP 16m app=mssql
default mssql-loadbalancer LoadBalancer 10.109.106.174 <pending> 1433:31430/TCP 16m app=mssql
default user-service-svc ClusterIP 10.111.128.73 <none> 80/TCP 16m app=user-service-app
ingress-nginx ingress-nginx-controller NodePort 10.101.112.245 <none> 80:31583/TCP,443:30735/TCP 68m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
ingress-nginx ingress-nginx-controller-admission ClusterIP 10.105.169.167 <none> 443/TCP 68m app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 72m k8s-app=kube-dns
所有 pods 和服务似乎 运行 正常。检查 pod 日志,所有迁移等都有效,应用程序已启动并且 运行。但是当我尝试发送 HTTP 请求时,出现套接字挂起错误。我检查了所有 pods 的所有日志,找不到任何有用的东西。
$kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-ingress nginx myapp.com localhost 80 74s
这个也有点奇怪,我希望 ADRESS 设置为 IP 而不是本地主机。因此,在 /etc/hosts 中为 myapp.com 添加 127.0.0.1 条目似乎也不太正确。
我的问题是我可能做错了什么?或者我怎样才能追踪我的请求被转发到哪里?
入口-svc.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
spec:
rules:
- host: myapp.com
http:
paths:
- path: /api/Users
pathType: Prefix
backend:
service:
name: user-service-svc
port:
number: 80
- path: /api/Events
pathType: Prefix
backend:
service:
name: event-service-svc
port:
number: 80
事件-depl.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: event-service-app
labels:
app: event-service-app
spec:
replicas: 1
selector:
matchLabels:
app: event-service-app
template:
metadata:
labels:
app: event-service-app
spec:
containers:
- name: event-service-app
image: ghcr.io/myapp/event-service:master
imagePullPolicy: Always
ports:
- containerPort: 80
imagePullSecrets:
- name: myapp
---
apiVersion: v1
kind: Service
metadata:
name: event-service-svc
spec:
selector:
app: event-service-app
ports:
- protocol: TCP
port: 80
targetPort: 80
复制
我使用 minikube v1.24.0
、Docker 桌面 4.2.0
、引擎 20.10.10
首先,localhost
in ingress 由于逻辑出现,/etc/hosts
中域后面的 IP 地址是什么并不重要,我添加了一个不同的用于测试,但它仍然显示本地主机。只有 metallb
会提供来自设置网络的 IP 地址。
会发生什么
当 minikube 驱动程序为 docker
时,minikube 创建一个大容器 (VM),其中 kubernetes 组件为 运行。这可以通过主机系统中的 运行ning docker ps
命令进行检查:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f087dc669944 gcr.io/k8s-minikube/kicbase:v0.0.28 "/usr/local/bin/entr…" 16 minutes ago Up 16 minutes 127.0.0.1:59762->22/tcp, 127.0.0.1:59758->2376/tcp, 127.0.0.1:59760->5000/tcp, 127.0.0.1:59761->8443/tcp, 127.0.0.1:59759->32443/tcp minikube
然后 minikube ssh
进入这个容器,运行 docker ps
查看所有 kubernetes 容器。
前进。在引入 ingress
之前,已经很清楚即使 NodePort
也不能按预期工作。让我们检查一下。
有两种获取方式minikube VM IP
:
- 运行
minikube IP
kubectl get nodes -o wide
并找到节点的 IP
NodePort
接下来应该发生的是请求应该转到 minikube_IP:Nodeport
而它不起作用。发生这种情况是因为 minikube VM 内的 docker 容器没有暴露在集群之外,这是另一个 docker 容器。
在 minikube
上访问集群内的服务有一个特殊的命令 - minikube service %service_name%
它将创建一个直接隧道到 minikube VM
内的服务(你可以看到它包含service URL
和 NodePort
应该可以工作):
$ minikube service echo
|-----------|------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------|-------------|---------------------------|
| default | echo | 8080 | http://192.168.49.2:32034 |
|-----------|------|-------------|---------------------------|
* Starting tunnel for service echo.
|-----------|------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|------|-------------|------------------------|
| default | echo | | http://127.0.0.1:61991 |
|-----------|------|-------------|------------------------|
* Opening service default/echo in default browser...
! Because you are using a Docker driver on windows, the terminal needs to be open to run it
现在可以在主机上使用了:
$ curl http://127.0.0.1:61991/
StatusCode : 200
StatusDescription : OK
添加入口
前进并添加入口。
$ minikube addons enable ingress
$ kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default echo NodePort 10.111.57.237 <none> 8080:32034/TCP 25m
ingress-nginx ingress-nginx-controller NodePort 10.104.52.175 <none> 80:31041/TCP,443:31275/TCP 2m12s
尝试通过点击 minikube_IP:NodePort
获得 ingress
的任何回应,但没有成功:
$ curl 192.168.49.2:31041
curl : Unable to connect to the remote server
At line:1 char:1
+ curl 192.168.49.2:31041
正在尝试使用 minikube service
命令创建隧道:
$ minikube service ingress-nginx-controller -n ingress-nginx
|---------------|--------------------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|---------------|--------------------------|-------------|---------------------------|
| ingress-nginx | ingress-nginx-controller | http/80 | http://192.168.49.2:31041 |
| | | https/443 | http://192.168.49.2:31275 |
|---------------|--------------------------|-------------|---------------------------|
* Starting tunnel for service ingress-nginx-controller.
|---------------|--------------------------|-------------|------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|---------------|--------------------------|-------------|------------------------|
| ingress-nginx | ingress-nginx-controller | | http://127.0.0.1:62234 |
| | | | http://127.0.0.1:62235 |
|---------------|--------------------------|-------------|------------------------|
* Opening service ingress-nginx/ingress-nginx-controller in default browser...
* Opening service ingress-nginx/ingress-nginx-controller in default browser...
! Because you are using a Docker driver on windows, the terminal needs to be open to run it.
并从 ingress-nginx
获取 404
这意味着我们可以向入口发送请求:
$ curl http://127.0.0.1:62234
curl : 404 Not Found
nginx
At line:1 char:1
+ curl http://127.0.0.1:62234
解决方案
上面我解释了会发生什么。以下是如何让它发挥作用的三种解决方案:
- 使用另一个 minikube driver(例如 virtualbox。我使用
hyperv
因为我的笔记本电脑有 windows 10 pro)
minikube ip
将 return 虚拟机的“正常”IP 地址和所有网络功能都可以正常工作。您需要将此 IP 地址添加到 /etc/hosts
中用于入口规则
注意! 即使 localhost
显示在 kubectl get ing ingress
输出中 ADDRESS
.
- 在 Docker 桌面中为 Windows 使用内置的 kubernetes 功能。
您将需要manually install ingress-nginx
and change ingress-nginx-controller
service type from NodePort
to LoadBalancer
so it will be available on localhost
and will be working. Please find
- (仅测试)- 使用端口转发
这与minikube service
命令几乎完全相同。但是有了更多的控制。您还将在端口 80
上打开从主机 VM 端口 80
到 ingress-nginx-controller
服务(最终是 pod)的隧道。 /etc/hosts
应包含 127.0.0.1 test.domain
个实体。
$ kubectl port-forward service/ingress-nginx-controller -n ingress-nginx 80:80
Forwarding from 127.0.0.1:80 -> 80
Forwarding from [::1]:80 -> 80
并测试它是否有效:
$ curl test.domain
StatusCode : 200
StatusDescription : OK
docker 桌面 windows 和入口中的 kubernetes 更新:
在现代 ingress-nginx
版本中 .spec.ingressClassName
应该添加到入口规则中。请参阅 last updates,因此入口规则应如下所示:
apiVersion: networking.k8s.io/v1
kind: Ingress
...
spec:
ingressClassName: nginx # can be checked by kubectl get ingressclass
rules:
- host: myapp.com
http:
...