K8S中的Service的存在理由
###前言 Kubernetes Pod是有生命周期的,它們可以被創(chuàng)建,也可以被銷毀,然而一旦被銷毀生命就永遠(yuǎn)結(jié)束。 通過ReplicationController能夠動態(tài)地創(chuàng)建和銷毀Pod(例如,需要進(jìn)行擴縮容,或者執(zhí)行滾動升級)。
每個 Pod 都會獲取它自己的 IP 地址,可一旦銷毀后,重新創(chuàng)建后,IP地址會產(chǎn)生改變。 這會導(dǎo)致一個問題:在 Kubernetes 集群中,如果一組 Pod(稱為 backend)為其它 Pod (稱為 frontend)提供服務(wù),一旦backend的Pod重新創(chuàng)建,那么frontend的Pod該如何發(fā)現(xiàn),并連接到這組 Pod 中的哪些 backend 呢? ###Service Service資源用于為pod對象提供一個固定、統(tǒng)一的訪問接口及負(fù)載均衡的能力,并借助新一代DNS系統(tǒng)的服務(wù)發(fā)現(xiàn)功能,解決客戶端發(fā)現(xiàn)并訪問容器化應(yīng)用的問題。
注意:service只是在k8s集群內(nèi)部起作用,集群外部訪問是無效的 ###實現(xiàn)原理 Service通過關(guān)注定義出多個POD對象組合而成的邏輯集合,以及訪問這組POD的策略,Service關(guān)聯(lián)POD需要標(biāo)簽選擇器完成,其基于標(biāo)簽選擇器將一組POD定義成一個邏輯集合,并通過自己的IP地址和端口調(diào)度代理請求至后端POD之上。 ```js apiVersion: v1 kind: Service metadata: name: a-service spec: selector: app: pod-label ports: - protocol: TCP port: 80 targetPort: 9376 ``` 上面的例子服務(wù)a-service關(guān)聯(lián)著label為【app:pod-label】的pod,這時候另一個服務(wù)B可以訪問跟a-service服務(wù)綁定的service,service信息是固定的提前告訴B就行了,service通過Label Selector跟a服務(wù)的pod綁定,無論a的pod如何變化對b來說都是透明的。
###虛擬IP service對象的IP地址稱為cluster IP,位于K8S集群配置指定的專用IP地址范圍內(nèi),其是一種虛擬IP地址,其在service對象創(chuàng)建后保持不變,并且能夠被同一集群中的POD資源訪問,service端口接受客戶端的請求并將其轉(zhuǎn)發(fā)至后端POD中的相應(yīng)端口,因此,其又被稱為四層代理,因其工作在TCP/IP層。
一個service對象就是工作節(jié)點上的一些iptables或ipvs,用于將到達(dá)service對象的IP地址的流量轉(zhuǎn)發(fā)到相應(yīng)的endpoint對象指定的IP地址和端口上,kube-proxy組件通過api-server持續(xù)監(jiān)控著各個service及其相關(guān)的POD對象,并將其創(chuàng)建或變動實時反映到工作節(jié)點的iptable或ipvs上 ###服務(wù)代理 k8s群集中的每個節(jié)點都運行一個kube-proxy的組件,kube-proxy其實是一個代理層負(fù)責(zé)實現(xiàn)service ###userspace模式 客戶端訪問ServiceIP(clusterIP)請求會先從用戶空間到內(nèi)核中的iptables,然后回到用戶空間kube-proxy,kube-proxy負(fù)責(zé)代理工作。
###具體細(xì)節(jié): 請求到達(dá)service后,其被轉(zhuǎn)發(fā)到內(nèi)核,經(jīng)由套接字送往用戶空間的kube-proxy,而后經(jīng)由kube-proxy送回內(nèi)核空間,并調(diào)度至后端POD,其傳輸方式效率太低。在1.1 版本之前,其是默認(rèn)的轉(zhuǎn)發(fā)策略。 ###iptables模式 客戶端訪問ServiceIP(clusterIP)請求會由iptables直接重定向到后端 ###具體細(xì)節(jié): 客戶端IP請求時,直接請求本地內(nèi)核service ip,根據(jù)iptables的規(guī)則直接將請求轉(zhuǎn)發(fā)到到各pod上,因為使用iptable NAT來完成轉(zhuǎn)發(fā),也存在不可忽視的性能損耗。
另外,如果集群中存在上萬的Service/Endpoint,那么Node上的iptables rules將會非常龐大,性能還會再打折扣 Kubernetes v1.2之前默認(rèn)是userspace之后是iptables模式,iptables模式性能和可靠性更好,但是iptables模式依賴健康檢查,在沒有健康檢查的情況下如果一個pod不響應(yīng),iptables模式不會切換另一個pod上 ###ipvs模型 此模型跟蹤API service上的service和endpoints對象的變動,據(jù)此來調(diào)用netlink接口創(chuàng)建IPVS規(guī)則,并確保API server中的變動保持同步,其流量調(diào)度策略在IPVS中實現(xiàn),其余的在iptables中實現(xiàn)。 ipvs 支持眾多調(diào)度算法,如rr、lc、dh、sh、sed和nq 等。 ###集群外部訪問 我們?nèi)绾卧诩和庠L問service呢?k8s提供了幾種方式 ###NodePort 通過每個 Node 上的 IP 和靜態(tài)端口(NodePort)暴露服務(wù)。NodePort 服務(wù)會路由到 ClusterIP 服務(wù),這個 ClusterIP 服務(wù)會自動創(chuàng)建。通過請求 NodeIP:Port,可以從集群的外部訪問一個 NodePort 服務(wù)。
這時要訪問這個Service的話,只需要通過訪問 :Port ###LoadBalancer 在NodePort基礎(chǔ)上,Kubernetes可以請求底層云平臺cloud provider 創(chuàng)建一個外部的負(fù)載均衡器,并將請求轉(zhuǎn)發(fā)到每個Node作為后端,進(jìn)行服務(wù)分發(fā)。 該模式需要底層云平臺(例如GCE、AWS)支持。 ###ExternalName 創(chuàng)建一個dns別名指到service name上,主要是防止service name發(fā)生變化,要配合dns插件使用。通過返回 CNAME 和它的值,可以將服務(wù)映射到 externalName 字段的內(nèi)容。
這只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持 ###Ingress 上面我們提到幾種方式,但是當(dāng)集群服務(wù)很多的時候,NodePort方式最大的缺點是會占用很多集群機器的端口;LB方式最大的缺點則是每個service一個LB又有點浪費和麻煩,并且需要k8s之外的支持; 而ingress則只需要一個NodePort或者一個LB就可以滿足所有service對外服務(wù)的需求。
聲明:免責(zé)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶自發(fā)貢獻(xiàn)自行上傳,本網(wǎng)站不擁有所有權(quán),也不承認(rèn)相關(guān)法律責(zé)任。如果您發(fā)現(xiàn)本社區(qū)中有涉嫌抄襲的內(nèi)容,請發(fā)
送郵件至:operations@xinnet.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,本站將立刻刪除涉嫌侵權(quán)內(nèi)容。本站原創(chuàng)內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時
需注明出處:新網(wǎng)idc知識百科