Kubernetes:Ingress總結(一)
- 2022 年 3 月 17 日
- 筆記
- cloudnative, Ingress, Kubernetes, 流量, 路由
Blog:部落格園 個人
參考:Ingress | Kubernetes、《Kubernetes進階實戰》、《Kubernetes網路權威指南 》
何謂Ingress?從字面意思解讀,就是入站流量。Kubernetes的Ingress資源對象是指授權入站連接到達集群內服務的規則集合。
我們知道,Kubernetes上的NodePort和LoadBalancer類型的Service資源能夠把集群內部服務暴露給集群外部客戶端訪問,但兩個負載均衡躍點(路由)必然產生更大的網路延遲,且無疑會大大增加組織在使用雲服務方面的費用開銷。
因此,Kubernetes為這種需求提供了一種更為高級的流量管理約束方式,尤其是對HTTP/HTTPS協議的約束。Kubernetes使用Ingress控制器作為統一的流量入口,管理內部各種必要的服務,並通過Ingress這一API資源來描述如何區分流量以及內部的路由邏輯。有了Ingress和Ingress控制器,我們就可通過定義路由流量的規則來完成服務發布,而無須創建一堆NodePort或LoadBalancer類型的Service,而且流量也會由Ingress控制器直接到達Pod對象。
Kubernetes Ingress提供了負載平衡器的典型特性:HTTP路由、黏性會話、SSL終止、SSL直通、TCP和UDP負載平衡等。目前,並不是所有的Ingress Controller都實現了這些功能,需要查看具體的Ingress Controller文檔。Ingress控制器有各種類型,包括GoogleCloud Load Balancer、Nginx、Istio等。有些Ingress Controller可能還依賴各種插件,例如cert-manager,它可以為服務自動提供SSL證書。
Tips:人們通常把Kubernetes集群內部的通訊稱為東西向流量,而把集群內外部的通訊稱為南北向流量。
下面是一個將所有流量都發送到同一 Service 的簡單 Ingress 示例:
通常情況下,Service和Pod僅可在集群內部網路中通過IP地址訪問。所有到達邊界路由的流量或被丟棄或被轉發到其他地方。
Ingress的作用就是在邊界路由處開個口子,放外部流量進來。因此,Ingress是建立在Service之上的L7訪問入口,它支援通過URL的方式將Service暴露到k8s集群外;支援自定義Service的訪問策略;提供按域名訪問的虛擬主機功能;支援TLS通訊。
Ingress規則
每個 HTTP 規則都包含以下資訊:
- 可選的
host
。在此示例中,未指定host
,因此該規則適用於通過指定 IP 地址的所有入站 HTTP 通訊。 如果提供了host
(例如 foo.bar.com),則rules
適用於該host
。 - 路徑列表 paths(例如,
/testpath
),每個路徑都有一個由serviceName
和servicePort
定義的關聯後端。 在負載均衡器將流量定向到引用的服務之前,主機和路徑都必須匹配傳入請求的內容。 backend
(後端)是 Kubernetes:服務與負載均衡中所述的服務和埠名稱的組合。 與規則的host
和path
匹配的對 Ingress 的 HTTP(和 HTTPS )請求將發送到列出的backend
。
通常在 Ingress 控制器中會配置 defaultBackend
(默認後端),以服務於任何不符合規約中 path
的請求。
注意:沒有
rules
的 Ingress 將所有流量發送到同一個默認後端。如果hosts
或paths
都沒有與 Ingress 對象中的 HTTP 請求匹配,則流量將路由到默認後端。
路徑類型
Ingress 中的每個路徑都需要有對應的路徑類型(Path Type)。未明確設置 pathType
的路徑無法通過合法性檢查。當前支援的路徑類型有三種:
ImplementationSpecific
:對於這種路徑類型,匹配方法取決於 IngressClass。 具體實現可以將其作為單獨的pathType
處理或者與Prefix
或Exact
類型作相同處理。Exact
:精確匹配 URL 路徑,且區分大小寫。Prefix
:基於以/
分隔的 URL 路徑前綴匹配。匹配區分大小寫,並且對路徑中的元素逐個完成。 路徑元素指的是由/
分隔符分隔的路徑中的標籤列表。 如果每個 p 都是請求路徑 p 的元素前綴,則請求與路徑 p 匹配。
注意:如果路徑的最後一個元素是請求路徑中最後一個元素的子字元串,則不會匹配 (例如:
/foo/bar
匹配/foo/bar/baz
, 但不匹配/foo/barbaz
)。
例如:
類型 | 路徑 | 請求路徑 | 匹配與否? |
---|---|---|---|
Prefix | / |
(所有路徑) | 是 |
Exact | /foo |
/foo |
是 |
Exact | /foo |
/bar |
否 |
Exact | /foo |
/foo/ |
否 |
Exact | /foo/ |
/foo |
否 |
Prefix | /foo |
/foo , /foo/ |
是 |
Prefix | /foo/ |
/foo , /foo/ |
是 |
Prefix | /aaa/bb |
/aaa/bbb |
否 |
Prefix | /aaa/bbb |
/aaa/bbb |
是 |
Prefix | /aaa/bbb/ |
/aaa/bbb |
是,忽略尾部斜線 |
Prefix | /aaa/bbb |
/aaa/bbb/ |
是,匹配尾部斜線 |
Prefix | /aaa/bbb |
/aaa/bbb/ccc |
是,匹配子路徑 |
Prefix | /aaa/bbb |
/aaa/bbbxyz |
否,字元串前綴不匹配 |
Prefix | / , /aaa |
/aaa/ccc |
是,匹配 /aaa 前綴 |
Prefix | / , /aaa , /aaa/bbb |
/aaa/bbb |
是,匹配 /aaa/bbb 前綴 |
Prefix | / , /aaa , /aaa/bbb |
/ccc |
是,匹配 / 前綴 |
Prefix | /aaa |
/ccc |
否,使用默認後端 |
混合 | /foo (Prefix), /foo (Exact) |
/foo |
是,優選 Exact 類型 |
在某些情況下,Ingress 中的多條路徑會匹配同一個請求。 這種情況下最長的匹配路徑優先。 如果仍然有兩條同等的匹配路徑,則精確路徑類型優先於前綴路徑類型。
主機名通配符
主機名可以是精確匹配(例如「foo.bar.com
」)或者使用通配符來匹配 (例如「*.foo.com
」)。 精確匹配要求 HTTP host
頭部欄位與 host
欄位值完全匹配。 通配符匹配則要求 HTTP host
頭部欄位與通配符規則中的後綴部分相同。
主機 | host 頭部 | 匹配與否? |
---|---|---|
*.foo.com |
bar.foo.com |
基於相同的後綴匹配 |
*.foo.com |
baz.bar.foo.com |
不匹配,通配符僅覆蓋了一個 DNS 標籤 |
*.foo.com |
foo.com |
不匹配,通配符僅覆蓋了一個 DNS 標籤 |
Ingress類型
單個Service實現
現有的 Kubernetes 概念允許你暴露單個 Service,例如:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: test
port:
number: 80
執行:
[root@master test]# kubectl apply -f ./test-ingress.yaml
ingress.networking.k8s.io/test-ingress created
簡單扇出(Simple fanout)
一個扇出(fanout)配置根據請求的 HTTP URI 將來自同一 IP 地址的流量路由到多個 Service。 Ingress 允許你將負載均衡器的數量降至最低。例如,這樣的設置:
配置如下:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /foo
pathType: Prefix
backend:
service:
name: service1
port:
number: 4200
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
基於名稱的虛擬託管(Name based virtual hosting)
基於名稱的虛擬主機支援將針對多個主機名的 HTTP 流量路由到同一 IP 地址上。
總結
Kubernetes的Ingress簡單理解就是個規則定義,例如某個域名對應某個Service,即當某個域名的請求進來時,轉發給某個Service。Ingress Controller負責實現這個規則,即Ingress Controller將其動態寫入負載均衡器的配置中,從而實現服務的負載均衡。