基本
3 个协议:TCP,UDP,ICMP
4 个状态:NEW,ESTABLISHED,INVALID,RELATED
4个表
- raw:高级功能,如:网址过滤。
- mangle:数据包修改(QOS),用于实现服务质量。
- net:地址转换,用于网关路由器。
- filter:包过滤,用于防火墙规则。
5个链
- PREROUTING链:用于目标地址转换(DNAT)。
- INPUT链:处理输入数据包。
- PORWARD链:处理转发数据包。
- OUTPUT链:处理输出数据包。
- POSTOUTING链:用于源地址转换(SNAT)。
常用方法
1
2
3
4
iptables -t filter -nL
iptables -t nat -nL
iptables -t raw -nL
iptables -t mangle -nL
用iptables分析kubernetes svc流量链路
node节点的iptables是由kube-proxy生成的,具体实现可以参见kube-proxy的代码
kube-proxy只修改了filter和nat表,它对iptables的链进行了扩充,自定义了KUBE-SERVICES,KUBE-NODEPORTS,KUBE-POSTROUTING,KUBE-MARK-MASQ和KUBE-MARK-DROP五个链,并主要通过为 KUBE-SERVICES链(附着在PREROUTING和OUTPUT)增加rule来配制traffic routing 规则
集群信息
Pod CIDR :172.31.0.0/16
阿里云kubernetes v1.12.6-aliyun.1
*.aliyuncs.com/acs/flannel:v0.8.0
SLB私有IP:172.6.6.6 (实际上还绑定了一个EIP)
以某个svc为例
以default名下的testsvc作为例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
➜ ~ kgsvc testsvc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) w
testsvc LoadBalancer 172.30.5.207 172.6.6.6 443:30031/TCP 106d
➜ ~ iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
# 所有的服务都在这个Chain里面,非常长
Chain KUBE-SERVICES (2 references)
target prot opt source destination
KUBE-MARK-MASQ tcp -- !172.31.0.0/16 172.30.5.207 /* default/testsvc: cluster IP */ tcp dpt:443
KUBE-SVC-M42ZCW2EYUCRBVAF tcp -- 0.0.0.0/0 172.30.5.207 /* default/testsvc: cluster IP */ tcp dpt:443
......
KUBE-FW-M42ZCW2EYUCRBVAF tcp -- 0.0.0.0/0 172.6.6.6 /* default/testsvc: loadbalancer IP */ tcp dpt:443
# 对经过的报文打标签
Chain KUBE-MARK-MASQ (522 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000
Chain KUBE-XLB-M42ZCW2EYUCRBVAF (2 references)
target prot opt source destination
KUBE-SVC-M42ZCW2EYUCRBVAF all -- 172.31.0.0/16 0.0.0.0/0 /* Redirect pods trying to reach external loadbalancer VIP to clusterIP */
KUBE-MARK-DROP all -- 0.0.0.0/0 0.0.0.0/0 /* default/testsvc: has no local endpoints */
Chain KUBE-SVC-M42ZCW2EYUCRBVAF (2 references)
target prot opt source destination
KUBE-SEP-EA7TYKWK2S6G4PQR all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.14286000002
KUBE-SEP-ZJI36FVTROQF5MX7 all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.16667000018
KUBE-SEP-JLGUPWE7JCRU2AGG all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.20000000019
KUBE-SEP-GCNPY23RDN22AOTX all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.25000000000
KUBE-SEP-FNDISD3HQYKEHL3T all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.33332999982
KUBE-SEP-3RWVMCKITDQWELSA all -- 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.50000000000
KUBE-SEP-BVMKBOC4GGNJ3567 all -- 0.0.0.0/0 0.0.0.0/0
Chain KUBE-SEP-BVMKBOC4GGNJ3567 (1 references)
# 172.31.9.52是pod虚拟IP
target prot opt source destination
KUBE-MARK-MASQ all -- 172.31.9.52 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp to:172.31.9.52:80
Chain KUBE-FW-M42ZCW2EYUCRBVAF (1 references)
target prot opt source destination
KUBE-XLB-M42ZCW2EYUCRBVAF all -- 0.0.0.0/0 0.0.0.0/0 /* default/testsvc: loadbalancer IP */
KUBE-MARK-DROP all -- 0.0.0.0/0 0.0.0.0/0 /* default/testsvc: loadbalancer IP */
Chain KUBE-MARK-DROP (60 references)
target prot opt source destination
MARK all -- 0.0.0.0/0 0.0.0.0/0 MARK or 0x8000
图形化:
1
2
3
4
5
6
7
8
9
10
11
graph TB
a(内部流量/PREROUTING)-->c(KUBE-SERVICES)
b(外部流量/OUTPUT)-->c
c-->d(KUBE-MARK-MASQ)
d-->|destination:172.30.5.207|e(KUBE-SVC-M42ZCW2EYUCRBVAF)
e-->|destination:172.30.5.207|p1(KUBE-SEP-EA7TYKWK2S6G4PQR)
e-->|destination:172.30.5.207|p2(KUBE-SEP-ZJI36FVTROQF5MX7)
p1-->|destination:<podIP1>|f(KUBE-FW-M42ZCW2EYUCRBVAF)
p2-->|destination:<podIP2>|f
f-->g(KUBE-XLB-M42ZCW2EYUCRBVAF)
g-->|loadbalancer的IP在节点上截获后转给service|h(KUBE-SVC-M42ZCW2EYUCRBVAF)
一些iptables的技巧
为什么pod的probability越来越大
第一个1/3概率 如果匹配上了说明命中了1/3, 没匹配上剩下2/3到下一条
第二条1/2概率 如果匹配上了说明命中了 2/3 * 1/2 = 1/3,没匹配上 1/2到下一条
第三条1的概率 匹配上了是2/3 * 1/2 * 1 = 1/3
最后一个chain KUBE-SEP-BVMKBOC4GGNJ3567为什么没有probability
顺序匹配,他吃剩下的,所以不再需要计算权重了
destination 0.0.0.0/0是什么意思
仔细观察整个链路,到KUBE-SEP-XXX
这一步时已经取得了pod的虚拟IP.所以除此以外的chain destination保持不变,不再需要修改
结论
- kubernetes 0.8版本的flannel是对iptables的大规模运用。
- KUBE-SERVICES这个又臭又长的chain链注定了服务匹配是O(n)的,随着svc越来越多,增删改查会越来越卡。
- svc数量大于1000时,卡顿会相当明显
- kube-proxy应基于IPVS模式,走iptables只会重蹈覆辙
- svcIP是一个中转的虚拟IP