碼迷,mamicode.com
首頁 > Web開發 > 詳細

kubernets kube-proxy的代理 iptables和ipvs

時間:2021-07-26 17:00:01      閱讀:0      評論:0      收藏:0      [點我收藏+]

標簽:sys   火墻   服務發現   屏幕   ipv4   nta   好的   ext   server   

 

一、service和iptables的關系

service 的代理是 kube-proxy

kube-proxy 運行在所有節點上,它監聽 apiserver 中 service 和 endpoint 的變化情況,創建路由規則以提供服務 IP 和負載均衡功能。簡單理解此進程是Service的透明代理兼負載均衡器,其核心功能是將到某個Service的訪問請求轉發到后端的多個Pod實例上,而kube-proxy底層又是通過iptables和ipvs實現的。

iptables原理

Kubernetes從1.2版本開始,將iptables作為kube-proxy的默認模式。iptables模式下的kube-proxy不再起到Proxy的作用,其核心功能:通過API Server的Watch接口實時跟蹤Service與Endpoint的變更信息,并更新對應的iptables規則,Client的請求流量則通過iptables的NAT機制“直接路由”到目標Pod。

ipvs原理

IPVS在Kubernetes1.11中升級為GA穩定版。IPVS則專門用于高性能負載均衡,并使用更高效的數據結構(Hash表),允許幾乎無限的規模擴張,因此被kube-proxy采納為最新模式。

在IPVS模式下,使用iptables的擴展ipset,而不是直接調用iptables來生成規則鏈。iptables規則鏈是一個線性的數據結構,ipset則引入了帶索引的數據結構,因此當規則很多時,也可以很高效地查找和匹配。

可以將ipset簡單理解為一個IP(段)的集合,這個集合的內容可以是IP地址、IP網段、端口等,iptables可以直接添加規則對這個“可變的集合”進行操作,這樣做的好處在于可以大大減少iptables規則的數量,從而減少性能損耗。

kube-proxy ipvs和iptables的異同

iptables與IPVS都是基于Netfilter實現的,但因為定位不同,二者有著本質的差別:iptables是為防火墻而設計的;IPVS則專門用于高性能負載均衡,并使用更高效的數據結構(Hash表),允許幾乎無限的規模擴張。

與iptables相比,IPVS擁有以下明顯優勢:

  • 為大型集群提供了更好的可擴展性和性能;

  • 支持比iptables更復雜的復制均衡算法(最小負載、最少連接、加權等);

  • 支持服務器健康檢查和連接重試等功能;

  • 可以動態修改ipset的集合,即使iptables的規則正在使用這個集合。

技術圖片

二、k8s集群中分析service和kube-proxy

技術圖片

訪問Service的請求,不論是Cluster IP+TargetPort的方式;還是用Node節點IP+NodePort的方式,都被Node節點的Iptables規則重定向到Kube-proxy監聽Service服務代理端口。kube-proxy接收到Service的訪問請求后,根據負載策略,轉發到后端的Pod。

# kubectl logs  kube-proxy-5clwf  -n kube-system  (查看某一個節點的kube-proxy日志)

1
2
3
4
5
W1014 13:25:02.120810       1 server_others.go:559] Unknown proxy mode"", assuming iptables proxy
I1014 13:25:02.137813       1 node.go:136] Successfully retrieved node IP: 192.168.40.133
I1014 13:25:02.137952       1 server_others.go:186] Using iptables Proxier.
I1014 13:25:02.138750       1 server.go:583] Version: v1.18.0
I1014 13:25:02.139344       1 conntrack.go:100] Set sysctl‘net/netfilter/nf_conntrack_max‘ to 131072

# iptables -vnL     查看所有的規則

1
2
3
4
5
6
Chain INPUT (policy ACCEPT 19577 packets, 3755K bytes)
 pkts bytes target     prot opt in     out     source               destination        
 622K  121M cali-INPUT  all  --  *      *       0.0.0.0/0            0.0.0.0/0           /* cali:Cz_u1IQiXIMmKD4c */
 3017  162K KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate NEW/* kubernetes service portals */
 3017  162K KUBE-EXTERNAL-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate NEW/* kubernetes externally-visible service portals */
 652K  140M KUBE-FIREWALL  all  --  *      *       0.0.0.0/0            0.0.0.0/0  

# iptables-save  > iptables 保存規則,并輸出到屏幕

1
2
3
4
5
6
:cali-OUTPUT - [0:0]
:cali-PREROUTING - [0:0]
:cali-from-host-endpoint - [0:0]
:cali-to-host-endpoint - [0:0]
-A PREROUTING -m comment --comment"cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
-A OUTPUT -m comment --comment"cali:tVnHkvAo15HuiPy0" -j cali-OUTPUT

第一步:接收流量

NodePort訪問入口規則:

1
2
3
4
5
6
7
8
9
10
11
# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP        78d
mydb          ClusterIP   10.108.118.149   <none>        80/TCP         50d
nginx-dns     NodePort    10.103.206.148   <none>        80:30296/TCP   49d
web-service   NodePort    10.111.113.171   <none>        80:32681/TCP   49d
web1          NodePort    10.110.180.143   <none>        80:30746/TCP   12h
 
# iptables -S -t nat  | grep 30746
-A KUBE-NODEPORTS -p tcp -m comment --comment"default/web1:" -m tcp --dport 30746 -j KUBE-MARK-MASQ
-A KUBE-NODEPORTS -p tcp -m comment --comment"default/web1:" -m tcp --dport 30746 -j KUBE-SVC-7YBM6NGNJ6RVLVXL

CLUSTER-IP 訪問入口規則:

1
2
3
# iptables -S -t nat  | grep 10.110.180.143 (cluster IP)
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.110.180.143/32 -p tcp -m comment --comment"default/web1: cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.110.180.143/32 -p tcp -m comment --comment"default/web1: cluster IP" -m tcp --dport 80 -j KUBE-SVC-7YBM6NGNJ6RVLVXL

第二步:按概率(probability)分配

(web1有3個pod副本,負載規則如下)

1
2
3
4
5
6
7
# iptables -S -t nat  | grep KUBE-SVC-7YBM6NGNJ6RVLVXL
-N KUBE-SVC-7YBM6NGNJ6RVLVXL
-A KUBE-NODEPORTS -p tcp -m comment --comment"default/web1:" -m tcp --dport 30746 -j KUBE-SVC-7YBM6NGNJ6RVLVXL
-A KUBE-SERVICES -d 10.110.180.143/32 -p tcp -m comment --comment"default/web1: cluster IP" -m tcp --dport 80 -j KUBE-SVC-7YBM6NGNJ6RVLVXL
-A KUBE-SVC-7YBM6NGNJ6RVLVXL -m comment --comment"default/web1:" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-IXSCGLPBJ6ROUJNA
-A KUBE-SVC-7YBM6NGNJ6RVLVXL -m comment --comment"default/web1:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-5MMDFR2YQS26JCDP  (概論大,因為有兩個pod在同一節點)
-A KUBE-SVC-7YBM6NGNJ6RVLVXL -m comment --comment"default/web1:" -j KUBE-SEP-DHYUVI6YLCFCEZBW

第三步:根據分配轉發到實際pod中

1
2
3
4
5
6
7
8
9
10
11
12
# kubectl get ep
NAME          ENDPOINTS                                             AGE
kubernetes    192.168.40.132:6443                                   78d
nginx-dns     10.244.166.145:80                                     49d
web-service   10.244.166.139:80                                     49d
web1          10.244.104.9:80,10.244.166.140:80,10.244.166.146:80   12h
 
# iptables -S -t nat  | grep KUBE-SEP-5MMDFR2YQS26JCDP
-N KUBE-SEP-5MMDFR2YQS26JCDP
-A KUBE-SEP-5MMDFR2YQS26JCDP -s 10.244.166.140/32 -m comment --comment"default/web1:" -j KUBE-MARK-MASQ
-A KUBE-SEP-5MMDFR2YQS26JCDP -p tcp -m comment --comment"default/web1:" -m tcp -j DNAT --to-destination 10.244.166.140:80(ep,到達某一節點的具體pod中)
-A KUBE-SVC-7YBM6NGNJ6RVLVXL -m comment --comment"default/web1:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-5MMDFR2YQS26JCDP

三、kube-proxy 工作原理

kube-proxy當前實現了三種代理模式:userspace, iptables, ipvs

(1)userspace mode:  userspace是在用戶空間,通過kube-proxy來實現service的代理服務

(2)iptables mode, 該模式完全利用內核iptables來實現service的代理和LB, 這是K8s在v1.2及之后版本默認模式

技術圖片

API Server 對內(集群中的其他組件)和對外(用戶)提供統一的 REST API,其他組件均通過 API Server 進行通信

Controller Manager、Scheduler、Kube-proxy 和 Kubelet 等均通過 API Server watch API 監測資源變化情況,并對資源作相應的操作

(3)ipvs mode.  在kubernetes 1.8以上的版本中,對于kube-proxy組件增加了除iptables模式和用戶模式之外還支持ipvs模式。

kube-proxy ipvs 是基于 NAT 實現的,通過ipvs的NAT模式,對訪問k8s service的請求進行虛IP到POD IP的轉發。當創建一個 service 后,kubernetes 會在每個節點上創建一個網卡,同時幫你將 Service IP(VIP) 綁定上,此時相當于每個 Node 都是一個 ds,而其他任何 Node 上的 Pod,甚至是宿主機服務(比如 kube-apiserver 的 6443)都可能成為 rs;

與iptables、userspace 模式一樣,kube-proxy 依然監聽Service以及Endpoints對象的變化, 不過它并不創建反向代理, 也不創建大量的 iptables 規則, 而是通過netlink 創建ipvs規則,并使用k8s Service與Endpoints信息,對所在節點的ipvs規則進行定期同步; netlink 與 iptables 底層都是基于 netfilter 鉤子,但是 netlink 由于采用了 hash table 而且直接工作在內核態,在性能上比 iptables 更優。其工作流程大體如下:

技術圖片

k8s的service和endpoine是如何關聯和相互影響的?
1、 api-server創建service對象,與service綁定的pod地址:稱之為endpoints(kubectl get ep可以查看)
2、服務發現方面:kube-proxy監控service后端endpoint的動態變化,并且維護service和endpoint的映射關系

kubernetes服務注冊(dns),服務發現是service

http://www.dockone.io/article/9936   有詳細講解

Kubernetes提供了兩種方式進行服務發現, 即環境變量和DNS

(1)環境變量: 當你創建一個Pod的時候,kubelet會在該Pod中注入集群內所有Service的相關環境變量。需要注意: 要想一個Pod中注入某個Service的環境變量,則必須Service要先比該Pod創建。這一點,幾乎使得這種方式進行服務發現不可用。比如,一個ServiceName為redis-master的Service,對應的ClusterIP:Port為172.16.50.11:6379,則其對應的環境變量為:

1
2
3
4
5
6
7
REDIS_MASTER_SERVICE_HOST=172.16.50.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://172.16.50.11:6379
REDIS_MASTER_PORT_6379_TCP=tcp://172.16.50.11:6379
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=172.16.50.11

(2)DNS:這是k8s官方強烈推薦的方式!!!  可以通過cluster add-on方式輕松的創建KubeDNS來對集群內的Service進行服務發現。

四、修改kube-proxy模式為ipvs(默認為iptables)

1、加載內核模塊

# lsmod | grep  ip_vs

1
2
3
4
5
6
ip_vs_sh               12688  0
ip_vs_wrr              12697  0
ip_vs_rr               12600  0
ip_vs                 145497  6 ip_vs_rr,ip_vs_sh,ip_vs_wrr
nf_conntrack          139264  7 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4
libcrc32c              12644  4 xfs,ip_vs,nf_nat,nf_conntrack

2、升級內核模塊,ipvs對內核版本有要求

1
yum update -y

3、查看kube-proxy組件

1
2
3
4
5
6
7
# kubectl get pod -n kube-system 
NAME                                       READY   STATUS    RESTARTS   AGE
kube-proxy-5clwf                           1/1     Running   29         78d
kube-proxy-ht25x                           1/1     Running   30         78d
kube-proxy-x9ml8                           1/1     Running   30         78d
kube-scheduler-master                      1/1     Running   49         78d
metrics-server-584b5f4754-7vlhm            1/1     Running   56         78d

4、產看kube-proxy的配置文件configmaps

1
2
3
4
5
6
7
8
# kubectl get configmaps  -n kube-system 
NAME                                 DATA   AGE
calico-config                        4      78d
coredns                              1      78d
extension-apiserver-authentication   6      78d
kube-proxy                           2      78d
kubeadm-config                       2      78d
kubelet-config-1.18                  1      78d

5、編輯kube-proxy的configmaps

1
2
3
4
5
6
7
8
9
10
11
12
13
# kubectl edit  configmaps  kube-proxy -n kube-system
mode"ipvs"
 
刪除舊的kube-proxy,kubelet自動重新拉起,應用ipvs
# kubectl delete pod   kube-proxy-x9ml8   -n kube-system 
pod"kube-proxy-x9ml8" deleted
[root@master ~]# kubectldelete pod   kube-proxy-ht25x   -n kube-system 
pod"kube-proxy-ht25x" deleted
 
# kubectl logs kube-proxy-4cnbn  -n kube-system
I1015 14:03:08.402147       1 node.go:136] Successfully retrieved node IP: 192.168.40.132
I1015 14:03:08.402259       1 server_others.go:259] Using ipvs Proxier.
W1015 14:03:08.402618       1 proxier.go:429] IPVS scheduler not specified, use rr bydefault

6、安裝ipvsadm 

1
2
3
4
5
6
7
8
9
10
11
12
13
# yum install -y ipvsadm.x86_64
 
# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  127.0.0.1:30564 rr  (輪詢規則)
  -> 10.244.104.36:8080           Masq    1      0          0        
  -> 10.244.166.147:8080          Masq    1      0          0        
TCP  127.0.0.1:32618 rr
  -> 10.244.104.20:80             Masq    1      0          0        
TCP  172.17.0.1:30564 rr
  -> 10.244.104.36:8080           Masq    1      0          0   

7、系統生成虛擬網卡kube-ipvs0

1
2
3
4
5
6
#  ip a
6: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN groupdefault
    link/ether a2:09:a4:9d:fb:f8 brd ff:ff:ff:ff:ff:ff
    inet 10.110.180.143/32 brd 10.110.180.143 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
inet 10.110.180.143/32專門用于接收svc web1的請求

8、svc的流量被ipvs分發

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
web1          NodePort    10.110.180.143   <none>        80:30746/TCP   23h
 
# curl  10.110.180.143
...
<title>Welcome to nginx!</title>
...
 
# kubectl get ep
NAME          ENDPOINTS                                              AGE
kubernetes    192.168.40.132:6443                                    78d
web1          10.244.104.15:80,10.244.166.143:80,10.244.166.148:80   23h
 
ipvs捕捉到svc的流量
# ipvsadm -L -n
TCP  10.110.180.143:80 rr
  -> 10.244.104.15:80             Masq    1      0          0        
  -> 10.244.166.143:80            Masq    1      0          0        
  -> 10.244.166.148:80            Masq    1      0          1  

 

kubernets kube-proxy的代理 iptables和ipvs

標簽:sys   火墻   服務發現   屏幕   ipv4   nta   好的   ext   server   

原文地址:https://www.cnblogs.com/lgj8/p/15060996.html

(0)
(0)
   
舉報
評論 一句話評論(0
登錄后才能評論!
? 2014 mamicode.com 版權所有  聯系我們:gaon5@hotmail.com
迷上了代碼!
4399在线看MV_久久99精品久久久久久久久久_成人又黄又爽又刺激视频_能收黄台的app不收费