为什么在本地 k8s 环境中使用 nginx-ingress 控制器和资源时有时需要编辑 /etc/hosts?

use*_*182 7 kubernetes kubernetes-ingress nginx-ingress

不确定这是否特定于操作系统,但在我的 M1 Mac 上,我正在安装 Nginx 控制器和控制器官方快速入门指南中的资源示例。适用于 Mac 的 Docker 桌面。说明如下:

// Create the Ingress
helm upgrade --install ingress-nginx ingress-nginx \
  --repo https://kubernetes.github.io/ingress-nginx \
  --namespace ingress-nginx --create-namespace

// Pre-flight checks
kubectl get pods --namespace=ingress-nginx

kubectl wait --namespace ingress-nginx \
  --for=condition=ready pod \
  --selector=app.kubernetes.io/component=controller \
  --timeout=120s

// and finally, deploy and test the resource.
kubectl create deployment demo --image=httpd --port=80
kubectl expose deployment demo

kubectl create ingress demo-localhost --class=nginx \
  --rule=demo.localdev.me/*=demo:80

kubectl port-forward --namespace=ingress-nginx service/ingress-nginx-controller 8080:80
Run Code Online (Sandbox Code Playgroud)

我注意到说明没有提到必须编辑文件/etc/hosts,我觉得这很奇怪。而且,当我将其放入demo.localdev.me:8080浏览器中进行测试时,它确实按预期工作了!

但为什么?Docker 容器内的应用程序能够影响我的主机上的行为并拦截其 Web 流量,而无需我编辑文件,这是怎么回事/etc/hosts

对于我的下一个测试,我重新执行了上面的所有内容,唯一的变化是我切换到demodemo2. 那没有。我确实必须进入/etc/hosts并添加demo2.localdev.me 127.0.0.1为条目。之后 demo 和 demo2 都按预期工作。

为什么会发生这种情况?不必编辑 /etc/hosts 文件是很有吸引力的。有没有办法配置它以便它们都能工作?如果我需要将流量路由回互联网而不是本地计算机,我该如何“关闭”它自动发生?

Mik*_* S. 7

我复制了您的问题,并在 Ubuntu 20.04.3 操作系统上遇到了类似的行为。

\n

问题是NGINX 入口控制器本地测试指南没有提到该demo.localdev.me地址指向127.0.0.1- 这就是它无需编辑/etc/hosts/etc/resolve.conf文件即可工作的原因。可能类似于*.localtest.me地址

\n
\n

这里\xe2\x80\x99是它的工作原理。整个域名localtest.me\xe2\x80\x94和所有通配符条目\xe2\x80\x94都指向127.0.0.1。因此,无需对主机文件进行任何更改,您就可以立即开始使用本地 URL 进行测试。

\n
\n

本主题也有很好且详细的解释。

\n

所以 Docker Desktop / Kubernetes 对你的主机没有任何改变。

\n

地址demo2.localdev.me还指向127.0.0.1,因此它应该也适合您 - 而且正如我在我的环境中测试的那样,该行为与demo.localdev.me.

\n

您可以运行nslookup命令查看哪个IP地址指向特定域名,例如:

\n
user@shell:~$ nslookup demo2.localdev.me\nServer:         127.0.0.53\nAddress:        127.0.0.53#53\n\nNon-authoritative answer:\nName:   demo2.localdev.me\nAddress: 127.0.0.1\n
Run Code Online (Sandbox Code Playgroud)\n

您可以尝试使用其他主机名进行一些测试,例如一些现有的主机名或不存在的主机名,那么当然它不会工作,因为地址不会被解析为,127.0.0.1因此它不会被转发到入口 NGINX 控制器。在这些情况下,您可以编辑/etc/hosts(就像您所做的那样)或使用curlflag-H,例如:

\n

我使用以下命令创建了入口:

\n
kubectl create ingress demo-localhost --class=nginx --rule=facebook.com/*=demo:80\n
Run Code Online (Sandbox Code Playgroud)\n

然后我开始端口转发并运行:

\n
user@shell:~$ curl -H "Host: facebook.com" localhost:8080\n<html><body><h1>It works!</h1></body></html>\n
Run Code Online (Sandbox Code Playgroud)\n

你写了:

\n
\n

对于我的下一个测试,我重新执行了上面的所有内容,唯一的变化是我切换到demodemo2. 那没有。我确实必须进入/etc/hosts并添加demo2.localdev.me 127.0.0.1为条目。之后 demo 和 demo2 都按预期工作。

\n
\n

嗯,这听起来很奇怪,您可以nslookup demo2.localdev.me在不添加条目的情况下运行/etc/hosts然后检查吗?您确定之前执行了正确的查询吗?您没有更改 Kubernetes 配置方面的某些内容吗?正如我测试的(以及上面介绍的),它的工作原理应该与demo.localdev.me.

\n