在上一章中,學習如何使用Service物件以固定的IP暴露一組 pod。如果使用LoadBalancer服務類型,此Service將利用負載平衡器提供給叢集外部的客戶端。 如果您只需要在外部暴露單個服務,則此方法很好,但是對於大量服務,它會出現問題,因為每個服務都需要自己的外部IP。
幸運的是,利用Ingress物件暴露這些服務,您只需要一個IP。 此外,Ingress還提供其他功能,例如 HTTP身份驗證、基於cookie的session affinity、URL rewrite以及其他Service物件無法提供的功能。
在k8s中,Ingress是外部客戶端訪問叢集中運行的應用程式服務的一種方式。Ingress功能由以下三個元件組成:
<aside> 💡 與forward proxy(轉發代理)不同,forward proxy轉發和過濾傳出流量並且通常與它所服務的客戶端位於同一位置。 reverse proxy處理傳入流量並將流量路由到一個或多個後端Server。reverse proxy位於這些服務器附近。
</aside>
在大多數線上內容中,Ingress controller 一詞通常來用將負載平衡器/反向代理和實際controller稱為一個實體,但它們是兩個不同的元件。
我還使用術語proxy來表示L7負載平衡器,因此您不要將它與處理LoadBalancer類型服務的流量的L4負載平衡器混淆。
當您想在外部暴露一組服務時,您可以建立一個Ingress物件並且在其中引用Service物件。 k8s使用這個Ingress物件來設定一個L7負載平衡器(一個 HTTP 反向代理),使外部客戶端可以透過一個通用入口點來訪問服務。
<aside> 💡 如果使用 Ingress 暴露 Service,通常可以保留Service的type設定為ClusterIP。但是,某些Ingress實作會要求Service類型為NodePort。
</aside>
雖然Ingress物件可用來暴露單個Service,但Ingress通常與多個Service物件結合使用,如下圖。 該圖顯示了單個Ingress物件如何使Kiada套件中的所有3個服務都可提供外部客戶端訪問。
圖 12.1 一個 Ingress 將外部流量轉發到多個服務
Ingress物件包含根據HTTP請求中的資訊將流量路由到3個服務的規則。這些服務的對外DNS紀錄都指向同一個Ingress。Ingress決定哪個服務應該從請求本身接收請求。 如果客戶端請求指定了host : kiada.example.com,則Ingress會將流量轉發到屬於kiada服務的pod。 而指定host : api.example.com的請求將轉發到quote或quiz服務,←這就取決於請求的路徑。
一個Ingress物件通常處理特定k8s命名空間中所有Service物件的流量,但多個Ingress也是一種選擇。 通常,每個Ingress物件都有自己的IP,但某些Ingress實作為您在叢集中建立的所有Ingress物件會使用一個共用入口點。
並非所有k8s叢集都支援開箱即用的Ingress。此功能由Ingress controller的叢集附加元件所提供的。 此controller是Ingress物件和真實實體ingress(反向代理)之間的連接。controller和proxy通常當作兩個程序在同一個容器中運行,或者當作兩個容器在同一個pod中運行。 這就是為什麼人們使用術語Ingress controller來表示兩者。
有時controller或proxy位於叢集外部。例如,GKE提供了自己的Ingress controller,該controller使用GCP的L7負載平衡器來幫叢集提供Ingress功能。
如果您的叢集部署在多個zone中,則單個Ingress就可以處理所有zone的流量。例如,它根據客戶端所在的位置將每個HTTP請求轉發到最佳zone。
有很多種Ingress controller可供選擇。k8s社區在https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/維護了一個列表。 其中最受歡迎的是Nginx ingress controller、Ambassador、Contour和Traefik。這些Ingress controller中的大多數使用Nginx、HAProxy或Envoy當作反向代理,但有些使用自己的proxy實作。