编辑:
我删除了 minikube,在适用于 Windows 的 Docker 桌面中启用了 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 文件,但这次 ingress 没有获取任何地址:
$kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
myapp-ingress <none> myapp.com 80 10m
我正在使用 docker 桌面(Windows)并通过 minikube addons enable 命令安装了 nginx-ingress Controller :
$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
所有 Pod 和服务似乎都运行正常。检查 Pod 日志,所有迁移等均已生效,并且应用程序已启动并运行。但是当我尝试发送 HTTP 请求时,出现套接字挂断错误。我检查了所有 Pod 的所有日志,找不到任何有用的内容。
$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
ingress 由于逻辑而出现,/etc/hosts
中的域后面的 IP 地址是什么并不重要。 ,我添加了一个不同的测试,但它仍然显示 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
:
- 运行
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
尝试从 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
来自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 driver (例如 virtualbox。我使用
hyperv
因为我的笔记本电脑有 Windows 10 Pro)
minikube ip
将返回虚拟机的“正常”IP 地址,并且所有网络功能都将正常工作。您需要将此 IP 地址添加到 /etc/hosts
对于入口规则中使用的域
注意!即使localhost
显示于 kubectl get ing ingress
输出 ADDRESS
.
- 使用适用于 Windows 的 Docker 桌面中的内置 kubernetes 功能。
您需要manually install ingress-nginx
并更改ingress-nginx-controller
服务类型来自NodePort
至LoadBalancer
所以它将在 localhost
上可用并将继续工作。请查找my another answer about Docker desktop for Windows
- (仅测试)- 使用端口转发
与 minikube service
的想法几乎完全相同命令。但有更多的控制。您将从主机 VM 端口 80
打开隧道至ingress-nginx-controller
端口 80
上的服务(最终是 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
Windows 和 ingress 上 docker 桌面中的 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:
...
关于nginx - Ingress 不转发请求 - 适用于 Windows 和 kubernetes 的 Docker 桌面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70011639/