<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          大規(guī)模微服務(wù)利器:eBPF + Kubernetes 介紹

          共 15260字,需瀏覽 31分鐘

           ·

          2021-01-15 18:59

          本文翻譯自 2020 年 Daniel Borkmann 在 KubeCon 的一篇分享:?eBPF and Kubernetes: Little Helper Minions for Scaling Microservices(https://kccnceu20.sched.com/event/ZemQ/ebpf-and-kubernetes-little-helper-minions-for-scaling-microservices-daniel-borkmann-cilium), 視頻見油管(https://www.youtube.com/watch?v=99jUcLt3rSk)。

          Daniel 是 eBPF 兩位 maintainer 之一,目前在 eBPF commits 榜單上排名第一,也是 Cilium 的核心開發(fā)者之一。

          本文內(nèi)容的時(shí)間跨度有 8 年,覆蓋了 eBPF 發(fā)展的整個(gè)歷史,非常值得一讀。時(shí)間限制, Daniel 很多地方只是點(diǎn)到,沒有展開。譯文中加了一些延展閱讀,有需要的同學(xué)可以參考。

          由于譯者水平有限,本文不免存在遺漏或錯(cuò)誤之處。如有疑問,請(qǐng)查閱原文。


          1 eBPF 正在吞噬世界

          1.1?Kubernetes 已經(jīng)是云操作系統(tǒng)

          Kubernetes 正在吞噬世界(eating the world)。越來越多的企業(yè)開始遷移到容器平臺(tái)上 ,而 Kubernetes 已經(jīng)是公認(rèn)的云操作系統(tǒng)(Cloud OS)。從技術(shù)層面來說,

          • Linux 內(nèi)核是一切的堅(jiān)實(shí)基礎(chǔ),例如,內(nèi)核提供了 cgroup、namespace 等特性。


          • Kubernetes CNI 插件串聯(lián)起了關(guān)鍵路徑(critical path)上的組件。例如,從網(wǎng)絡(luò)的 視角看,包括
            • 廣義的 Pod 連通性:一個(gè)容器創(chuàng)建之后,CNI 插件會(huì)給它創(chuàng)建網(wǎng)絡(luò)設(shè)備,移動(dòng)到容?器的網(wǎng)絡(luò)命名空間。
            • IPAM:CNI 向 IPAM 發(fā)送請(qǐng)求,為容器分配 IP 地址,然后配置路由。
            • Kubernetes 的 Service 處理和負(fù)載均衡功能。
            • 網(wǎng)絡(luò)策略的生效(network policy enforcement)。
            • 監(jiān)控和排障。

          1.2 兩個(gè)清晰的容器技術(shù)趨勢(shì)

          今天我們能清晰地看到兩個(gè)技術(shù)發(fā)展趨勢(shì):

          • 容器的部署密度越來越高(increasing Pod density)。
          • 容器的生命周期越來越短(decreasing Pod lifespan)。甚至短到秒級(jí)或毫秒級(jí)

          大家有興趣的可以查閱相關(guān)調(diào)查:

          • CNCF’19 survey report
          • sysdig’19 container usage report

          2 內(nèi)核面臨的挑戰(zhàn)

          從操作系統(tǒng)內(nèi)核的角度看,我們面臨很多挑戰(zhàn)。

          2.1 復(fù)雜度性不斷增長,性能和可擴(kuò)展性新需求

          內(nèi)核,或者說通用內(nèi)核(general kernel),必須在子系統(tǒng)復(fù)雜度不斷增長( increasing complexity of kernel subsystems)的前提下,滿足這些性能和可擴(kuò)展性?需求(performance & scalability requirements)。

          2.2 永遠(yuǎn)保持后向兼容

          Linus torvalds 的名言大家都知道:never break user space。

          這對(duì)用戶來說是好事,但對(duì)內(nèi)核開發(fā)者來說意味著:我們必須保證在引入新代碼時(shí),五年前 甚至十幾年前的老代碼仍然能正常工作。

          顯然,這會(huì)使原本就復(fù)雜的內(nèi)核變得更加復(fù)雜,對(duì)于網(wǎng)絡(luò)來說,這意味著快速收發(fā)包路徑 (fast path)將受到影響

          2.3 Feature creeping normality

          開發(fā)者和用戶不斷往內(nèi)核加入新功能,導(dǎo)致內(nèi)核非常復(fù)雜,現(xiàn)在已經(jīng)沒有一個(gè)人能理解所有東西了

          Wikipedia 對(duì) creeping normality 的定義:

          Def. creeping normality: … is a process by which a major change can be accepted as normal and acceptable if it happens slowly through small, often unnoticeable, increments of change. The change could otherwise be regarded as objectionable if it took place in a single step or short period.

          應(yīng)用到這里,意思就是:內(nèi)核不允許一次性引入非常大的改動(dòng),只能將它們拆 分成數(shù)量眾多的小 patch,每次合并的 patch 保證系統(tǒng)后向兼容,并且對(duì)系統(tǒng)的影響非 常小。

          來看 Linus torvalds 的原話:

          Linus Torvalds on crazy new kernel features:

          So I can work with crazy people, that’s not the problem. They just need to?sell?their crazy stuff to me using non-crazy arguments, and in small and well-defined pieces. When I ask for killer features, I want them to lull me into a safe and cozy world where the stuff they are pushing is actually useful to mainline people?first.

          In other words, every new crazy feature should be hidden in a nice solid “Trojan Horse” gift: something that looks?obviously?good at first sight.

          Linus Torvalds,

          https://lore.kernel.org/lkml/[email protected]/

          3 eBPF 降世:重新定義數(shù)據(jù)平面(datapth)

          這就是我們最開始想將 eBPF 合并到內(nèi)核時(shí)遇到的問題:改動(dòng)太大,功能太新(a crazy new kernel feature)。

          但是,eBPF 帶來的好處也是無與倫比的。

          首先,從長期看,eBPF 這項(xiàng)新功能會(huì)減少未來的 feature creeping normality。?因?yàn)橛脩艋蜷_發(fā)者希望內(nèi)核實(shí)現(xiàn)的功能,以后不需要再通過改內(nèi)核的方式來實(shí)現(xiàn)了。?只需要一段 eBPF 代碼,實(shí)時(shí)動(dòng)態(tài)加載到內(nèi)核就行了。

          其次,因?yàn)?eBPF,內(nèi)核也不會(huì)再引入那些影響 fast path 的蹩腳甚至 hardcode 代碼 ,從而也避免了性能的下降

          第三,eBPF 還使得內(nèi)核完全可編程,安全地可編程(fully and safely programmable ),用戶編寫的 eBPF 程序不會(huì)導(dǎo)致內(nèi)核 crash。另外,eBPF 設(shè)計(jì)用來解決真實(shí)世界 中的線上問題,而且我們現(xiàn)在仍然在堅(jiān)守這個(gè)初衷。

          4 eBPF 長什么樣,怎么用?Cilium eBPF networking 案例研究

          eBPF 程序長什么樣?如下圖所示,和 C 語言差不多,一般由用戶空間 application 或 agent 來生成。

          4.1 Cilium eBPF 流程

          下面我們將看看 Cilium 是如何用 eBPF 實(shí)現(xiàn)容器網(wǎng)絡(luò)方案的。

          如上圖所示,幾個(gè)步驟:

          1. Cilium agent?生成 eBPF 程序
          2. 用 LLVM 編譯 eBPF 程序,生成 eBPF 對(duì)象文件(object file,*.o)。
          3. 用 eBPF loader?將對(duì)象文件加載到 Linux 內(nèi)核
          4. 校驗(yàn)器(verifier)對(duì) eBPF 指令會(huì)進(jìn)行合法性驗(yàn)證,以確保程序是安全的,例如 ,無非法內(nèi)存訪問、不會(huì) crash 內(nèi)核、不會(huì)有無限循環(huán)等。
          5. 對(duì)象文件被即時(shí)編譯(JIT)為能直接在底層平臺(tái)(例如 x86)運(yùn)行的 native code。
          6. 如果要在內(nèi)核和用戶態(tài)之間共享狀態(tài),BPF 程序可以使用 BPF map,這種一種共享存儲(chǔ)?,BPF 側(cè)和用戶側(cè)都可以訪問。
          7. BPF 程序就緒,等待事件觸發(fā)其執(zhí)行。對(duì)于這個(gè)例子,就是有數(shù)據(jù)包到達(dá)網(wǎng)絡(luò)設(shè)備時(shí),觸發(fā) BPF 程序的執(zhí)行。
          8. BPF 程序?qū)κ盏降陌M(jìn)行處理,例如 mangle。最后返回一個(gè)裁決(verdict)結(jié)果。
          9. 根據(jù)裁決結(jié)果,如果是 DROP,這個(gè)包將被丟棄;如果是 PASS,包會(huì)被送到更網(wǎng)絡(luò)棧的 更上層繼續(xù)處理;如果是重定向,就發(fā)送給其他設(shè)備。

          4.2 eBPF 特點(diǎn)

          1. 最重要的一點(diǎn):不能 crash 內(nèi)核。
          2. 執(zhí)行起來,與內(nèi)核模塊(kernel module)一樣快。
          3. 提供穩(wěn)定的 API。

          這意味著什么?簡單來說,如果一段 BPF 程序能在老內(nèi)核上執(zhí)行,那它一定也能繼續(xù)在新 內(nèi)核上執(zhí)行,而無需做任何修改。

          這就像是內(nèi)核空間與用戶空間的契約,內(nèi)核保證對(duì)用戶空間應(yīng)用的兼容性,類似地,內(nèi)核也 會(huì)保證 eBPF 程序的兼容性。

          5 溫故:kube-proxy 包轉(zhuǎn)發(fā)路徑

          從網(wǎng)絡(luò)角度看,使用傳統(tǒng)的 kube-proxy 處理 Kubernetes Service 時(shí),包在內(nèi)核中的 轉(zhuǎn)發(fā)路徑是怎樣的?如下圖所示:

          步驟:

          1. 網(wǎng)卡收到一個(gè)包(通過 DMA 放到 ring-buffer)。
          2. 包經(jīng)過 XDP hook 點(diǎn)。
          3. 內(nèi)核給包分配內(nèi)存,此時(shí)才有了大家熟悉的?skb(包的內(nèi)核結(jié)構(gòu)體表示),然后 送到內(nèi)核協(xié)議棧。
          4. 包經(jīng)過 GRO 處理,對(duì)分片包進(jìn)行重組。
          5. 包進(jìn)入 tc(traffic control)的 ingress hook。接下來,所有橙色的框都是 Netfilter 處理點(diǎn)
          6. Netfilter:在?PREROUTING?hook 點(diǎn)處理?raw?table 里的 iptables 規(guī)則。
          7. 包經(jīng)過內(nèi)核的連接跟蹤(conntrack)模塊。
          8. Netfilter:在?PREROUTING?hook 點(diǎn)處理?mangle?table 的 iptables 規(guī)則。
          9. Netfilter:在?PREROUTING?hook 點(diǎn)處理?nat?table 的 iptables 規(guī)則。
          10. 進(jìn)行路由判斷(FIB:Forwarding Information Base,路由條目的內(nèi)核表示,譯者注) 。接下來又是四個(gè) Netfilter 處理點(diǎn)。
          11. Netfilter:在?FORWARD?hook 點(diǎn)處理?mangle?table 里的 iptables 規(guī)則。
          12. Netfilter:在?FORWARD?hook 點(diǎn)處理?filter?table 里的 iptables 規(guī)則。
          13. Netfilter:在?POSTROUTING?hook 點(diǎn)處理?mangle?table 里的 iptables 規(guī)則。
          14. Netfilter:在?POSTROUTING?hook 點(diǎn)處理?nat?table 里的 iptables 規(guī)則。
          15. 包到達(dá) TC egress hook 點(diǎn),會(huì)進(jìn)行出方向(egress)的判斷,例如判斷這個(gè)包是到本 地設(shè)備,還是到主機(jī)外。
          16. 對(duì)大包進(jìn)行分片。根據(jù) step 15 判斷的結(jié)果,這個(gè)包接下來可能會(huì):
          17. 發(fā)送到一個(gè)本機(jī) veth 設(shè)備,或者一個(gè)本機(jī) service endpoint,
          18. 或者,如果目的 IP 是主機(jī)外,就通過網(wǎng)卡發(fā)出去。

          相關(guān)閱讀,有助于理解以上過程:

          1. Cracking Kubernetes Node Proxy (aka kube-proxy)
          2. (譯) 深入理解 iptables 和 netfilter 架構(gòu)
          3. 連接跟蹤(conntrack):原理、應(yīng)用及 Linux 內(nèi)核實(shí)現(xiàn)
          4. (譯) 深入理解 Cilium 的 eBPF 收發(fā)包路徑(datapath)

          譯者注。

          6 知新:Cilium eBPF 包轉(zhuǎn)發(fā)路徑

          作為對(duì)比,再來看下 Cilium eBPF 中的包轉(zhuǎn)發(fā)路徑:

          建議和?(譯) 深入理解 Cilium 的 eBPF 收發(fā)包路徑(datapath)?對(duì)照看。

          譯者注。

          對(duì)比可以看出,Cilium eBPF datapath 做了短路處理:從 tc ingress 直接 shortcut 到 tc egress,節(jié)省了 9 個(gè)中間步驟(總共 17 個(gè))。更重要的是:這個(gè) datapath 繞過了 整個(gè) Netfilter 框架(橘黃色的框們),Netfilter 在大流量情況下性能是很差的。

          去掉那些不用的框之后,Cilium eBPF datapath 長這樣:

          Cilium/eBPF 還能走的更遠(yuǎn)。例如,如果包的目的端是另一臺(tái)主機(jī)上的 service endpoint,那你可以直接在 XDP 框中完成包的重定向(收包?1->2,在步驟?2?中對(duì)包 進(jìn)行修改,再通過?2->1?發(fā)送出去),將其發(fā)送出去,如下圖所示:

          可以看到,這種情況下包都**沒有進(jìn)入內(nèi)核協(xié)議棧(準(zhǔn)確地說,都沒有創(chuàng)建 skb)**就被轉(zhuǎn) 發(fā)出去了,性能可想而知。

          XDP 是 eXpress DataPath 的縮寫,支持在網(wǎng)卡驅(qū)動(dòng)中運(yùn)行 eBPF 代碼,而無需將包送 到復(fù)雜的協(xié)議棧進(jìn)行處理,因此處理代價(jià)很小,速度極快。

          7 eBPF 年鑒

          eBPF 是如何誕生的呢?我最初開始講起。這里“最初”我指的是 2013 年之前。

          2013

          前浪工具和子系統(tǒng)

          回顧一下當(dāng)時(shí)的 “SDN” 藍(lán)圖。

          1. 當(dāng)時(shí)有 OpenvSwitch(OVS)、tc(Traffic control),以及內(nèi)核中的 Netfilter 子系 統(tǒng)(包括?iptablesipvsnftalbes?工具),可以用這些工具對(duì) datapath 進(jìn)行“ 編程”:。
          2. BPF 當(dāng)時(shí)用于?tcpdump在內(nèi)核中盡量前面的位置抓包,它不會(huì) crash 內(nèi)核;此 外,它還用于 seccomp,對(duì)系統(tǒng)調(diào)用進(jìn)行過濾(system call filtering),但當(dāng)時(shí) 使用的非常受限,遠(yuǎn)不是今天我們已經(jīng)在用的樣子。
          3. 此外就是前面提到的 feature creeping 問題,以及?tc 和 netfilter 的代碼重復(fù)問題,因?yàn)檫@兩個(gè)子系統(tǒng)是競(jìng)爭(zhēng)關(guān)系
          4. OVS 當(dāng)時(shí)被認(rèn)為是內(nèi)核中最先進(jìn)的數(shù)據(jù)平面,但它最大的問題是:與內(nèi)核中其他網(wǎng) 絡(luò)模塊的集成不好【譯者注 1】。此外,很多核心的內(nèi)核開發(fā)者也比較抵觸 OVS,覺得它很怪。

          【譯者注 1】

          例如,OVS 的 internal port、patch port 用 tcpdump 都是?抓不到包的,排障非常不方便。

          eBPF 與前浪的區(qū)別

          對(duì)比 eBPF 和這些已經(jīng)存在很多年的工具:

          1. tc、OVS、netfilter 可以對(duì) datapath 進(jìn)行“編程”:但前提是 datapath 知道你想做什 么(but only if the datapath knows what you want to do)。
            • 只能利用這些工具或模塊提供的既有功能。
          2. eBPF 能夠讓你創(chuàng)建新的 datapath(eBPF lets you create the datapath instead)。
          • eBPF 就是內(nèi)核本身的代碼,想象空間無限,并且熱加載到內(nèi)核;換句話說,一旦加 載到內(nèi)核,內(nèi)核的行為就變了。
          • 在 eBPF 之前,改變內(nèi)核行為這件事情,只能通過修改內(nèi)核再重新編譯,或者開發(fā)內(nèi) 核模塊才能實(shí)現(xiàn)。

          譯者注

          eBPF:第一個(gè)(巨型)patch

          • 描述 eBPF 的 RFC 引起了廣泛討論,但普遍認(rèn)為侵入性太強(qiáng)了(改動(dòng)太大)。
          • 另外,當(dāng)時(shí) nftables (inspired by BPF) 正在上升期,它是一個(gè)與 eBPF 有點(diǎn)類似的 BPF 解釋器,大家不想同時(shí)維護(hù)兩個(gè)解釋器。

          最終這個(gè) patch 被拒絕了。

          被拒的另外一個(gè)原因是前面提到的,沒有遵循“大改動(dòng)小提交”原則,全部代碼放到了一個(gè) patch。Linus 會(huì)瘋的。

          2014

          第一個(gè) eBPF patch 合并到內(nèi)核

          • 用一個(gè)擴(kuò)展(extended)指令集逐步、全面替換原來老的 BPF 解釋器。
          • 自動(dòng)新老 BPF 轉(zhuǎn)換:in-kernel translation。
          • 后續(xù) patch 將 eBPF 暴露給 UAPI,并添加了 verifier 代碼和 JIT 代碼。
          • 更多后續(xù) patch,從核心代碼中移除老的 BPF。

          我們也從那時(shí)開始,順理成章地成為了 eBPF 的 maintainer。

          Kubernetes 提交第一個(gè) commit

          巧合的是,對(duì)后來影響深遠(yuǎn)的 Kubernetes,也在這一年提交了第一個(gè) commit

          2015

          eBPF 分成兩個(gè)方向:networking & tracing

          到了 2015 年,eBPF 開發(fā)分成了兩個(gè)方向:

          • networking
          • tracing

          eBPF backend 合并到 LLVM 3.7

          這一年的一個(gè)重要里程碑是 eBPF backend 合并到了 upstream LLVM 編譯器套件,因此你 現(xiàn)在才能用 clang 編譯 eBPF 代碼。

          支持將 eBPF attach 到 kprobes

          這是 tracing 的第一個(gè)使用案例。

          Alexei 主要負(fù)責(zé) tracing 部分,他添加了一個(gè) patch,支持加載 eBPF 用來做 tracing, 能獲取系統(tǒng)的觀測(cè)數(shù)據(jù)。

          通過 cls_bpf,tc 變得完全可編程

          我主要負(fù)責(zé) networking 部分,使 tc 子系統(tǒng)可編程,這樣我們就能用 eBPF 來靈活的對(duì) datapath 進(jìn)行編程,獲得一個(gè)高性能 datapath。

          為 tc 添加了一個(gè) lockless ingress & egress hook 點(diǎn)

          添加了很多 verifer 和 eBPF 輔助代碼(helper)

          使用更方便。

          bcc 項(xiàng)目發(fā)布

          作為 tracing frontend for eBPF。

          2016

          eBPF 添加了一個(gè)新 fast path:XDP

          • XDP 合并到內(nèi)核,支持在驅(qū)動(dòng)的 ingress 層 attach BPF 程序。
          • nfp 最為第一家網(wǎng)卡及驅(qū)動(dòng),支持將 eBPF 程序 offload 到 cls_bpf & XDP hook 點(diǎn)。

          Cilium 項(xiàng)目發(fā)布

          Cilium 最開始的目標(biāo)是?docker 網(wǎng)絡(luò)解決方案

          • 通過 eBPF 實(shí)現(xiàn)高效的 label-based policy、NAT64、tunnel mesh、容器連通性。
          • 整個(gè) datapath & forwarding 邏輯全用 eBPF 實(shí)現(xiàn),不再需要 Docker 或 OVS 橋接設(shè)備。

          2017

          eBPF 開始大規(guī)模應(yīng)用于生產(chǎn)環(huán)境

          2016 ~ 2017 年,eBPF 開始應(yīng)用于生產(chǎn)環(huán)境:

          1. Netflix on eBPF for tracing: ‘Linux BPF superpowers’
          2. Facebook 公布了生產(chǎn)環(huán)境 XDP+eBPF 使用案例(DDoS & LB)
            • 用 XDP/eBPF 重寫了原來基于 IPVS 的 L4LB,性能?10x
            • eBPF 經(jīng)受住了嚴(yán)苛的考驗(yàn):從 2017 開始,每個(gè)進(jìn)入 facebook.com 的包,都是經(jīng)過了 XDP & eBPF 處理的。
          3. Cloudflare 將 XDP+BPF 集成到了它們的 DDoS mitigation 產(chǎn)品。
            • 成功將其組件從基于 Netfilter 遷移到基于 eBPF。
            • 到 2018 年,它們的 XDP L4LB 完全接管生產(chǎn)環(huán)境。
            • 擴(kuò)展閱讀:(譯) Cloudflare 邊緣網(wǎng)絡(luò)架構(gòu):無處不在的 BPF(2019)

          譯者注:基于 XDP/eBPF 的 L4LB 原理都是類似的,簡單來說,

          1. 通過 BGP 宣告 VIP
          2. 通過 ECMP 做物理鏈路高可用
          3. 通過 XDP/eBPF 代碼做重定向,將請(qǐng)求轉(zhuǎn)發(fā)到后端(VIP -> Backend)

          對(duì)此感興趣可參考入門級(jí)介紹:L4LB for Kubernetes: Theory and Practice with Cilium+BGP+ECMP

          2017 ~ 2018

          eBPF 成為內(nèi)核獨(dú)立子系統(tǒng)

          隨著 eBPF 社區(qū)的發(fā)展,feature 和 patch 越來越多,為了管理這些 patch,Alexei、我和 networking 的一位 maintainer David Miller 經(jīng)過討論,決定將 eBPF 作為獨(dú)立的內(nèi)核子 系統(tǒng)。

          • eBPF patch 合并到?bpf?&?bpf-next?kernel trees on git.kernel.org
          • 拆分 eBPF 郵件列表:[email protected]?(archive at:?lore.kernel.org/bpf/)
          • eBPF PR 經(jīng)內(nèi)核網(wǎng)絡(luò)部分的 maintainer David S. Miller 提交給 Linus Torvalds

          kTLS & eBPF

          kTLS & eBPF for introspection and ability for in-kernel TLS policy enforcement

          kTLS 是將 TLS 處理 offload 到內(nèi)核,例如,將加解密過程從 openssl 下放到內(nèi)核進(jìn) 行,以使得內(nèi)核具備更強(qiáng)的可觀測(cè)性(gain visibility)。

          有了 kTLS,就可以用 eBPF 查看數(shù)據(jù)和狀態(tài),在內(nèi)核應(yīng)用安全策略。?目前 openssl 已經(jīng)完全原生支持這個(gè)功能

          bpftool & libbpf

          為了檢查內(nèi)核內(nèi) eBPF 的狀態(tài)(introspection)、查看內(nèi)核加載了哪些 BPF 程序等, 我們添加了一個(gè)新工具 bpftool。現(xiàn)在這個(gè)工具已經(jīng)功能非常強(qiáng)大了。

          同樣,為了方便用戶空間應(yīng)用使用 eBPF,我們提供了用戶空間 API(user space API for applications)?libbpf。這是一個(gè) C 庫,接管了所有加載工作,這樣用戶就不需要 自己處理復(fù)雜的加載過程了。

          BPF to BPF function calls

          增加了一個(gè) BPF 函數(shù)調(diào)用另一個(gè) BPF 函數(shù)的支持,使得 BPF 程序的編寫更加靈活。

          2018

          Cilium 1.0 發(fā)布

          這標(biāo)志著?BPF 革命之火燃燒到了 Kubernetes networking & security 領(lǐng)域

          Cilium 此時(shí)支持的功能:

          • K8s CNI
          • Identity-based L3-L7 policy
          • ClusterIP Services

          BTF(Byte Type Format)

          內(nèi)核添加了一個(gè)稱為 BTF 的組件。這是一種元數(shù)據(jù)格式,和 DWARF 這樣的 debugging data 類似。但 BTF 的 size 要小的多,而更重要的是,有史以來,內(nèi)核第一次變得可自 描述了(self-descriptive)。什么意思?

          想象一下當(dāng)前正在運(yùn)行中的內(nèi)核,它內(nèi)置了自己的數(shù)據(jù)格式(its own data format) 和內(nèi)部數(shù)據(jù)結(jié)構(gòu)(internal structures),你能用工具來查看這些東西(you can introspect them)。還是不太懂?這么說吧,BTF 是后來的 “一次編譯、到處運(yùn)行”、 熱補(bǔ)丁(live-patching)、BPF global data 處理等等所有這些 BPF 特性的基礎(chǔ)

          新的特性不斷加入,它們都依賴 BTF 提供富元數(shù)據(jù)(rich metadata)這個(gè)基礎(chǔ)。

          更多 BTF 內(nèi)容,可參考?(譯) Cilium:BPF 和 XDP 參考指南(2019)

          譯者注

          Linux Plumbers 會(huì)議開辟 BPF/XDP 主題

          這一年,Linux Plumbers 會(huì)議第一次開辟了專門討論 BPF/XDP 的微型分會(huì),我們 一起組織這場(chǎng)會(huì)議。其中,Networking Track 一半以上的議題都涉及 BPF 和 XDP 主題,因?yàn)檫@是一個(gè)非常振奮人心的特性,越來越多的人用它來解決實(shí)際問題。

          新 socket 類型:AF_XDP

          內(nèi)核添加了一個(gè)新 socket 類型 AF_XDP。它提供的能力是:在零拷貝( zero-copy)的前提下將包從網(wǎng)卡驅(qū)動(dòng)送到用戶空間

          回憶前面的內(nèi)容,數(shù)據(jù)包到達(dá)網(wǎng)卡后,先經(jīng)過 XDP,然后才為這個(gè)包分配內(nèi)存。?因此在 XDP 層直接將包送到用戶態(tài)是無需拷貝的。

          譯者注

          AF_XDP?提供的能力與 DPDK 有點(diǎn)類似,不過

          • DPDK 需要重寫網(wǎng)卡驅(qū)動(dòng),需要額外維護(hù)用戶空間的驅(qū)動(dòng)代碼
          • AF_XDP?在復(fù)用內(nèi)核網(wǎng)卡驅(qū)動(dòng)的情況下,能達(dá)到與 DPDK 一樣的性能。

          而且由于復(fù)用了內(nèi)核基礎(chǔ)設(shè)施,所有的網(wǎng)絡(luò)管理工具還都是可以用的,因此非常方便, 而 DPDK 這種 bypass 內(nèi)核的方案導(dǎo)致絕大大部分現(xiàn)有工具都用不了了。

          由于所有這些操作都是發(fā)生在 XDP 層的,因此它稱為?AF_XDP。插入到這里的 BPF 代碼 能直接將包送到 socket。

          bpffilter

          開始了 bpffilter prototype,作用是通過用戶空間驅(qū)動(dòng)(userspace driver),將 iptables 規(guī)則轉(zhuǎn)換成 eBPF 代碼

          這是將 iptables 轉(zhuǎn)換成 eBPF 的第一次嘗試,整個(gè)過程對(duì)用戶都是無感知的,其中的某些 組件現(xiàn)在還在用,用于在其他方面擴(kuò)展內(nèi)核的功能。

          2018 ~ 2019

          bpftrace

          Brendan 發(fā)布了 bpftrace 工具,作為 DTrace 2.0 for Linux。

          BPF 專著《BPF Performance Tools》

          Berendan 寫了一本 800 多頁的 BPF 書。

          Cilium 1.6 發(fā)布

          第一次支持完全干掉基于 iptables 的 kube-proxy,全部功能基于 eBPF。

          這個(gè)版本其實(shí)是有問題的,例如 1.6 發(fā)布之后我們發(fā)現(xiàn) externalIPs 的實(shí)現(xiàn)是有問題 ,社區(qū)在后面的版本修復(fù)了這個(gè)問題。在修復(fù)之前,還是得用 kube-proxy:https://github.com/cilium/cilium/issues/9285

          譯者注

          BPF live-patching

          添加了一些內(nèi)核新特性,例如尾調(diào)用(tail call),這使得?eBPF 核心基礎(chǔ) 設(shè)施第一次實(shí)現(xiàn)了熱加載。這個(gè)功能幫我們極大地優(yōu)化了 datapath。

          另一個(gè)重要功能是 BPF trampolines,這里就不展開了,感興趣的可以搜索相關(guān)資料,我只 能說這是另一個(gè)振奮人心的技術(shù)。

          第一次 bpfconf:受邀請(qǐng)才能參加的 BPF 內(nèi)核專家會(huì)議

          如題,這是 BPF 內(nèi)核專家交換想法和討論問題的會(huì)議。與 Linux Plumbers 會(huì)議互補(bǔ)。

          BPF backend 合并到 GCC

          前面提到,BPF backend 很早就合并到 LLVM/Clang,現(xiàn)在,它終于合并到 GCC 了。?至此,GCC 和 LLVM 這兩個(gè)最主要的編譯器套件都支持了 BPF backend

          此外,BPF 開始支持有限循環(huán)(bounded loops),在此之前,是不支持循環(huán)的,以防止程 序無限執(zhí)行。

          2019 ~ 2020

          不知疲倦的增長和 eBPF 的第三個(gè)方向:Linux security modules

          • Google 貢獻(xiàn)了 BPF LSM(安全),部署在了他們的數(shù)據(jù)中心服務(wù)器上。
          • BPF verifier 防護(hù) Spectre 漏洞(2018 年轟動(dòng)世界的 CPU bug):even verifying safety on speculative program paths。
          • 主流云廠商開始通過 SRIOV 支持 XDP:AWS (ena driver), Azure (hv_netvsc driver), …
          • Cilium 1.8 支持基于 XDP 的 Service 負(fù)載均衡和 host network policies。
          • Facebook 開發(fā)了基于 BPF 的 TCP 擁塞控制模塊。
          • Microsoft 基于 BPF 重寫了將他們的 Windows monitoring 工具。

          8 eBPF:過去 50 年操作系統(tǒng)最大的變革

          Brendan 說在他的職業(yè)生涯中,eBPF 是他見過的操作系統(tǒng)中最大的變革之一(one of the biggest operating system changes),他為能身處其中而感到非常興奮。

          我接下來只能用數(shù)字證明:Brendan 的興奮是沒錯(cuò)的。

          9 eBPF 數(shù)字榜單(截至 2020.07)

          eBPF 內(nèi)核社區(qū)截至 7 月份的一些數(shù)據(jù):

          • 347 個(gè)貢獻(xiàn)者,貢獻(xiàn)了 4,935 個(gè) patch 到 BPF 子系統(tǒng)。
          • BPF 內(nèi)核郵件列表日均 50 封郵件 (高峰經(jīng)常超過日均 100)。
            • 23,395 mails since mailing list git archive was added in Feb 2019
          • 每天合并 4 個(gè)新 patch。patch 接受率 30% 左右。
          • 30 個(gè)程序(different program),27 種 BPF map 類型,141 個(gè) BPF helpers,超過 3,500 個(gè)測(cè)試。
          • 2 個(gè) BPF kernel maintainers & team of 6 senior core reviewers。
            • 主要貢獻(xiàn)來自:Isovalent(Cilium), Facebook and Google

          毫無疑問,這是內(nèi)核里發(fā)展最快的子系統(tǒng)!

          10 業(yè)界趨勢(shì)

          注意貢獻(xiàn)榜排名第一的就是演講者本人,譯者注。

          列舉幾個(gè)生產(chǎn)環(huán)境大規(guī)模使用 BPF 的大廠:

          • Facebook:L4LB、DDoS、tracing。
          • Netflix:BPF 重度用戶,例如生產(chǎn)環(huán)境 tracing。
          • Google:Android、服務(wù)器安全以及其他很多方面。
          • Cloudflare:L4LB、DDoS。
          • Cilium

          上圖中,右下角是前 Netfilter 維護(hù)者?Rusty Russel 說的一句,業(yè)界對(duì) eBPF 的受認(rèn)可程度可窺一斑。

          11 eBPF 革命:燃燒到 Kubernetes 社區(qū)

          eBPF 已無處不在,而你還在使用 iptables?

          11.1 干掉 kube-proxy/iptables

          不用再忍受 iptables 復(fù)雜冗長的規(guī)則和差勁的性能了,以前沒得選,現(xiàn)在你可以做個(gè)好人:

          $?kubectl?-n?kube-system?delete?ds?kube-proxy

          作為例子,我們來看看 Cilium 是怎么做 Service 的負(fù)載均衡的。

          Service 細(xì)節(jié)實(shí)現(xiàn)可參考 Cracking Kubernetes Node Proxy (aka kube-proxy)。

          譯者注。

          11.2 Cilium 的 Service load balancing 設(shè)計(jì)

          如上圖所示,主要涉及兩部分:

          1. 在 socket 層運(yùn)行的 BPF 程序
          2. 在 XDP 和 tc 層運(yùn)行的 BPF 程序

          東西向流量

          我們先來看 socker 層。

          如上圖所示,

          Socket 層的 BPF 程序主要處理 Cilium 節(jié)點(diǎn)的東西向流量(E-W)。

          • 將 Service 的?IP:Port?映射到具體的 backend pods,并做負(fù)載均衡。
          • 當(dāng)應(yīng)用發(fā)起?connect、sendmsg、recvmsg 等請(qǐng)求(系統(tǒng)調(diào)用)時(shí),攔截這些請(qǐng)求, 并根據(jù)請(qǐng)求的?IP:Port?映射到后端 pod,直接發(fā)送過去。反向進(jìn)行相反的變換。

          這里實(shí)現(xiàn)的好處:性能更高。

          • 不需要包級(jí)別(packet leve)的地址轉(zhuǎn)換(NAT)。在系統(tǒng)調(diào)用時(shí),還沒有創(chuàng)建包,因此性能更高。
          • 省去了 kube-proxy 路徑中的很多中間節(jié)點(diǎn)(intermediate node hops)

          可以看出,應(yīng)用對(duì)這種攔截和重定向是無感知的(符合 k8s Service 的設(shè)計(jì))。

          南北向流量

          再來看從 k8s 集群外進(jìn)入節(jié)點(diǎn),或者從節(jié)點(diǎn)出 k8s 集群的流量(external traffic), 即南北向流量(N-S)

          區(qū)分集群外流量的一個(gè)原因是:Pod IP 很多情況下都是不可路由的(與跨主機(jī)選用的網(wǎng) 絡(luò)方案有關(guān)),只在集群內(nèi)有效,即,集群外訪問 Pod IP 是不通的。

          因此,如果 Pod 流量直接從 node 出宿主機(jī),必須確保它能正常回來。而 node IP 一般都是全局可達(dá)的,集群外也可以訪問,所以常見的解決方案就是:在 Pod 通過 node 出集群時(shí),對(duì)其進(jìn)行 SNAT,將源 IP 地址換成 node IP 地址;應(yīng)答包回來時(shí),再進(jìn)行相 反的 DNAT,這樣包就能回到 Pod 了。

          譯者注

          如上圖所示,集群外來的流量到達(dá) node 時(shí),由?XDP 和 tc 層的 BPF 程序進(jìn)行處理, 它們做的事情與 socket 層的差不多,將 Service 的?IP:Port?映射到后端的?PodIP:Port,如果 backend pod 不在本 node,就通過網(wǎng)絡(luò)再發(fā)出去。發(fā)出去的流程我們 在前面?Cilium eBPF 包轉(zhuǎn)發(fā)路徑?講過了。

          這里 BPF 做的事情:執(zhí)行 DNAT。這個(gè)功能可以在 XDP 層做,也可以在 TC 層做,但 在 XDP 層代價(jià)更小,性能也更高。

          總結(jié)起來,這里的核心理念就是:

          1. 東西向流量放在離 socket 層盡量近的地方做。
          2. 南北向流量放在離驅(qū)動(dòng)(XDP 和 tc)層盡量近的地方做。

          11.3 XDP/eBPF vs kube-proxy 性能對(duì)比

          網(wǎng)絡(luò)吞吐

          測(cè)試環(huán)境:兩臺(tái)物理節(jié)點(diǎn),一個(gè)發(fā)包,一個(gè)收包,收到的包做 Service loadbalancing 轉(zhuǎn)發(fā)給后端 Pods。

          可以看出:

          1. Cilium XDP eBPF 模式能處理接收到的全部 10Mpps(packets per second)。
          2. Cilium tc eBPF 模式能處理 3.5Mpps。
          3. kube-proxy iptables 只能處理 2.3Mpps,因?yàn)樗?hook 點(diǎn)在收發(fā)包路徑上更后面的位置。
          4. kube-proxy ipvs 模式這里表現(xiàn)更差,它相比 iptables 的優(yōu)勢(shì)要在 backend 數(shù)量很多的時(shí)候才能體現(xiàn)出來

          CPU 利用率

          我們生成了 1Mpps、2Mpps 和 4Mpps 流量,空閑 CPU 占比(可以被應(yīng)用使用的 CPU)結(jié)果如下:

          結(jié)論與上面吞吐類似。

          • XDP 性能最好,是因?yàn)?XDP BPF 在驅(qū)動(dòng)層執(zhí)行,不需要將包 push 到內(nèi)核協(xié)議棧
          • kube-proxy 不管是 iptables 還是 ipvs 模式,都在處理軟中斷(softirq)上消耗了大量 CPU

          12 eBPF 和 Kubernetes:未來展望

          “The Linux kernel continues its march towards becoming BPF runtime-powered microkernel.”

          “Linux 內(nèi)核繼續(xù)朝著成為 BPF runtime-powered microkernel 而前進(jìn)”。這是一個(gè)非 常有趣的思考角度。

          • 設(shè)想在將來,Linux 只會(huì)保留一個(gè)非常小的核心內(nèi)核(tiny core kernel),其他所有 內(nèi)核功能都由用戶定義,并用 BPF 實(shí)現(xiàn)(而不再是開發(fā)內(nèi)核模塊的方式)。
          • 這樣可以減少受攻擊面,因?yàn)榇藭r(shí)的核心內(nèi)核非常小;另外,所有 BPF 代碼都會(huì)經(jīng)過 verifer 校驗(yàn)。
          • 極大減少 ‘static’ feature creep,資源(例如 CPU)可以用在更有意義的地方。
          • 設(shè)想一下,未來 Kubernetes 可能會(huì)內(nèi)置 custom BPF-tailored extensions,能根據(jù)用戶的應(yīng)用自動(dòng)適配(optimize needs for user workloads);例如,判斷 pod 是跑在數(shù)據(jù)中心,還是在嵌入式系統(tǒng)上。

          BPF will replace Linux.

          我們的目標(biāo)是星辰大海,與此相比,kube-proxy replacement 只是最微不足道的開端。

          13 結(jié)束語

          • Try it out:https://cilium.link/kubeproxy-free
          • Contribute:https://github.com/cilium/cilium

          翻譯鏈接:http://arthurchiao.art/blog/ebpf-and-k8s-zh/


          進(jìn)階訓(xùn)練營第二期

          本次訓(xùn)練營采用線上直播的形式,基于1.19.x版本,根據(jù)第1期課程的打磨,我們總結(jié)出了 Docker 基礎(chǔ) + Kubernetes 基礎(chǔ) + 原理 + 基本使用 + 進(jìn)階技能 +?完整項(xiàng)目實(shí)踐?的課程體系。加強(qiáng)系統(tǒng)知識(shí)吸收夯實(shí)基礎(chǔ)的同時(shí),并在實(shí)際操作過程中去了解排查問題的方式方法,更為重要的是我們的老師非常負(fù)責(zé)任,隨時(shí)幫你答疑解惑,我們認(rèn)為不只是課堂上講授知識(shí),更重要的是售后支持,完全不用擔(dān)心學(xué)習(xí)不到知識(shí)。


          ?點(diǎn)擊屏末?|??|?即刻學(xué)習(xí)

          瀏覽 70
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天堂AV网站 | 国产精品九九九九九九九九九 | 日韩AV电影网 | 大香蕉在线大香蕉国产 | 黄片网站在线观看 |