Kubernetes:Ingress總結(一)

不羈的羅恩發表於2022-03-17

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 示例:

image-20220317141340808

通常情況下,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),每個路徑都有一個由 serviceNameservicePort 定義的關聯後端。 在負載均衡器將流量定向到引用的服務之前,主機和路徑都必須匹配傳入請求的內容。
  • backend(後端)是 Kubernetes:服務與負載均衡中所述的服務和埠名稱的組合。 與規則的 hostpath 匹配的對 Ingress 的 HTTP(和 HTTPS )請求將傳送到列出的 backend

通常在 Ingress 控制器中會配置 defaultBackend(預設後端),以服務於任何不符合規約中 path 的請求。

?注意:沒有 rules 的 Ingress 將所有流量傳送到同一個預設後端。如果 hostspaths 都沒有與 Ingress 物件中的 HTTP 請求匹配,則流量將路由到預設後端。

路徑型別

Ingress 中的每個路徑都需要有對應的路徑型別(Path Type)。未明確設定 pathType 的路徑無法通過合法性檢查。當前支援的路徑型別有三種:

  • ImplementationSpecific:對於這種路徑型別,匹配方法取決於 IngressClass。 具體實現可以將其作為單獨的 pathType 處理或者與 PrefixExact 型別作相同處理。
  • 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 允許你將負載均衡器的數量降至最低。例如,這樣的設定:

image-20220317143027055

配置如下:

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 地址上。

image-20220317145747418

總結

Kubernetes的Ingress簡單理解就是個規則定義,例如某個域名對應某個Service,即當某個域名的請求進來時,轉發給某個Service。Ingress Controller負責實現這個規則,即Ingress Controller將其動態寫入負載均衡器的配置中,從而實現服務的負載均衡。

相關文章