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
管理,这里不作过深讨论。