网络隔离的对象
使用NetworkPolicy对象来实现。
NetworkPolicy对象示例
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978
可以看到上面我们的例子中from的写法是或得关系,如果是 AND 的关系的话写法如下:
...
ingress:
- from:
- namespaceSelector:
matchLabels:
user: alice
podSelector:
matchLabels:
role: client
...
上述namespace和pod则是与的关系。
NetworkPolicy生效的前提
CNI网络插件必须支持NetworkPolicy,该类型的插件都会维护着一个NetworkPolicy Controller,通过控制循环的方式对NetworkPolicy对象的增删改查作出响应,然后在宿主机上完成 iptables规则的配置工作。
如何实现网络的隔离
Kubernetes对Pod进行隔离依靠的就是在宿主机上生成NetworkPolicy对应的iptables规则来进行实现。
for dstIP := range 所有被networkpolicy.spec.podSelector选中的Pod的IP地址
for srcIP := range 所有被ingress.from.podSelector选中的Pod的IP地址
for port, protocol := range ingress.ports {
iptables -A KUBE-NWPLCY-CHAIN -s $srcIP -d $dstIP -p $protocol -m $protocol --dport $port -j ACCEPT
}
}
}
这是一条名称为KUBE-NWPLCY-CHAIN的规则,含义是当ip包源地址是srcIp,目的ip地址是dstIp,协议是protocol,目的端口是port的时候就允许他通过。
如何将Pod的访问请求转发到上述规则上去?
CNI网络插件需要设置两组iptables规则来实现。
第一组规则是用来负责拦截被隔离Pod的访问请求本机ip查询,生成的伪代码如下:
for pod := range 该Node上的所有Pod{
if pod是networkpolicy.spec.podSelector选中的 {
iptables -A FORWARD -d $podIP -m physdev --physdev-is-bridged -j KUBE-POD-SPECIFIC-FW-CHAIN
iptables -A FORWARD -d $podIP -j KUBE-POD-SPECIFIC-FW-CHAIN
...
}
}
上述规则都被转发到KUBE-POD-SPECIFIC-FW-CHAIN规则上,该规则就是第二组规则,该规则就是用来对请求做通过和拒绝操作,如下:
iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j KUBE-NWPLCY-CHAIN
iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j REJECT --reject-with icmp-port-unreachable
上述第一条规则中我们会将请求转给前面定义的KUBE-NWPLCY-CHAIN规则进行匹配,如果匹配成功则通过本机ip查询,如果匹配不成功,IP 包则会命中第二条规则,这一条规则则是进行拒绝,通过这条规则则实现了不满足NetworkPolicy定义的请求就会被拒绝掉。
iptables的作用
iptables是用来操作Linux内核Netfilter,Netfilter是Linux内核里挡在用户态进程和网卡之间的一道防火墙,用来进行过滤,转发数据包。
iptables处理IP包的流程
IP包进入主机网卡(Netfilter流入路径)后,在查询路由表决定下一步走向之前,会经过PREROUTING链的检查,经过检查并且成功路由以后,IP包会有两个走向:
第一种走向在进入传输层之前,会经过 INPUT链的检查,检查通过以后即可进入用户空间交由用户进程处理。用户处理完成以后会通过本机响应IP包,此时IP包会到达Netfliter流出路径,此时会先根据路由表进行路由,路由结束后会经过一个OUTPUT链进行检查,OUTPUT链检查通过以后,会经过POSTROUTING链的检查。
第二种走向不会进入传输层,会在网络层继续流动,从而进入到转发路径(FORWARD PATH),在这里会经过FORWARD链的检查,检查通过以后不再经过路由,会直接到达流出路径的POSTROUTING链的检查。
Netfilter原理图
Netfliter的原理图如下,可以看出Netfilter不仅存在于传输层,也存在于数据链路层。
【知识星球】
知识星球正在初期搭建中,在星球中可以互相提问,分享经验,我也会在星球中分享基础技术架构的全流程搭建,包括但不仅限于DevOps,监控、Flink开发,Java开发(JVM、多线程、MySQL数据库)等相关技术类文章,期待大家的加入
娜娜项目网每日更新创业和副业教程
网址:nanaxm.cn 点击前往娜娜项目网
站 长 微 信: nanadh666