您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“kubernetes中kube-proxy的工作原理是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“kubernetes中kube-proxy的工作原理是什么”吧!
說到kube-proxy,就不得不提到k8s中service,下面對它們兩做簡單說明:
kube-proxy其實就是管理service的訪問入口,包括集群內(nèi)Pod到Service的訪問和集群外訪問service。
kube-proxy管理sevice的Endpoints,該service對外暴露一個Virtual IP,也成為Cluster IP, 集群內(nèi)通過訪問這個Cluster IP:Port
就能訪問到集群內(nèi)對應(yīng)的serivce下的Pod。
service是通過Selector選擇的一組Pods的服務(wù)抽象,其實就是一個微服務(wù),提供了服務(wù)的LB和反向代理的能力,而kube-proxy的主要作用就是負(fù)責(zé)service的實現(xiàn)。
service另外一個重要作用是,一個服務(wù)后端的Pods可能會隨著生存滅亡而發(fā)生IP的改變,service的出現(xiàn),給服務(wù)提供了一個固定的IP,而無視后端Endpoint的變化。
k8s提供了兩種方式進(jìn)行服務(wù)發(fā)現(xiàn):
環(huán)境變量: 當(dāng)你創(chuàng)建一個Pod的時候,kubelet會在該Pod中注入集群內(nèi)所有Service的相關(guān)環(huán)境變量。需要注意的是,要想一個Pod中注入某個Service的環(huán)境變量,則必須Service要先比該Pod創(chuàng)建。這一點,幾乎使得這種方式進(jìn)行服務(wù)發(fā)現(xiàn)不可用。
比如,一個ServiceName為redis-master的Service,對應(yīng)的ClusterIP:Port為10.0.0.11:6379,則其對應(yīng)的環(huán)境變量為:
REDIS_MASTER_SERVICE_HOST=10.0.0.11 REDIS_MASTER_SERVICE_PORT=6379 REDIS_MASTER_PORT=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379 REDIS_MASTER_PORT_6379_TCP_PROTO=tcp REDIS_MASTER_PORT_6379_TCP_PORT=6379 REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
DNS:這也是k8s官方強烈推薦的方式??梢酝ㄟ^cluster add-on的方式輕松的創(chuàng)建KubeDNS來對集群內(nèi)的Service進(jìn)行服務(wù)發(fā)現(xiàn)。更多關(guān)于KubeDNS的內(nèi)容,請查看我的博文:Kubernetes DNS Service技術(shù)研究 ,在此不再贅述。
k8s原生的,一個Service的ServiceType決定了其發(fā)布服務(wù)的方式。
ClusterIP:這是k8s默認(rèn)的ServiceType。通過集群內(nèi)的ClusterIP在內(nèi)部發(fā)布服務(wù)。
NodePort:這種方式是常用的,用來對集群外暴露Service,你可以通過訪問集群內(nèi)的每個NodeIP:NodePort的方式,訪問到對應(yīng)Service后端的Endpoint。
LoadBalancer: 這也是用來對集群外暴露服務(wù)的,不同的是這需要Cloud Provider的支持,比如AWS等。
ExternalName:這個也是在集群內(nèi)發(fā)布服務(wù)用的,需要借助KubeDNS(version >= 1.7)的支持,就是用KubeDNS將該service和ExternalName做一個Map,KubeDNS返回一個CNAME記錄。
##kube-proxy內(nèi)部原理
kube-proxy當(dāng)前實現(xiàn)了兩種proxyMode:userspace和iptables。其中userspace mode是v1.0及之前版本的默認(rèn)模式,從v1.1版本中開始增加了iptables mode,在v1.2版本中正式替代userspace模式成為默認(rèn)模式。
###userspace mode userspace是在用戶空間,通過kube-proxy來實現(xiàn)service的代理服務(wù)。廢話不多說,其原理如下如圖所示:
可見,這種mode最大的問題是,service的請求會先從用戶空間進(jìn)入內(nèi)核iptables,然后再回到用戶空間,由kube-proxy完成后端Endpoints的選擇和代理工作,這樣流量從用戶空間進(jìn)出內(nèi)核帶來的性能損耗是不可接受的。這也是k8s v1.0及之前版本中對kube-proxy質(zhì)疑最大的一點,因此社區(qū)就開始研究iptables mode。
####Example
$ kubectl get service NAME LABELS SELECTOR IP(S) PORT(S) kubernetes component=apiserver,provider=kubernetes <none> 10.254.0.1 443/TCP ssh-service1 name=ssh,role=service ssh-service=true 10.254.132.107 2222/TCP $ kubectl describe service ssh-service1 Name: ssh-service1 Namespace: default Labels: name=ssh,role=service Selector: ssh-service=true Type: LoadBalancer IP: 10.254.132.107 Port: <unnamed> 2222/TCP NodePort: <unnamed> 30239/TCP Endpoints: <none> Session Affinity: None No events.
NodePort的工作原理與ClusterIP大致相同,發(fā)送到某個NodeIP:NodePort的請求,通過iptables重定向到kube-proxy對應(yīng)的端口(Node上的隨機端口)上,然后由kube-proxy再將請求發(fā)送到其中的一個Pod:TargetPort。
這里,假如Node的ip為10.0.0.5,則對應(yīng)的iptables如下:
$ sudo iptables -S -t nat ... -A KUBE-NODEPORT-CONTAINER -p tcp -m comment --comment "default/ssh-service1:" -m tcp --dport 30239 -j REDIRECT --to-ports 36463 -A KUBE-NODEPORT-HOST -p tcp -m comment --comment "default/ssh-service1:" -m tcp --dport 30239 -j DNAT --to-destination 10.0.0.5:36463 -A KUBE-PORTALS-CONTAINER -d 10.254.132.107/32 -p tcp -m comment --comment "default/ssh-service1:" -m tcp --dport 2222 -j REDIRECT --to-ports 36463 -A KUBE-PORTALS-HOST -d 10.254.132.107/32 -p tcp -m comment --comment "default/ssh-service1:" -m tcp --dport 2222 -j DNAT --to-destination 10.0.0.5:36463
可見:訪問10.0.0.5:30239端口會被轉(zhuǎn)發(fā)到node上的36463端口(隨機監(jiān)聽端口)。而且在訪問clusterIP 10.254.132.107的2222端口時,也會把請求轉(zhuǎn)發(fā)到本地的36463端口。 36463端口實際被kube-proxy所監(jiān)聽,將流量進(jìn)行導(dǎo)向到后端的pod上。
###iptables mode 另一種mode是iptables,它完全利用內(nèi)核iptables來實現(xiàn)service的代理和LB。是v1.2及之后版本默認(rèn)模式,其原理圖如下所示:
iptables mode因為使用iptable NAT來完成轉(zhuǎn)發(fā),也存在不可忽視的性能損耗。另外,如果集群中存在上萬的Service/Endpoint,那么Node上的iptables rules將會非常龐大,性能還會再打折扣。
這也導(dǎo)致,目前大部分企業(yè)用k8s上生產(chǎn)時,都不會直接用kube-proxy作為服務(wù)代理,而是通過自己開發(fā)或者通過Ingress Controller來集成HAProxy, Nginx來代替kube-proxy。
####Example iptables的方式則是利用了linux的iptables的nat轉(zhuǎn)發(fā)進(jìn)行實現(xiàn)。
apiVersion: v1 kind: Service metadata: labels: name: mysql role: service name: mysql-service spec: ports: - port: 3306 targetPort: 3306 nodePort: 30964 type: NodePort selector: mysql-service: "true"
mysql-service對應(yīng)的nodePort暴露出來的端口為30964,對應(yīng)的cluster IP(10.254.162.44)的端口為3306,進(jìn)一步對應(yīng)于后端的pod的端口為3306。
mysql-service后端代理了兩個pod,ip分別是192.168.125.129和192.168.125.131。先來看一下iptables。
$iptables -S -t nat ... -A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES -A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES -A POSTROUTING -m comment --comment "kubernetes postrouting rules" -j KUBE-POSTROUTING -A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000 -A KUBE-NODEPORTS -p tcp -m comment --comment "default/mysql-service:" -m tcp --dport 30964 -j KUBE-MARK-MASQ -A KUBE-NODEPORTS -p tcp -m comment --comment "default/mysql-service:" -m tcp --dport 30964 -j KUBE-SVC-67RL4FN6JRUPOJYM -A KUBE-SEP-ID6YWIT3F6WNZ47P -s 192.168.125.129/32 -m comment --comment "default/mysql-service:" -j KUBE-MARK-MASQ -A KUBE-SEP-ID6YWIT3F6WNZ47P -p tcp -m comment --comment "default/mysql-service:" -m tcp -j DNAT --to-destination 192.168.125.129:3306 -A KUBE-SEP-IN2YML2VIFH5RO2T -s 192.168.125.131/32 -m comment --comment "default/mysql-service:" -j KUBE-MARK-MASQ -A KUBE-SEP-IN2YML2VIFH5RO2T -p tcp -m comment --comment "default/mysql-service:" -m tcp -j DNAT --to-destination 192.168.125.131:3306 -A KUBE-SERVICES -d 10.254.162.44/32 -p tcp -m comment --comment "default/mysql-service: cluster IP" -m tcp --dport 3306 -j KUBE-SVC-67RL4FN6JRUPOJYM -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 -A KUBE-SVC-67RL4FN6JRUPOJYM -m comment --comment "default/mysql-service:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-ID6YWIT3F6WNZ47P -A KUBE-SVC-67RL4FN6JRUPOJYM -m comment --comment "default/mysql-service:" -j KUBE-SEP-IN2YML2VIFH5RO2T
首先如果是通過node的30964端口訪問,則會進(jìn)入到以下鏈:
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/mysql-service:" -m tcp --dport 30964 -j KUBE-MARK-MASQ -A KUBE-NODEPORTS -p tcp -m comment --comment "default/mysql-service:" -m tcp --dport 30964 -j KUBE-SVC-67RL4FN6JRUPOJYM
然后進(jìn)一步跳轉(zhuǎn)到KUBE-SVC-67RL4FN6JRUPOJYM的鏈:
-A KUBE-SVC-67RL4FN6JRUPOJYM -m comment --comment "default/mysql-service:" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-ID6YWIT3F6WNZ47P -A KUBE-SVC-67RL4FN6JRUPOJYM -m comment --comment "default/mysql-service:" -j KUBE-SEP-IN2YML2VIFH5RO2T
這里利用了iptables的–probability的特性,使連接有50%的概率進(jìn)入到KUBE-SEP-ID6YWIT3F6WNZ47P鏈,50%的概率進(jìn)入到KUBE-SEP-IN2YML2VIFH5RO2T鏈。
KUBE-SEP-ID6YWIT3F6WNZ47P的鏈的具體作用就是將請求通過DNAT發(fā)送到192.168.125.129的3306端口。
-A KUBE-SEP-ID6YWIT3F6WNZ47P -s 192.168.125.129/32 -m comment --comment "default/mysql-service:" -j KUBE-MARK-MASQ -A KUBE-SEP-ID6YWIT3F6WNZ47P -p tcp -m comment --comment "default/mysql-service:" -m tcp -j DNAT --to-destination 192.168.125.129:3306
同理KUBE-SEP-IN2YML2VIFH5RO2T的作用是通過DNAT發(fā)送到192.168.125.131的3306端口。
-A KUBE-SEP-IN2YML2VIFH5RO2T -s 192.168.125.131/32 -m comment --comment "default/mysql-service:" -j KUBE-MARK-MASQ -A KUBE-SEP-IN2YML2VIFH5RO2T -p tcp -m comment --comment "default/mysql-service:" -m tcp -j DNAT --to-destination 192.168.125.131:3306
分析完nodePort的工作方式,接下里說一下clusterIP的訪問方式。 對于直接訪問cluster IP(10.254.162.44)的3306端口會直接跳轉(zhuǎn)到KUBE-SVC-67RL4FN6JRUPOJYM。
-A KUBE-SERVICES -d 10.254.162.44/32 -p tcp -m comment --comment "default/mysql-service: cluster IP" -m tcp --dport 3306 -j KUBE-SVC-67RL4FN6JRUPOJYM
接下來的跳轉(zhuǎn)方式同NodePort方式。
到此,相信大家對“kubernetes中kube-proxy的工作原理是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。