天天看點

Marathon-lb 服務自動發現和負載均衡

Marathon-lb用途

在使用Marathon+Mesos 的容器叢集中,我們會建構很多個容器,這些容器在不同的slave上配置設定了不同的随機端口,這些Docker容器在HA模式下運作,如果任何slave節點故障導緻容器執行個體意外退出,它将自動重新建立到健康的節點上。 是以我們不必擔心高可用性問題,Marathon會自動幫我們處理這些問題。

但是,當我們要使用這些容器處理我們的業務資料時,問題就來了。如我們有多個nginx提供web服務,我們如何配置設定流量? 如果slave節點發生硬體故障,或者容器執行個體崩潰,那麼新建立的容器IP和端口随時可能發生變化。 我們需要確定我們的負載均衡器能夠在最短時間内檢測這些變化,并相應地路由流量。 要解決這個問題,我們就要使用Marathon-lb。 Marathon-lb是通過監測Marathon應用程式狀态來管理HAProxy的工具。而 HAProxy是一款快速,高效,經過測試的高可用性負載平衡器,具有許多進階功能,如健康檢查,SSL,會話持久性等。

Marathon-lb設計思想

Marathon-lb通過調用自身的marathon_lb.py 腳本,連接配接到Marathon API以檢索所有正在運作的應用程式,根據檢索的資訊生成HAProxy配置并重新加載HAProxy。 每當應用程式狀态有任何變化時,Marathon-lb就會使用最新的IP和端口号更新haproxy配置檔案,并重新加載haproxy。 預設情況下,Marathon-lb會綁定到每個應用的服務端口,并将傳入的請求發送到應用執行個體。

Marathon-lb依賴于嵌入在haproxy中的最新lua支援來生成配置檔案。 我們需要下載下傳并安裝具有Lua支援的Haproxy,需要使用haproxy 1.6.0以上版本。

Marathon-lb可以直接從官方下載下傳docker鏡像,簡單配置之後就可以和其它容器一起放在Mesos叢集中以容器的方式運作,也可以使用傳統的方法在某一兩台主機上安裝,設定vip,配置為高可用的模式,這兩種方式各有優缺點,可以根據自己的業務要求進行合理規劃。下面就這兩種方式為大家一一介紹。

使用單獨主機配置Marathon-lb

在本地主機IP為192.168.20.47的主機上部署Marathon-lb。

安裝Haproxy

1、Haproxy需要lua5.3及以上版本,CentOS7.2預設的lua版本是5.1.4,是以首先安裝lua5.3.4,這裡使用編譯安裝,需要確定系統中已經安裝gcc和readline-devel:

1

2

3

4

5

6

7

8

<code>[root@marathon-lb ~]</code><code># wget http://www.lua.org/ftp/lua-5.3.4.tar.gz</code>

<code>[root@marathon-lb ~]</code><code># tar  xf lua-5.3.4.tar.gz </code>

<code>[root@marathon-lb ~]</code><code># cd lua-5.3.4 </code>

<code>[root@marathon-lb lua-5.3.4]</code><code># make linux test</code>

<code>[root@marathon-lb lua-5.3.4]</code><code># cd src</code>

<code>[root@marathon-lb src]</code><code># cp lua luac /usr/bin/ </code>

<code>[root@marathon-lb ~]</code><code># lua -v</code>

<code>Lua 5.3.4  Copyright (C) 1994-2017 Lua.org, PUC-Rio</code>

2、安裝Haproxy

先安裝必要的子產品:

<code>[root@marathon-lb ~]</code><code># yum install socat openssl-devel pcre-devel zlib-devel libcurl-devel -y</code>

下載下傳最新的源碼包安裝:

<code>[root@marathon-lb ~]</code><code># wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.8.tar.gz </code>

<code>[root@marathon-lb ~]</code><code># tar xf haproxy-1.7.8.tar.gz </code>

<code>[root@marathon-lb ~]</code><code># cd haproxy-1.7.8</code>

<code>[root@marathon-lb haproxy-1.7.8]</code><code># make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_CRYPT_H=1 USE_LIBCRYPT=1 USE_LUA=1</code>

<code>[root@marathon-lb haproxy-1.7.8]</code><code># make install PREFIX=/usr/local/haproxy</code>

<code>[root@marathon-lb haproxy-1.7.8]</code><code># haproxy -v</code>

<code>HA-Proxy version 1.7.8 2017</code><code>/07/07</code>

<code>Copyright 2000-2017 Willy Tarreau &lt;[email protected]&gt;</code>

3、編寫啟動腳本,此處可參考系統自帶的啟動腳本,設定配置檔案路徑。測試使用reload指令是否正常。

<code>/etc/init</code><code>.d</code><code>/haproxy</code> <code>start</code>

<code>/etc/init</code><code>.d</code><code>/haproxy</code> <code>reload</code>

安裝Marathon-lb

1、從github上下載下傳安裝Marathon-lb

<code>[root@marathon-lb ~]</code><code># git clone https://github.com/mesosphere/marathon-lb.git </code>

<code>[root@marathon-lb ~]</code><code># mv marathon-lb  /</code>

<code>[root@marathon-lb ~]</code><code># cd /marathon-lb</code>

2、建立ca證書和pem檔案(防止啟動時報錯,這裡隻做内部使用,可根據自己的實際需求申請證書)

<code>cd</code> <code>/etc/ssl/</code>

<code>openssl genrsa -out ca.key 1024</code>

<code>openssl req -new -key ca.key -out ca.csr </code>

<code>openssl x509 -req -days 365 -</code><code>in</code> <code>ca.csr -signkey ca.key -out ca.crt </code>

<code>cat</code> <code>ca.crt ca.key &gt; cert.pem</code>

3、建立haproxy的global配置檔案,啟動haproxy

<code>haproxy -f </code><code>/etc/haproxy/haproxy</code><code>.cfg</code>

4、在marathon上釋出含有HAPROXY_GROUP類型的标簽的app,這裡釋出一個haproxy組資訊為“external”标簽的tomcat容器:

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<code>{  </code>

<code>"id"</code><code>:</code><code>"tomcat"</code><code>, </code>

<code>"labels"</code><code>: {</code>

<code>  </code><code>"HAPROXY_GROUP"</code><code>:</code><code>"external"</code><code>,</code>

<code>  </code><code>"HAPROXY_0_VHOST"</code><code>:</code><code>"tomcat-test.com"</code>

<code>   </code><code>},</code>

<code> </code> 

<code>"cpus"</code><code>:1,  </code>

<code>"mem"</code><code>:128,  </code>

<code>"instances"</code><code>: 1,  </code>

<code>"constraints"</code><code>: [[</code><code>"hostname"</code><code>, </code><code>"UNIQUE"</code><code>,</code><code>""</code><code>]],  </code>

<code>"container"</code><code>: {  </code>

<code>"type"</code><code>:</code><code>"DOCKER"</code><code>,  </code>

<code>"docker"</code><code>: {  </code>

<code>"image"</code><code>: </code><code>"tomcat"</code><code>,                                              </code>

<code>"network"</code><code>: </code><code>"BRIDGE"</code><code>, </code>

<code>"portMappings"</code><code>: [  </code>

<code>{</code><code>"containerPort"</code><code>: 8080, </code><code>"hostPort"</code><code>: 0,</code><code>"servicePort"</code><code>: 0, </code><code>"protocol"</code><code>: </code><code>"tcp"</code> <code>}  </code>

<code>]  </code>

<code>  </code><code>}  </code>

<code>    </code><code>}  </code>

<code>      </code><code>}</code>

5、配置Marathon-lb通過Marathon API擷取容器應用狀态,使用marathon-lb.py腳本更新haproxy配置資訊并自動重新加載haproxy,這裡需要指定marathon叢集主機資訊:

<code>[root@marathon-lb marathon-lb]</code><code># ./marathon_lb.py -m http://192.168.20.41:8080 \</code>

<code>-m http:</code><code>//192</code><code>.168.20.42:8080 -m http:</code><code>//192</code><code>.168.20.43:8080 sse --group external \</code>

<code>--health-check</code>

此時,會在/etc/haproxy目錄下生成一個haproxy.cfg的檔案。并會自動執行happroxy的reload操作。

6、每次執行marathon-lb.py的檔案才會去更新haproxy配置,可以寫一個marathon-lb的啟動腳本使marathon-lb持續運作,這裡隻是示例,腳本比較粗糙,大家可以自行優化:

23

24

25

26

27

28

29

30

31

32

33

34

35

36

<code>#!/bin/bash</code>

<code># marathon-lb management script</code>

<code># tryingstuff.blog.51cto.com</code>

<code>PIDFILE=</code><code>/var/run/haproxy</code><code>.pid</code>

<code>SINGNFILE=</code><code>/tmp/marathon-lb</code><code>.sign</code>

<code>MLB_HOME=</code><code>/marathon-lb/</code>

<code>start() {</code>

<code>PRO_CUNT=`</code><code>ps</code> <code>-ef|</code><code>grep</code> <code>marathon_lb|</code><code>grep</code> <code>-</code><code>v</code> <code>'grep'</code><code>|</code><code>wc</code> <code>-l`</code>

<code>if</code> <code>[ $PRO_CUNT -gt 1 ]</code>

<code>  </code><code>then</code>

<code>    </code><code>echo</code> <code>"marathon-lb already running!"</code>

<code>    </code><code>exit</code> <code>1</code>

<code>else</code> 

<code>    </code><code>echo</code> <code>"marathon-lb start! "</code> <code>&gt;  $SINGNFILE</code>

<code>fi</code>

<code>while</code> <code>[ -f $SINGNFILE ]</code>

<code>  </code><code>do</code>

<code>    </code><code>cd</code> <code>$MLB_HOME &amp;&amp; .</code><code>/marathon_lb</code><code>.py -m http:</code><code>//192</code><code>.168.20.41:8080 -m http:</code><code>//192</code><code>.168.20.42:8080 -m http:</code><code>//192</code><code>.168.20.43:8080 sse --group external --health-check &amp;&gt; </code><code>/dev/null</code>

<code>   </code><code>done</code>  

<code>}</code>

<code>stop() {</code>

<code>rm</code> <code>-f $SINGNFILE</code>

<code>echo</code> <code>"marathon-lb stopped!"</code>

<code>case</code> <code>"$1"</code> <code>in</code>

<code>  </code><code>start)</code>

<code>    </code><code>start</code>

<code>    </code><code>;;</code>

<code>  </code><code>stop)</code>

<code>    </code><code>stop</code>

<code>  </code><code>*)</code>

<code>    </code><code>echo</code> <code>$</code><code>"Usage: $0 {start|stop}"</code>

<code>esac</code>

給腳本添加執行權限并命名為marathon-lb,啟動marathon-lb:

<code>nohub marathon-lb start &amp;</code>

關閉marathon-lb:

<code>marathon-lb stop</code>

7、通路tomcat容器:

在本地hosts 檔案中添加 marathon-lb IP(此處為192.168.20.47)和域名的對應記錄(tomcat-test.com),通路tomcat-test.com:

<a href="https://s2.51cto.com/wyfs02/M00/9E/93/wKiom1mSo7iAa20zAAGS-H0PbwU647.jpg" target="_blank"></a>

以容器方式配置Marathon-lb

了解了主機配置的方式,相對于以容器方式配置Marathon-lb那就太簡單了,隻需下載下傳鏡像,啟動容器兩步即可, 生産中推薦使用這種方式。

1、從官方下載下傳Marathon-lb容器鏡像

<code>docker pull docker.io</code><code>/mesosphere/marathon-lb</code>

2、指定mesos的master主機和Haproxy 組,啟動Marathon-lb容器:

<code>docker run -d --privileged -e PORTS=9090 --net=host \</code>

<code>docker.io</code><code>/mesosphere/marathon-lb</code> <code>sse \</code>

<code>-m http:</code><code>//192</code><code>.168.20.41:8080 -m http:</code><code>//192</code><code>.168.20.42:8080 \</code>

<code>-m http:</code><code>//192</code><code>.168.20.43:8080  --group external</code>

這裡所指定網絡模式為host.

3、釋出APP要指定标簽類型,否則不會被marathon-lb擷取到狀态資訊:

<code>{</code>

<code>  </code><code>"id"</code><code>:</code><code>"nginx"</code><code>,</code>

<code>  </code><code>"labels"</code><code>: {</code>

<code>  </code><code>"HAPROXY_0_VHOST"</code><code>:</code><code>"nginx1.com"</code>

<code>  </code><code>"cpus"</code><code>:0.2,</code>

<code>  </code><code>"mem"</code><code>:20.0,</code>

<code> </code><code>"instances"</code><code>: 1,</code>

<code> </code><code>"constraints"</code><code>: [[</code><code>"hostname"</code><code>, </code><code>"UNIQUE"</code><code>,</code><code>""</code><code>]],</code>

<code> </code><code>"container"</code><code>: {</code>

<code>    </code><code>"type"</code><code>:</code><code>"DOCKER"</code><code>,</code>

<code>   </code><code>"docker"</code><code>: {</code>

<code>     </code><code>"image"</code><code>: </code><code>"nginx"</code><code>,</code>

<code>     </code><code>"network"</code><code>: </code><code>"BRIDGE"</code><code>,</code>

<code>     </code><code>"portMappings"</code><code>: [</code>

<code>        </code><code>{</code><code>"containerPort"</code><code>: 80, </code><code>"hostPort"</code><code>: 0,</code><code>"servicePort"</code><code>: 0, </code><code>"protocol"</code><code>: </code><code>"tcp"</code> <code>}</code>

<code>      </code><code>]</code>

<code>    </code><code>}</code>

<code>  </code><code>}</code>

如果要實作多個APP負載均衡,可以直接在marathon上對目前的app進行擴容,點選“scale application”節點會自動添加到haproxy中。

4、我們可以通過通路marathon-lb容器所在的主機IP來通路nginx(指定了VHOST需要做解析或在本地添加hosts記錄),使用如下格式通路9090端口來檢視目前haproxy的狀态:

可以建立多個marathon-lb容器作為高可用。

參考資料:

 本文轉自 酥心糖 51CTO部落格,原文連結:http://blog.51cto.com/tryingstuff/1955757

繼續閱讀