iptables
基础概念
本文讨论内容需具备一定iptables基础:
常用指令
查询链是否存在
$ iptables -t nat -L <chain-name>
模块解析
该模块需指定--make-iptables-util-chains=true开启,默认开启。
func (kl *Kubelet) Run(updates <-chan kubetypes.PodUpdate) {
...
if kl.makeIPTablesUtilChains {
kl.initNetworkUtil()
}
...
}
内部逻辑非常简单:初始化kubernetes定义的iptables链、规则。
并周期性(每分钟)对这些iptables链、规则检查变更,
func (kl *Kubelet) initNetworkUtil() {
kl.syncNetworkUtil()
go kl.iptClient.Monitor(utiliptables.Chain("KUBE-KUBELET-CANARY"),
[]utiliptables.Table{utiliptables.TableMangle, utiliptables.TableNAT, utiliptables.TableFilter},
kl.syncNetworkUtil, 1*time.Minute, wait.NeverStop)
}
iptables配置初始化
确认防火墙链是否存在
确认链是否存在,确认方式为执行创建命令:
$ iptables -N <链名称> -t <表名> <args>
创建成功返回true,若链已存在也返回true
func (runner *runner) EnsureChain(table Table, chain Chain) (bool, error) {
fullArgs := makeFullArgs(table, chain)
runner.mu.Lock()
defer runner.mu.Unlock()
/* $ iptables -t nat -N KUBE-KUBELET-CANARY
iptables: Chain already exists.
*/
out, err := runner.run(opCreateChain, fullArgs)
if err != nil {
if ee, ok := err.(utilexec.ExitError); ok {
if ee.Exited() && ee.ExitStatus() == 1 {
return true, nil
}
}
return false, fmt.Errorf("error creating chain %q: %v: %s", chain, err, out)
}
return false, nil
}
创建的链如下:
nat/KUBE-MARK-DROP: 对于未能匹配到跳转规则的traffic set mark 0x8000,有此标记的数据包会在filter表drop掉nat/KUBE-MARK-MASQ: 对于符合条件的包set mark 0x4000, 有此标记的数据包会在KUBE-POSTROUTING chain中统一做MASQUERADE(动态SNAT)nat/KUBE-POSTROUTING: 该链对打上了0x4000标记的报文进行SNAT转换filter/KUBE-FIREWALL: 该链对所有标记了0x8000的报文进行丢弃
规则的创建
确认防火墙规则,检测未存在进行创建:
$ iptables -C
具体路由方式由kube-proxy管理,这里不作过深讨论。