Kubernetes Gateway API v1.1 解讀,你看懂了嗎?
幾天前,K8s Network SIG 發(fā)布了 Gateway API(簡(jiǎn)稱 gwapi)的 v1.1 版本[1],這個(gè)版本的發(fā)布包含了多項(xiàng)重要功能的 GA(一般可用),以及一些實(shí)驗(yàn)功能的引入。這兩部分分別通過標(biāo)準(zhǔn)渠道和實(shí)驗(yàn)渠道發(fā)布。
發(fā)布渠道用于指示網(wǎng)關(guān) API 內(nèi)的功能的穩(wěn)定性。所有新功能和資源都是先從實(shí)驗(yàn)發(fā)布渠道開始,在后續(xù)迭代演進(jìn)的過程中可能會(huì)升級(jí)到標(biāo)準(zhǔn)發(fā)布渠道,也有可能完全從 API 中廢除。
通過下圖可以對(duì) gwapi 的發(fā)布渠道有個(gè)清晰的了解。
圖片
在這些更新中,在我看來(lái)當(dāng)屬服務(wù)網(wǎng)格的支持 GA 最為重要,這意味著服務(wù)網(wǎng)格標(biāo)準(zhǔn) API 向著統(tǒng)一又邁進(jìn)了一步。差不多兩年前,我曾寫過 SMI 與 Gateway API 的 GAMMA 倡議意味著什么, 在 gwapi 差不多 1.0 的時(shí)候,SMI 在停止更新的幾個(gè)月后歸檔了。
標(biāo)準(zhǔn)發(fā)布渠道
GRPCRoute GA
GRPCRoute API 的 v1 版本發(fā)布,標(biāo)志著其可以在生產(chǎn)環(huán)境中穩(wěn)定使用,并得到長(zhǎng)期的支持的維護(hù)。同時(shí) v1alpha2 版本被標(biāo)記為廢棄,在未來(lái)的版本中將會(huì)被移除。
Service Mesh Support GA
gwapi 對(duì)服務(wù)網(wǎng)格的支持正式畢業(yè),并進(jìn)入標(biāo)準(zhǔn)發(fā)布渠道。實(shí)現(xiàn)了對(duì)網(wǎng)格的支持后,可以使用同樣的 API 來(lái)管理東西向(服務(wù)間)的流量,也因此基于 gwapi 構(gòu)建的策略可以在網(wǎng)格中復(fù)用。有興趣的可以看一下去年寫的 探索 Gateway API 在 Service Mesh 中的工作機(jī)制,也可參考 官方文檔[2]。
從 v1.1 開始 xRoute 的可以 attach 到(父資源) Gateway 和 Service 上,具體表現(xiàn)為 parentRef.kind 可以是 Gateway(默認(rèn)) 和 Service。比如:
HTTPRoute 用于網(wǎng)關(guān): 省略 kind: Gateway。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-app-1
spec:
parentRefs:
- name: my-gateway
rules:
...
HTTPRoute 用于服務(wù)網(wǎng)格:
kind: HTTPRoute
metadata:
name: smiley-route
namespace: faces
spec:
parentRefs:
- name: smiley
kind: Service
group: ""
port: 80
rules:
...
一致性檢查的配置文件和報(bào)告 GA
一致性報(bào)告 API 和相應(yīng)的測(cè)試套件已升級(jí)為 GA v1 版本。
關(guān)于一致性報(bào)告:
符合 Gateway API 規(guī)范的實(shí)現(xiàn)是指通過每個(gè) gwapi 捆綁版本(如 gateway.networking.k8s.io/bundle-version: v1.1.0)發(fā)布中包含的一致性測(cè)試的實(shí)現(xiàn)。 所有的 gwapi 實(shí)現(xiàn)必須通過一致性測(cè)試,且不能跳過任何一個(gè)測(cè)試。
在 v1 版本中,ConformanceReport API 擴(kuò)展了 mode 和 gatewayAPIChannel 兩個(gè)字段。前者用于指定實(shí)現(xiàn)的工作模式,后者標(biāo)識(shí)該報(bào)告適用的發(fā)布渠道:標(biāo)準(zhǔn)發(fā)布 standard 或?qū)嶒?yàn)發(fā)布 experimental。
報(bào)告也以更結(jié)構(gòu)化的方式重新組織,實(shí)現(xiàn)現(xiàn)在可以添加有關(guān)測(cè)試運(yùn)行方式的信息并提供復(fù)現(xiàn)步驟。
ParentRef 的 Port 字段 GA
之前,當(dāng)一個(gè) Gateway 上配置了多個(gè)監(jiān)聽器時(shí),如果想要將路由 attach 到指定的端口,
listeners:
- name: foo
protocol: HTTP
port: 8080
...
- name: bar
protocol: HTTP
port: 8090
...
- name: baz
protocol: HTTP
port: 8090
...
可以使用 sectionName 指定監(jiān)聽器的名字,因此需要為監(jiān)聽器通過 name 字段設(shè)置名字。
spec:
parentRefs:
- name: acme-lb
sectionName: foo
現(xiàn)在可以通過 port 字段來(lái)實(shí)現(xiàn)了,因?yàn)槎丝谠诰W(wǎng)關(guān)上也是唯一的,這樣就無(wú)需使用 name 字段。
spec:
parentRefs:
- name: acme-lb
port: 8080
實(shí)驗(yàn)發(fā)布渠道
通過 BackendLBPolicy 支持會(huì)話持久性
通過 BackendLBPolicy 引入會(huì)話持久性(session persistence)支持,該功能來(lái)自 網(wǎng)關(guān)增強(qiáng)提案 GEP-1619[3]。
會(huì)話持久性是指客戶端請(qǐng)求在“會(huì)話”持續(xù)時(shí)間內(nèi)定向到同一后端服務(wù)器。
當(dāng)客戶端直接提供信息(例如請(qǐng)求頭中的 cookie)時(shí),代理將其用作將流量定向到特定服務(wù)器的參考。持久性是負(fù)載均衡的一個(gè)例外:持久性客戶端請(qǐng)求繞過代理的負(fù)載平衡算法,直接到達(dá)之前與之建立會(huì)話的后端服務(wù)器。
見官方的 會(huì)話持久性定義[4]。
gwapi 的會(huì)話持久性,可以作用于服務(wù)粒度,也可以作用與單個(gè)路由。后者的優(yōu)先級(jí)更高,會(huì)覆蓋服務(wù)粒度的會(huì)話持久性配置。
路由粒度的會(huì)話持久性,通過路由規(guī)則中 sessionPersistence 配置。
kind: HTTPRoute
metadata:
name: routeX
spec:
rules:
- matches:
- path:
value: /a
backendRefs:
- name: servicev1
sessionPersistence:
name: session-a
服務(wù)粒度的會(huì)話持久性則是通過 BackendLBPolicy 來(lái)配置。
kind: BackendLBPolicy
metadata:
name: lbp
spec:
targetRef:
kind: Service
Name: servicev1
sessionPersistence:
sessionName: service-cookie
type: Cookie
注:核心 API 中的 type 是 Cookie,在實(shí)現(xiàn)可以擴(kuò)展支持任意請(qǐng)求頭,類型為 Header。
客戶端證書校驗(yàn)
網(wǎng)關(guān)增強(qiáng)提案 GEP-91[5] 討論了如何驗(yàn)證前端客戶端在 TLS 握手協(xié)議期間向服務(wù)器提供的 TLS 證書,可以看作是 mTLS 中的客戶端認(rèn)證。
在官方的核心 API 設(shè)計(jì)中,使用監(jiān)聽器的 tls.frontendValidation 指定的 ConfigMap 中的 CA 證書來(lái)對(duì)客戶端進(jìn)行認(rèn)證。核心 API 只支持一個(gè) ConfigMap,在實(shí)現(xiàn)是可擴(kuò)展支持多個(gè) ConfigMap 或者其他類型如 Service。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: client-validation-basic
spec:
gatewayClassName: acme-lb
listeners:
- name: foo-https
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: foo-example-com-cert
frontendValidation:
caCertificateRefs:
- kind: ConfigMap
group: ""
name: foo-example-com-ca-cert
BackendTLSPolicy
BackendTLSPolicy[6] 是 gwapi 中的一種類型,用于指定通過 Service API 對(duì)象從網(wǎng)關(guān)到后端 Pod(或多個(gè) Pod)的連接的 TLS 配置。與客戶端認(rèn)證正好相反,是對(duì)后端服務(wù)的認(rèn)證。
對(duì)后端服務(wù)的認(rèn)證有兩種:
- 由網(wǎng)關(guān)對(duì)后端服務(wù)進(jìn)行認(rèn)證,即在網(wǎng)關(guān)配置用于認(rèn)證的 CA 證書。
- 有客戶端進(jìn)行認(rèn)證,也就是網(wǎng)關(guān)的透?jìng)鳎╬assthrough)模式。
圖片
相比 v1.0 里的 v1alpha2,v1.1 中的 v1alpha3 發(fā)生的重大變化:
- targetRef 字段現(xiàn)在變?yōu)?nbsp;targetRefs 列表,并且這些引用不再包含命名空間字段。
- tls 字段已更名為 validation。
- caCertRefs 字段已更名為 caCertificateRefs。
- wellKnownCACerts 字段已更名為 wellKnownCACertificates。
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: tls-upstream-auth
spec:
targetRefs:
- kind: Service
name: auth
group: ""
validation:
caCertificateRefs:
- kind: ConfigMap
name: auth-cert
group: ""
hostname: auth.example.com
網(wǎng)關(guān)參數(shù)
不同的 gwapi 實(shí)現(xiàn)使用了不同的負(fù)載均衡器,比如 Envoy Gateway 使用 Envoy,F(xiàn)SM Gateway 使用 Pipy。不同負(fù)載均衡器自身的配置各不相同,而 gwapi 無(wú)法提供通用的接口。因此在 GatewayClass API 上通過 spec.parametersRef 字段提供了配置接口。
不過 GatewayClass 的配置是全局的,針對(duì)所有的 Gateway 實(shí)例,無(wú)法針對(duì)特定的 Gateway 實(shí)例進(jìn)行配置,難以滿足需求。然后就有了 網(wǎng)關(guān)增強(qiáng)提案 GEP-1867[7]。
與 GatewayClass 類似的方式,該提案中 Gateway API 通過 infrastructure.parametersRef 字段配置 `LocalParametersReference`[8],具體由各 gwapi 實(shí)現(xiàn)來(lái)定義。
其他更新
除了兩個(gè)發(fā)布渠道的功能外,還有其他的更新就不一一介紹了。
- gwctl:
get 命令擴(kuò)展以支持 gateways、gatewayclasses 和 namespaces。
describe 命令現(xiàn)在支持描述 policycrds 和 namespaces。
增加了使用標(biāo)簽過濾資源的能力(通過 -l 選項(xiàng))。
修復(fù)了描述 gatewayclasses 時(shí)未描述的錯(cuò)誤。
- 驗(yàn)證變更:不再需要在 Gateway Listeners 上配置 TLS,以實(shí)現(xiàn)更靈活的 TLS 配置。
- 一致性測(cè)試:一致性配置文件已重命名,并新增了 Mesh-GRPC 配置文件。
- 依賴項(xiàng)更新:Gateway API 升級(jí)到 Go v1.22 和 Kubernetes v1.30。
- 清理:刪除了驗(yàn)證 webhook,CEL 驗(yàn)證現(xiàn)在內(nèi)置在 CRDs 中替代 webhook。
更多內(nèi)容可以參考 v1.1.0 更新說明[9]。
參考資料
[1] v1.1 版本: https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0
[2] 官方文檔: https://gateway-api.sigs.k8s.io/mesh/
[3] 網(wǎng)關(guān)增強(qiáng)提案 GEP-1619: https://gateway-api.sigs.k8s.io/geps/gep-1619
[4] 會(huì)話持久性定義: https://gateway-api.sigs.k8s.io/geps/gep-1619/?h=backendlbpolicy#defining-session-persistence
[5] 網(wǎng)關(guān)增強(qiáng)提案 GEP-91: https://gateway-api.sigs.k8s.io/geps/gep-91/
[6] BackendTLSPolicy: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy
[7] 網(wǎng)關(guān)增強(qiáng)提案 GEP-1867: https://gateway-api.sigs.k8s.io/geps/gep-1867
[8] LocalParametersReference: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalParametersReference
[9] v1.1.0 更新說明: https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0