Kubernetes上的負載均衡詳解

店家小二發表於2018-12-18
如果您的應用程式是面向大量使用者、會吸引大量流量,那麼一個不變的目標一定是在高效滿足使用者需求的同時、不讓使用者感知到任何類似於“伺服器繁忙!”的情況。這一訴求的典型解決方案是橫向擴充套件部署,以便有多個應用程式容器可以為使用者請求提供服務。但是,這種技術需要可靠的路由功能,需要可以有效地在多個伺服器之間分配流量。本文分享的內容就是要解決負載均衡解決方案的問題。

Rancher 1.6是Docker和Kubernetes的容器編排平臺,為負載均衡提供了功能豐富的支援。在Rancher 1.6中,使用者可以通過使用開箱即用的HAProxy負載均衡器,來提供基於HTTP / HTTPS / TCP主機名/路徑的路由。

而在本文中,我們將探討如何在原生使用Kubernetes進行編排的Rancher 2.0平臺上實現這些流行的負載均衡技術。

Rancher 2.0 負載均衡功能



通過Rancher 2.0,使用者可以開箱即用地使用由NGINX Ingress Controller支援的原生Kubernetes Ingress功能進行7層負載均衡。因為Kubernetes Ingress僅支援HTTP和HTTPS協議,所以目前如果您使用的是Ingress支援,那麼負載均衡僅限於上述這兩種協議。

對於TCP協議,Rancher 2.0支援在部署Kubernetes叢集的雲上配置第4層TCP負載均衡器。後文中我們還將介紹如何通過ConfigMaps為TCP均衡配置NGINX Ingress Controller。

HTTP/HTTPS 負載均衡功能

在Rancher 1.6中,您新增了埠/服務規則以配置HAProxy負載均衡器,以均衡目標服務。您還可以配置基於主機名/路徑的路由規則。

例如,下面讓我們來看看一個在Rancher 1.6上啟動了兩個容器的服務。啟動的容器正在監聽私有80埠。



為了均衡兩個容器之間的外部流量,我們可以為應用程式建立一個負載均衡器,如下所示。在這裡,我們會配置負載均衡器,將進入埠80的所有流量轉發到目標服務的容器埠,然後Rancher 1.6在負載均衡器服務上放置了一個方便的連結到公共端點。






Rancher 2.0提供了一種使用非常相似的、由NGINX Ingress Controller支援的、使用Kubernetes Ingress的負載均衡器功能。下文中我們一起來看看我們該如何做。


Rancher 2.0 Ingress Controller部署

Ingress只是一種規則,控制器元件會將這一規則應用於實際負載均衡器中。實際負載均衡器可以在叢集外部執行,也可以在叢集中部署。

通過RKE(Rancher Kubernetes安裝程式),Rancher 2.0讓使用者可以開箱即用地在配置的叢集上部署NGINX Ingress Controller和負載均衡器,以處理Kubernetes Ingress規則。請注意,NGINX Ingress Controller預設安裝在RKE配置的叢集上。通過雲提供商(如GKE)配置的叢集具有自己的Ingress Controller來配置負載均衡器。本文的範圍僅適用於使用RKE安裝的NGINX Ingress Controller。

RKE將NGINX Ingress Controller部署為Kubernetes DaemonSet——因此NGINX例項會部署在叢集中的每個節點上。NGINX就像一個Ingress Controller,在整個叢集中監聽Ingress建立,它還會將自身配置為滿足Ingress規則的負載均衡器。DaemonSet配置有hostNetwork以暴露兩個埠——埠80和埠443。有關如何部署NGINX Ingress Controller DaemonSet和部署配置選項的詳細資訊,請參閱此處:

https://rancher.com/docs/rke/v … lers/

如果您是Rancher 1.6使用者,那麼將Rancher 2.0 Ingress Controller以DaemonSet的形式部署,會帶來一些你需要知悉的重要的改變。

在Rancher 1.6中,您可以在堆疊中部署可擴充套件的負載均衡器服務。因此,如果您在Cattle環境中有四臺主機,則可以部署一臺規模為2的負載均衡器服務,並通過埠80在這兩個主機IP地址上指向您的應用程式。然後,您還可以在剩餘的兩臺主機上啟動另一臺負載均衡器,以通過埠80再次均衡不同的服務(因為負載均衡器使用不同的主機IP地址)。



Rancher 2.0 Ingress Controller是一個DaemonSet——因此它全域性部署在所有可排程節點上,以便為整個Kubernetes叢集提供服務。因此,在對Ingress規則進行程式設計時,你需要使用唯一的主機名和路徑指向工作負載,因為負載均衡器節點IP地址和埠80/443是所有工作負載的公共訪問點。




現在讓我們看看如何使用Ingress將上述1.6示例部署到Rancher 2.0上。在Rancher UI上,我們可以導航到Kubernetes Cluster和Project,並選擇【部署工作負載/Deploy Workloads】功能,在名稱空間下部署所需映象的工作負載。讓我們將工作負載的規模設定為兩個副本,如下所示:




以下是工作負載選項卡上部署和列出工作負載的方式:




要達到這兩個pod之間的均衡,您必須建立Kubernetes Ingress規則。要建立此規則,請導航到您的叢集和專案,然後選擇“ 負載均衡”選項卡。




與Rancher 1.6中的服務/埠規則類似,您可以在此處指定針對工作負載的容器埠的規則。




基於主機和路徑的路由


Rancher 2.0允許您新增基於主機名或URL路徑的Ingress規則。根據您的規則,NGINX Ingress Controller將流量路由到多個目標工作負載。下面讓我們看看如何使用相同的Ingress規範將流量路由到名稱空間中的多個服務。比如如下兩個在名稱空間中部署的工作負載:



我們可以使用相同的主機名但不同的路徑新增Ingress來均衡這兩個工作負載的流量。




Rancher 2.0還為Ingress記錄中的工作負載提供了方便的連結。如果配置外部DNS以對DNS記錄進行程式設計,則可以將此主機名對映到Kubernetes Ingress地址。




Ingress地址是您的叢集中Ingress Controller為您的工作負載分配的IP地址。您可以通過瀏覽此IP地址來達到工作負載。使用kubectl檢視控制器分配入口地址。




您可以使用Curl來測試基於主機名/路徑的路由規則是否正常工作,如下所示:






以下是使用基於主機名/路徑的規則的Rancher 1.6配置規範,與2.0 Kubernetes Ingress YAML規範進行比較:




HTTPS /證書選項


Rancher 2.0 Ingress功能還支援HTTPS協議。您可以在配置Ingress規則時上載證書並使用它們,如下所示:



新增Ingress規則時選擇證書:




Ingress限制


儘管Rancher 2.0支援HTTP- / HTTPS-基於主機名/路徑的負載均衡,但要突出的一個重要區別是在為工作負載配置Ingress時需要使用唯一的主機名/路徑。原因是Ingress功能僅允許將埠80/443用於路由,負載均衡器和Ingress Controller則可作為DaemonSet全域性啟動。

從最新的Rancher 2.x版本開始,Kubernetes Ingress不支援TCP協議,但我們將在下一節中討論使用NGINX Ingress Controller的解決方法。

TCP負載均衡選項

  • 四層負載均衡器


對於TCP協議,Rancher 2.0支援在部署Kubernetes叢集的雲提供程式中配置四層負載均衡器。為叢集配置此負載均衡器裝置後,Layer-4 Load Balancer在工作負載部署期間選擇for port-mapping 選項時,Rancher會建立Load Balancer服務。此服務會讓Kubernetes的相應雲提供商配置負載均衡器裝置。然後,此裝置將外部流量路由到您的應用程式pod。請注意,上述功能需要該Kubernetes雲提供商滿足負載均衡器服務的要求,按此文件配置:

https://rancher.com/docs/ranch … ders/



一旦負載均衡器配置成功,Rancher將在Rancher UI中為您的工作負載的公共端點提供一個連結。
  • 通過ConfigMaps支援NGINX Ingress Controller TCP


如上所述,Kubernetes Ingress本身不支援TCP協議。因此,即使TCP不是NGINX的限制,也無法通過Ingress建立來配置NGINX Ingress Controller以進行TCP負載均衡。

但是,您可以通過建立一個Kubernetes ConfigMap,來使用NGINX的TCP負載均衡功能,具體可參閱這裡:https://github.com/kubernetes/ … es.md。您可以建立Kuberenetes ConfigMap物件,來將pod配置引數儲存為鍵值對,與pod映象分開,更多細節可以參考這裡:

https://kubernetes.io/docs/tas … gmap/

要配置NGINX以通過TCP暴露服務,您可以新增或更新名稱空間tcp-services中的ConfigMap ingress-nginx。此名稱空間還包含NGINX Ingress Controller pod。



ConfigMap條目中的金鑰應該是您要公開訪問的TCP埠,其值應為格式<namespace/service name>:<service port>。如上所示,我暴露了Default名稱空間中存在的兩個工作負載。例如,上面ConfigMap中的第一個條目告訴NGINX我想在外部埠上暴露執行在default名稱空間上的myapp工作負載,並監聽在外部埠6790上的私有埠80。


將這些條目新增到Configmap,將自動更新NGINX pod,以配置這些工作負載來進行TCP負載均衡。您可以執行部署在ingress-nginx名稱空間中的這些pod,並檢視如何在/etc/nginx/nginx.conf檔案中配置這些TCP埠。<NodeIP>:<TCP Port>在NGINX配置/etc/nginx/nginx.conf更新後,應該可以使用公開的工作負載。如果它們不可訪問,則可能必須使用NodePort服務來暴露TCP埠。

Rancher 2.0負載均衡的限制

Cattle提供了功能豐富的負載均衡器支援(詳細介紹在此:https://rancher.com/docs/ranch … ncers)。其中一些功能在Rancher 2.0中暫時沒有等效功能:

當前NGINX Ingress Controller不支援SNI。

TCP負載均衡需要叢集中的雲提供程式啟用的負載均衡器裝置。Kubernetes上沒有對TCP的Ingress支援。

只能通過Ingress為埠80/443配置HTTP / HTTPS路由。此外,Ingress Controller作為Daemonset進行全域性部署,而不是作為可擴充套件服務啟動。此外,使用者無法隨機分配外部埠來進行負載均衡。因此,使用者需要確保它們配置的主機名/路徑組合是唯一的,以避免使用相同的兩個埠發生路由衝突。

無法指定埠規則優先順序和排序。

Rancher 1.6增加了對draining後端連線和drain超時的支援。Rancher 2.0暫不支援此功能。

目前在Rancher 2.0中,不支援指定自定義粘性策略和自定義負載均衡器配置以附加到預設配置。原生Kubernetes對此有一定的支援,不過也只限於定製NGINX配置:

https://kubernetes.github.io/i … ADME/

將負載均衡器配置從Docker Compose遷移到Kubernetes YAML?

Rancher 1.6通過啟動自己的微服務提供負載均衡器支援,該微服務啟動並配置了HAProxy。使用者新增的負載均衡器配置在rancher-compose.yml檔案中指定,而不是標準的docker-compose.yml。Kompose工具適用於標準的docker-compose引數,但在本文的情況下,是無法解析Rancher負載均衡器配置結構的。截至目前,我們暫時無法使用Kompose工具將負載均衡器配置從Docker Compose轉換為Kubernetes YAML。

結 論

由於Rancher 2.0基於Kubernetes並使用NGINX Ingress Controller(與Cattle使用HAProxy相比),因此原先Rancher 1.6中Cattle支援的一些負載均衡器的功能目前暫時沒有直接等效功能。但是,Rancher 2.0支援流行的HTTP / HTTPS基於主機名/路徑的路由,這種路由最常用於實際部署。還通過Kubernetes Load Balancer服務使用雲提供商提供四層(TCP)支援。2.0中的負載均衡功能也具有類似的直觀UI體驗。

Kubernetes生態系統在不斷髮展,我相信我們能找到更多適合所有負載均衡細微差別的解決方案!

本文轉自DockOne-Kubernetes上的負載均衡詳解


相關文章