k8的service和DNS服務發現機制


Service介紹

     Kubernetes 之所以需要 Service,一方面是因為 Pod的IP不是固定的,另一方面則是因為一組 Pod 實例之間總會有負載均衡的需求

     Service是由Kube-proxy組件加上iptables來共同實現的

     Service vip(vip 是k8s自動為Service分配的)到Pod的轉發

         iptables 對流入的IP包還設置了一個“標志”(–set-xmark)

         只有處於Running狀態,且readinessProbe檢查通過的Pod,才會出現在Service的Endpoints 列表里.並且,當某一個 Pod 出現問題時,Kubernetes會自動把它從Service里摘除掉

 

Service基本原理

       當用戶把一個service yaml文件提交給k8s后,kube-proxy組件通過Service的Informer感知到一個Service對象的添加,作為對這個事件的響應它就會在宿主機上創建一條iptables規則 可以通過iptables-save命令來查看

       Service的VIP地址只是一條iptables規則上的配置 並沒有真正的網絡設備 所以ping這個地址 是不會有任何響應的

       DNAT的作用,就是在PREROUTING檢查點之前,也就是在路由之前,將流入IP包的目的地址和端口,改成–to-destination指定的新目的地址和端口

      訪問Service VIP的IP包經過上述 iptables 處理之后,就已經變成了訪問具體某一個后端Pod的IP包了.

      不難理解,這些 Endpoints 對應的iptables規則,正是kube-proxy通過監聽Pod的變化事件,在宿主機上生成並維護的

     

iptables模式和ipvs模式  

     kube-proxy通過iptables處理Service 的過程,其實需要在宿主機上設置相當多的 iptables 規則 
     當你的宿主機上有大量Pod的時候,成百上千條iptables規則不斷地被刷新,會大量占用該宿主機的CPU資源
 
     IPVS 模式
       IPVS 模式的工作原理,其實跟iptables模式類似.當我們創建了前面的 Service 之后,kube-proxy首先會在宿主機上創建一個虛擬網卡(叫作:kube-ipvs0)並為它分配 Service VIP作為 IP 地址 
       

       kube-proxy就會通過Linux的IPVS 模塊,為這個IP地址設置三個IPVS 虛擬主機,並設置這三個虛擬主機之間使用輪詢模式 (rr) 來作為負載均衡策略

     

    而相比於 iptables,IPVS 在內核中的實現其實也是基於 Netfilter的NAT模式,所以在轉發這一層上,理論上 IPVS 並沒有顯著的性能提升.但是IPVS 並不需要在宿主機上為每個Pod設置 iptables 規則,而是把對這些“規則”的處理放到了內核態,極大地降低了維護這些規則的代價
   不過需要注意的是,IPVS 模塊只負責上述的負載均衡和代理功能.而一個完整的 Service 流程正常工作所需要的包過濾,SNAT等操作,還是要靠iptables來實現.只不過,這些輔助性的 iptables 規則數量有限,也不會隨着Pod數量的增加而增加

 

Service和DNS的關系

        在kubernetes中,所有的Service和Pod都會被分配一條對應的DNS A記錄( 通過域名解析到IP地址的記錄 )

clusterIP Service的分配方式
     ClusterIP模式的Service 來說,它的 A 記錄的格式是:myservicename.mynamespace.svc.cluster.local 當你訪問這條 A 記錄的時候,它解析到的就是該Service的VIP 地址
Headliness Service的分配方式

     ClusterIP=None 的 Headless Service 來說,它的 A 記錄的格式也是:myservicename.mynamespace.svc.cluster.local 當你訪問這條A記錄的時候,它返回的是所有被代理的Pod的IP地址的集合.當然,如果你的客戶端沒辦法解析這個集合的話,它可能會只會拿到第一個Pod的IP地址

clusterIP Service被代理Pod的分配方式

     對於ClusterIP模式的Service來說,它代理的Pod被自動分配的A記錄的格式是:PodIP.mynamespace.pod.cluster.local  這條記錄指向Pod的IP地址

Headliness Service被代理Pod的分配方式
    1.對Headless Service 來說,它代理的Pod被自動分配的A記錄的格式是:mypodname.myservicename.mynamespace.svc.cluster.local 這條記錄也指向Pod的IP地址
    2. 如果Pod本身聲明了hostname和subdomain字段,那么這時候Pod的A記錄就會變成:  podhostname.mysubdomain.mynamespace.svc.cluster.local
 
    

 

    在上面這個Service和Pod被創建之后,你就可以通過busybox-1.default-subdomain.default.svc.cluster.local 解析到這個Pod的IP地址了

    在 Kubernetes 里,/etc/hosts 文件是單獨掛載的,這也是為什么kubelet能夠對hostname進行修改並且Pod 重建后依然有效的原因這跟 Docke的Init層是一個原理

用途

      ClusterIP模式的Service為你提供的,就是一個Pod的穩定的IP地址,即 VIP.  並且,這里Pod和Service 的關系是可以通過 Label 確定的 
      Headless Service 為你提供的,則是一個 Pod 的穩定的 DNS 名字,並且,這個名字是可以通過Pod名字和Service名字拼接出來 
      服務發現: 即當我的一個服務(Pod)的IP地址是不固定的且沒辦法提前獲知時,該如何通過一個固定的方式訪問到這個Pod 

        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM