Kubernetes如何利用iptables
Posted: September 23, 2016 | Author: Cui Hua | Filed under: PaaS | 3 Comments »Linux内置的防ç«å¢™å¯ä»¥å¯¹IPæ•°æ®åŒ…åšä¸€ç³»åˆ—å¦‚è¿‡æ»¤ã€æ›´æ”¹ã€è½¬å‘è¿™æ ·çš„æ“作,防ç«å¢™åœ¨å¯¹æ•°æ®åŒ…åšè¿‡æ»¤å†³å®šæ—¶ï¼Œæœ‰ä¸€å¥—éµå¾ªçš„规则,这些规则å˜å‚¨åœ¨ä¸“用的数æ®åŒ…过滤表(table)ä¸ï¼Œè€Œè¿™äº›è¡¨é›†æˆåœ¨Linux å†…æ ¸ä¸ã€‚在数æ®åŒ…过滤表ä¸ï¼Œè§„则被分组放在我们所谓的链(chain)ä¸ã€‚
我们通常说的iptables就是指Linux内置的防ç«å¢™ï¼Œå®ƒå®žé™…上由两个组件netfilterå’Œiptables组æˆã€‚netfilterç»„ä»¶ä¹Ÿç§°ä¸ºå†…æ ¸ç©ºé—´ï¼ˆkernel spaceï¼‰ï¼Œå®ƒæ˜¯å†…æ ¸çš„ä¸€éƒ¨åˆ†ï¼Œç”±ä¸€äº›æ•°æ®åŒ…过滤表组æˆï¼Œè¿™äº›è¡¨åŒ…å«å†…æ ¸ç”¨æ¥æŽ§åˆ¶æ•°æ®åŒ…过滤处ç†çš„规则集。iptables组件是一个工具,也称为用户空间(user space),它使æ’å…¥ã€ä¿®æ”¹å’Œåˆ 除数æ®åŒ…过滤表ä¸çš„规则å˜å¾—å®¹æ˜“ï¼Œå³æˆ‘们通常用iptablesæ¥å¯¹chainä¸çš„è§„åˆ™è¿›è¡Œæ·»åŠ ã€ä¿®æ”¹å’Œåˆ 除以实现我们自己的防ç«å¢™é€»è¾‘。
iptables内置了5个table,å¯ä»¥ç”¨manæ¥æŸ¥çœ‹è¿™5个tableçš„åå—å’Œä½œç”¨ï¼ˆå…¶ä¸æˆ‘们最常用的就是filterå’Œnat这两个表):
filterã€natå’Œmangle这三个表的作用为如下所示:
filter表是专门过滤包的,它也是iptables缺çœçš„表,它内建三个链,å¯ä»¥æ¯«æ— 问题地对包进行DROPã€LOGã€ACCEPTå’ŒREJECTç‰æ“作。FORWARDé“¾è¿‡æ»¤æ‰€æœ‰ä¸æ˜¯æœ¬åœ°äº§ç”Ÿçš„å¹¶ä¸”ç›®çš„åœ°ä¸æ˜¯æœ¬åœ°çš„包,而 INPUT是针对那些目的地是本地的包。OUTPUT 用æ¥è¿‡æ»¤æ‰€æœ‰æœ¬åœ°ç”Ÿæˆçš„包。
nat表的主è¦ç”¨å¤„是网络地å€è½¬æ¢ï¼Œå³Network Address Translation,缩写为NAT。åšè¿‡NATæ“作的数æ®åŒ…的地å€å°±è¢«æ”¹å˜äº†ï¼Œå½“ç„¶è¿™ç§æ”¹å˜æ˜¯æ ¹æ®æˆ‘们的规则进行的。属于一个æµçš„包åªä¼šç»è¿‡è¿™ä¸ªè¡¨ä¸€æ¬¡ã€‚如果第一个包被å…许åšNAT或Masqueraded,那么余下的包都会自动地被åšç›¸åŒçš„æ“ä½œã€‚ä¹Ÿå°±æ˜¯è¯´ï¼Œä½™ä¸‹çš„åŒ…ä¸ä¼šå†é€šè¿‡è¿™ä¸ªè¡¨ï¼Œä¸€ä¸ªä¸€ä¸ªçš„被NAT,而是自动地完æˆã€‚PREROUTING 链的作用是在包刚刚到达防ç«å¢™æ—¶æ”¹å˜å®ƒçš„目的地å€ï¼ˆDNAT),如果需è¦çš„è¯ã€‚OUTPUTé“¾æ”¹å˜æœ¬åœ°äº§ç”Ÿçš„包的目的地å€ï¼ˆDNAT)。POSTROUTING链在包就è¦ç¦»å¼€é˜²ç«å¢™ä¹‹å‰æ”¹å˜å…¶æºåœ°å€ï¼ˆSNAT)。DNAT 是åšç›®çš„网络地å€è½¬æ¢çš„,就是é‡å†™åŒ…的目的IP地å€ã€‚如果一个包被匹é…了,那么和它属于åŒä¸€ä¸ªæµçš„æ‰€æœ‰çš„包都会被自动转æ¢ï¼Œç„¶åŽå°±å¯ä»¥è¢«è·¯ç”±åˆ°æ£ç¡®çš„主机或网络。DNAT是éžå¸¸æœ‰ç”¨çš„ã€‚æ¯”å¦‚ï¼Œä½ çš„WebæœåŠ¡å™¨åœ¨LAN内部,而且没有å¯åœ¨Internet上使用的真实IP地å€ï¼Œé‚£å°±å¯ä»¥ä½¿ç”¨DNAT让防ç«å¢™æŠŠæ‰€æœ‰åˆ°å®ƒè‡ªå·±HTTP端å£çš„包转å‘ç»™LAN内部真æ£çš„WebæœåŠ¡å™¨ã€‚DNAT的目的地å€ä¹Ÿå¯ä»¥æ˜¯ä¸€ä¸ªèŒƒå›´ï¼Œè¿™æ ·çš„è¯ï¼ŒDNAT会为æ¯ä¸€ä¸ªæµéšæœºåˆ†é…一个地å€ã€‚å› æ¤ï¼Œæˆ‘们å¯ä»¥ç”¨è¿™ä¸ªDNATåšæŸç§ç±»åž‹çš„è´Ÿè½½å‡è¡¡ã€‚
mangle这个表主è¦ç”¨æ¥ä¿®æ”¹æ•°æ®åŒ…。我们å¯ä»¥æ”¹å˜ä¸åŒçš„包åŠåŒ…头的内容,比如TTL,TOS或MARK。 注æ„MARK并没有真æ£åœ°æ”¹åŠ¨æ•°æ®åŒ…ï¼Œå®ƒåªæ˜¯åœ¨å†…æ ¸ç©ºé—´ä¸ºåŒ…è®¾äº†ä¸€ä¸ªæ ‡è®°ã€‚é˜²ç«å¢™å†…的其他的规则或程åºå¯ä»¥ä½¿ç”¨è¿™ç§æ ‡è®°å¯¹åŒ…进行过滤或高级路由。这个表有五个内建的链:PREROUTING,POSTROUTING,OUTPUT,INPUTå’ŒFORWARD。PREROUTING在包进入防ç«å¢™ä¹‹åŽã€è·¯ç”±åˆ¤æ–之剿”¹å˜åŒ…,POSTROUTING是在所有路由判æ–之åŽã€‚ OUTPUTåœ¨ç¡®å®šåŒ…çš„ç›®çš„ä¹‹å‰æ›´æ”¹æ•°æ®åŒ…。INPUT在包被路由到本地之åŽï¼Œä½†åœ¨ç”¨æˆ·ç©ºé—´çš„程åºçœ‹åˆ°å®ƒä¹‹å‰æ”¹å˜åŒ…。FORWARD在最åˆçš„路由判æ–之åŽã€æœ€åŽä¸€æ¬¡æ›´æ”¹åŒ…的目的之å‰mangle包。注æ„,mangle表ä¸èƒ½åšä»»ä½•NATï¼Œå®ƒåªæ˜¯æ”¹å˜æ•°æ®åŒ…çš„TTL,TOS或MARK。
æ•°æ®åŒ…在iptablesä¸çš„å„个表ã€å„个chainä¸çš„æµè½¬è¿‡ç¨‹å¦‚ä¸‹å›¾æ‰€ç¤ºï¼š
从上图å¯ä»¥çœ‹å‡ºï¼Œå¦‚果我们è¦è®©æŸå°Linux主机充当路由和负载å‡è¡¡è§’色的è¯ï¼Œæˆ‘们显然应该在该主机的nat表的prerouting链ä¸å¯¹æ•°æ®åŒ…åšDNATæ“作。
Kuberneteså¯ä»¥åˆ©ç”¨iptablesæ¥åšé’ˆå¯¹service的路由和负载å‡è¡¡ï¼Œå…¶æ ¸å¿ƒé€»è¾‘是通过kubernetes/pkg/proxy/iptables/proxier.goä¸çš„函数syncProxyRulesæ¥å®žçŽ°çš„ï¼ˆè¿™éƒ¨åˆ†ä»£ç åšçš„事情主è¦å°±æ˜¯åœ¨service所在nodeçš„nat表的prerouting链ä¸å¯¹æ•°æ®åŒ…åšDNATæ“作)。
䏋颿ˆ‘们就æ¥åˆ†æžä¸€ä¸‹syncProxyRulesä¸çš„主è¦é€»è¾‘:
Part1:
这里定义了kubernetes将创建的自定义链的å称。
Part2:
上述代ç åšäº†å¦‚下事情:
1〠分别在表filterå’Œnatä¸åˆ›å»ºå为“KUBE-SERVICES”的自定义链
2〠调用iptables对filter表的output链ã€å¯¹nat表的outputå’Œprerouting链创建了如下三æ¡è§„则:
//å°†ç»è¿‡filter表的output链的数æ®åŒ…é‡å®šå‘到自定义链KUBE-SERVICESä¸
//这里-jçš„æ„æ€æ˜¯jump
iptables -I OUTPUT -m comment –comment “kubernetes service portals” -j KUBE-SERVICES
//å°†ç»è¿‡nat表的prerouting链的数æ®åŒ…é‡å®šå‘到自定义链KUBE-SERVICESä¸
//显然kubernetes这里è¦åšDNAT
iptables –t nat -I PREROUTING -m comment –comment “kubernetes service portals” -j KUBE-SERVICES
//å°†ç»è¿‡nat表的output链的数æ®åŒ…é‡å®šå‘到自定义链KUBE-SERVICESä¸
iptables –t nat –I OUTPUT -m comment –comment “kubernetes service portals” -j KUBE-SERVICES
Part3:
上述代ç åšäº†å¦‚下事情:
1〠在表natä¸åˆ›å»ºäº†å为“KUBE-POSTROUTING”的自定义链
2〠调用iptables对nat表的postrouting链创建了如下规则:
//å°†ç»è¿‡nat表的postrouting链的数æ®åŒ…é‡å®šå‘到自定义链KUBE-POSTROUTINGä¸
//显然kubernetes这里è¦åšSNAT
iptables –t nat -I POSTROUTING -m comment –comment “kubernetes postrouting rules” -j KUBE-POSTROUTING
Part4:
上述代ç åšçš„事情是:kubernetes调用iptables-save命令解æžå½“å‰nodeä¸iptablesçš„filter表和nat表ä¸å·²ç»å˜åœ¨çš„chain,kubernetes会将这些chainå˜åœ¨ä¸¤ä¸ªmapä¸ï¼ˆexistingFilterChainså’ŒexistingNATChains),然åŽå†åˆ›å»ºå››ä¸ªprotobufä¸çš„buffer(分别是filterChainsã€filterRulesã€natChainså’ŒnatRules),åŽç»kubernetes会往这四个bufferä¸å†™å…¥å¤§é‡iptables规则,最åŽå†è°ƒç”¨iptables-restore写回到当å‰nodeçš„iptablesä¸ã€‚
Part5:
上述代ç åšäº†å¦‚下事情:
1〠如果当å‰nodeçš„iptablesçš„filter表和nat表ä¸å·²ç»å˜åœ¨å为“KUBE-SERVICES”〓KUBE-NODEPORTS”〓KUBE-POSTROUTING”å’Œ“KUBE-MARK-MASQ”的自定义链,那就原å°ä¸åŠ¨å°†å®ƒä»¬æŒ‰ç…§åŽŸæ¥çš„å½¢å¼ï¼ˆ:<chain-name> <chain-policy> [<packet-counter>:<byte-counter>])写入到filterChainså’ŒnatChainsä¸ï¼›å¦‚果没有,则以“:<chain-name> <chain-policy> [0:0]â€çš„æ ¼å¼å†™å…¥ä¸Šè¿°4个chain(å³å°†â€œ:KUBE-SERVICES – [0:0]â€ã€â€œ:KUBE-NODEPORTS – [0:0]â€ã€â€œ:KUBE-POSTROUTING – [0:0]â€å’Œâ€œ:KUBE-MARK-MASQ – [0:0]â€å†™å…¥åˆ°filterChainså’ŒnatChainsä¸ï¼Œè¿™ç›¸å½“于在filter表和nat表ä¸åˆ›å»ºäº†ä¸Šè¿°4个自定义链);
2〠对nat表的自定义链“KUBE-POSTROUTING”写入如下规则:
-A KUBE-POSTROUTING -m comment –comment “kubernetes service traffic requiring SNAT” -m mark –mark 0x4000/0x4000 -j MASQUERADE
3〠对nat表的自定义链“KUBE-MARK-MASQ”写入如下规则:
-A KUBE-MARK-MASQ -j MARK –set-xmark 0x4000/0x4000
这里2å’Œ3åšçš„事情的实际å«ä¹‰æ˜¯kubernetes会让所有kubernetes集群内部产生的数æ®åŒ…æµç»nat表的自定义链“KUBE-MARK-MASQ”,然åŽåœ¨è¿™é‡Œkubernetes会对这些数æ®åŒ…æ‰“ä¸€ä¸ªæ ‡è®°ï¼ˆ0x4000/0x4000),接ç€åœ¨nat的自定义链“KUBE-POSTROUTING”䏿 ¹æ®ä¸Šè¿°æ ‡è®°åŒ¹é…所有的kubernetes集群内部的数æ®åŒ…,匹é…的目的是kubernetes会对这些包åšSNATæ“作。
Part6:
上述代ç 主è¦åšäº†å¦‚下事情:
1〠é历所有æœåŠ¡ï¼Œå¯¹æ¯ä¸€ä¸ªæœåŠ¡ï¼Œåœ¨nat表ä¸åˆ›å»ºå为“KUBE-SVC-XXXXXXXXXXXXXXXX”的自定义链(这里的XXXXXXXXXXXXXXXX是一个16ä½å—符串,kubernetes使用SHA256 算法对“æœåŠ¡å+åè®®åâ€ç”Ÿæˆå“ˆå¸Œå€¼ï¼Œç„¶åŽé€šè¿‡base32对该哈希值编ç ,最åŽå–ç¼–ç 值的å‰16ä½ï¼Œkubernetesé€šè¿‡è¿™ç§æ–¹å¼ä¿è¯æ¯ä¸ªæœåŠ¡å¯¹åº”çš„“KUBE-SVC-XXXXXXXXXXXXXXXX”都ä¸ä¸€æ ·ï¼‰ã€‚ç„¶åŽå¯¹æ¯ä¸ªæœåŠ¡ï¼Œæ ¹æ®æœåŠ¡æ˜¯å¦æœ‰cluster ipã€æ˜¯å¦æœ‰external ipã€æ˜¯å¦å¯ç”¨äº†å¤–部负载å‡è¡¡æœåŠ¡åœ¨nat表的自定义链“KUBE-SERVICES”ä¸åŠ å…¥ç±»ä¼¼å¦‚ä¸‹è¿™æ ·çš„è§„åˆ™ï¼š
//所有æµç»è‡ªå®šä¹‰é“¾KUBE-SERVICESçš„æ¥è‡ªäºŽæœåŠ¡“kongxl/test2:8778-tcp”的数æ®åŒ…都会
//跳转到自定义链KUBE-SVC-XAKTM6QUKQ53BZHSä¸
-A KUBE-SERVICES -d 172.30.32.92/32 -p tcp -m comment –comment “kongxl/test2:8778-tcp cluster IP” -m tcp –dport 8778 -j KUBE-SVC-XAKTM6QUKQ53BZHS
2〠在é历æ¯ä¸€ä¸ªæœåŠ¡çš„è¿‡ç¨‹ä¸ï¼Œè¿˜ä¼šæ£€æŸ¥è¯¥æœåŠ¡æ˜¯å¦å¯ç”¨äº†nodeports,如果å¯ç”¨äº†ä¸”该æœåŠ¡æœ‰å¯¹åº”çš„endpoints,则会在nat表的自定义链“KUBE-NODEPORTS”ä¸åР入如䏋䏤æ¡è§„则:
//所有æµç»è‡ªå®šä¹‰é“¾KUBE-NODEPORTSçš„æ¥è‡ªäºŽæœåŠ¡“ym/echo-app-nodeport”的数æ®åŒ…
//都会跳转到自定义链KUBE-MARK-MASQä¸ï¼Œå³kubernetes会对æ¥è‡ªä¸Šè¿°æœåŠ¡çš„è¿™äº›
//æ•°æ®åŒ…æ‰“ä¸€ä¸ªæ ‡è®°ï¼ˆ0x4000/0x4000)
-A KUBE-NODEPORTS -p tcp -m comment –comment “ym/echo-app-nodeport:” -m tcp –dport 30001 -j KUBE-MARK-MASQ
//所有æµç»è‡ªå®šä¹‰é“¾KUBE-NODEPORTSçš„æ¥è‡ªäºŽæœåŠ¡“ym/echo-app-nodeport”的数æ®åŒ…
//都会跳转到自定义链KUBE-SVC-LQ6G5YLNLUHHZYH5ä¸
-A KUBE-NODEPORTS -p tcp -m comment –comment “ym/echo-app-nodeport:” -m tcp –dport 30001 -j KUBE-SVC-LQ6G5YLNLUHHZYH5
3〠在é历æ¯ä¸€ä¸ªæœåŠ¡çš„è¿‡ç¨‹ä¸ï¼Œè¿˜ä¼šæ£€æŸ¥è¯¥æœåŠ¡æ˜¯å¦å¯ç”¨äº†nodeports,如果å¯ç”¨äº†ä½†è¯¥æœåŠ¡æ²¡æœ‰å¯¹åº”çš„endpoints,则会在filter表的自定义链“KUBE-SERVICES”ä¸åŠ å…¥å¦‚ä¸‹è§„åˆ™ï¼š
//如果service没有é…ç½®endpoints,那么kubernetes这里会REJECT所有数æ®åŒ…,è¿™æ„味ç€//没有endpointsçš„serviceæ˜¯æ— æ³•è¢«è®¿é—®åˆ°çš„
-A KUBE-SERVICES -d 172.30.32.92/32 -p tcp -m comment –comment “kongxl/test2:8080-tcp has no endpoints” -m tcp –dport 8080 -j REJECT
4〠在é历æ¯ä¸€ä¸ªæœåŠ¡çš„è¿‡ç¨‹ä¸ï¼Œå¯¹æ¯ä¸€ä¸ªæœåŠ¡ï¼Œå¦‚æžœè¿™ä¸ªæœåŠ¡æœ‰å¯¹åº”çš„endpoints,那么在nat表ä¸åˆ›å»ºå为“KUBE-SEP-XXXXXXXXXXXXXXXX”的自定义链(这里的XXXXXXXXXXXXXXXX是一个16ä½å—符串,kubernetes使用SHA256 算法对“æœåŠ¡å+åè®®å+端å£â€ç”Ÿæˆå“ˆå¸Œå€¼ï¼Œç„¶åŽé€šè¿‡base32对该哈希值编ç ,最åŽå–ç¼–ç 值的å‰16ä½ï¼Œkubernetesé€šè¿‡è¿™ç§æ–¹å¼ä¿è¯æ¯ä¸ªæœåŠ¡çš„endpoint对应的“KUBE-SEP-XXXXXXXXXXXXXXXX”都ä¸ä¸€æ ·ï¼‰ã€‚ç„¶åŽå¯¹æ¯ä¸ªendpoint,如果该æœåŠ¡é…置了session affinity,则在nat表的该service对应的自定义链“KUBE-SVC-XXXXXXXXXXXXXXXX”ä¸åŠ å…¥ç±»ä¼¼å¦‚ä¸‹è¿™æ ·çš„è§„åˆ™ï¼š
//所有æµç»è‡ªå®šä¹‰é“¾KUBE-SVC-ECTPRXTXBM34L34Qçš„æ¥è‡ªäºŽæœåŠ¡
//”default/docker-registry:5000-tcp”的数æ®åŒ…都会跳转到自定义链 //KUBE-SEP-LPCU5ERTNL2YBWXGä¸ï¼Œ
//ä¸”ä¼šåœ¨ä¸€æ®µæ—¶é—´å†…ä¿æŒsession affinityï¼Œä¿æŒæ—¶é—´ä¸º180ç§’
//这里kubernetes用“-m recent –rcheck –seconds 180 –reapâ€å®žçŽ°äº†ä¼šè¯ä¿æŒ
-A KUBE-SVC-ECTPRXTXBM34L34Q -m comment –comment “default/docker-registry:5000-tcp” -m recent –rcheck –seconds 180 –reap –name KUBE-SEP-LPCU5ERTNL2YBWXG –mask 255.255.255.255 –rsource -j KUBE-SEP-LPCU5ERTNL2YBWXG
5〠在é历æ¯ä¸€ä¸ªæœåŠ¡çš„è¿‡ç¨‹ä¸ï¼Œå¯¹æ¯ä¸€ä¸ªæœåŠ¡ï¼Œå¦‚æžœè¿™ä¸ªæœåŠ¡æœ‰å¯¹åº”çš„endpoints,且没有é…ç½®session affinity,则在nat表的该service对应的自定义链“KUBE-SVC-XXXXXXXXXXXXXXXX”ä¸åŠ å…¥ç±»ä¼¼å¦‚ä¸‹è¿™æ ·çš„è§„åˆ™ï¼ˆå¦‚æžœè¯¥æœåŠ¡å¯¹åº”çš„endpoints大于ç‰äºŽ2ï¼Œåˆ™è¿˜ä¼šåŠ å…¥è´Ÿè½½å‡è¡¡è§„则):
//所有æµç»è‡ªå®šä¹‰é“¾KUBE-SVC-VX5XTMYNLWGXYEL4çš„æ¥è‡ªäºŽæœåŠ¡“ym/echo-app”的数æ®//包既å¯èƒ½ä¼šè·³è½¬åˆ°è‡ªå®šä¹‰é“¾KUBE-SEP-27OZWHQEIJ47W5ZW,也å¯èƒ½ä¼šè·³è½¬åˆ°è‡ªå®šä¹‰
//链KUBE-SEP-AA6LE4U3XA6T2EZB,这里kubernetes用“-m statistic –mode random //–probability 0.50000000000â€å®žçŽ°äº†å¯¹è¯¥æœåŠ¡è®¿é—®çš„è´Ÿè½½å‡è¡¡
-A KUBE-SVC-VX5XTMYNLWGXYEL4 -m comment –comment “ym/echo-app:” -m statistic –mode random –probability 0.50000000000 -j KUBE-SEP-27OZWHQEIJ47W5ZW
-A KUBE-SVC-VX5XTMYNLWGXYEL4 -m comment –comment “ym/echo-app:” -j KUBE-SEP-AA6LE4U3XA6T2EZB
6〠最åŽï¼Œåœ¨é历æ¯ä¸€ä¸ªæœåŠ¡çš„è¿‡ç¨‹ä¸ï¼Œå¯¹æ¯ä¸€ä¸ªæœåŠ¡çš„endpoints,在nat表的该endpoint对应的自定义链“KUBE-SEP-XXXXXXXXXXXXXXXX”ä¸åŠ å…¥å¦‚ä¸‹è§„åˆ™ï¼Œå®žçŽ°åˆ°è¯¥æœåŠ¡æœ€ç»ˆç›®çš„åœ°çš„DNAT:
//æœåŠ¡“ym/echo-app”有两个endpoints,之å‰kuberneteså·²ç»å¯¹è¯¥æœåŠ¡åšäº†è´Ÿè½½å‡è¡¡ï¼Œ
//所以这里一共会产生4æ¡è·³è½¬è§„则
-A KUBE-SEP-27OZWHQEIJ47W5ZW -s 10.1.0.8/32 -m comment –comment “ym/echo-app:” -j KUBE-MARK-MASQ
-A KUBE-SEP-27OZWHQEIJ47W5ZW -p tcp -m comment –comment “ym/echo-app:” -m tcp -j DNAT –to-destination 10.1.0.8:8080
-A KUBE-SEP-AA6LE4U3XA6T2EZB -s 10.1.1.4/32 -m comment –comment “ym/echo-app:” -j KUBE-MARK-MASQ
-A KUBE-SEP-AA6LE4U3XA6T2EZB -p tcp -m comment –comment “ym/echo-app:” -m tcp -j DNAT –to-destination 10.1.1.4:8080
Part7:
上述代ç åšçš„事情是:
1ã€ åˆ æŽ‰å½“å‰èŠ‚ç‚¹ä¸å·²ç»ä¸å˜åœ¨çš„æœåŠ¡æ‰€å¯¹åº”çš„“KUBE-SVC-XXXXXXXXXXXXXXXX”链和“KUBE-SEP- XXXXXXXXXXXXXXXX”链;
2〠å‘nat表的自定义链“KUBE-SERVICESâ€ä¸å†™å…¥å¦‚ä¸‹è¿™æ ·è§„åˆ™ï¼š
//å°†ç›®çš„åœ°å€æ˜¯æœ¬åœ°çš„æ•°æ®åŒ…跳转到自定义链KUBE-NODEPORTSä¸
-A KUBE-SERVICES -m comment –comment “kubernetes service nodeports; NOTE: this must be the last rule in this chain” -m addrtype –dst-type LOCAL -j KUBE-NODEPORTS
Part8:
上述代ç åšçš„事情是:åˆå¹¶å·²ç»è¢«å†™å…¥äº†å¤§é‡è§„则的四个protobufä¸çš„buffer(分别是filterChainsã€filterRulesã€natChainså’ŒnatRules),然åŽè°ƒç”¨iptables-restore写回到当å‰nodeçš„iptablesä¸ã€‚
总结
Kubernetes使用iptables的主è¦ç”¨æ³•用一å¥è¯æ€»ç»“就是:
Kubernetesé€šè¿‡åœ¨ç›®æ ‡nodeçš„iptablesä¸çš„nat表的PREROUTINGå’ŒPOSTROUTING链ä¸åˆ›å»ºä¸€ç³»åˆ—的自定义链 ï¼ˆè¿™äº›è‡ªå®šä¹‰é“¾ä¸»è¦æ˜¯“KUBE-SERVICES”链〓KUBE-POSTROUTING”é“¾ã€æ¯ä¸ªæœåŠ¡æ‰€å¯¹åº”çš„“KUBE-SVC-XXXXXXXXXXXXXXXX”链和“KUBE-SEP-XXXXXXXXXXXXXXXX”链),然åŽé€šè¿‡è¿™äº›è‡ªå®šä¹‰é“¾å¯¹æµç»åˆ°è¯¥node的数æ®åŒ…åšDNATå’ŒSNATæ“作以实现路由ã€è´Ÿè½½å‡è¡¡å’Œåœ°å€è½¬æ¢ã€‚
上述总结å¯ä»¥ç”¨å¦‚ä¸‹è¿™å¼ å›¾æ¥è¯´æ˜Žï¼š
关于直方图统计信æ¯çš„两个有趣的知识点
Posted: March 4, 2015 | Author: Cui Hua | Filed under: Oracle | 4 Comments »æœ‰æœ‹å‹é—®äº†æˆ‘å¦‚ä¸‹è¿™æ ·ä¸€ä¸ªé—®é¢˜ï¼Œæœ€åŽçš„è§£å†³è¿‡ç¨‹æŒºæœ‰æ„æ€çš„,让我å‘现了直方图统计信æ¯é‡Œæˆ‘之剿²¡æœ‰æ³¨æ„到的两个知识点,这里跟大家分享一下。
è¿™ä¸ªé—®é¢˜æ˜¯è¿™æ ·ï¼š
æ•°æ®åº“的版本是11.2.0.3:
SQL> select * from v$version;
BANNER
——————————————————————————–
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – 64bit Production
PL/SQL Release 11.2.0.3.0 – Production
CORE 11.2.0.3.0 Production
TNS for Linux: Version 11.2.0.3.0 – Production
NLSRTL Version 11.2.0.3.0 – Production
创建一个测试表T1:
SQL> create table t1 as select * from dba_users;
Table created
ä»Žå¦‚ä¸‹æŸ¥è¯¢ç»“æžœä¸æˆ‘们å¯ä»¥çœ‹åˆ°ï¼Œè¡¨T1çš„OBJECT_ID是104192:
SQL> select object_id from dba_objects where owner=’SCOTT’ and object_name=’T1′;
OBJECT_ID
——————-
104192
表T1的列user_id所对应的INTCOL#是2:
SQL> select name,intcol# from sys.col$ where obj#=104192 and name=’USER_ID’;
NAME INTCOL#
—————————— ———-
USER_ID 2
从如下结果里å¯ä»¥çœ‹åˆ°ï¼ŒSYS.COL_USAGE$现在还没有列USER_ID的使用记录:
SQL> select obj#,intcol#,equality_preds from sys.col_usage$ where obj#=104192;
OBJ# INTCOL# EQUALITY_PREDS
———- ———- ————–
我们现在æ¥ä½¿ç”¨ä¸€ä¸‹åˆ—USER_ID:
SQL> select count(*) from t1 where user_id=5;
COUNT(*)
—————–
1
使用完åŽï¼Œæˆ‘们å‘现SYS.COL_USAGE$还是没有列USER_ID的使用记录:
SQL> select obj#,intcol#,equality_preds from sys.col_usage$ where obj#=104192;
OBJ# INTCOL# EQUALITY_PREDS
———- ———- ————–
这个是æ£å¸¸çš„ï¼Œè¿™é‡Œä¸æ˜¯æ²¡æœ‰åˆ—USER_IDçš„ä½¿ç”¨è®°å½•ï¼Œæ˜¯å·²ç»æœ‰äº†ä½†åªæ˜¯è¿˜æ²¡æœ‰è¢«æŒä¹…化到SYS.COL_USAGE$ä¸ï¼Œè¿™é‡Œéœ€è¦æˆ‘们手工执行一下dbms_stats.gather_table_statsï¼Œè¿™æ ·å°±èƒ½å°†USER_ID的使用记录flush到SYS.COL_USAGE$ä¸äº†ï¼Œç„¶åŽæˆ‘们就能看到了:
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,estimate_percent=>100);
PL/SQL procedure successfully completed
SQL> select obj#,intcol#,equality_preds from sys.col_usage$ where obj#=104192;
OBJ# INTCOL# EQUALITY_PREDS
———- ———- ————–
104192 2 1
ä½†çŽ°åœ¨çš„é—®é¢˜æ˜¯æ— è®ºæˆ‘ä»¬æ€Žä¹ˆæ‰§è¡Œdbms_stats.gather_table_stats,列user_id上的直方图统计信æ¯å°±æ˜¯æ²¡æœ‰ï¼ˆè¿™ä¹Ÿæ˜¯é‚£ä½æœ‹å‹é—®çš„问题):
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,method_opt=>’for all columns size auto‘,estimate_percent=>100);
PL/SQL procedure successfully completed
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ———-
T1 USER_ID 39 1 NONE
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,method_opt=>’for columns size auto USER_ID‘,estimate_percent=>100);
PL/SQL procedure successfully completed
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ———-
T1 USER_ID 39 1 NONE
è¿™é‡Œé™¤éžæˆ‘们手工指定user_id列所用的bucket的数é‡ï¼š
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,method_opt=>’for columns size 39 USER_ID‘,estimate_percent=>100);
PL/SQL procedure successfully completed
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ——————–
T1 USER_ID 39 39 HEIGHT BALANCED
手工指定了直方图统计信æ¯çš„bucket的数é‡ä¸º39åŽï¼Œæ˜Žæ˜Žåˆ—user_idçš„distinct值的数é‡ä¹Ÿæ˜¯39,为什么这里直方图的类型居然是HEIGHT BALANCED?按é“ç†è®²åº”该是FREQUENCY啊ï¼
当看到上述测试结果的时候,我æ„è¯†åˆ°ä¸€å®šæ˜¯ä»€ä¹ˆåœ°æ–¹å‡ºäº†é—®é¢˜ï¼Œå› ä¸ºä¸Šè¿°çŽ°è±¡çš„å‡ºçŽ°å·²ç»é¢ 覆了我之å‰å¯¹ç›´æ–¹å›¾ç»Ÿè®¡ä¿¡æ¯çš„如下两个认识:
1ã€æˆ‘原先一直以为如果METHOD_OPT的值是默认的“FOR ALL COLUMNS SIZE AUTOâ€çš„è¯ï¼Œé‚£ä¹ˆåªè¦SYS.COL_USAGE$䏿œ‰ç›®æ ‡åˆ—的使用记录,则Oracle在在自动收集直方图统计信æ¯çš„æ—¶å€™å°±ä¼šåŽ»æ”¶é›†è¯¥åˆ—çš„ç›´æ–¹å›¾ç»Ÿè®¡ä¿¡æ¯ï¼›
2ã€åœ¨æ‰‹å·¥æ”¶é›†ç›´æ–¹å›¾ç»Ÿè®¡ä¿¡æ¯çš„æ—¶å€™ï¼Œå¦‚果我手工指定的bucket的数é‡ç‰äºŽç›®æ ‡åˆ—çš„distinct值的数é‡ï¼Œä¸”这个值是å°äºŽç‰äºŽ254çš„è¯ï¼Œé‚£ä¹ˆOracleæ¤æ—¶æ”¶é›†çš„直方图统计信æ¯çš„类型应该是FREQUENCY。
到底是什么地方出了问题?
我们æ¥å¤ä¹ 一下Oracle关于自动收集直方图统计信æ¯çš„定义:
Oracle在“SIZE Clause in METHOD_OPT Parameter of DBMS_STATS Package (Doc ID 338926.1)â€ä¸æ˜Žç¡®æŒ‡å‡ºï¼ŒMETHOD_OPT的值ä¸çš„AUTOçš„å«ä¹‰ä¸ºå¦‚下所示:
AUTO: Oracle determines the columns to collect histograms based on data distribution and the workload of the columns.
这里的“workload of the columnsâ€æŒ‡çš„åº”è¯¥å°±æ˜¯ç›®æ ‡åˆ—æ˜¯å¦åœ¨SYS.COL_USAGE$䏿œ‰ä½¿ç”¨è®°å½•。注æ„到Oracle这里还æåˆ°äº†å¦å¤–一个æ¡ä»¶â€”—“based on data distributionâ€ï¼ˆè¿™ä¹Ÿæ˜¯æˆ‘之剿²¡æœ‰æ³¨æ„到的æ¡ä»¶ï¼‰ï¼Œä½†è¿™é‡Œçš„具体å«ä¹‰æ˜¯ä»€ä¹ˆï¼Ÿ
“based on data distributionâ€ç›´è¯‘过æ¥å°±æ˜¯ç›®æ ‡åˆ—æ•°æ®çš„åˆ†å¸ƒï¼Œè¯´ç™½äº†å°±æ˜¯ç›®æ ‡åˆ—çš„æ•°æ®åˆ†å¸ƒç¡®å®žå¾—æ˜¯å€¾æ–œçš„ï¼Œåªæœ‰æ»¡è¶³è¿™ä¸ªå‰ææ¡ä»¶ï¼Œå†åŠ ä¸Šè¯¥ç›®æ ‡åˆ—åœ¨SYS.COL_USAGE$䏿œ‰ä½¿ç”¨è®°å½•,Oracle在自动收集直方图统计信æ¯çš„æ—¶å€™æ‰ä¼šå¯¹è¯¥åˆ—收集直方图统计信æ¯ã€‚
Oracle是怎么æ¥åˆ¤æ–æŸåˆ—的数æ®åˆ†å¸ƒæ˜¯å¦æ˜¯å€¾æ–œçš„呢?
æˆ‘ç ”ç©¶äº†ä¸€ä¸‹ï¼Œå‘现Oracle采用了一ç§å¾ˆç®€å•的方法——就是判æ–ç›®æ ‡åˆ—çš„distinctå€¼çš„æ•°é‡æ˜¯å¦å’Œç›®æ ‡è¡¨çš„æ•°æ®é‡ç›¸åŒï¼Œå¦‚果相åŒï¼ŒOracle就认为该列的数æ®åˆ†å¸ƒä¸æ˜¯å€¾æ–œçš„,å¦åˆ™å°±æ˜¯å€¾æ–œçš„ã€‚ä¹Ÿå°±æ˜¯è¯´ï¼Œå¦‚æžœç›®æ ‡åˆ—çš„distinct值的数é‡å’Œç›®æ ‡è¡¨çš„æ•°æ®é‡ç›¸åŒï¼Œå³ä½¿è¯¥ç›®æ ‡åˆ—在SYS.COL_USAGE$䏿œ‰ä½¿ç”¨è®°å½•,Oracle在自动收集直方图统计信æ¯çš„æ—¶å€™ä¹Ÿä¸ä¼šå¯¹è¯¥åˆ—收集直方图统计信æ¯ã€‚
æžæ¸…æ¥šäº†ä¸Šè¿°çŸ¥è¯†ç‚¹ï¼Œé‚£ä½æœ‹å‹é—®çš„é—®é¢˜è‡ªç„¶å°±æœ‰ç”æ¡ˆäº†â€”—对于表T1的列user_id而言,其distinct值的数é‡å’Œè¡¨T1的数æ®é‡ç›¸åŒï¼Œæ‰€ä»¥è¿™é‡Œå³ä½¿user_id在SYS.COL_USAGE$䏿œ‰ä½¿ç”¨è®°å½•,Oracle在自动收集直方图统计信æ¯çš„æ—¶å€™ä¹Ÿä¸ä¼šå¯¹user_id收集直方图统计信æ¯ï¼š
SQL> select count(distinct user_id) from t1;
COUNT(DISTINCTUSER_ID)
———————-
39
SQL> select count(*) from t1;
COUNT(*)
———-
39
现在我们æ¥éªŒè¯ä¸€ä¸‹ä¸Šè¿°ç†è®ºï¼Œå¾€è¡¨T1䏿’入一æ¡è®°å½•,使得user_idçš„distinct值的数é‡å°äºŽè¡¨T1的数æ®é‡ï¼Œè¿™æ ·å½“æˆ‘ä»¬å†æ¬¡å¯¹è¡¨T1收集统计信æ¯çš„æ—¶å€™ï¼Œuser_id列的直方图统计信æ¯åº”该就有了。
先把之å‰å¯¹user_id列手工指定bucketæ•°é‡æ”¶é›†çš„直方图统计信æ¯åˆ 掉:
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,method_opt=>’for columns size 1 USER_ID‘,estimate_percent=>100);
PL/SQL procedure successfully completed
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ——————–
T1 USER_ID 39 1 NONE
对表T1æ’入一æ¡user_id列的值和现有值é‡å¤çš„记录:
SQL> insert into t1 select * from t1 where user_id=5;
1 row inserted
SQL> commit;
Commit complete
现在user_id列的distinct值的数é‡å·²ç»å°äºŽè¡¨T1的数æ®é‡äº†ï¼š
SQL> select count(distinct user_id) from t1;
COUNT(DISTINCTUSER_ID)
———————-
39
SQL> select count(*) from t1;
COUNT(*)
———-
40
æ¤æ—¶å¯¹è¡¨T1冿¬¡æ”¶é›†ç»Ÿè®¡ä¿¡æ¯ï¼š
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,estimate_percent=>100);
PL/SQL procedure successfully completed
从如下查询结果里我们å¯ä»¥çœ‹åˆ°ï¼ŒçŽ°åœ¨user_id列上终于有了直方图统计信æ¯ï¼Œä¸”其类型就是FREQUENCY,这就和我们以å‰çš„认知匹é…ä¸Šäº†ï¼ŒåŒæ—¶ä¹ŸéªŒè¯äº†æˆ‘们刚æ‰çš„分æžç»“论:
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ——————–
T1 USER_ID 39 39 FREQUENCY
冿¬¡åˆ 除user_id列上的直方图统计信æ¯ï¼š
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,method_opt=>’for columns size 1 USER_ID‘,estimate_percent=>100);
PL/SQL procedure successfully completed
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ——————–
T1 USER_ID 39 1 NONE
æˆ‘ä»¬å†æ¬¡ä»¥æ‰‹å·¥æŒ‡å®šbucketæ•°é‡çš„æ–¹å¼æ”¶é›†user_id列上的直方图统计信æ¯ï¼š
SQL> exec dbms_stats.gather_table_stats(ownname=>’SCOTT’,tabname=>’T1′,method_opt=>’for columns size 39 USER_ID‘,estimate_percent=>100);
PL/SQL procedure successfully completed
从如下查询结果我们å¯ä»¥çœ‹åˆ°ï¼ŒçŽ°åœ¨user_id列上的直方图统计信æ¯çš„类型已ç»ä¸æ˜¯ä¹‹å‰çš„HEIGHT BALANCEDäº†ï¼Œè€Œæ˜¯å˜æˆäº†FREQUENCY:
SQL> select table_name,column_name,num_distinct,num_buckets,histogram from dba_tab_col_statistics where owner=’SCOTT’ and table_name=’T1′ and column_name=’USER_ID’;
TABLE_NAME COLUMN_NAM NUM_DISTINCT NUM_BUCKETS HISTOGRAM
———- ———- ———— ———– ——————–
T1 USER_ID 39 39 FREQUENCY
这说明我们之å‰çš„认识(在手工收集直方图统计信æ¯çš„æ—¶å€™ï¼Œå¦‚果我手工指定的bucket的数é‡ç‰äºŽç›®æ ‡åˆ—çš„distinct值的数é‡ï¼Œä¸”这个值是å°äºŽç‰äºŽ254çš„è¯ï¼Œé‚£ä¹ˆOracleæ¤æ—¶æ”¶é›†çš„直方图统计信æ¯çš„类型应该是FREQUENCY)æˆç«‹çš„剿æ¡ä»¶æ˜¯è¯¥åˆ—的数æ®åˆ†å¸ƒæ˜¯å€¾æ–œçš„。
æ€»ç»“ä¸€ä¸‹ï¼Œé€šè¿‡è¿™ç¯‡æ–‡ç« ï¼Œæˆ‘ä»¬ä»‹ç»äº†å¦‚下两个关于直方图统计信æ¯çš„æœ‰è¶£çŸ¥è¯†ç‚¹ï¼š
1ã€å¦‚æžœç›®æ ‡åˆ—çš„distinct值的数é‡å’Œç›®æ ‡è¡¨çš„æ•°æ®é‡ç›¸åŒï¼Œå³ä½¿è¯¥ç›®æ ‡åˆ—在SYS.COL_USAGE$䏿œ‰ä½¿ç”¨è®°å½•,Oracle在自动收集直方图统计信æ¯çš„æ—¶å€™ä¹Ÿä¸ä¼šå¯¹è¯¥åˆ—收集直方图统计信æ¯ï¼›
2ã€åœ¨æ‰‹å·¥æ”¶é›†ç›´æ–¹å›¾ç»Ÿè®¡ä¿¡æ¯çš„æ—¶å€™ï¼Œå¦‚果我手工指定的bucket的数é‡ç‰äºŽç›®æ ‡åˆ—çš„distinct值的数é‡ï¼Œä¸”这个值是å°äºŽç‰äºŽ254çš„è¯ï¼Œé‚£ä¹ˆOracleæ¤æ—¶æ”¶é›†çš„直方图统计信æ¯çš„类型应该是FREQUENCY——这个结论æˆç«‹çš„剿æ¡ä»¶æ˜¯è¯¥åˆ—的数æ®åˆ†å¸ƒæ˜¯å€¾æ–œçš„。
Recent Comments