日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

目錄
  • k8s 中的 service 如何找到綁定的 Pod 以及如何實現 Pod 負載均衡
    • 前言
    • endpoint
    • kube-proxy
    • userspace 模式
    • iptables
    • ipvs
    • kernelspace
    • 服務發現
    • 環境變量
    • DNS
    • 總結
    • 參考

k8s 中的 service 如何找到綁定的 Pod 以及如何實現 Pod 負載均衡

前言

Service 資源主要用于為 Pod 對象提供一個固定、統一的訪問接口及負載均衡的能力。

service 是一組具有相同 label pod 集合的抽象,集群內外的各個服務可以通過 service 進行互相通信。

當創建一個 service 對象時也會對應創建一個 endpoint 對象,endpoint 是用來做容器發現的,service 只是將多個 pod 進行關聯,實際的路由轉發都是由 kubernetes 中的 kube-proxy 組件來實現,因此,service 必須結合 kube-proxy 使用,kube-proxy 組件可以運行在 kubernetes 集群中的每一個節點上也可以只運行在單獨的幾個節點上,其會根據 service 和 endpoints 的變動來改變節點上 iptables 或者 ipvs 中保存的路由規則。

endpoint

endpoint 是 k8s 集群中的一個資源對象,存儲在 etcd 中,用來記錄一個 service 對應的所有 pod 的訪問地址。

service 通過 selector 和 pod 建立關聯。k8s 會根據 service 關聯到 pod 的 podIP 信息組合成一個 endpoint。

如果 service 沒有 selector 字段,當一個 service 被創建的時候,endpoint controller 不會自動創建 endpoint。

$ kubectl get svc -n study-k8s
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
go-web-svc   ClusterIP   10.233.55.112   <none>        8000/TCP   9d

$ kubectl get endpoints -n study-k8s
NAME         ENDPOINTS                                                                AGE
go-web-svc   10.233.111.171:8000,10.233.111.172:8000,10.233.72.153:8000 + 2 more...   9d

栗如

上面的 service go-web-svc,就有一個對應的 endpoint,ENDPOINTS 里面展示的就是 service 關聯的 pod 的 ip 地址和端口。

其中 endpoint controller 負載維護 endpoint 對象,主要的功能有下面幾種

1、負責生成和維護所有endpoint對象的控制器;

2、負責監聽 service 和對應 pod 的變化;

3、監聽到 service 被刪除,則刪除和該 service 同名的 endpoint 對象;

4、監聽到新的 service 被創建,則根據新建 service 信息獲取相關 pod 列表,然后創建對應 endpoint 對象;

5、監聽到 service 被更新,則根據更新后的 service 信息獲取相關 pod 列表,然后更新對應 endpoint 對象;

6、監聽到 pod 事件,則更新對應的 service 的 endpoint 對象,將 podIp 記錄到 endpoint中;

kube-proxy

kube-proxy 是 Kubernetes 的核心組件,部署在每個 Node 節點上,它是實現 Kubernetes Service 的通信與負載均衡機制的重要組件; kube-proxy 負責為 Pod 創建代理服務,從 apiserver 獲取所有 server 信息,并根據 server 信息創建代理服務,實現server到Pod的請求路由和轉發,從而實現K8s層級的虛擬轉發網絡。

在 k8s 中提供相同服務的一組 pod 可以抽象成一個 service,通過 service 提供統一的服務對外提供服務,kube-proxy 存在于各個 node 節點上,負責為 service 提供 cluster 內部的服務發現和負載均衡,負責 Pod 的網絡代理,它會定時從 etcd 中獲取 service 信息來做相應的策略,維護網絡規則和四層負載均衡工作。k8s 中集群內部的負載均衡就是由 kube-proxy 實現的,它是 k8s 中內部的負載均衡器,也是一個分布式代理服務器,可以在每個節點中部署一個,部署的節點越多,提供負載均衡能力的 Kube-proxy 就越多,高可用節點就越多。

簡單點講就是 k8s 內部的 pod 要訪問 service ,kube-proxy 會將請求轉發到 service 所代表的一個具體 pod,也就是 service 關聯的 Pod。

同理對于外部訪問 service 的請求,不論是 Cluster IP+TargetPort 的方式;還是用 Node 節點 IP+NodePort 的方式,都被 Node 節點的 Iptables 規則重定向到 Kube-proxy 監聽 Service 服務代理端口。kube-proxy 接收到 Service 的訪問請求后,根據負載策略,轉發到后端的 Pod。

kube-proxy 的路由轉發規則是通過其后端的代理模塊實現的,其中 kube-proxy 的代理模塊目前有四種實現方案,userspace、iptables、ipvs、kernelspace 。

userspace 模式

userspace 模式在 k8s v1.2 后就已經被淘汰了,userspace 的作用就是在 proxy 的用戶空間監聽一個端口,所有的 svc 都轉到這個端口,然后 proxy 內部應用層對其進行轉發。proxy 會為每一個 svc 隨機監聽一個端口,并增加一個 iptables 規則。

從客戶端到 ClusterIP:Port 的報文都會通過 iptables 規則被重定向到 Proxy Port,Kube-Proxy 收到報文后,然后分發給對應的 Pod。

k8s 中的 service 如何找到綁定的 Pod 及實現 Pod 負載均衡的方法

userspace 模式下,流量的轉發主要是在用戶空間下完成的,上面提到了客戶端的請求需要借助于 iptables 規則找到對應的 Proxy Port,因為 iptables 是在內核空間,這里就會請求就會有一次從用戶態到內核態再返回到用戶態的傳遞過程, 一定程度降低了服務性能。所以就會認為這種方式會有一定的性能損耗。

默認情況下,用戶空間模式下的 kube-proxy 通過輪轉算法選擇后端。

iptables

首先來簡單了解下 iptables:

iptables 是 Linux 中最常用的一種防火墻工具,除了防火墻它還可以用作 IP 轉發和簡單的負載均衡功能?;?Linux 中的 netfilter 內核模塊實現。 Netfilter 在協議中添加了一些鉤子,它允許內核模塊通過這些鉤子注冊回調函數,這樣經過鉤子的所有數據都會被注冊在響應鉤子上的函數處理,包括修改數據包內容、給數據包打標記或者丟掉數據包等。iptables 是運行在用戶態的一個程序,通過 netlink 和內核的 netfilter 框架打交道,具有足夠的靈活性來處理各種常見的數據包操作和過濾需求。它允許將靈活的規則序列附加到內核的數據包處理管道中的各種鉤子上。

Netfilter 是 Linux 2.4.x 引入的一個子系統,它作為一個通用的、抽象的框架,提供一整套的 hook 函數的管理機制,使得諸如數據包過濾、網絡地址轉換(NAT)和基于協議類型的連接跟蹤成為了可能。

在 kubernetes v1.2 之后 iptables 成為默認代理模式,這種模式下,kube-proxy 會監視 Kubernetes master 對 Service 對象和 Endpoints 對象的添加和移除。 對每個 Service,它會安裝 iptables 規則,從而捕獲到達該 Service 的 clusterIP(虛擬 IP)和端口的請求,進而將請求重定向到 Service 的一組 backend 中的某個上面。因為流量轉發都是在內核進行的,所以性能更高更加可靠。

k8s 中的 service 如何找到綁定的 Pod 及實現 Pod 負載均衡的方法

可以看到該模式下 iptables 來做用戶態的入口,kube-proxy 只是持續監聽 Service 以及 Endpoints 對象的變化, iptables 通過設置的轉發策略,直接將對 VIP 的請求轉發給后端 Pod,iptables 使用 DNAT 來完成轉發,其采用了隨機數實現負載均衡。

如果 kube-proxy 在 iptables 模式下運行,并且所選的第一個 Pod 沒有響應,則連接失敗。 這與用戶空間模式不同:在這種情況下,kube-proxy 將檢測到與第一個 Pod 的連接已失敗, 并會自動使用其他后端 Pod 重試。

該模式相比 userspace 模式,克服了請求在用戶態-內核態反復傳遞的問題,性能上有所提升,但使用 iptables NAT 來完成轉發,存在不可忽視的性能損耗,iptables 模式最主要的問題是在 service 數量大的時候會產生太多的 iptables 規則,使用非增量式更新會引入一定的時延,大規模情況下有明顯的性能問題。

ipvs

當集群的規模比較大時,iptables 規則刷新就會很慢,難以支撐大規模的集群。因為 iptables 的底層實現是鏈表,對路由規則的增刪查改都需要遍歷一次鏈表。

在 kubernetes v1.2 之后 ipvs 成為kube-proxy的默認代理模式。ipvs 正是解決這一問題的,ipvs 是 LVS 的負載均衡模塊,與 iptables 比較像的是,ipvs 的實現雖然也基于 netfilter 的鉤子函數,但是它卻使用哈希表作為底層的數據結構并且工作在內核態,也就是說 ipvs 在重定向流量和同步代理規則有著更好的性能,幾乎允許無限的規模擴張。

k8s 中的 service 如何找到綁定的 Pod 及實現 Pod 負載均衡的方法

ipvs 支持三種負載均衡模式:

1、DR模式(Direct Routing);

2、NAT 模式(Network Address Translation);

3、Tunneling(也稱 ipip 模式)。

三種模式中只有 NAT 支持端口映射,所以 ipvs 使用 NAT 模式。linux 內核原生的 ipvs 只支持 DNAT,當在數據包過濾,SNAT 和支持 NodePort 類型的服務這幾個場景中ipvs 還是會使用 iptables。

ipvs 也支持更多的負載均衡算法:

  • rr:round-robin/輪詢;

  • lc:least connection/最少連接;

  • dh:destination hashing/目標哈希;

  • sh:source hashing/源哈希;

  • sed:shortest expected delay/預計延遲時間最短;

  • nq:never queue/從不排隊

kernelspace

kernelspace 模式是 windows 上的代理模式,這里不展開討論了

服務發現

service 的 endpoints 解決了容器發現問題,但是不提前知道 service 的 Cluster IP,就無法知道 service 服務了。Kubernetes 支持兩種基本的服務發現模式 —— 環境變量和 DNS。

環境變量

當一個 pod 創建完成之后,kubelet 會在該 pod 中注冊該集群已經創建的所有 service 相關的環境變量,但是需要注意的是,在 service 創建之前的所有 pod 是不會注冊該環境變量的,所以在平時使用時,建議通過 DNS 的方式進行 service 之間的服務發現。

舉個例子,一個名稱為 redis-primary 的 Service 暴露了 TCP 端口 6379, 同時給它分配了 Cluster IP 地址 10.0.0.11,這個 Service 生成了如下環境變量:

REDIS_PRIMARY_SERVICE_HOST=10.0.0.11
REDIS_PRIMARY_SERVICE_PORT=6379
REDIS_PRIMARY_PORT=tcp://10.0.0.11:6379
REDIS_PRIMARY_PORT_6379_TCP=tcp://10.0.0.11:6379
REDIS_PRIMARY_PORT_6379_TCP_PROTO=tcp
REDIS_PRIMARY_PORT_6379_TCP_PORT=6379
REDIS_PRIMARY_PORT_6379_TCP_ADDR=10.0.0.11

DNS

可以在集群中部署 CoreDNS 服務(舊版本的 kubernetes 群使用的是 kubeDNS), 來達到集群內部的 pod 通過DNS 的方式進行集群內部各個服務之間的通訊。

當前 kubernetes 集群默認使用 CoreDNS 作為默認的 DNS 服務,主要原因是 CoreDNS 是基于 Plugin 的方式進行擴展的,簡單,靈活,并且不完全被Kubernetes所捆綁。

同時 k8s 中也建議使用 DNS 來做服務發現。

Kubernetes DNS 服務器是唯一的一種能夠訪問 ExternalName 類型的 Service 的方式。

總結

k8s 中一般使用 Service 為 Pod 對象提供一個固定、統一的訪問接口及負載均衡的能力;

k8s 中的負載均衡主要借助于 endpoint 和 kube-proxy 來實現;

endpoint 是 k8s 集群中的一個資源對象,存儲在 etcd 中,用來記錄一個 service 對應的所有 pod 的訪問地址,當一個 service 關聯的 pod 被刪除,更新,新增,對應的 endpoint 資源都會更新;

kube-proxy 是 Kubernetes 的核心組件,部署在每個 Node 節點上,它是實現 Kubernetes Service 的通信與負載均衡機制的重要組件; kube-proxy 負責為 Pod 創建代理服務,從 apiserver 獲取所有 server 信息,并根據 server 信息創建代理服務,實現server到Pod的請求路由和轉發,從而實現K8s層級的虛擬轉發網絡;

kube-proxy 的路由轉發規則是通過其后端的代理模塊實現的,其中 kube-proxy 的代理模塊目前有四種實現方案,userspace、iptables、ipvs、kernelspace ;

service 的 endpoints 和 kube-proxy 解決了容器的發現和負載均衡的問題,但是 service 服務如何被內部的服務找到呢,Kubernetes 支持兩種基本的服務發現模式 —— 環境變量和 DNS;

其中 k8s 中推薦使用 DNS 來做 service 的服務發現,當前 kubernetes 集群默認使用 CoreDNS 作為默認的 DNS 服務,主要原因是 CoreDNS 是基于 Plugin 的方式進行擴展的,簡單,靈活,并且不完全被Kubernetes所捆綁。

參考

【kubernetes service 原理解析】https://zhuanlan.zhihu.com/p/111244353

【service selector】https://blog.csdn.net/luanpeng825485697/article/details/84296765

【一文看懂 Kube-proxy】https://zhuanlan.zhihu.com/p/337806843

【Kubernetes 【網絡組件】kube-proxy使用詳解】https://blog.csdn.net/xixihahalelehehe/article/details/115370095

【Service】https://jimmysong.io/kubernetes-handbook/concepts/service.html

【Service】https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/

【k8s 中的 service 如何找到綁定的 Pod 以及如何實現 Pod 負載均衡】https://boilingfrog.github.io/2022/10/16/k8s中的service如何找到綁定的Pod以及如何實現Pod負載均衡/

分享到:
標簽:找到 方法 服務器 綁定 負載均衡
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定