深入理解k8s网络原理之-Service原理
在深入理解k8s网路原理之-POD连接主机中主要介绍了POD
与主机及POD
访问外网的原理。
Linux
网络基础知识
netfilter
netfileter
子系统5个关键扩展点:
PREROUTING
,数据包刚到达时会经过这个点,通常用来完成DNAT的功能。INPUT
,数据包要进入本机的传输层时会经过这个点,通常用来完成防火墙入站检测。FORWARD
,数据包要通过本机转发时会经过这个点,通常用来完成防火墙转发过滤。OUTPUT
,从本机的数据包要出去的时候会经过这个点,通常用来做DNAT和防火墙出站检测。POSTROUTING
,数据包离开本机前会经过这个点,通常用来做SNAT。
1、 主机的应用程序接收外部的数据包会经过的点: PREROUTING -> INPUT
2、 主机的应用程序发送数据包到外部经过的点: OUTPUT -> POSTROUTING
3、 主机的POD
发送的数据包去外部或者去主机的另外一个POD
: PREROUTING -> FORWARD -> POSTROUTING
主机上运行的
POD
虽然也是主机上的一个进程,但是POD
发送数据包出去的流程去和主机的其他进程不一样,由于POD
在新的NS
中,所以他的发包流程适合主机收到另一台主机的数据然后转发的流程是一样的。
4、注意图中的IPIsLocal
?的判断,如果数据包的目标IP
是本机IP
,则往INPUT
点走,否则查看net.ipv4.ip_forward
是否为1,是则往FORWARD
走,0则丢弃。
iptables
基础知识
iptables
初识别
iptables -A INPUT -t filter -s 192.168.1.10 -j DROP
意思是指不允许来源为192.168.1.10
的ip
访问本机的服务。
命令详解:
- -A 是指后面加一条规则,其他为
- -I 是前面加一条规则,优先级更高
- -D 删除规则
- -N 新增加链
- -F 清除链上的所有规则或者所有链
- -X 删除一条用户的自定义链
- -P 更改链的默认策略
- -L 真是指定链上的规则
- 防火墙规则一般制工作在
INPUT/OUTPUT/FORWARD
三个扩展点 - -t 指定当前命令操作所属的表,主要有:
filter
表,主要用于拦截或者房型,不修改包,如果不指定,则默认为filter
表nat
表,用于修改ip
包的源/目的地址mangle
表,用于给数据包打标记raw
表,#TODOsecurity
表, #TODO
- -s 数据包的匹配规则,规则可以一个或者多个,多个是与的效果,这里 -s 是匹配来源的的意思,其他的还有
- -d 匹配目标地址
- –sport 匹配来源端口
- –dport 匹配目标端口
- -p tcp 匹配协议类型
- -j
DROP
是执行的动作,这里是跳转到(jump
)DROP
链,iptables
有几个预定义的链:DROP
丢弃进入该链的包ACCEPT
接收进入该链的包RETURN
返回上一级链SNAT
源地址转换,要指定转换后的源地址DNAT
目标地址转换,要指定转换后目标地址MASQUEREDE
对进入该链的包进行源地址转换,与SNAT
类似,但不用指定具体的转换后的源地址,会自动应用网卡的地址作为原地址,通常都用这条链完成SNAT
。
进阶示例:
— 把本机应用发往10.96.0.100的数据包的目标地址转换为10.244.3.10上,注意使要影响本机应用,
1 | iptables -A OUTPUT -t nat -d 10.96.0.100 -j DNAT --to-distination 10.244.3.10 |
- 上面的规则支队本机的应用程序发送的流量有影响, 对于本机的
POD
发出的流量乜有影响,如果要影响本机的POD
,还要加一条,规则都一样,只是工作在PREROUTING
链.
1 | iptables -A RPEROTING -t nat -d 10.96.0.100 -j DNAT --to-distination 10.244.3.10 |
- 对本机发送的数据包中来源
ip
为172.20.1.10 的数据包进行源地址伪装,注意修改源地址只有个一个点可以用,就是POSTROUTING
,下面的规则就是配置POD
上外网时使用的:
1 | iptabels -A POSTROUTING -t NAT -S 172.20.1.10 -j MASQUEREDE |
- 允许来源
IP
为192.168.6.166并访问本机的TCP
80 端口
1 | iptables -A INPUT -t filter -s 192.168.8.166 -p tcp --dport 80 -j ACCEPT |
iptables
上的规则创建会有一些限制,如无法在POSTROUTING
链上创建DNAT
的规则,因为饿在POSTROUTING
之前,数据包要进行路由判决,内核会根据当前的目的地选择一个最合适的出口,而POSTROUTING
链的规则是在路由判决后发生,在这里修改数据包的目的地会造成数据包不可到达的后果。
K8S
的 Service
设计
主要考虑如下两个原因:
pod
的特性是快速创建销毁,所以pod
的ip
是不固定的,要让调用方有个固定依赖,所以需要一个VIP
来代表服务- 一般来说为了追求应用的高可用,一个应用会部署多个
POD
,这时需要一个VIP
充当多个pod
的流量负载
service
几种类型的使用场景
clusterIP
: 只能在集群的节点和pod
中访问,解决的就是集群内应用间的相互访问的问题nodeport
: 通过节点的地址和端口将pod
暴露到集群外,让集群外的应用能够访问集群内的应用,设置服务类型为nodeport
时,是在clusterIP
的基础上再给节点开个端口转发,所以nodeport
的服务也会有一个clusterIP
loadBalancer
: 因为使用nodeport
方式时,需要在应用的调用方写死一个集群节点的IP
,此方式并非为高可用方式,这个时候使用第三方负载均衡器的方式,转发到多个节点的nodeport
,loadBanlancer
是在nodeport
的基础上再创建一个lb
,所以也会先分配一个clusterIP
,再创建节点的端口转发。headless
: 应用多个副本彼此间相互访问,比如要部署到mysql
的主从,从的副本想要找主的副本:externalName
: 相当于coredns
里面的cname
记录
在
iptables
模式下,clusterIP
都是ping
不通的,这是因为kube-proxy
在实现时之根据ip
+端口+协议精确匹配才转发,这才导致clusterIP
不能ping
hairpin flow
场景: pod
通过clusterIP
访问自己
推荐一篇万字长文
iptables
长文详解