我已经使用 Rancher 建立了一个正常运行的 Kubernetes 集群,它定义了两个网络:
10.42.0.0/16
对于 Pod IP 地址10.43.0.0./16
对于服务端点
我想使用我现有的 Caddy 反向代理来访问这些服务端点,所以我定义了一条路由(10.10.10.172
是我的一个 kubernetes 节点):
sudo route add -net 10.43.0.0 netmask 255.255.0.0 gw 10.10.10.172
Caddy Web 服务器上的路由表:
arturh@web:~$ sudo route
[sudo] password for arturh:
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default DD-WRT.local 0.0.0.0 UG 0 0 0 eth0
10.10.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.43.0.0 rancherkube1.lo 255.255.0.0 UG 0 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
使用此设置,我可以访问和使用10.43.0.1:443
而不会出现任何问题(它是主要的 kubernetes api 端点):
arturh@web:~$ nmap 10.43.0.1 -p 443 | grep 443
443/tcp open https
arturh@web:~$ curl -k https://10.43.0.1
Unauthorized
但访问 10.43.0.0/16 网络中的任何其他 IP 地址都会失败,我无法弄清楚原因:
arturh@web:~$ kubectl get svc | grep prometheus-server
prometheus-prometheus-server 10.43.115.122 <none> 80/TCP 1d
arturh@web:~$ curl 10.43.115.122
curl: (7) Failed to connect to 10.43.115.122 port 80: No route to host
arturh@web:~$ traceroute 10.43.115.122
traceroute to 10.43.115.122 (10.43.115.122), 30 hops max, 60 byte packets
1 rancherkube1.local (10.10.10.172) 0.348 ms 0.341 ms 0.332 ms
2 rancherkube1.local (10.10.10.172) 3060.710 ms !H 3060.722 ms !H 3060.716 ms !H
我可以从 Kubernetes 节点本身访问所有内容:
[rancher@rancherkube1 ~]$ wget -qO- 10.43.115.122
<!DOCTYPE html>
<html lang="en">...
这是因为 iptable NAT 规则起作用的:
[rancher@rancherkube1 ~]$ sudo iptables -t nat -L -n | grep 10.43
KUBE-SVC-NGLRF5PTGH2R7LSO tcp -- 0.0.0.0/0 10.43.115.122 /* default/prometheus-prometheus-server:http cluster IP */ tcp dpt:80
KUBE-SVC-NPX46M4PTMTKRN6Y tcp -- 0.0.0.0/0 10.43.0.1 /* default/kubernetes:https cluster IP */ tcp dpt:443
我很困惑,因为有效的条目10.43.0.1
看起来与无效的条目相同...我想我需要添加一个 iptables 规则来允许访问子网10.43.0.0/16
,但我对 iptables 不熟悉。
我对整个 kubernetes 业务还很陌生,这是访问服务端点的正确方法吗?如果是,有人能帮我提供正确的 iptables 命令吗?
答案1
您可以从运行 kubernetes 工作负载的主机访问内容,因为它具有 iptables 规则和可能的路由表规则来路由流量。
如果您想从集群外部访问 kubernetes 服务,那么您需要使用带有入口服务的入口控制器。
https://kubernetes.io/docs/concepts/services-networking/ingress/
答案2
我正在寻找一种更简单的方法,让外部主机可以访问 K8S,而无需使用 loadBalance 和 NodePort。
我也使用 Rancher 部署了 K8S,其中一个节点是 192.168.1.4 。默认情况下,只有 k8S 节点可以访问虚拟 IP 10.42.0.0/16 和 10.43.0.0/16 。
感谢@arturh 提供的示例,我在非 K8S 主机上添加了一条路由规则并且它起作用了:
[root@CentOS ~]# curl 10.43.1.15:27017
^C
[root@CentOS ~]# ip route add 10.43.0.0/16 via 192.168.1.4
[root@CentOS ~]# curl 10.43.1.15:27017
It looks like you are trying to access MongoDB over HTTP on the native driver port.
可能的错误:
sysctl net.ipv4.ip_forward
主机已被禁用。- 非k8s主机与K8S节点位于不同的子网,因此它们无法直接相互通信。