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

Why do I have to edit /etc/hosts just sometimes when using nginx-ingress controller and resources in my local k8s environment?

不确定这是否是 OS 特定的,但是在我的 M1 Mac 上,我正在为 [=33] 安装官方 Quick Start guide for the controller. 中的 Nginx 控制器和资源示例=] Mac 的桌面。说明如下:

// 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

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

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

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

为什么会这样?不必编辑 /etc/hosts 文件很吸引人。有没有办法配置它,使它们都工作?如果我需要将流量路由回 Internet 而不是我的本地计算机,我如何将其自动“关闭”?

我复制了你的问题并在 Ubuntu 20.04.3 OS.

上得到了类似的行为

问题是 NGINX Ingress controller Local testing guide did not mention that demo.localdev.me address points to 127.0.0.1 - that's why it works without editing /etc/hosts or /etc/resolve.conf file. Probably it's something like *.localtest.me addresses:

Here’s how it works. The entire domain name localtest.me—and all wildcard entries—point to 127.0.0.1. So without any changes to your host file you can immediate start testing with a local URL.

this topic 中也有详细的解释。

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

address demo2.localdev.me also points to 127.0.0.1,因此它应该也适用于您 - 正如我在我的环境中测试的那样,行为与 demo.localdev.me.

完全相同

您可以运行 nslookup command查看哪个IP地址指向具体的域名,例如:

user@shell:~$ nslookup demo2.localdev.me
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
Name:   demo2.localdev.me
Address: 127.0.0.1

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

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

kubectl create ingress demo-localhost --class=nginx --rule=facebook.com/*=demo:80

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

user@shell:~$ curl -H "Host: facebook.com" localhost:8080
<html><body><h1>It works!</h1></body></html>

您写道:

For my next test, I re-executed everything above with the only change being that I switched demo to demo2. That did not work. I did have to go into /etc/hosts and add demo2.localdev.me 127.0.0.1 as an entry. After that both demo and demo2 work as expected.

嗯,这听起来很奇怪,你可以 运行 nslookup demo2.localdev.me 而不是在 /etc/hosts 中添加条目然后检查吗?你确定你之前执行了正确的查询,你没有在 Kubernetes 配置端更改一些东西吗?正如我测试的(和上面介绍的),它应该与 demo.localdev.me.

完全相同