共計(jì) 3063 個(gè)字符,預(yù)計(jì)需要花費(fèi) 8 分鐘才能閱讀完成。
這篇文章將為大家詳細(xì)講解有關(guān) Kubernetes 里的 Service 究竟是如何工作的,文章內(nèi)容質(zhì)量較高,因此丸趣 TV 小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識(shí)有一定的了解。
Service 是 Kubernetes 接入層的一種抽象資源,它為我們提供了一種固定的、統(tǒng)一的訪問接口地址和負(fù)載均衡能力,這時(shí)可能會(huì)想到,當(dāng)時(shí)使用 docker-compose 的時(shí)候,不存在 Service 概念,不也運(yùn)行起來了嗎?是的,在 Kubernetes 集群內(nèi)部 Pod ip 也是互通的,但是 Pod 的 ip 會(huì)經(jīng)常因?yàn)閿U(kuò)容、重建而導(dǎo)致客戶端訪問錯(cuò)誤,pod 訪問無法提供負(fù)載均衡的能力,而 Service 通過選擇一組 Pod 的 label 就直接可以訪問到 Pod,而且可以使用萬年不變的域名,所以就選擇 Service 了。
1、Service 是怎么產(chǎn)生的,在集群內(nèi)部是如何存在的呢?
在 kubernetes 當(dāng)中所謂的 Service 是 kube-proxy 生成 iptables 或 ipvs 規(guī)則,它會(huì)產(chǎn)生一組虛擬地址,在集群環(huán)境下有效。Service 不能直接到達(dá) Pod 內(nèi)部,中間會(huì)間隔 EndPoints,這是一組 ip 和 port 的組合。默認(rèn)類型是 ClusterIP 它僅能接收集群中 pod 客戶端程序的訪問請求。這也是最常用的一種類型,另外還有 NodePort、LoadBalancer、ExternalName。
2、iptables 或 ipvs,到底是 iptables 還是 ipvs 呢?
一個(gè) Service 對象就是工作節(jié)點(diǎn)上的一些 iptables 或 ipvs 規(guī)則,用于將到達(dá) Service 對象 IP 地址的流量調(diào)度轉(zhuǎn)發(fā)至相應(yīng)的 Endpoints 對象指向的 IP 地址和端口之上。
這句話我們經(jīng)常看到,如何理解呢?
Kubernetes1.1 之前是基于 userspace 實(shí)現(xiàn),這種模型之下,每次請求流量要先到達(dá)內(nèi)核空間,經(jīng)有套接字轉(zhuǎn)發(fā)到 kube-proxy,然后再由它送回到內(nèi)核空間,之后調(diào)度到后端 pod 之上,可以看出請求在用戶空間和內(nèi)核空間來回轉(zhuǎn)發(fā),效率必然不高。但是當(dāng) pod 無響應(yīng)時(shí),能夠自動(dòng)重定向到其它 pod。
在 Kubernetes1.1 版本開始引入 iptables 規(guī)則,Kubernetes1.2 開始成為默認(rèn)類型。即在創(chuàng)建 Service 資源時(shí),集群上每個(gè)節(jié)點(diǎn)的 kube-proxy 都會(huì)收到通知,并且創(chuàng)建 iptables 規(guī)則,用于轉(zhuǎn)發(fā)到此 Service ClusterIP 的流量。工作 TCP/IP 的傳輸層,高效穩(wěn)定。
但是這種方式有如下缺點(diǎn):1、iptables 代理模型挑中的 pod 無響應(yīng)時(shí),不能自動(dòng)重定向到集群內(nèi)部其它 pod 資源對象之上。
2、kube-proxy 通過 iptables 處理 Service 和 pod 的交互,每產(chǎn)生一個(gè)計(jì)算節(jié)點(diǎn)或者產(chǎn)生大量的 pod 就需要產(chǎn)生相應(yīng)大量的 iptables 規(guī)則,不難想象,這些 iptables 規(guī)則每次需要刷新匹配保證正確性,就需要占用大量的 CPU 資源,所以基于 iptables 的 Service 實(shí)現(xiàn)就成了制約 Kubernetes 承載更多 pod 的瓶頸。
在 Kubernetes1.11 開始默認(rèn)使用 ipvs 模型,在這種模型下 kube-proxy 會(huì)跟蹤 APIServer 上 Service 和 endpoints 對象變化,調(diào)用 netlink 創(chuàng)建 ipvs 規(guī)則,請求調(diào)度流量功能由 ipvs 實(shí)現(xiàn),運(yùn)行于 netfilter 之上的鉤子函數(shù),具有流量轉(zhuǎn)發(fā)速度快,規(guī)則性能同步好的特點(diǎn),支持眾多調(diào)度算法,剩下仍然由 iptables 完成。說到這里我們就大概明白了 iptables 和 ipvs 的作用和關(guān)系了。
3、Kubernetes 的服務(wù)發(fā)現(xiàn)是通過 dns 實(shí)現(xiàn),那么為什么會(huì)出現(xiàn)四種類型的服務(wù)暴露方式呢?
說到 Service 不得不介紹 kubernetes 網(wǎng)絡(luò)模型和通信方式
一個(gè)完整的 Kubernetes 集群應(yīng)該包含三層網(wǎng)絡(luò),首先第一層是 mater 和 node 節(jié)點(diǎn)之間的網(wǎng)絡(luò),這個(gè)網(wǎng)絡(luò)需要在部署 kubernetes 集群之前配置完成;第二層網(wǎng)絡(luò)是 pod 的網(wǎng)絡(luò)通過 kubelet 或者 cni 插件實(shí)現(xiàn),用于 pod 之間或者內(nèi)部的通信,集群中的所有 pod 均處在同一個(gè)網(wǎng)絡(luò)平面空間內(nèi),可以直接通信;第三層網(wǎng)絡(luò)是 Service 資源的網(wǎng)絡(luò),是一個(gè)虛擬網(wǎng)絡(luò),用于為 Kubernetes 集群配置 IP 地址,但此地址并不配置于任何主機(jī)或者容器的網(wǎng)絡(luò)接口之上,而是通過 kubeproxy 配置為 iptables 規(guī)則,將發(fā)往該地址的所有流量調(diào)度至后端的 pod 之上。
通信方式分為以下四種:
同一個(gè) pod 的內(nèi)部通信;
各個(gè) pod 彼此通信;
pod 和 service 的通信;
集群外部流向 service 的通信。
所以 Service 為了滿足這些通信方式就出現(xiàn)了如下類型:ClusterIP:為集群內(nèi)部 ip 地址暴露服務(wù),僅在集群內(nèi)可達(dá),外部 ip 無法訪問,默認(rèn) Service 類型;
NodePort:這種類型建立在 clusterIp 之上,為節(jié)點(diǎn)的 IP 地址暴 NodePort 服務(wù),外部節(jié)點(diǎn)可以通過 NodeIP:NodePort 直接訪問;
LoadBalancer:這種類型構(gòu)建在 NodePort 之上,它可以關(guān)聯(lián)到集群外部的某個(gè)負(fù)載均衡設(shè)備。Kubernetes 沒有為私有化集群提供 LoadBalancer 的支持。如果在私有化集群使用需要自建負(fù)載均衡器;
ExternalName:其通過將 Service 映射至由 externalName 字段的內(nèi)容指定的主機(jī)名來暴露服務(wù),此主機(jī)名需要被 DNS 服務(wù)解析至 CNAME 類型的記錄。這句話怎么理解呢?
舉個(gè)例子,你所有的服務(wù)都在集群內(nèi)部,但是你有個(gè)數(shù)據(jù)庫是 mongodb,沒有實(shí)現(xiàn)容器化,更沒有部署在 Kubernetes 內(nèi)部,當(dāng)然你可以通過在 ConfigMap 中添加配置訪問這個(gè)外部服務(wù),但是當(dāng)你的環(huán)境發(fā)生變化,比如從開發(fā)環(huán)境和生產(chǎn)環(huán)境的數(shù)據(jù)地址不同,這個(gè)時(shí)候你需要修改和重建 ConfigMap。這個(gè)時(shí)候可以使用 Kubernetes ExternalName 內(nèi)置服務(wù)發(fā)現(xiàn)機(jī)制運(yùn)用于集群外部運(yùn)行的服務(wù),像使用集群內(nèi)的服務(wù)一樣使用外部服務(wù)!通過這種方式,您可以在開發(fā)環(huán)境和生產(chǎn)環(huán)境中實(shí)現(xiàn)相同的功能,如果您最終將服務(wù)移入集群內(nèi),則不需要更改任何代碼和配置。
kind: ServiceapiVersion: v1metadata: name: mongospec: type: ExternalName externalName: mango123456.com
你只需要訪問:mongodb:// dbuser : dbpassword @mongo: port 就可以自動(dòng)訪問外部服務(wù)。
4、Service 本身有端口、Pod 也有端口、容器也有端口,之間有什么關(guān)系呢?
containerPort:一個(gè)信息性數(shù)據(jù),為集群提供一個(gè)可以快速了解相關(guān) pod 可以訪問端口的途徑,而且顯式指定容器端口,無論你是否指定都不影響其他節(jié)點(diǎn)上的客戶端 pod 對其進(jìn)行訪問;
port:服務(wù)提供端口,用于 kubernetes 集群內(nèi)部服務(wù)訪問;
targetPort:pod 目標(biāo)端口,如果不設(shè)置使用默認(rèn) port 端口,port 和 nodePort 的數(shù)據(jù)通過這個(gè)端口進(jìn)入到 Pod 內(nèi)部,Pod 里面的 containers 的端口映射到這個(gè)端口,提供服務(wù);
nodePort:Kubernetes 集群外部用戶訪問端口;
關(guān)于 Kubernetes 里的 Service 究竟是如何工作的就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。