问题:

  • 因为K8S服务开启了nodeport,对外暴露的端口30001端口,但是要求对30001端口进行限制,只允许个别IP访问

解决思路:

  • 通过添加iptables策略,来限制某些主机的访问
    经实践:发现不论在iptables的filler表中添加规则,都无法对k8s的nodeport生效

分析原因:
在这里插入图片描述
上图为iptables策略图
K8S网络经过 PREROUTING 进入 KUBE-SERVICES,由于 nat 在 filter 之前,所以在 INPUT 链做限制不会起作用

kube-proxy 在 ipvs 模式下自定义了八条链,分别为 KUBE-SERVICES、KUBE-FIREWALL、KUBE-POSTROUTING、KUBE-MARK-MASQ、KUBE-NODE-PORT、KUBE-MARK-DROP、KUBE-FORWARD、KUBE-LOAD-BALANCER

NodePort的过程:

  1. NAT表PREROUTING
    在这里插入图片描述

  2. PREROUTING的规则非常简单,凡是发给自己的包,*(经过KUBE-SERVICES直接转发给KUBE-NODEPORTS)则交给子链KUBE-NODEPORTS处理 KUBE-NODEPORTS规则如下:
    在这里插入图片描述
    在这里插入图片描述
    其中通过KUBE-MARK-MASQ给包打0x4000/0x4000的标记,然后交给子链KUBE-SVC-UVFA6R2T7DODYNMU处理,具体流程如下:
    在这里插入图片描述
    其功能就是按照概率均等的原则DNAT到其中一个Endpoint
    IP,即就是通过DNAT把该主机的30090端口的访问转发至->10.233.10.67:443上
    以上流程可以归纳为:
    外部主机访问master01:30090->NAT表PREROUTING->NAT表KUBE-SERVICES(因为不是CLUSTER_IP,因此不用判断,直接进入下一步)->NAT表KUBE-NODE-PORT->NAT表KUBE-MARK-MASQ->NAT表KUBE-SVC-UVFA6R2T7DODYNMU->DNAT把该主机的30090端口的访问转发至->10.233.10.67:443上
    *[如果10.233.10.67不是该节点上的pod,则会通过cni网络插件“calico或者fannel”转发至对应节点的pods上]**

CLUSTER_IP的流程
clusteip为10.223.13.16
在这里插入图片描述
查看ipvs配置,发现策略为rr
在这里插入图片描述
在这里插入图片描述
并且创建了对应的虚拟网卡上添加了对应的svc的clusterip
在这里插入图片描述
iptables的Service,ClusterIP是一个虚拟的IP,因此这个IP是ping不通的,但ipvs中这个IP是在每个节点上真实存在的,因此可以ping通
因此经过ipvs,ipvs会从RS ip列中选择其中一个Pod ip作为目标IP:
即从10.223.13.16:27782 ->10.223.90.130:27782
查看nat表OUTPUT安全组规则:
在这里插入图片描述
以上规则的内容所有访问clusterip的包都打上0x4000
在这里插入图片描述
没看懂,最后是要做SNAT转发,即通过MASQUERADE【地址伪装,算是snat中的一种特例,可以实现自动化的snat】把包转发出去,最终通过calico或者flannel转发出去到对用的pods所在地主机上
流程就是:
nat表OUTPUT->nat表KUBE-SERVICES->nat表KUBE-MARK-MASQ->nat表POSTROUTING->nat表KUBE-POSTROUTING->nat表MASQUERADE

解决方法
在 PREROUTING 中加入一条规则,将要屏蔽的ip直接DNAT到一个不用的端口,这样就不会在PREROUTING 的时候直接跳过INPUT进入K8S网络中
iptables -t nat -I PREROUTING -p tcp ! -s x.x.x.x/30 --dport 30001-j REDIRECT --to-ports 65535

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐