service連通k8s外部


外界連通Service

        Service 的訪問信息在Kubernetes集群之外,其實是無效的 
        如何從外部(Kubernetes 集群之外),訪問到 Kubernetes 里創建的Service
方式1(NodePort)

        創建一個NodePort類型的service

        不顯式地聲明nodePort字段,Kubernetes就會為你分配隨機的可用端口來設置代理.這個端口的范圍默認是30000-32767

        ClusterIP模式的Service和NodePort類型的Service定義格式

        

       在NodePort 方式下,Kubernetes 會在 IP 包離開宿主機發往目的 Pod 時,對這個 IP 包做一次 SNAT 操作 .
       這條規則設置在 POSTROUTING 檢查點,也就是它給即將離開這台主機的 IP 包,進行了一次 SNAT 操作 .將這個IP包的源地址替換成了這台宿主機上的 CNI 網橋地址或者宿主機本身的 IP 地址(如果 CNI 網橋不存在的話) .當然,這個SNAT 操作只需要對 Service 轉發出來的 IP 包進行(否則普通的IP包就被影響了)而 iptables 做這個判斷的依據,就是查看該IP包是否有一個“0x4000”的“標志
      

    當一個外部的 client 通過 node 2 的地址訪問一個 Service 的時候,node 2 上的負載均衡規則,就可能把這個 IP 包轉發給一個在 node 1 上的 Pod.而當 node1上的這個Pod處理完請求之后,它就會按照這個IP包的源地址發出回復.可是,如果沒有做 SNAT 操作的話,這時候,被轉發來的IP包的源地址就是 client 的 IP 地址.所以此時Pod 就會直接將回復發給client.對於 client 來說,它的請求明明發給了node2,收到的回復卻來自node1 這個client很可能會報錯

    所以,在上圖中,當IP包離開node2之后,它的源IP地址就會被SNAT改成 node2的CNI網橋地址或者 node2自己的地址.這樣Pod 在處理完成之后就會先回復給node2(而不是 client)然后再由node2發送給client.這也就意味着這個Pod只知道該IP包來自於node2,而不是外部的 client

   如果Pod需要明確知道所有請求的來源情況   就必須把Service的spec.externalTrafficPolicy字段設置為local,這就保證了所有Pod通過Service收到請求之后,一定可以看到真正的,外部 client 的源地址

   這個機制的實現原理也非常簡單:這時候,一台宿主機上的iptables規則,會設置為只將IP包轉發給運行在這台宿主機上的 Pod.所以這時候Pod 就可以直接使用源地址將回復包發出,不需要事先進行 SNAT
     

     這就意味着如果在一台宿主機上,沒有任何一個被代理的Pod存在,比如上圖中的node2那么你使用node2 的IP地址訪問這個Service就是無效的.此時請求會直接被DROP掉

方式2(LoadBalancer)

       適合公有雲上的kubernetes的服務

      公有雲提供的Kubernetes服務里,都使用了一個叫作CloudProvider的轉接層,來跟公有雲本身的API進行對接.所以,在上述LoadBalancer類型的Service被提交后Kubernetes 就會調用CloudProvider在公有雲上為你創建一個負載均衡服務,並且把被代理的Pod的IP地址配置給負載均衡服務做后端

       創建負載均衡的功能交給集群外部的系統來實現 這是和普通service的區別 普通service負載均衡的功能都是由集群內部的組件來實現的

     

 方式3(ExternalName)

     

     這種類型的Service不需要指定selector 因為響應請求的不會是集群中的Pod,而是把用戶請求轉發到公網中(集群外部)的某個服務器上由它進行響應

     通過Service的DNS名字訪問它的時候如訪問my-service.default.svc.cluster.local.那么k8s返回的就是 my.database.example.com
    ExternalName類型的 Service,其實是在 kube-dns里為你添加了一條CNAME記錄.這時,訪問my-service.default.svc.cluster.local 就和訪問  my.database.example.com 這個域名是一個效果了 
 方式4(ExternalIPs)

       Kubernetes的Service還允許你為Service分配公有IP地址

       當用戶向公網(集群外的節點)中的指定的主機和端口發起請求的時候 會把請求轉發到k8s由集群中的Pod對用戶的請求進行響應 所以定義有selector選擇相關Pod

     

    在上述 Service 中,我為它指定的 externalIPs= 80.11.12.10那么此時,你就可以通過訪問  80.11.12.10:80 訪問到被代理的Pod了.不過,在這里Kubernetes要求externalIP必須是至少能夠路由到一個Kubernetes的節點 
 

Service總結

       在理解了Kubernetes Service 機制的工作原理之后很多與Service相關的問題,其實都可以通過分析Service在宿主機上對應的 iptables 規則(或者IPVS配置)得到解決
       Kubernetes里面的Service和DNS 機制,也都不具備強多租戶能力.比如,在多租戶情況下,每個租戶應該擁有一套獨立的 Service 規則(Service 只應該看到和代理同一個租戶下的 Pod)再比如DNS,在多租戶情況下,每個租戶應該擁有自己的kube-dns(kube-dns 只應該為同一個租戶下的 Service 和 Pod 創建 DNS Entry)


免責聲明!

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



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