若是您的應用程序是面向大量用戶、會吸引大量流量,那麼一個不變的目標必定是在高效知足用戶需求的同時、不讓用戶感知到任何相似於「服務器繁忙!」的狀況。這一訴求的典型解決方案是橫向擴展部署,以便有多個應用程序容器能夠爲用戶請求提供服務。可是,這種技術須要可靠的路由功能,須要能夠有效地在多個服務器之間分配流量。本文分享的內容就是要解決負載均衡解決方案的問題。nginx
Rancher 1.6是Docker和Kubernetes的容器編排平臺,爲負載均衡提供了功能豐富的支持。在Rancher 1.6中,用戶能夠經過使用開箱即用的HAProxy負載均衡器,來提供基於HTTP / HTTPS / TCP主機名/路徑的路由。git
而在本文中,咱們將探討如何在原生使用Kubernetes進行編排的Rancher 2.0平臺上實現這些流行的負載均衡技術。github
Rancher 2.0 負載均衡功能docker
經過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負載均衡器,以均衡目標服務。您還能夠配置基於主機名/路徑的路由規則。app
例如,下面讓咱們來看看一個在Rancher 1.6上啓動了兩個容器的服務。啓動的容器正在監聽私有80端口。負載均衡
爲了均衡兩個容器之間的外部流量,咱們能夠爲應用程序建立一個負載均衡器,以下所示。在這裏,咱們會配置負載均衡器,將進入端口80的全部流量轉發到目標服務的容器端口,而後Rancher 1.6在負載均衡器服務上放置了一個方便的連接到公共端點。tcp
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/v0.1.x/en/config-options/add-ons/ingress-controllers/
若是您是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/rancher/v2.x/en/cluster-provisioning/rke-clusters/options/cloud-providers/
一旦負載均衡器配置成功,Rancher將在Rancher UI中爲您的工做負載的公共端點提供一個連接。
如上所述,Kubernetes Ingress自己不支持TCP協議。所以,即便TCP不是NGINX的限制,也沒法經過Ingress建立來配置NGINX Ingress Controller以進行TCP負載均衡。
可是,您能夠經過建立一個Kubernetes ConfigMap,來使用NGINX的TCP負載均衡功能,具體可參閱這裏:https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/exposing-tcp-udp-services.md。您能夠建立Kuberenetes ConfigMap對象,來將pod配置參數存儲爲鍵值對,與pod鏡像分開,更多細節能夠參考這裏:
https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
要配置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/rancher/v1.6/en/cattle/adding-load-balancers/#load-balancers)。其中一些功能在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/ingress-nginx/examples/customization/custom-configuration/README/。
將負載均衡器配置從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生態系統在不斷髮展,我相信咱們能找到更多適合全部負載均衡細微差異的解決方案!