再生产
我使用 minikube 重现了这个案例v1.24.0
, Docker 桌面4.2.0
, 引擎20.10.10
First, localhost
ingress 中的出现是出于逻辑原因,域后面的 IP 地址是什么并不重要/etc/hosts
,我添加了一个不同的测试,但它仍然显示 localhost。仅有的metallb
将提供来自设置网络的 IP 地址。
会发生什么
当 minikube 驱动程序为docker
,minikube 创建一个大容器(VM),在其中运行 kubernetes 组件。这可以通过运行来检查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
:
- run
minikube IP
-
kubectl get nodes -o wide
并找到节点的IP
接下来会发生什么NodePort
请求应该发送至minikube_IP:Nodeport
虽然它不起作用。发生这种情况是因为 minikube VM 内的 docker 容器没有暴露在集群之外(另一个 docker 容器)。
On minikube
要访问集群内的服务,有一个特殊的命令 -minikube service %service_name% https://minikube.sigs.k8s.io/docs/commands/service/这将创建一个到内部服务的直接隧道minikube VM
(你可以看到它包含service URL
with 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
试图得到任何回应ingress
通过击打minikube_IP:NodePort
没有运气:
$ 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.
并得到404
from ingress-nginx
这意味着我们可以向 ingress 发送请求:
$ 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 驱动程序 https://minikube.sigs.k8s.io/docs/drivers/(例如 virtualbox。我用过
hyperv
因为我的笔记本电脑有 Windows 10 Pro)
minikube ip
将返回虚拟机的“正常”IP 地址,并且所有网络功能都将正常工作。您需要将此 IP 地址添加到/etc/hosts
用于入口规则中使用的域
Note!虽然localhost
被显示在kubectl get ing ingress
输出在ADDRESS
.
- 使用适用于 Windows 的 Docker 桌面中的内置 kubernetes 功能。
您将需要手动安装ingress-nginx https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters并改变ingress-nginx-controller
服务类型来自NodePort
to LoadBalancer
所以它可以在localhost
并将继续工作。请找到我关于 Windows 的 Docker 桌面的另一个答案 https://stackoverflow.com/a/69113528/15537201
- (仅测试) - 使用端口转发
这几乎与完全相同的想法minikube service
命令。但有更多的控制。您将从主机 VM 端口打开隧道80
to ingress-nginx-controller
端口上的服务(最终是 pod)80
以及。/etc/hosts
应包含127.0.0.1 test.domain
entity.
$ 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
Windows 和 ingress 上 docker 桌面中的 kubernetes 更新:
论现代ingress-nginx
版本.spec.ingressClassName
应添加到入口规则中。看最后更新 https://kubernetes.github.io/ingress-nginx/#i-have-only-one-instance-of-the-ingresss-nginx-controller-in-my-cluster-what-should-i-do,因此入口规则应如下所示:
apiVersion: networking.k8s.io/v1
kind: Ingress
...
spec:
ingressClassName: nginx # can be checked by kubectl get ingressclass
rules:
- host: myapp.com
http:
...