天天看點

Kubernetes中kube-proxy三種工作模式詳解

作者:全棧行動派

1、概述

在kubernetes中,pod是應用程式的載體,我們可以通過pod的ip來通路應用程式,但是pod的ip位址不是固定的,這也就意味着不友善直接采用pod的ip對服務進行通路。

為了解決這個問題,kubernetes提供了Service資源,Service會對提供同一個服務的多個pod進行聚合,并且提供一個統一的入口位址。通過通路Service的入口位址就能通路到後面的pod服務。

Kubernetes中kube-proxy三種工作模式詳解

Service在很多情況下隻是一個概念,真正起作用的其實是kube-proxy服務程序,每個Node節點上都運作着一個kube-proxy服務程序。當建立Service的時候會通過api-server向etcd寫入建立的service的資訊,而kube-proxy會基于監聽的機制發現這種Service的變動,然後它會将最新的Service資訊轉換成對應的通路規則。

Kubernetes中kube-proxy三種工作模式詳解

2、kube-proxy三種工作模式

2.1、userspace 模式

這種(遺留)模式使用 iptables 添加攔截規則,然後使用 kube-proxy 工具執行流量轉發。 kube-proxy 監視 Kubernetes 控制平面對 Service 和 EndpointSlice 對象的增加、修改和删除。 對于每個 Service,kube-proxy 在本地節點上打開一個端口(随機選擇)。 任何對這個代理端口的連接配接都将代理到 Service 的一個後端 Pod(通過 EndpointSlices 報告)。 kube-proxy 在決定使用哪個後端 Pod 時會考慮 Service 的 sessionAffinity 設定。

使用者空間代理添加 iptables 規則,這些規則捕獲流向 Service 的 clusterIP(虛拟 IP)和 port 的流量。 這些規則将這些流量重定向到代理後端 Pod 的代理端口。

預設情況下,使用者空間模式下的 kube-proxy 通過輪詢算法選擇後端。

Kubernetes中kube-proxy三種工作模式詳解

2.2、iptables 模式

iptables模式下,kube-proxy為service後端的每個Pod建立對應的iptables規則,直接将發向Cluster IP的請求重定向到一個Pod IP。 該模式下kube-proxy不承擔四層負責均衡器的角色,隻負責建立iptables規則。該模式的優點是較userspace模式效率更高,但不能提供靈活的LB政策,當後端Pod不可用時也無法進行重試。

Kubernetes中kube-proxy三種工作模式詳解

2.3、ipvs 模式

ipvs模式和iptables類似,kube-proxy監控Pod的變化并建立相應的ipvs規則。ipvs相對iptables轉發效率更高。除此以外,IPVS 為将流量均衡到後端 Pod 提供了更多選擇。

IPSV 支援LB算法如下:

  • rr:輪詢 預設是這個
  • lc:最少連接配接(打開連接配接數最少)
  • dh:目标位址哈希
  • sh:源位址哈希
  • sed:最短預期延遲
  • nq:最少隊列
Kubernetes中kube-proxy三種工作模式詳解

說明:

要在 IPVS 模式下運作 kube-proxy,必須在啟動 kube-proxy 之前確定節點上的 IPVS 可用。

當 kube-proxy 以 IPVS 代理模式啟動時,它會驗證 IPVS 核心子產品是否可用。 如果未檢測到 IPVS 核心子產品,則 kube-proxy 會退回到 iptables 代理模式運作。

3、更改kube-proxy工作模式

因為kube-proxy 的配置是通過 ConfigMap 完成的,是以我們隻需要更改 name=kube-proxy 的 ConfigmMap 然後删除 所有 擁有标簽k8s-app=kube-proxy(更改後不會立即生效,需要删除後,自動重建pod)的pod,即可生效。當然針對每種工作模式,是有前提要求的,咱們以ipvs為例講解。

3.1、更改ConigMap

# 在kube-system命名空間中查找 name=kube-proxy 的 ConfigMap(cm)
[root@k8s-master ~]# kubectl get cm -n kube-system
NAME                                 DATA   AGE
calico-config                        4      12d
coredns                              1      12d
extension-apiserver-authentication   6      12d
kube-proxy                           2      12d
kube-root-ca.crt                     1      12d
kubeadm-config                       1      12d
kubelet-config                       1      12d


# 編輯 大概47行 修改 mode=ipvs 儲存
[root@k8s-master ~]# kubectl edit cm kube-proxy -n kube-system
configmap/kube-proxy edited           
Kubernetes中kube-proxy三種工作模式詳解

3.2、删除kube-system

由于更改了配置檔案不會立即生效,将所有kube-system pod删除,k8s會立即建立kube-system pod這個時候新的配置即可生效

#檢視 kube-system 命名空間下所有的 pod 可發現 3個以“kube-proxy-” 為字首的pod,是因為我本地隻有3個k8s節點,這三個節點都有相同的label叫“k8s-app=kube-proxy” 那咱們通過label删除即可全部删除
[root@k8s-master ~]# kubectl get pod -n kube-system --show-labels
NAME                                       READY   STATUS    RESTARTS   AGE    LABELS
calico-kube-controllers-59697b644f-bqhsg   1/1     Running   0          12d    k8s-app=calico-kube-controllers,pod-template-hash=59697b644f
calico-node-6x9rq                          1/1     Running   0          12d    controller-revision-hash=55f6f6844b,k8s-app=calico-node,pod-template-generation=1
calico-node-9npwl                          1/1     Running   0          12d    controller-revision-hash=55f6f6844b,k8s-app=calico-node,pod-template-generation=1
calico-node-s9g7k                          1/1     Running   0          12d    controller-revision-hash=55f6f6844b,k8s-app=calico-node,pod-template-generation=1
coredns-c676cc86f-n4nj8                    1/1     Running   0          12d    k8s-app=kube-dns,pod-template-hash=c676cc86f
coredns-c676cc86f-rhvwg                    1/1     Running   0          12d    k8s-app=kube-dns,pod-template-hash=c676cc86f
etcd-k8s-master                            1/1     Running   0          12d    component=etcd,tier=control-plane
kube-apiserver-k8s-master                  1/1     Running   0          12d    component=kube-apiserver,tier=control-plane
kube-controller-manager-k8s-master         1/1     Running   0          12d    component=kube-controller-manager,tier=control-plane
kube-proxy-2jk2g                           1/1     Running   0          16m    controller-revision-hash=dd4c999cf,k8s-app=kube-proxy,pod-template-generation=1
kube-proxy-h5tgq                           1/1     Running   0          16m    controller-revision-hash=dd4c999cf,k8s-app=kube-proxy,pod-template-generation=1
kube-proxy-nbmv2                           1/1     Running   0          16m    controller-revision-hash=dd4c999cf,k8s-app=kube-proxy,pod-template-generation=1
kube-scheduler-k8s-master                  1/1     Running   0          12d    component=kube-scheduler,tier=control-plane
metrics-server-f68c598fc-vt4pz             1/1     Running   0          2d2h   k8s-app=metrics-server,pod-template-hash=f68c598fc


# 通過label 删除所有kube-proxy pod
[root@k8s-master ~]# kubectl delete pod -l k8s-app=kube-proxy -n kube-system
pod "kube-proxy-2jk2g" deleted
pod "kube-proxy-h5tgq" deleted
pod "kube-proxy-nbmv2" deleted
[root@k8s-master ~]#

# 再次檢視 發現 kube-proxy pod已建立
[root@k8s-master ~]# kubectl get pod -n kube-system --show-labels
NAME                                       READY   STATUS    RESTARTS   AGE    LABELS
calico-kube-controllers-59697b644f-bqhsg   1/1     Running   0          12d    k8s-app=calico-kube-controllers,pod-template-hash=59697b644f
calico-node-6x9rq                          1/1     Running   0          12d    controller-revision-hash=55f6f6844b,k8s-app=calico-node,pod-template-generation=1
calico-node-9npwl                          1/1     Running   0          12d    controller-revision-hash=55f6f6844b,k8s-app=calico-node,pod-template-generation=1
calico-node-s9g7k                          1/1     Running   0          12d    controller-revision-hash=55f6f6844b,k8s-app=calico-node,pod-template-generation=1
coredns-c676cc86f-n4nj8                    1/1     Running   0          12d    k8s-app=kube-dns,pod-template-hash=c676cc86f
coredns-c676cc86f-rhvwg                    1/1     Running   0          12d    k8s-app=kube-dns,pod-template-hash=c676cc86f
etcd-k8s-master                            1/1     Running   0          12d    component=etcd,tier=control-plane
kube-apiserver-k8s-master                  1/1     Running   0          12d    component=kube-apiserver,tier=control-plane
kube-controller-manager-k8s-master         1/1     Running   0          12d    component=kube-controller-manager,tier=control-plane
kube-proxy-57d4m                           1/1     Running   0          3s     controller-revision-hash=dd4c999cf,k8s-app=kube-proxy,pod-template-generation=1
kube-proxy-5zxrg                           1/1     Running   0          3s     controller-revision-hash=dd4c999cf,k8s-app=kube-proxy,pod-template-generation=1
kube-proxy-z2fpg                           1/1     Running   0          3s     controller-revision-hash=dd4c999cf,k8s-app=kube-proxy,pod-template-generation=1
kube-scheduler-k8s-master                  1/1     Running   0          12d    component=kube-scheduler,tier=control-plane
metrics-server-f68c598fc-vt4pz             1/1     Running   0          2d2h   k8s-app=metrics-server,pod-template-hash=f68c598fc           
Kubernetes中kube-proxy三種工作模式詳解

3.3、安裝ipvsadm

ipvsadm 是一個用戶端工具,可以讓我們和ipvs表的資料進行互動

# 在master 上安裝 即可
yum install -y ipvsadm           
Kubernetes中kube-proxy三種工作模式詳解

3.4、通過ipvsadm檢視流量轉發資訊

ipvsadm -Ln

Kubernetes中kube-proxy三種工作模式詳解

3.5、kube-proxy預設工作模式以及注意點

目前 Linux 平台上有三種可用的代理模式:'userspace'(相對較老,即将被淘汰)、 'iptables'(相對較新,速度較快)、'ipvs'(最新,在性能和可擴縮性上表現好)。

在 Windows 平台上有兩種可用的代理模式:'userspace'(相對較老,但穩定)和 'kernelspace'(相對較新,速度更快)。

在 Linux 平台上,如果代理的 mode 為空,則使用可用的最佳代理(目前是 iptables, 将來可能會發生變化)。如果選擇的是 iptables 代理(無論原因如何),但系統的核心 或者 iptables 的版本不夠高,kube-proxy 也會回退為 userspace 代理伺服器所使用的模式。 當代理的 mode 設定為 'ipvs' 時會啟用 IPVS 模式,對應的回退路徑是先嘗試 iptables, 最後回退到 userspace。

在 Windows 平台上,如果代理 mode 為空,則使用可用的最佳代理(目前是 userspace, 不過将來可能會發生變化)。如果所選擇的是 winkernel 代理(無論原因如何), 但 Windows 核心不支援此代理模式,則 kube-proxy 會回退到 userspace 代理。

ipvs模式需要啟動IPVS時依賴子產品:

ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack           
Kubernetes中kube-proxy三種工作模式詳解

可通過如下指令确定系統是否啟用了這些子產品

lsmod | grep -e ip_vs -e nf_conntrack           
Kubernetes中kube-proxy三種工作模式詳解

如果沒有啟用,通過如下指令啟用

modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack           
Kubernetes中kube-proxy三種工作模式詳解

繼續閱讀