Ingress

在本篇文章中你將會看到一些在其他地方被交叉使用的術語,爲了防止產生歧義,我們首先來澄清下。

  • 節點:Kubernetes 集群中的服務器;

  • 集群:Kubernetes 管理的一組服務器集合;

  • 邊界路由器:爲局域網和 Internet 路由數據包的路由器,執行防火牆保護局域網絡;

  • 集群網絡:遵循 Kubernetes網絡模型 實現集群內的通信的具體實現,比如 flannelOVS

  • 服務:Kubernetes 的服務 (Service) 是使用標籤選擇器標識的一組 pod Service。 除非另有說明,否則服務的虛擬 IP 僅可在集群內部訪問。

什麼是 Ingress?

通常情況下,service 和 pod 的 IP 僅可在集群內部訪問。集群外部的請求需要通過負載均衡轉發到 service 在 Node 上暴露的 NodePort 上,然後再由 kube-proxy 通過邊緣路由器 (edge router) 將其轉發給相關的 Pod 或者丟棄。如下圖所示

   internet
        |
  ------------
  [Services]

而 Ingress 就是爲進入集群的請求提供路由規則的集合,如下圖所示

image-20190316184154726

Ingress 可以給 service 提供集群外部訪問的 URL、負載均衡、SSL 終止、HTTP 路由等。爲了配置這些 Ingress 規則,集群管理員需要部署一個 Ingress controller,它監聽 Ingress 和 service 的變化,並根據規則配置負載均衡並提供訪問入口。

Ingress 格式

每個 Ingress 都需要配置 rules,目前 Kubernetes 僅支持 http 規則。上面的示例表示請求 /testpath 時轉發到服務 test 的 80 端口。

API 版本對照表

Kubernetes 版本
Extension 版本

v1.5-v1.17

extensions/v1beta1

v1.8-v1.18

networking.k8s.io/v1beta1

v1.19+

networking.k8s.io/v1

Ingress 類型

根據 Ingress Spec 配置的不同,Ingress 可以分爲以下幾種類型:

單服務 Ingress

單服務 Ingress 即該 Ingress 僅指定一個沒有任何規則的後端服務。

注:單個服務還可以通過設置 Service.Type=NodePort 或者 Service.Type=LoadBalancer 來對外暴露。

多服務的 Ingress

路由到多服務的 Ingress 即根據請求路徑的不同轉發到不同的後端服務上,比如

可以通過下面的 Ingress 來定義:

使用 kubectl create -f 創建完 ingress 後:

虛擬主機 Ingress

虛擬主機 Ingress 即根據名字的不同轉發到不同的後端服務上,而他們共用同一個的 IP 地址,如下所示

下面是一個基於 Host header 路由請求的 Ingress:

注:沒有定義規則的後端服務稱爲默認後端服務,可以用來方便的處理 404 頁面。

TLS Ingress

TLS Ingress 通過 Secret 獲取 TLS 私鑰和證書 (名爲 tls.crttls.key),來執行 TLS 終止。如果 Ingress 中的 TLS 配置部分指定了不同的主機,則它們將根據通過 SNI TLS 擴展指定的主機名(假如 Ingress controller 支持 SNI)在多個相同端口上進行復用。

定義一個包含 tls.crttls.key 的 secret:

Ingress 中引用 secret:

注意,不同 Ingress controller 支持的 TLS 功能不盡相同。 請參閱有關 nginxGCE 或任何其他 Ingress controller 的文檔,以瞭解 TLS 的支持情況。

更新 Ingress

可以通過 kubectl edit ing name 的方法來更新 ingress:

這會彈出一個包含已有 IngressSpec yaml 文件的編輯器,修改並保存就會將其更新到 kubernetes API server,進而觸發 Ingress Controller 重新配置負載均衡:

更新後:

當然,也可以通過 kubectl replace -f new-ingress.yaml 命令來更新,其中 new-ingress.yaml 是修改過的 Ingress yaml。

Ingress Controller

Ingress 正常工作需要集群中運行 Ingress Controller。Ingress Controller 與其他作爲 kube-controller-manager 中的在集群創建時自動啓動的 controller 成員不同,需要用戶選擇最適合自己集群的 Ingress Controller,或者自己實現一個。

Ingress Controller 以 Kubernetes Pod 的方式部署,以 daemon 方式運行,保持 watch Apiserver 的 /ingress 接口以更新 Ingress 資源,以滿足 Ingress 的請求。比如可以使用 Nginx Ingress Controller

其他 Ingress Controller 還有:

Ingress Class

在 Ingress Class 之前,要給 Ingress 選擇具體的 Controller,需要加上特殊的 annotation(如 kubernetes.io/ingress.class: nginx)。而有了 IngressClass,集群管理員就可以預先創建好支持的 Ingress 類型,並可以 Ingress 中直接引用。

參考文檔

Last updated