精品国产一级在线观看,国产成人综合久久精品亚洲,免费一级欧美大片在线观看

當前位置:新聞中心行業動態 → 正文

擁抱云原生,UCloud優刻得基于eBPF技術實現Serverless節點訪問K8S Service

責任編輯:cres |來源:企業網D1Net  2021-04-07 15:19:01 本文摘自:互聯網

Serverless容器的服務發現

2020年9月,UCloud 優刻得上線了Serverless容器產品Cube,它具備了虛擬機級別的安全隔離、輕量化的系統占用、秒級的啟動速度,高度自動化的彈性伸縮,以及簡潔明了的易用性。結合虛擬節點技術(Virtual Kubelet),Cube可以和UCloud 優刻得容器托管產品UK8S無縫對接,極大地豐富了Kubernetes集群的彈性能力。如下圖所示,Virtual Node作為一個虛擬Node在Kubernetes集群中,每個Cube實例被視為VK節點上的一個Pod。

然而,Virtual Kubelet僅僅實現了集群中Cube實例的彈性伸縮。要使得Cube實例正式成為K8s集群大家庭的一員,運行在Cube中的應用需要能利用K8s的服務發現能力,即訪問Service地址。

為什么不是kube-proxy?

眾所周知, kube-proxy為K8s實現了service流量負載均衡。kube-proxy不斷感知K8s內Service和Endpoints地址的對應關系及其變化,生成ServiceIP的流量轉發規則。它提供了三種轉發實現機制:userspace, iptables和ipvs, 其中userspace由于較高的性能代價已不再被使用。

然而,我們發現,直接把kube-proxy部署在Cube虛擬機內部并不合適,有如下原因:

1 、kube-proxy采用go語言開發,編譯產生的目標文件體積龐大。以K8s v1.19.5 linux環境為例,經strip過的kube-proxy ELF可執行文件大小為37MB。對于普通K8s環境來說,這個體積可以忽略不計;但對于Serverless產品來說,為了保證秒起輕量級虛擬機,虛擬機操作系統和鏡像需要高度裁剪,寸土寸金,我們想要一個部署體積不超過10MB的proxy控制程序。

2 、kube-proxy的運行性能問題。同樣由于使用go語言開發,相對于C/C++和Rust等無gc、具備精細控制底層資源能力的高級語言來說,要付出更多的性能代價。Cube通常存在較細粒度的資源交付配額,例如0.5C 500MiB,我們不希望kube-proxy這類輔助組件喧賓奪主。

3 、ipvs的問題。在eBPF被廣為周知之前,ipvs被認為是最合理的K8s service轉發面實現。iptables因為擴展性問題被鞭尸已久,ipvs卻能隨著services和endpoints規模增大依然保持穩定的轉發能力和較低的規則刷新間隔。

但事實是,ipvs并不完美,甚至存在嚴重的問題。

例如,同樣實現nat , iptables是在PREROUTING或者OUTPUT完成DNAT;而ipvs需要經歷INPUT和OUTPUT,鏈路更長。因此,較少svc和ep數量下的service ip壓測場景下,無論是帶寬還是短連接請求延遲,ipvs都會獲得全場最低分。此外,conn_reuse_mode的參數為1導致的滾動發布時服務訪問失敗的問題至今(2021年4月)也解決的不太干凈。

4 、iptables的問題。擴展差,更新慢,O(n)時間復雜度的規則查找(這幾句話背不出來是找不到一份K8s相關的工作的), 同樣的問題還會出現在基于iptables實現的NetworkPolicy上。1.6.2以下iptables甚至不支持full_random端口選擇,導致SNAT的性能在高并發短連接的業務場景下雪上加霜。

eBPF能為容器網絡帶來什么?

eBPF近年來被視為linux的革命性技術,它允許開發者在linux的內核里動態實時地加載運行自己編寫的沙盒程序,無需更改內核源碼或者加載內核模塊。同時,用戶態的程序可以通過bpf(2)系統調用和bpf map結構與內核中的eBPF程序實時交換數據,如下圖所示。

編寫好的eBPF程序在內核中以事件觸發的模式運行,這些事件可以是系統調用入出口,網絡收發包的關鍵路徑點(xdp, tc, qdisc, socket),內核函數入出口kprobes/kretprobes和用戶態函數入出口uprobes/uretprobes等。加載到網絡收發路徑的hook點的eBPF程序通常用于控制和修改網絡報文, 來實現負載均衡,安全策略和監控觀測。

cilium的出現使得eBPF正式進入K8s的視野,并正在深刻地改變k8s的網絡,安全,負載均衡,可觀測性等領域。 從1.6開始,cilium可以100%替換kube-proxy,真正通過eBPF實現了kube-proxy的全部轉發功能。 讓我們首先考察一下ClusterIP(東西流量)的實現。

ClusterIP的實現

無論對于TCP還是UDP來說,客戶端訪問ClusterIP只需要實現針對ClusterIP的DNAT,把Frontend與對應的Backends地址記錄在eBPF map中,這個表的內容即為后面執行DNAT的依據。那這個DNAT在什么環節實現呢?

對于一般環境,DNAT操作可以發生在tc egress,同時在tc ingress

中對回程的流量進行反向操作,即將源地址由真實的PodIP改成ClusterIP, 此外完成NAT后需要重新計算IP和TCP頭部的checksum。

如果是支持cgroup2的linux環境,使用cgroup2的sockaddr hook點進行DNAT。cgroup2為一些需要引用L4地址的socket系統調用,如connect(2), sendmsg(2), recvmsg(2)提供了一個BPF攔截層(BPF_PROG_TYPE_CGROUP_SOCK_ADDR)。這些BPF程序可以在packet生成之前完成對目的地址的修改,如下圖所示。

對于tcp和有連接的udp的流量(即針對udp fd調用過connect(2))來說, 只需要做一次正向轉換,即利用bpf程序,將出向流量的目的地址改成Pod的地址。這種場景下,負載均衡是最高效的,因為開銷一次性的,作用效果則持續貫穿整個通信流的生命周期。

而對于無連接的udp流量,還需要做一次反向轉換,即將來自Pod的入向流量做一個SNAT,將源地址改回ClusterIP。如果缺了這一步操作,基于recvmsg的UDP應用會無法收到來自ClusterIP的消息,因為socket的對端地址被改寫成了Pod的地址。流量示意圖如下所示。

綜述,這是一種用戶無感知的地址轉換。用戶認為自己連接的地址是Service, 但實際的tcp連接直接指向Pod。一個能說明問題的對比是,當你使用kube-proxy的時候,在Pod中進行tcpdump時,你能發現目的地址依然是ClusterIP,因為ipvs或者iptables規則在host上;當你使用cilium時,在Pod中進行tcpdump,你已經能發現目的地址是Backend Pod。NAT不需要借助conntrack就能完成,相對于ipvs和iptables來說,轉發路徑減少,性能更優。而對比剛才提到的tc-bpf,它更輕量,無需重新計算checksum。

Cube的Service服務發現

Cube為每個需要開啟ClusterIP訪問功能的Serverless容器組啟動了一個叫cproxy的agent程序來實現kube-proxy的核心功能。由于Cube的輕量級虛擬機鏡像使用較高版本的linux內核,cproxy采用了上述cgroup2 socket hook的方式進行ClusterIP轉發。cproxy使用Rust開發,編譯后的目標文件只有不到10MiB。運行開銷相比kube-proxy也有不小優勢。部署結構如下所示。

以下是一些測試情況對比。我們使用wrk對ClusterIP進行2000并發HTTP短連接測試,分別比較svc數量為10和svc數量為5000,觀察請求耗時情況(單位ms)。

結論是cproxy無論在svc數量較少和較多的情況下,都擁有最好的性能;ipvs在svc數量較大的情況下性能遠好于iptables,但在svc數量較小的情況下,性能不如iptables。

svc數量=10

svc數量=5000

后續我們會繼續完善基于eBPF實現LoadBalancer(南北流量)轉發,以及基于eBPF的網絡訪問策略(NetworkPolicy)。

UCloud 優刻得容器產品擁抱eBPF

eBPF正在改變云原生生態, 未來UCloud 優刻得容器云產品 UK8S與Serverless容器產品Cube將緊密結合業內最新進展,挖掘eBPF在網絡,負載均衡,監控等領域的應用,為用戶提供更好的觀測、定位和調優能力。

關鍵字:云原生

本文摘自:互聯網

x 擁抱云原生,UCloud優刻得基于eBPF技術實現Serverless節點訪問K8S Service 掃一掃
分享本文到朋友圈
當前位置:新聞中心行業動態 → 正文

擁抱云原生,UCloud優刻得基于eBPF技術實現Serverless節點訪問K8S Service

責任編輯:cres |來源:企業網D1Net  2021-04-07 15:19:01 本文摘自:互聯網

Serverless容器的服務發現

2020年9月,UCloud 優刻得上線了Serverless容器產品Cube,它具備了虛擬機級別的安全隔離、輕量化的系統占用、秒級的啟動速度,高度自動化的彈性伸縮,以及簡潔明了的易用性。結合虛擬節點技術(Virtual Kubelet),Cube可以和UCloud 優刻得容器托管產品UK8S無縫對接,極大地豐富了Kubernetes集群的彈性能力。如下圖所示,Virtual Node作為一個虛擬Node在Kubernetes集群中,每個Cube實例被視為VK節點上的一個Pod。

然而,Virtual Kubelet僅僅實現了集群中Cube實例的彈性伸縮。要使得Cube實例正式成為K8s集群大家庭的一員,運行在Cube中的應用需要能利用K8s的服務發現能力,即訪問Service地址。

為什么不是kube-proxy?

眾所周知, kube-proxy為K8s實現了service流量負載均衡。kube-proxy不斷感知K8s內Service和Endpoints地址的對應關系及其變化,生成ServiceIP的流量轉發規則。它提供了三種轉發實現機制:userspace, iptables和ipvs, 其中userspace由于較高的性能代價已不再被使用。

然而,我們發現,直接把kube-proxy部署在Cube虛擬機內部并不合適,有如下原因:

1 、kube-proxy采用go語言開發,編譯產生的目標文件體積龐大。以K8s v1.19.5 linux環境為例,經strip過的kube-proxy ELF可執行文件大小為37MB。對于普通K8s環境來說,這個體積可以忽略不計;但對于Serverless產品來說,為了保證秒起輕量級虛擬機,虛擬機操作系統和鏡像需要高度裁剪,寸土寸金,我們想要一個部署體積不超過10MB的proxy控制程序。

2 、kube-proxy的運行性能問題。同樣由于使用go語言開發,相對于C/C++和Rust等無gc、具備精細控制底層資源能力的高級語言來說,要付出更多的性能代價。Cube通常存在較細粒度的資源交付配額,例如0.5C 500MiB,我們不希望kube-proxy這類輔助組件喧賓奪主。

3 、ipvs的問題。在eBPF被廣為周知之前,ipvs被認為是最合理的K8s service轉發面實現。iptables因為擴展性問題被鞭尸已久,ipvs卻能隨著services和endpoints規模增大依然保持穩定的轉發能力和較低的規則刷新間隔。

但事實是,ipvs并不完美,甚至存在嚴重的問題。

例如,同樣實現nat , iptables是在PREROUTING或者OUTPUT完成DNAT;而ipvs需要經歷INPUT和OUTPUT,鏈路更長。因此,較少svc和ep數量下的service ip壓測場景下,無論是帶寬還是短連接請求延遲,ipvs都會獲得全場最低分。此外,conn_reuse_mode的參數為1導致的滾動發布時服務訪問失敗的問題至今(2021年4月)也解決的不太干凈。

4 、iptables的問題。擴展差,更新慢,O(n)時間復雜度的規則查找(這幾句話背不出來是找不到一份K8s相關的工作的), 同樣的問題還會出現在基于iptables實現的NetworkPolicy上。1.6.2以下iptables甚至不支持full_random端口選擇,導致SNAT的性能在高并發短連接的業務場景下雪上加霜。

eBPF能為容器網絡帶來什么?

eBPF近年來被視為linux的革命性技術,它允許開發者在linux的內核里動態實時地加載運行自己編寫的沙盒程序,無需更改內核源碼或者加載內核模塊。同時,用戶態的程序可以通過bpf(2)系統調用和bpf map結構與內核中的eBPF程序實時交換數據,如下圖所示。

編寫好的eBPF程序在內核中以事件觸發的模式運行,這些事件可以是系統調用入出口,網絡收發包的關鍵路徑點(xdp, tc, qdisc, socket),內核函數入出口kprobes/kretprobes和用戶態函數入出口uprobes/uretprobes等。加載到網絡收發路徑的hook點的eBPF程序通常用于控制和修改網絡報文, 來實現負載均衡,安全策略和監控觀測。

cilium的出現使得eBPF正式進入K8s的視野,并正在深刻地改變k8s的網絡,安全,負載均衡,可觀測性等領域。 從1.6開始,cilium可以100%替換kube-proxy,真正通過eBPF實現了kube-proxy的全部轉發功能。 讓我們首先考察一下ClusterIP(東西流量)的實現。

ClusterIP的實現

無論對于TCP還是UDP來說,客戶端訪問ClusterIP只需要實現針對ClusterIP的DNAT,把Frontend與對應的Backends地址記錄在eBPF map中,這個表的內容即為后面執行DNAT的依據。那這個DNAT在什么環節實現呢?

對于一般環境,DNAT操作可以發生在tc egress,同時在tc ingress

中對回程的流量進行反向操作,即將源地址由真實的PodIP改成ClusterIP, 此外完成NAT后需要重新計算IP和TCP頭部的checksum。

如果是支持cgroup2的linux環境,使用cgroup2的sockaddr hook點進行DNAT。cgroup2為一些需要引用L4地址的socket系統調用,如connect(2), sendmsg(2), recvmsg(2)提供了一個BPF攔截層(BPF_PROG_TYPE_CGROUP_SOCK_ADDR)。這些BPF程序可以在packet生成之前完成對目的地址的修改,如下圖所示。

對于tcp和有連接的udp的流量(即針對udp fd調用過connect(2))來說, 只需要做一次正向轉換,即利用bpf程序,將出向流量的目的地址改成Pod的地址。這種場景下,負載均衡是最高效的,因為開銷一次性的,作用效果則持續貫穿整個通信流的生命周期。

而對于無連接的udp流量,還需要做一次反向轉換,即將來自Pod的入向流量做一個SNAT,將源地址改回ClusterIP。如果缺了這一步操作,基于recvmsg的UDP應用會無法收到來自ClusterIP的消息,因為socket的對端地址被改寫成了Pod的地址。流量示意圖如下所示。

綜述,這是一種用戶無感知的地址轉換。用戶認為自己連接的地址是Service, 但實際的tcp連接直接指向Pod。一個能說明問題的對比是,當你使用kube-proxy的時候,在Pod中進行tcpdump時,你能發現目的地址依然是ClusterIP,因為ipvs或者iptables規則在host上;當你使用cilium時,在Pod中進行tcpdump,你已經能發現目的地址是Backend Pod。NAT不需要借助conntrack就能完成,相對于ipvs和iptables來說,轉發路徑減少,性能更優。而對比剛才提到的tc-bpf,它更輕量,無需重新計算checksum。

Cube的Service服務發現

Cube為每個需要開啟ClusterIP訪問功能的Serverless容器組啟動了一個叫cproxy的agent程序來實現kube-proxy的核心功能。由于Cube的輕量級虛擬機鏡像使用較高版本的linux內核,cproxy采用了上述cgroup2 socket hook的方式進行ClusterIP轉發。cproxy使用Rust開發,編譯后的目標文件只有不到10MiB。運行開銷相比kube-proxy也有不小優勢。部署結構如下所示。

以下是一些測試情況對比。我們使用wrk對ClusterIP進行2000并發HTTP短連接測試,分別比較svc數量為10和svc數量為5000,觀察請求耗時情況(單位ms)。

結論是cproxy無論在svc數量較少和較多的情況下,都擁有最好的性能;ipvs在svc數量較大的情況下性能遠好于iptables,但在svc數量較小的情況下,性能不如iptables。

svc數量=10

svc數量=5000

后續我們會繼續完善基于eBPF實現LoadBalancer(南北流量)轉發,以及基于eBPF的網絡訪問策略(NetworkPolicy)。

UCloud 優刻得容器產品擁抱eBPF

eBPF正在改變云原生生態, 未來UCloud 優刻得容器云產品 UK8S與Serverless容器產品Cube將緊密結合業內最新進展,挖掘eBPF在網絡,負載均衡,監控等領域的應用,為用戶提供更好的觀測、定位和調優能力。

關鍵字:云原生

本文摘自:互聯網

電子周刊
回到頂部

關于我們聯系我們版權聲明隱私條款廣告服務友情鏈接投稿中心招賢納士

企業網版權所有 ©2010-2024 京ICP備09108050號-6 京公網安備 11010502049343號

^
  • <menuitem id="jw4sk"></menuitem>

    1. <form id="jw4sk"><tbody id="jw4sk"><dfn id="jw4sk"></dfn></tbody></form>
      主站蜘蛛池模板: 盱眙县| 天水市| 乐陵市| 云梦县| 肥城市| 区。| 扶风县| 禹城市| 贺州市| 通江县| 兰溪市| 大姚县| 盱眙县| 仁怀市| 和田市| 拜泉县| 溆浦县| 乐至县| 定日县| 玉树县| 民和| 精河县| 靖安县| 宜城市| 澄迈县| 开阳县| 三台县| 长葛市| 沁水县| 广平县| 永宁县| 荆门市| 突泉县| 陆良县| 徐汇区| 罗田县| 汉阴县| 玛曲县| 于田县| 乐至县| 英德市|