我的 ingress yaml 文件或流程有错误吗?
Mistakes in my ingress yaml file or process?
我正在尝试 kubernetes 并取得了一些进展,但在尝试公开我的 hello world 应用程序时,我 运行 遇到了入口问题。
部署和服务成功
我创建了一个简单的 hello world
类型的 nodejs 应用程序并将图像推送到我的 docker 中心 johnlai2004/swarm2
。我使用此 yaml 文件成功创建了部署和服务:
nodejs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-hello
labels:
app: nodejs-hello
spec:
replicas: 1
selector:
matchLabels:
app: nodejs-hello
template:
metadata:
labels:
app: nodejs-hello
spec:
containers:
- name: nodejs-hello
image: johnlai2004/swarm2
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: nodejs-hello-service
spec:
selector:
app: nodejs-hello
type: LoadBalancer
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30000
我将这些文件上传到 VPS 并安装了 ubuntu 20.04、minikube、kubectl 和 docker.
我运行下面的命令得到了我想要的结果:
minikube start --driver=docker
kubectl apply -f nodejs.yaml
minikube service nodejs-hello-service
|-----------|----------------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|----------------------|-------------|---------------------------|
| default | nodejs-hello-service | 3000 | http://192.168.49.2:30000 |
|-----------|----------------------|-------------|---------------------------|
当我执行 wget http://192.168.49.2:30000
时,我得到一个 index.html
文件,上面写着 hello from nodejs-hello-556dc868-6lrdz at 12/19/2021, 10:29:56 PM
。这太完美了。
进入失败
接下来,我想使用 ingress 以便我可以看到位于 http://website.example.com
的页面(将 website.example.com
替换为指向我的服务器的实际域)。我把这个文件放在我的服务器上:
nodejs-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nodejs-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: website.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nodejs-hello-service
port:
number: 3000
我运行命令
minikube addons enable ingress
kubectl apply -f nodejs-ingress.yaml
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nodejs-ingress <none> website.example.com localhost 80 15m
但是当我用浏览器访问http://website.example.com
时,浏览器说无法连接。使用 wget http://website.example.com
出现相同的连接问题。
谁能指出我做错了什么?
更新
我 运行 这些命令是因为我认为它表明我没有以正确的名称安装 ingress-controller space?
kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-tqsrp 0/1 Completed 0 4h25m
ingress-nginx-admission-patch--1-sth26 0/1 Completed 0 4h25m
ingress-nginx-controller-5f66978484-tmx72 1/1 Running 0 4h25m
kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
nodejs-hello-556dc868-6lrdz 1/1 Running 0 40m
这是否意味着我的 nodejs 应用的名称 space 无法访问入口控制器?
更新 2
我也试着按照 this guide 一步一步来。
我注意到的一个区别是当我 运行 命令 kubectl get ingress
时,ADDRESS
说 localhost
。但是在指南中,它说它应该是 172.17.0.15
这种差异重要吗?我在名为 linode.com 的云 vps 中托管东西。这会改变我做事的方式吗?
能不能试试kubectl get ingress nodejs-ingress
看ingress资源是否创建成功
然后用 curl -H 'HOST: <replace with HOSTS from the output of get ingress command>' http://<ADDRESS from the output of get ingress command>:<PORTS from the output of get ingress command>
卷曲
您的行为符合预期。让我解释一下为什么。一点一滴地讲,最后我会提出我的建议。
首先,我认为有必要介绍一下 minikube 架构。我假设您已经使用默认驱动程序 docker
安装了 minikube,因为您的地址 192.168.49.2
是 docker
driver.
的标准地址
图层是:
- 你的虚拟机 Ubuntu 20.04
- Kubernetes 集群由 minikube 设置,它是 docker VM 上地址为
192.168.49.2
的容器
所以...您不能只 运行 curl
在 VM 上使用 localhost
地址连接到服务。 The localhost
is referring to the device that you are making curl request (so your VM),不是 docker 容器。这就是为什么您需要使用 192.168.49.2
地址。
你可以输入docker ps -a
,你会看到容器是一个真正的Kubernetes集群。您可以使用 docker exec
命令执行它,然后使用 运行 curl
命令和本地主机地址:
user@example-ubuntu-minikube-template-1:~$ curl -H "Host: hello-world.info" localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
user@example-ubuntu-minikube-template-1:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a4ba3895990 gcr.io/k8s-minikube/kicbase:v0.0.28 "/usr/local/bin/entr…" 4 days ago Up 4 days 127.0.0.1:49157->22/tcp, 127.0.0.1:49156->2376/tcp, 127.0.0.1:49155->5000/tcp, 127.0.0.1:49154->8443/tcp, 127.0.0.1:49153->32443/tcp minikube
user@example-ubuntu-minikube-template-1:~$ docker exec -it 1a sh
# curl -H "Host: hello-world.info" localhost
Hello, world!
Version: 1.0.0
Hostname: web-79d88c97d6-nl4c7
请记住,您只能从托管此容器的 VM 访问此容器。如果没有任何进一步的配置,您不能只从其他 VM 访问它。可以,但不推荐。
很好的解释在minikube FAQ:
minikube’s primary goal is to quickly set up local Kubernetes clusters, and therefore we strongly discourage using minikube in production or for listening to remote traffic. By design, minikube is meant to only listen on the local network.
However, it is possible to configure minikube to listen on a remote network. This will open your network to the outside world and is not recommended. If you are not fully aware of the security implications, please avoid using this.
For the docker and podman driver, use --listen-address
flag:
minikube start --listen-address=0.0.0.0
所以我会避免它。我会在答案的最后提出一个更好的可能解决方案。
您问的是:
But when I visit http://website.example.com
with my browser, the browser says it can't connect. Using wget http://website.example.com
gave the same connection issue.
Can someone point out what I may have done wrong?
您的计算机不知道它是什么website.example.com
。它不知道您的 Ingress 使用了此名称。如果您的计算机在 hosts file 中找不到此名称,它将开始通过 Internet 查找此名称。
所以你有一些可能的解决方案:
- 使用
curl -H 'HOST: website.example.com' http://192.168.49.2:80
- 它只适用于 minikube 所在的虚拟机
- add host to the hosts file - 类似于
192.168.49.2 website.example.com
- 它只能在 minikube 所在的虚拟机上运行
- 设置裸机集群(总结部分有更多详细信息)并将域地址指向 VM 地址。在 GCP 和 AWS 中,您可以使用 Google Cloud DNS or Amazon Route 53. On linode cloud maybe this one - DNS Manager ?
编辑:
你写道你有一个指向服务器的域,所以请检查我的答案的总结部分。
你还问了:
I ran these commands because I think it shows I didn't install ingress-controller in the right name space?
So does this mean my nodejs app is in a name space that doesn't have access to the ingress controller?
It will install the controller in the ingress-nginx
namespace, creating that namespace if it doesn't already exist.
还有:
I also tried following this guide step by step: https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
One difference I noticed was when I ran the command kubectl get ingress
, ADDRESS
says localhost
. But in the guide, it says it is supposed to be 172.17.0.15
Does this difference matter? I'm hosting things in a cloud vps called linode.com. Does that change the way I do things?
将 minikube 与 docker 驱动程序一起使用时,这也是正常和预期的。
总结/其他技巧:
- Minkube 适合本地测试;您可以使用主机轻松访问应用程序和服务 - 检查 Accessing apps。
- 但是,要将其暴露在网络之外,您应该考虑使用 kubeadm or kubespray for cluster setup + MetalLB for LoadBalancer solution. Check "Bare-metal considerations" and Exposing a Kubernetes service on a bare-metal cluster over the external network architecture
等解决方案
- 如果您打算将服务与入口一起使用,请不要使用 LoadBalancer 类型。用ClusterIP就可以了
我正在尝试 kubernetes 并取得了一些进展,但在尝试公开我的 hello world 应用程序时,我 运行 遇到了入口问题。
部署和服务成功
我创建了一个简单的 hello world
类型的 nodejs 应用程序并将图像推送到我的 docker 中心 johnlai2004/swarm2
。我使用此 yaml 文件成功创建了部署和服务:
nodejs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-hello
labels:
app: nodejs-hello
spec:
replicas: 1
selector:
matchLabels:
app: nodejs-hello
template:
metadata:
labels:
app: nodejs-hello
spec:
containers:
- name: nodejs-hello
image: johnlai2004/swarm2
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: nodejs-hello-service
spec:
selector:
app: nodejs-hello
type: LoadBalancer
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30000
我将这些文件上传到 VPS 并安装了 ubuntu 20.04、minikube、kubectl 和 docker.
我运行下面的命令得到了我想要的结果:
minikube start --driver=docker
kubectl apply -f nodejs.yaml
minikube service nodejs-hello-service
|-----------|----------------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|----------------------|-------------|---------------------------|
| default | nodejs-hello-service | 3000 | http://192.168.49.2:30000 |
|-----------|----------------------|-------------|---------------------------|
当我执行 wget http://192.168.49.2:30000
时,我得到一个 index.html
文件,上面写着 hello from nodejs-hello-556dc868-6lrdz at 12/19/2021, 10:29:56 PM
。这太完美了。
进入失败
接下来,我想使用 ingress 以便我可以看到位于 http://website.example.com
的页面(将 website.example.com
替换为指向我的服务器的实际域)。我把这个文件放在我的服务器上:
nodejs-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nodejs-ingress
namespace: default
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: website.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nodejs-hello-service
port:
number: 3000
我运行命令
minikube addons enable ingress
kubectl apply -f nodejs-ingress.yaml
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
nodejs-ingress <none> website.example.com localhost 80 15m
但是当我用浏览器访问http://website.example.com
时,浏览器说无法连接。使用 wget http://website.example.com
出现相同的连接问题。
谁能指出我做错了什么?
更新
我 运行 这些命令是因为我认为它表明我没有以正确的名称安装 ingress-controller space?
kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS AGE
ingress-nginx-admission-create--1-tqsrp 0/1 Completed 0 4h25m
ingress-nginx-admission-patch--1-sth26 0/1 Completed 0 4h25m
ingress-nginx-controller-5f66978484-tmx72 1/1 Running 0 4h25m
kubectl get pod -n default
NAME READY STATUS RESTARTS AGE
nodejs-hello-556dc868-6lrdz 1/1 Running 0 40m
这是否意味着我的 nodejs 应用的名称 space 无法访问入口控制器?
更新 2
我也试着按照 this guide 一步一步来。
我注意到的一个区别是当我 运行 命令 kubectl get ingress
时,ADDRESS
说 localhost
。但是在指南中,它说它应该是 172.17.0.15
这种差异重要吗?我在名为 linode.com 的云 vps 中托管东西。这会改变我做事的方式吗?
能不能试试kubectl get ingress nodejs-ingress
看ingress资源是否创建成功
然后用 curl -H 'HOST: <replace with HOSTS from the output of get ingress command>' http://<ADDRESS from the output of get ingress command>:<PORTS from the output of get ingress command>
您的行为符合预期。让我解释一下为什么。一点一滴地讲,最后我会提出我的建议。
首先,我认为有必要介绍一下 minikube 架构。我假设您已经使用默认驱动程序 docker
安装了 minikube,因为您的地址 192.168.49.2
是 docker
driver.
图层是:
- 你的虚拟机 Ubuntu 20.04
- Kubernetes 集群由 minikube 设置,它是 docker VM 上地址为
192.168.49.2
的容器
所以...您不能只 运行 curl
在 VM 上使用 localhost
地址连接到服务。 The localhost
is referring to the device that you are making curl request (so your VM),不是 docker 容器。这就是为什么您需要使用 192.168.49.2
地址。
你可以输入docker ps -a
,你会看到容器是一个真正的Kubernetes集群。您可以使用 docker exec
命令执行它,然后使用 运行 curl
命令和本地主机地址:
user@example-ubuntu-minikube-template-1:~$ curl -H "Host: hello-world.info" localhost
curl: (7) Failed to connect to localhost port 80: Connection refused
user@example-ubuntu-minikube-template-1:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1a4ba3895990 gcr.io/k8s-minikube/kicbase:v0.0.28 "/usr/local/bin/entr…" 4 days ago Up 4 days 127.0.0.1:49157->22/tcp, 127.0.0.1:49156->2376/tcp, 127.0.0.1:49155->5000/tcp, 127.0.0.1:49154->8443/tcp, 127.0.0.1:49153->32443/tcp minikube
user@example-ubuntu-minikube-template-1:~$ docker exec -it 1a sh
# curl -H "Host: hello-world.info" localhost
Hello, world!
Version: 1.0.0
Hostname: web-79d88c97d6-nl4c7
请记住,您只能从托管此容器的 VM 访问此容器。如果没有任何进一步的配置,您不能只从其他 VM 访问它。可以,但不推荐。
很好的解释在minikube FAQ:
minikube’s primary goal is to quickly set up local Kubernetes clusters, and therefore we strongly discourage using minikube in production or for listening to remote traffic. By design, minikube is meant to only listen on the local network.
However, it is possible to configure minikube to listen on a remote network. This will open your network to the outside world and is not recommended. If you are not fully aware of the security implications, please avoid using this.
For the docker and podman driver, use
--listen-address
flag:minikube start --listen-address=0.0.0.0
所以我会避免它。我会在答案的最后提出一个更好的可能解决方案。
您问的是:
But when I visit
http://website.example.com
with my browser, the browser says it can't connect. Usingwget http://website.example.com
gave the same connection issue.
Can someone point out what I may have done wrong?
您的计算机不知道它是什么website.example.com
。它不知道您的 Ingress 使用了此名称。如果您的计算机在 hosts file 中找不到此名称,它将开始通过 Internet 查找此名称。
所以你有一些可能的解决方案:
- 使用
curl -H 'HOST: website.example.com' http://192.168.49.2:80
- 它只适用于 minikube 所在的虚拟机
- add host to the hosts file - 类似于
192.168.49.2 website.example.com
- 它只能在 minikube 所在的虚拟机上运行
- 设置裸机集群(总结部分有更多详细信息)并将域地址指向 VM 地址。在 GCP 和 AWS 中,您可以使用 Google Cloud DNS or Amazon Route 53. On linode cloud maybe this one - DNS Manager ?
编辑: 你写道你有一个指向服务器的域,所以请检查我的答案的总结部分。
你还问了:
I ran these commands because I think it shows I didn't install ingress-controller in the right name space?
So does this mean my nodejs app is in a name space that doesn't have access to the ingress controller?
It will install the controller in the
ingress-nginx
namespace, creating that namespace if it doesn't already exist.
还有:
I also tried following this guide step by step: https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/
One difference I noticed was when I ran the command
kubectl get ingress
,ADDRESS
sayslocalhost
. But in the guide, it says it is supposed to be172.17.0.15
Does this difference matter? I'm hosting things in a cloud vps called linode.com. Does that change the way I do things?
将 minikube 与 docker 驱动程序一起使用时,这也是正常和预期的。
总结/其他技巧:
- Minkube 适合本地测试;您可以使用主机轻松访问应用程序和服务 - 检查 Accessing apps。
- 但是,要将其暴露在网络之外,您应该考虑使用 kubeadm or kubespray for cluster setup + MetalLB for LoadBalancer solution. Check "Bare-metal considerations" and Exposing a Kubernetes service on a bare-metal cluster over the external network architecture 等解决方案
- 如果您打算将服务与入口一起使用,请不要使用 LoadBalancer 类型。用ClusterIP就可以了