分享實錄|NGINX Gateway API(下)

語言: CN / TW / HK
原文作者:林靜
原文鏈接: 分享實錄|NGINX Gateway API(下)
轉載來源:NGINX 開源社區

NGINX 唯一中文官方社區 ,盡在 nginx.org.cn

編者按 —— 本文為 NGINX Sprint China 2022 年度線上大會的分享實錄,點擊文末此處免費觀看大會完整視頻回放。

本文主要講解關於 NGINX Gateway API 的話題,會從五個方面去和大家探討 NGINX Gateway 的技術實現,內容包括什麼是 Gateway API、理解 Gateway API、為何要發展 Gateway API、瞭解 Gateway API 的當前發展、兩個不同的 Gateway API 實現與演示。

大家可能會有一點點疑問,我們經常説的 API Gatewa 和今天講的 Gateway API,只是説法反過來還是完全不同。線上的小夥伴有知道什麼是 Gateway API 的,可以快速在互動區談談對 G・ateway API 的一個印象,或者是關鍵的一些技術點、關鍵要素。

其實 Gateway API 並沒有錯,API Gateway 會在最後一場專門講述,今天這一場講的是用 NGINX 實現 Gateway API。聽起來繞口,深入瞭解之後,大家就會明白為什麼叫 Gateway API。

理解 Gateway API 的一些細節

瞭解完什麼是 Gateway API 的時候,我們來看一些細節。深潛到海龜維度,海龜一般表達出來的就是穩重,它會有什麼樣的細節?這是一張 CRD 導圖,看不清楚沒有關係,重點去看它的結構就可以了。

首先,導圖的第一個維度,是剛才我們談到的分類 Gateway class,因為當前整個社區的重點還是在 Gateway API 上邊,比如 class、Gateway 以及 http route、像 TCP、UDP 以及 TLS 這些都在實驗階段,沒有更多的定義。

所以上面的已定義的資源對象有很大的一個特點是可以看到它的結構基本上是一個 Metadata,原要素方面的一個描述。

接下來就是關於它的一個 spec。最後關於它的 status 的狀態,所有看到它定義的對象,基本上都是這樣的一個模型,利用 spec 或者利用這樣一個結構去學習這些 CRD 資源的時候,就容易掌握一些,去學習或者瞭解它的時候,你很快通過結構上就可以感受得到。

下面把上面剛才説到的 3 個重要的資源對象,分別截圖再去看。Gateway Class 很重要的一點就是 private reference 。意味着 Gateway Class 是可以去引用一些自定義對象,或者是引用 Kubernetes 裏面的 config map 對象,利用 Gateway Class 裏面屬性的字段去給底層的基礎實施 proxy 產品一些全局性的配置,然後下發。

舉個例子,剛才我們談到 Gatway class 所表述的底層的 provide,f5 的 BIG IP 或者是 NGINX,怎麼去利用?在 Kubernetes 層面,通過直接下發一些配置項或者是參數,直接影響底層的 NGINX 或者是 BIG IP 的配置,可以利用裏面的 private 事情去做。

在一個集羣裏面有很多個不同的 Gatway Class,可以對應到不同的底層 provider,給一個集羣同時提供 NGINX 也同時提供 f5 的 BIG IP,甚至是第三方其他 privacy 類的產品都可以同時使用。

然後是 Gatway,剛才有提到它是表述 proxy 上面具體的配置,比如 address, virtual address 就是 VIP 地址,或者你的端口還有處理的協議、加載什麼樣的證書,都可以看到這樣的一些配置。在這個維度還有 host name,如果大家都在學 NGINX,就知道這個地方的配置很像 NGINX 裏面 server 塊,映射到底層的一些配置項。

到 HTTP Route 裏就更多了,這是我們剛才説到的在網關層面作用,圍繞着 HTTP 流量去處理,很多流量上層的事情要去操作。這個時候你就會看到,在 HTTP route 裏面,rules 可以去做 URL 的匹配、rewrite、改寫或者是 head 頭的改寫都可以在 filter 裏面去做。

backend 這樣的引用到我們剛才説到的 Kubernetes 後面的 service 等等一些對象上去就表述出來了。相當於是從 Gatway 到 HTTP route 之間的層次關係。Gatway 定義了一些基本網絡層面的屬性、IP 地址協議等等。在 root 層面就定義更多的一些策略或者是一些操作的 action。

另外一點,大家也可以注意看到,在 HTTP route 裏面也有一個 host name 的字段,Gatway 裏面也有字段,server 層面也有 host name,到下面具體的路由層面還有一個 host name。而真正去做的時候,這些地方應該是匹配起來的。

再一點,剛才我們提到的,在所有的這些資源對象當中,都有 statues 的狀態。這些 statues 的狀態非常好的幫助我們去了解下發資源的狀態。比如這樣的配置有沒有正確的下發到底層。

這樣一些配置的關聯,比如 route 跟 Gateway 之間關聯有沒有出錯或者是為什麼不能關聯上,就可以通過各個資源的 status 對應出來,整個設計還是比較精簡化的。沒有什麼太多沒有用的東西,基本上只是定義了現在必須要的東西。

有了這樣的一些基本知識或者瞭解一些細節之後,可以做一個簡單的小總結。也就是今天講的 Gateway API 到底可以總結出哪些關鍵屬性?

第一點總結,它是幫助我們從單一的自服務演進到了基於角色的自服務。這句話聽起來有點抽象,但是大家如果已經在實踐中大量使用了 Ingress,畢竟在企業當中,你會把整個 Kubernetes 平台給到業務員去使用的時候,就能深刻感受到這裏面的變化。

左邊是一個標準的 Ingress,在定義裏面會看到有相應的 TLS 證書部分的要素,還有規則部分的要素、host name 的要素,業務部分基於 PaaS 這些應用部門關心的一些要素。

你會看到所有的這些要素都在同一個文件裏面,那麼在實際工作中到底是讓誰來管理?如果是業務部門來管理,往往實際功能,很多用户還是由業務部門來寫這些 Ingress 或者是應用的負責人去寫這些 Ingress。

這個時候 Ingress 就意味着業務部門或者應用管理人員,實際上是需要向企業裏面的一些基礎實施人員去了解到這個東西底層用的是什麼技術、上面有哪些可擴展的字段配置是給到我的,我要去學習跟底層相關性的一些東西。

同時還會知道,這個服務到底要掛公司的哪一套證書,證書的有效期什麼時候去更新,什麼時候去迭代?本身這個事情不應該由業務部門去管?它應該有基礎架構實施的一些平台或者是基礎架構層面的人去管。

但是因為 Ingress 的設計,使得我們不得不去讓業務部門或者應用人員去考慮這些問題。所以即便後來我們有了 Ingress class 去做區分,但是它依然不能夠很有效地把上底層的這種基礎架構實施直接表達在上層一個對象。

因為 Ingress Class 更多的時候表達出來的是一個 shutting,它很難去傳遞一些配置、要素到底層。所以它即便加了 Ingress Class 之後,Ingress 裏面角色對象區分還是不夠清晰。

當進入到 Gateway API 模型之後,就可以比較清晰地看到把三個維度全部拆開,每一個維度的人員、每一個維度的對象都有自己的資源對象去管控,各個部分都有邊界。這樣的好處是進入到演進 2, 因為有了角色、資源對象,就可以做 RBAC。

什麼樣的人基於什麼樣的角色做什麼樣的資源控制,RBAC 就很好去設計。建議有 4 種標準的對象,還可以做一些其他工作,比如應用的管理人員,在局部的 name space 下有 Gateway 層面的瞭解權限。

比如現在一個應用是一個大項目組,它底下有很多的小應用,找到足夠派到大應用的一個基礎架構人員去了解到它或者管理到在 name space 下的一些屬性,包括剛才談到的提供什麼樣的證書,使用什麼樣的 Gateway Class。

這樣調整的邊界或者邏輯就會比較清晰,不至於是混合在一起的時候,讓不同的人去管理同一個文件,相對來説,一個企業裏面安全度、協作度會高一些,RBAC 就很好做。

第三點就是剛才談到的可移植性,因為我們已經談到了很多的資源對象,但是這些資源對象怎麼分類、怎麼樣去實現、確保可移植性是標準化可落地的?Kubernetes 的 Gateway API 在社區裏面定義了三類資源對象。

第一類是核心類的 Core。剛才談到的 routing、Traffic Splitting、Gateway、Gateway Class 等等都屬於 Core 部分要去實現的,意味着所有的提供商實現者都必須按照嚴格的要求做擴展,去實現一定是按照社區的標準,隨着使用越來越多,未來普遍性越來越高。它可能會把 extended 部分的 API 資源挪到 Core 部分中去。

第三部分就是完全自定義的,不同的實現者和不同的實現廠商去實現會有自己的操作空間,有 room 去實現它自己的能力。比如 NGINX、NGINX plus 裏面有很多特有的特性,能不能通過在這個位置上面去實現這些特性?其實可以通過 Custom 這個地方去實現,以之為導向。這些東西生態上是統一的,大家都遵循同樣一套規範、標準,發展起來會比較容易。

為何要發展 Gateway API

另外一個維度,是剛才談到的技術層面,Ingress 有很多的缺陷或者能力不足,包括它剛才説到需要很多的 annotations,很多協議是不能夠擴展的。怎麼樣去解決這些問題,就要依賴於 Gateway API 去解決 Ingress 的不足。

剛才談到的角色同樣也需要解決。整個社區資源和資源所屬對象之間充滿摩擦,這個時候團隊之間需要基於契約來討論一個事情,那麼團隊和 owner 之間溝通成本就會比較低,比如企業的 SRE 有具體的細分,每個角色之間就需要更多的溝通,如果溝通不在一張白紙上去溝通,那就意味着要儘量讓大家在同一個層面溝通。

有了這個能力後,我們談到的 Gateway Class 實現它有一個很大的好處是它可以引用自定義,或者是引用 Kubernetes 的 config map。

所引用配置項、配置對象資源,都屬於 Kubernetes 裏面的資源。那就意味着底層的基礎實施提供者所維護的這些東西,變成了站在 Kubernetes 角度去維護,會把傳統的團隊和 Kubernetes 團隊更好地融合起來,在企業裏面做的 SRE 和 Devops 也更好地融合起來。這樣就幫助企業融合了傳統技術架構師和 Kubernetes 團隊之間的關係。

另外一方面它也解決了一個問題,以前 Kubernetes 都是站在開發者的角度思考問題。當然也有小夥伴表示,現在 Kubernetes 很多都是在平台部門在做,但本質上講,Kubernetes 本身在設計階段很多東西還是站在有利於開發者的角度定義非常簡單的網絡規範。

只要兩個之間能夠通,不管用什麼方法通,就意味着兩個 pose 之間是可以服務通訊的,是站在比較理想化的角度去做這些事情,但是當你把整個 Kubernetes 這樣一套平台落到一個企業當中的時候,考慮的問題不單單是有利於開發者的一個問題,還要考慮有利於基礎架構實施、有利於網絡、有利於安全。

Gateway API 其實就是要去做這樣一些融合的事情。正如剛才我們講到的,一個 Ingress 的資源是耦合的,可以通過一個很具體的當前資源考慮怎麼去把它拆分開。先在界面上看這兩個資源拆分,就可以看出來它的一些變化。

左側是標準的 Ingress,如果我們要做這個事情,它有很多的 Annotations、規則要去考慮。但是如果在新的 Kubernetes Gateway API 的模型下去考慮這個問題,可以通過拆分成不同的資源對象、不同的要素,去實現。

Gateway & route 層面,都是在關注自己的東西,而不是關注別的東西,每個人都有每個人的角色,大家在一個規則的角度、遵守一種規則,去做同樣的一個事情或者達成同樣一個目標,這才是融合。

剛才我們談的這些,其實都是技術層面的原因,實際上,如果拋開技術問題,思考為什麼社區要去做 Gateway API,大家可以從三個角度去理解的,第一個就是產品,第二個是市場,第三個是客户。

從產品角度來講,本質上是因為 Kubernetes 已經趨於穩定,大量的客户在踐行 Kubernetes,這個時候它早期面向開發者設計的很多能力都需要去補齊。

大家今天看 Kubernetes 的一些更新迭代發展,它增加 endpoint slices、增加多集羣的這些功能其實都是在真正落進深水區之後。它本身並不是面向開發者的,但也越來越開始面向基礎架構實施去增強一些能力。所以從產品的角度,社區、Kubernetes 上游社區,需要解決上邊的不足去還這樣的技術債。

第二個就是市場,市場其實是教育了 Kubernetes 的上游。在開源社區裏面,Kubernetes 提供了一個生態,有眾多的玩家在這裏玩。甚至有很多的玩家是來自於非常強的企業級市場的領導者,他們實際上對真正的企業用户、實際終端用户有大量的經驗,這些企業所製造的產品或者是所提出來的概念會被反哺,或者是會被吸收到社區當中。

其實我們剛才談到的 Gateway API 裏面很多的資源對象設計的思路,在 Istio、Aspen mesh 都能夠看得到。包括 NGINX 做的 Ingress controller 當中提供的 mogeable 的 Ingress,基於 CRD 模式的概念等,本質上都是講角色拆分的概念,幫助我們去解決實際的問題。所以你會看到它們最終都被社區或者上游吸收過去了,這是市場給到社區的反饋。

一個 a 解決方案,不能遷移到另外一個環境,不能遷移到 b 解決方案的時候,對於用户來説是有成本的,所以從社區角度來講,它需要面對客户去提供一個儘量標準的方向。隨着用户成熟度提高,生產場景越來越豐富,就意味着社區需要去做這些事情。

瞭解 Gateway API 的當前發展

我們深知用户的企業當中,很難有真正理想化的團隊在一起的工作。越是踐行 Kubernetes 技術比較早的大型客户,它的歷史 IT 規模越大。往往它都是多團隊、跨團隊的,這些基礎實施、團隊相互之間是需要協作、互相連接的。

所以從產品、市場到客户,我們都可以看到 Kubernetes 本身是極大要改變的,因此當前 Gateway API 的發展就變得非常的迫切。截至 2022.11. 尚處於 Beta,主要實現了 HTTP Route,其它部分資源對象依然尚未實現或處於試驗狀態。

Istio 也開始兼容 Gateway API,使得在服務網格中使用統一的 Gateway API 管理南北與東西流量成為新晉方向。對於用户來説,管理成本低、心智好。

Tetrate、linkerd、Istio 均在繼續推進支持 Gateway API 的接口規範。社區裏面有一個 GAMMA 小組,是 Gateway API for Mesh 的管理小組,他們會去推動在南北向、東西向規範的統一。這樣用户在 Kubernetes 裏面,管理流量標準會更加統一。

我們剛才講可移植性、標準化是很好的,但它也會帶來限制性。上游社區本身非常開放會比較好,但是如果上游社區,希望藉助這樣一個標準去非標準化,可能會限制一些實現廠商的創新,這個也是在社羣裏看到的一個爭議比較大的地方。

不要讓 Gateway API 變成少數公司控制方向的一個東西,而是要儘量的兼容,我們希望是真正能夠站在用户的角度去考慮,而不是過度標準化。

另外一點,整個生態當中,f5、NGINX 在積極發展,我們有一張圖去闡述這樣的一個生態。整個生態中,上游的 Kubernetes 的 SIG 小組帶領 Gateway API 規範定義之後,整個生態比較豐富。無論是貢獻者、控制器層面的開發者,還是數據面的參與者都是比較豐富的。

可以看到大量的 proxy 類型,或者是 Ingress 領域當中已經存在的玩家,依然在這裏是最活躍的,因為本身這些技術是相通的,它只是一個新的下一代標準。

其中數據面還是比較有意思的,數據面依然是公有云廠商基於自己的 load Balance 數據面去實現 Gateway API。我們看到 GCP 是目前唯一一個在公有云上進入到一個 GA 狀態的,基於 Gateway API 實現了很多的特點。

另外一點就是基於 proxy 軟件,比如 envoy、NGINX,envoy 屬於雲原生領域上大家比較關注的新生代,它功能確實很強大,但是也很複雜。另外一點就是像 NGINX 這些老牌的廠商或者老牌的產品,本身的技術棧已經被大量的用户使用,今天上午看到的很多的企業都在用 NGINX。

這樣的好處是對於用户來説學習的成本比較低,學習的曲線不會像 envoy 那麼高,掌控度也更容易,因為我們使用的是熟悉的技術領域去做這樣的事情。

還有一塊領域基於 F5,F5 本身屬於在基礎架構層面提供了很多能力的實施,它可以是軟件的,也可以是硬件的。當我們需要在企業裏面提供很多企業級的豐富特性、專有協議的一些特性,或者是需要非常高的性能的時候,以 F5 作為這種模型的數據面,它也是一個很好的選擇,可以有效地把基礎實施層面和 K8s 這樣的一些流量進行連接,幫助 K8s 更好地發佈流量,所以生態還是比較豐富的。

當前的 Gateway API 的實現方其實有很多,剛才説的整個社區,本身只是做了一個規範,並沒有去做實現,實際上要靠各種各樣的解決方案去提供。當然大家也可以看到,目前所有的廠商或者是所有的解決方案都還沒有進入到真正激烈的狀態。也是因為 Gateway API 還在定義或者發展當中,所以這些實現方也都還沒有進入到激烈的狀態。

但是我們相信隨着 Gateway API 進一步的發展,相應的實現方也就會伴隨着它很快實現產品的發佈。


NGINX 唯一中文官方社區 ,盡在 nginx.org.cn

更多 NGINX 相關的技術乾貨、互動問答、系列課程、活動資源: