作者:Nick Ramirez
原文鏈接:https://thenewstack.io/kubernetes-ingress-for-beginners/
本文轉載自Rancher Labs
不知道你是否注意到一個奇怪的現象,盡管Kubernetes Ingress API仍然處于beta狀態,但是已經有許多公司使用它來暴露Kubernetes服務,從事相關專案的工程師表示,Kubernetes Ingress API越來越有可能摘下其beta標簽,實際上,Kubernetes Ingress API處于beta狀態已經持續了幾年的時間,準確來說,是在2015年秋季開始進入該階段的,但是,漫長的beta階段可以讓Kubernetes貢獻者有時間來完善規范并使其與已經搭建好的實施軟體(HAProxy、NGINX、Traefik等)保持一致,從而使API標準化以反映最常見并且有需求的功能,

隨著該功能GA的臨近,那么現在應該是一個合適的時機可以幫助新手快速了解Ingress的作業方式,簡而言之,Ingress是一個規則,可以繪制出在集群內部的服務如何彌合鴻溝,暴露到客戶可以使用它的外部世界,同時,稱為Ingress controller的代理在集群網路的邊緣進行偵聽(監視要添加的規則),并將每個服務映射到特定的URL路徑或域名以供公眾使用,在Kubernetes維護者開發API的同時,其他開源專案也實作了Ingress Controller并為其代理添加了自己的獨特功能,
在本文中,我將介紹這些概念,并幫助你了解Ingress模式背后的驅動力,
路由問題
在Kubernetes中創建Pod時,需要為其分配selector標簽,如Deployment manifest的以下片段所示:

該Deployment創建了運行Docker鏡像my-app的三個副本,并為其分配app=foo標簽,除了直接訪問Pod,通常將它們分組在Service下,這使它們可以在單個集群IP地址上使用(但是只能在同一集群中使用),Service充當抽象層,隱藏了pod的周期短暫特性,可以隨時增加或減少或替換它們,它還可以執行基本的回圈負載均衡,
例如,以下Service定義收集所有帶有selector標簽app = foo的Pod,并在其中平均路由流量,

但是,只能從集群內部以及運行在附近的其他Pod訪問此服務,Kubernetes Operator正在努力解決如何為集群外部的客戶端提供訪問權限,該問題在早期就已經出現,并且將兩種機制直接集成到Service規范中進行處理,撰寫service manifest時,包括一個名為type的欄位,該欄位的值為NodePort或LoadBalancer,這是一個將型別設定為NodePort的示例:

NodePort型別的服務使用起來很簡單,本質上,這些服務希望Kubernetes API為他們分配一個隨機的TCP埠,并將其暴露到集群之外,這樣做的方便之處在于,客戶端可以使用該埠將集群中的任何節點作為目標,并且他們的訊息將被中轉到正確的位置,這就類似于你可以撥打美國境內的任何電話,而接聽電話的人都會確保為你轉接到合適的人,
缺點在于,該埠的值必須介于30000到32767之間,雖然這個范圍安全地避開了常用埠地范圍,但是與常見的HTTP埠80和HTTPS 443相比,該埠顯然不是很標準,此外,隨機性本身也是一個障礙,因為它意味著你事先不知道值是什么,這使得配置NAT、防火墻規則更具挑戰性——尤其是需要為每項服務設定不同的隨機埠,
另一個選項是將型別設定為LoadBalancer,但是,這有一些前提條件——僅當你在GKE或EKS之類的云托管環境中運行并且可以使用該云供應商的負載均衡器技術時,它才有效,因為它是自動選擇并配置的,其缺點是比較昂貴,因為使用這種型別的服務會為每個服務啟動一個托管的負載均衡器以及一個新的公共IP地址,這會產生額外的費用,
Ingress路由
分配一個隨機埠或外部負載均衡器是很容易操作的,但也帶來了獨特的挑戰,定義許多NodePort服務會造成隨機埠混亂,而定義許多負載均衡器服務會導致需要支付比實際所需更多的云資源費用,這些情況不可能完全避免,但也許可以減少它的使用范圍,甚至你只需要分配1個隨機埠或1個負載均衡器就能夠暴露許多內部服務,因此,這一平臺需要一個新的抽象層,該層可以在入口點(entrypoint)后面整合許多服務,
那時,Kubernetes API引入了一種稱為Ingress的新型manifest,它為路由問題提供了新的思路,它的作業方式是這樣的:你撰寫一個Ingress manifest,宣告你希望客戶端如何路由到服務,manifest實際上并不自行執行任何操作,你必須將Ingress Controller部署到你的集群中,以監視這些宣告并對其執行操作,
與其他任何應用程式一樣,Ingress controller是Pod,因此它們是集群的一部分并且可以看到其他Pod,它們是使用在市場上已經發展了多年的反向代理搭建的,因此,你可以選擇HAProxy Ingress Controller、NGINX Ingress Controller等,底層代理為其提供了第7層路由和負載均衡功能,不同的代理將自己的功能集放到表中,例如,HAProxy Ingress Controller不需要像NGINX Ingress Controller那樣頻繁地重新加載,因為它為服務器分配了slot,并使用Runtime API在運行時填充slot,這使得該Ingress Controller擁有更好的性能,
Ingress Controller本身位于集群內部,與其他Kubernetes Pod一樣,也容易受到同一“監獄”的“監禁”,你需要通過NodePort或LoadBalancer型別的服務將它們暴露到外部,但是,現在你只有一個入口點,所有流量都將通過此處:一個服務連接到一個Ingress Controller,Ingress Controller依次連接到許多內部Pod,Controller具有檢查HTTP請求的功能,可以根據其發現的特征(例如URL路徑或域名)將客戶端定向到正確的Pod,
參考這個Ingress的示例,該示例定義了URL路徑/foo應該如何連接到名為foo-service的后端服務,而URL路徑/bar被定向到名稱為bar-service的服務,

如上文所示,你依舊需要為你的Pod設定服務,但是你不需要在Pod上設定型別欄位,因為路由和負載均衡將由Ingress層處理,服務的作用被簡化為以通用名稱對Pod進行分組,最終,兩個路徑,/foo和/bar,將由一個公共IP地址和域名提供服務,例如example.com/foo 和 example.com/bar ,本質上,這是API網關模式,在API網關中,單個地址將請求路由到多個后端應用程式,
添加Ingress Controller
Ingress manifest的宣告式方法是你可以指定所需的內容,而無需知道如何實作,Ingress Controller的作業之一是執行,它需要監控新的ingress規則并配置其底層代理以制定相應的路由,
你可以使用Kubernetes包管理工具Helm安裝HAProxy Ingress Controller,首先,通過下載Helm二進制檔案并將其復制到PATH環境變數中包含的檔案夾(例如/usr/local/bin/)中來安裝Helm,接下來,添加HAProxy Technologies Helm庫,并使用helm install命令部署Ingress Controller,

通過運行命令kubectl get service列出所有正在運行的服務來驗證是否已創建Ingress Controller,

HAProxy Ingress Controller在集群的pod中運行,并使用NodePort型別的Service資源發布對外部客戶端的訪問,在上面顯示的輸出中,你可以看到為HTTP選擇了埠31704,為HTTPS選擇了埠32255,你還可以在埠30347上查看HAProxy資訊統計頁面,HAProxy Ingress Controller會提供有關流經它的流量的詳細指標,因此你可以更好地觀察到進入集群的流量,
在controller創建型別為NodePort的服務時,這意味著需要分配一個隨機的埠并且埠編號往往很高,但是現在你只需管理幾個此類埠,也就是只需管理連接到Ingress Controller的埠,無需再為每個服務創建一個埠,你也可以將其配置為使用LoadBalancer型別,只要在云端進行操作即可,它看起來如下:

總體而言,不需要管理太多Ingress Controller,安裝后,它基本上會在后臺執行其作業,你只需要定義Ingress manifest,controller就會立即將它們連接起來,Ingress manifest的定義與參考的服務有所區別,因此你可以控制何時暴露服務,
結 論
Ingress資源通過允許API網關樣式的流量路由,整合了外部客戶端如何訪問Kubernetes集群中的服務,代理服務通過公共入口點(entrypoint)進行中轉,你可以使用intent-driven、YAML宣告來控制何時以及如何公開服務,
當Ingress API這一功能GA之后,你一定會看到這種模式變得越來越流行,當然,可能產生一些細微的變化,主要是為了使API與現有controller中已經實作的功能保持一致,其他改進可能會指導controller如何繼續發展以符合Kubernetes維護者的愿景,總而言之,現在是開始使用此功能的好時機!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/10727.html
標籤:其他
