使用NGINX和NGINX Plus進行Docker Swarm負載均衡
在2016年九月奧斯丁nginx.conf大會上,我做了一個關于如何在Docker Swarm集群中使用NGINX和NGINX Plus的 介紹 。在本文中,我將討論如何結合Docker 1.12中引入的功能使用NGINX和NGINX Plus進行Docker Swarm負載均衡。所有演示示例中使用的文件在GitHub上都可以找到。
概述
Docker 1.12版本,在2016年7月下旬發布,集成了Docker Engine和Swarm,并添加了一些新的編排功能,創建一個類似于其他容器平臺(例如Kubernetes)的平臺。在Docker 1.12中,Swarm模式允許您將一組Docker主機組合成一個群集,提供一種容錯、自我修復的分散式架構。這種新平臺設置Swarm集群更加容易,并且使用密鑰保護所有節點,節點之間的所有通信都通過TLS加密。
同時,Docker API已經朝著認知服務方面進行擴展,這些服務是使用相同鏡像的容器集(類似于Docker Compose中的服務,但具有更多功能)。您可以創建和擴展服務,執行回滾更新,創建運行狀況檢查等。此外,內置了DNS服務發現和負載均衡,您可以設置覆蓋集群范圍的網絡。
Docker Swarm負載均衡拓撲
在本次討論與演示中,我創建了三個Swarm結點——一個master結點和兩個worker結點。【注意:在演示文稿的幻燈片中,結點被標注為Swarm Manager和Swarm Node。】在Master結點上可以運行Swarm命令。Swarm在所有結點上進行調度、DNS服務發現、擴展和容器負載均衡(在圖中由小框表示)。

<center>圖1 一個master結點兩個worker結點的Docker Swarm集群</center>
要在集群內的容器之間提供私有網絡通信,容器可以連接到跨集群所有節點的多個內部覆蓋網絡。容器可以通過Swarm負載均衡器連接集群外部。

<center>圖2 Docker Swarm集群內外網絡連接圖</center>
Docker Swarm負載均衡器運行在每個節點上,可以在集群中任何主機上跨容器負載均衡請求。在沒有NGINX或NGINX Plus的Swarm部署中,Swarm負載均衡器處理入站客戶端請求(由圖3中的綠色箭頭表示)以及內部服務到服務請求(由紅色箭頭表示)。

<center>圖3 在沒有NGINX或NGINX Plus的集群中客戶端和服務到服務請求的負載均衡</center>
既然Swarm擁有負載均衡,為什么需要另一個負載均衡器? 一個原因是Swarm負載均衡器是TCP層負載均衡器。許多應用程序需要額外的功能,如下所示:
- SSL/TLS終端
- 基于內容的路由(例如,基于URL或header)
- 訪問控制和授權
- 重寫和重定向
此外,您可能已經具有負載均衡器的經驗,與Swarm一起使用它,能夠充分利用已有的工具和您豐富的知識。
使用開源的 NGINX 和 NGINX Plus
開源NGINX和NGINX Plus是兩個負載均衡器,提供了Swarm自身負載均衡器缺少的關鍵應用功能。
使用開源 NGINX
開源的NGINX軟件提供了前面提到的功能(SSL/TLS終端等),包括:
- 負載均衡算法的選擇
- 多種協議,例如HTTP/2和WebSocket
- 可配置的日志記錄
- 流量限制,包括請求速率,帶寬和連接數
- 高級用例的腳本,使用Lua,Perl和JavaScript(使用nginScript動態模塊)
- 安全功能(例如白名單和黑名單)
使用開源NGINX的最簡單的方法是將其部署為具有一個或多個容器的服務。 NGINX服務的必要端口暴露在集群上,Swarm負載均衡器將這些端口上的請求分發到NGINX容器。

<center>圖4 Swarm負載均衡器在實例之間分配對NGINX服務的請求</center>
在本示例中,NGINX提供的服務是SSL/TLS終端。為了說明這是如何工作的,我們在集群中部署后端服務A,并將其擴展為具有三個容器(一個節點上有兩個實例,另一個節點上有一個實例,如圖5所示)。Swarm向服務A分配虛擬IP地址(VIP),用以在群集內使用。我們在服務A上游組的NGINX配置中使用此VIP,而不是列出容器的各個IP地址。這樣我們可以擴展服務A,而不必更改NGINX配置。
如圖5所示,當客戶端向第一個Swarm節點發出服務A請求時,該節點上的Swarm負載均衡器將請求路由到NGINX。NGINX處理請求,進行SSL/TLS解密,并將其路由到服務A的VIP。Swarm負載均衡器將任何Swarm節點上的(現在未加密的)請求路由到服務A的容器之一。

<center>圖5 NGINX為外部客戶端請求提供SSL/TLS終端功能</center>
NGINX可以直接向后端容器提供負載均衡請求,并且還可以處理內部服務到服務請求,但是解決方案更為復雜,每次對服務A進行擴展時,需要更改和重新加載NGINX配置。稍后將討論如何使用NGINX Plus更容易完成。
使用NGINX Plus
NGINX Plus提供的一些附加功能包括:
- 活躍應用健康檢查 ——NGINX Plus會持續檢查后端節點,以確保其正常運行并正確響應,并從負載均衡輪換中刪除不正常的節點。
- 會話持久性 ——也稱為粘性會話,并且需要客戶端繼續將其請求發送到同一后端的應用程序。 當您需要使后端服務器脫機而不影響有打開會話的客戶端時,NGINX Plus支持會話耗盡。
- 動態重新配置 ——這提供了伸縮后端的能力,而不需要更改和重新加載NGINX配置。這在使用諸如Swarm的微服務平臺進行服務發現時尤其有用,它是允許NGINX Plus與這些平臺完全集成的最重要的功能之一。
有兩種動態重新配置方法:一種是通過API允許您將更改推送到NGINX Plus;另一種是DNS,NGINX Plus會持續檢查連接到域名的節點數量的變化,在NGINX Plus演示中使用的就是這種方法,用以集成Swarm中內置的服務發現。 - 實時活動監控 ——提供用于從NGINX Plus獲取大量指標的API,以及基于API構建的Web信息中心,您可以在其中查看指標以及添加,刪除和更改后端服務器。
在上述開源NGINX配置中,Swarm負載均衡器將外部請求分發到后端容器,并在其中處理服務到服務請求。NGINX的作用是SSL/TLS卸載。
當使用NGINX Plus時,來自外部客戶端的客戶端請求首先訪問Swarm負載均衡器,而NGINX Plus對后端容器進行實際負載均衡(圖6)。有客戶端請求到達Swarm負載均衡器時,提供一個簡單的方法使NGINX Plus高可用。

<center>圖6 Docker Swarm負載均衡器將客戶端請求轉發到NGINX Plus用以實現服務實例之間負載均衡</center>
類似地,Swarm負載均衡器接收服務間請求,而NGINX Plus實際上在服務之間分發它們(圖7)。

<center>圖7 Docker Swarm負載均衡器將服務間請求轉發到NGINX Plus用以海鮮服務實例之間負載負載</center>
示例
為了提供一些在使用和不使用NGINX的情況下使用Swarm for Docker負載均衡的例子,我創建了三個示例。所有這些演示的文件以及詳細的說明都可以在 GitHub 上找到。三個示例如下:
Docker Swarm負載均衡
這個示例是使用Docker Swarm負載均衡請求到一個簡單的web應用后端,沒有NGINX或NGINX Plus。
使用開源NGINX的Docker Swarm負載均衡
這個示例添加了開源的NGINX,為外部請求提供SSL/TLS卸載。Swarm負載均衡器將請求分發到與上一個演示中相同的簡單Web應用程序后端,并處理內部服務到服務請求。
使用NGINX Plus的Docker Swarm負載均衡
這個示例有兩部分。第一部分使用NGINX Plus,它除了執行SSL/TLS卸載外,還將請求直接加載到后端容器,并處理內部服務到服務請求。它與Swarm服務發現集成,使用動態DNS來頻繁地重新解析與后端關聯的域名。NGINX Plus負載平衡兩個后端服務Service1和Service2。它通過讓Service1向Service2發出請求來演示內部服務到服務請求。

<center>圖8 NGINX Plus使用Swarm的動態DNS服務發現機制負載均衡后端服務</center>
第二部分顯示如何將NGINX Status API與Docker Service API組合,以自動伸縮后端容器。Python程序使用NGINX Plus Status API來監視Service1和Service2上的負載,以及Docker Swarm Service API進行后端容器的伸縮。

<center>圖9 Docker Swarm使用NGINX Plus實時活動監視來跟蹤服務負載以實現自動伸縮</center>
總結
Docker 1.12中引入的新功能使Swarm成為一個更強大的平臺,也可以通過利用開源NGINX和NGINX Plus來進一步增強。NGINX Plus使用DNS動態重新配置后端容器實現負載均衡的能力,加上Status API提供的可見性,是一個非常強大的容器解決方案。
來自:http://dockone.io/article/2050