天天看點

kube-proxy的功能

kube-proxy的功能說明

Kube-proxy的功能

我們知道POD的IP是動态配置設定的而且經常會變,是以為了可以通過一個不太容易變化的IP通路POD就會使用一個叫做service的東西,通過标簽選擇器和POD進行關聯。

Service提供常用的類型有:

  • ClusterIP,也是預設方式。Service會配置設定一個叢集内部的固定虛拟IP,實作叢集内通過該IP來對POD進行通路。這個又有兩類,上面說到的最普通的Service,ClusterIP還有一種是Headless Service,這種形式不會配置設定IP也不會通過kube-proxy做反向代理或者負載均衡,而是通過DNS提供穩定的網絡ID來通路,DNS會将headless service的後端直接解析為POD的IP清單,這種主要是共StatefulSet類型使用。
  • NodePort,這種類型的Service是除了使用ClusterIP的功能外還會映射一個主控端随機端口到service上,這樣叢集外部可以通過主控端IP+随機端口來通路。
  • LoadBalancer:和nodePort類似,不過除了使用ClusterIP和NodePort之外還會向使用的公有雲申請一個負載均衡器,進而實作叢集外部通過LB來通路服務
  • ExternalName:是Service的一種特例,此模式主要面對運作在叢集外部的服務,通過它可以将外部服務映射到k8s叢集,具備k8s内服務的一些特性,來為叢集内部提供服務。

我們要說一下ClusterIP這個東西,這是通過yaml安裝的一個coredns插件,它就的配置清單中就定義了service。

kube-proxy的功能

這個servic ip位址段是在部署API SERVER時API SERVER服務啟動配置檔案中定義的位址段。而且在Flannel中都沒有這個位址段。相比之下POD的IP其實是實實在在配置在容器中的,最終要的是叢集中任何節點上都沒有關于這個網段的路由資訊,那麼叢集内部是如何通過這個完全虛拟的IP來通路的呢?這就要說到kube-proxy了

kube-proxy的功能

你看在叢集的任何機器上都可以PING通這個位址。我們來看看這個svc的詳情

kube-proxy的功能

這個10.254.0.2 serviceIP關聯了Endpoints(這裡是2個endpoints因為POD開放了TCP和UDP的53号端口,是以是2個)。那麼現在就有了一個大緻的認識就是你通路10.254.0.2就是通路172.30.23.2,而這個172的IP就是POD的真實IP,這個IP段是在Flannel上配置過的。下面再來看一張圖:

kube-proxy的功能

在IPVS規則中定義了通路10.254.0.2就會轉發到172.30.23.2,而172.30.23.2就是POD的IP。

是以通過上面我們就知道它其實是通過IPVS規則來轉發的根本不是通過路由來實作的。可是你想過沒有這個規則是誰生成的呢?其實就是kube-proxy來生成的,而且這樣的規則會同步到叢集其他機器上,哪怕這個POD沒有運作在自己的機器上也要有這樣的規則,隻有這樣才能保證叢集任何一台主機都可以通過這個serviceIP來通路到POD,當面臨跨主機的時候才會用到路由規則,由Flannel的隧道來進行轉發到真實POD所在主機,然後由該主機的kube-proxy來轉發到具體的POD上。

這時候我們就明白了kube-proxy的大緻作用,當service有了IP、端口以及POD的IP和端口對應關系以及主控端随機端口到service的映射,就可以完成對内、外請求的轉發,而轉發就是,本地轉發還是用IPVS規則,而遠端則用了路由資訊。

叢集中每個NODE都運作一個kube-proxy程序,這個就是service的載體。它負責建立和删除包括更新IPVS規則、通知API SERVER自己的更新,或者從API SERVER哪裡擷取其他kube-proxy的IPVS規則變化來更新自己的。我們說了多次IPVS,其實kube-proxy支援3中模式

Userspace模式

userspace,這種模式時最早的,不過已經不推薦使用了,效率低,因為需要在核心空間和使用者空間轉換。

Iptables模式

kube-proxy的功能

這是預設方案,在核心中通過iptables的NAT實作本地轉發和負載均衡。在大規模試用下存在性能問題。

Ipvs模式

kube-proxy的功能

可選方案,如果核心支援且使用者指定那麼kube-proxy将使用這種模式。在早期版本的K8S中不支援。

如果POD不在本機怎麼辦

kube-proxy的功能

本機是srv01而這個coredns是運作在srv02上,你從srv01通路會先進行ipvs找到目标POD的IP位址,發現不在本機就通過路由,通路的網段172.30.23.0走flannel.1這個網絡接口,這個接口其實和其他主機的flannel.1通過實體鍊路做了隧道,是以就可以通。那麼10.254.0.2是如何與這個172.30.23.2這個IP建立關系的呢?其實就是service,看下圖

kube-proxy的功能

繼續閱讀