用DCOS和marathon-lb實現服務發現和負載均衡:第二部分
最近在研究使用Mesos,對marathon-lb和mesos-dns等諸多工具,只是停留在知道和會用的階段,特別是對於基於marathon-lb的HAProxy的應用分組和使用更是一頭霧水。現在資料也少,看了官網上的這篇文章覺得講得還算是全面。兄弟英文水平差,先用Google翻譯了一下,然後再梳理整理,同時,加上了一些自己的理解的說明。因為每個人的經歷和經驗都不同,以下這些東西對於有些人可能很難對於有些人可能很簡單,所以不當之處還請大家多多見諒。歡迎討論和拍磚。
這是服務發現和負載平衡的兩部分系列文章的第二篇。
在上一篇文章中,我們討論了marathon-lb的基本知識。在這篇文章中,我們將探討一些更高階的功能。
marathon-lb的工作原理是自動生成用於HAProxy的配置,然後根據需要重灌HAProxy的。marathon-lb是通過marathon REST api,根據可用的application資料來生成HAProxy的配置。它也可以訂閱Marathon Event Bus進行實時更新。當一個應用程式啟動,停止,重新定位,或健康狀況有任何的變化,marathon-lb會自動重新生成HAProxy的配置並重新載入HAProxy的。
marathon-lb具有用於指定任意HAProxy的配置引數的模板功能。模板可以進行全域性設定(適用於所有應用程式),或者每個應用程式的基礎上使用標籤進行設定。我們來演示如何指定自己的全域性模板的例子。以下是我們將使用模板:
global
daemon
log /dev/log local0
log /dev/log local1 notice
maxconn 4096
tune.ssl.default-dh-param 2048
defaults
log global
retries 3
maxconn 3000
timeout connect 5s
timeout client 30s
timeout server 30s
option redispatch
listen stats
bind 0.0 .0.0:9090
balance
mode http
stats enable
monitor-uri /_haproxy_health_check
在上面的例子中,我們已經將以下這些設定的預設值進行了修改:maxconn,timeout client,和timeout server。接下來,建立一個名為HAPROXY_HEAD的檔案,將以上配置資訊寫入這個檔案中,最後將其放在一個名為templates目錄下。然後,把整個目錄打tar或zip檔案。下面是你可以用來做一個方便的指令碼。
接下來,將模版url資訊儲存至options.json,我們將通過這個檔案來增加marathon-lb配置:
{
"marathon-lb":{
"template-url":"https://downloads.mesosphere.com/marathon/marathon-lb/templates.tgz"
}
}
建立一個新的marathon-lb:
$ dcos package install --options=options.json marathon-lb
我們定製的marathon-lb HAProxy的例項基於該新模板執行。完整的模板列表可以在這裡找到。
下一步是什麼?如何指定每個應用程式模板?下面是使用我們的忠實nginx的一個例子:
{
"id": "nginx-external",
"container": {
"type": "DOCKER",
"docker": {
"image": "nginx:1.7.7",
"network": "BRIDGE",
"portMappings": [
{ "hostPort": 0, "containerPort": 80, "servicePort": 10000 }
],
"forcePullImage":true
}
},
"instances": 1,
"cpus": 0.1,
"mem": 65,
"healthChecks": [{
"protocol": "HTTP",
"path": "/",
"portIndex": 0,
"timeoutSeconds": 10,
"gracePeriodSeconds": 10,
"intervalSeconds": 2,
"maxConsecutiveFailures": 10
}],
"labels":{
"HAPROXY_GROUP":"external",
"HAPROXY_0_BACKEND_HTTP_OPTIONS":" option forwardfor\n no option http-keep-alive\n http-request set-header X-Forwarded-Port %[dst_port]\n http-request add-header X-Forwarded-Proto https if { ssl_fc }\n"
}
}
在上面的例子中,我們修改了預設模板,禁用 HTTP keep-alive。雖然這是一個人為的例子,可能有你需要重寫每個應用程式的某些預設情況。
"labels":{
"HAPROXY_0_STICKY":true,
"HAPROXY_0_REDIRECT_TO_HTTPS":true,
"HAPROXY_0_VHOST":"nginx.mesosphere.com"
}
SSL支援
marathon-lb支援SSL,並且可以指定每個前端多個SSL證書。通過–ssl-certs命令列引數,就可以將額外的SSL證書包含進來。你可以通過設定HAPROXY_SSL_CERT環境變數,指定注入自己的SSL證書到marathon-lb的配置中。
如果不指定SSL證書,marathon-lb在啟動時將產生自簽名的證書。如果你使用多個SSL證書,你可以通過指定選擇每個應用服務埠的SSL證書HAPROXY_{n}_SSL_CERT引數,它對應於指定的SSL證書的檔案路徑。例如:
"labels":{
"HAPROXY_0_VHOST":"nginx.mesosphere.com",
"HAPROXY_0_SSL_CERT":"/etc/ssl/certs/nginx.mesosphere.com"
}
該SSL證書必須預先載入到marathon-lb載入它們容器(您可以通過構建marathon-lb的自己的映象,而不是使用中間層提供的映象做到這一點)。如果沒有提供一個SSL證書,自簽名的證書將在啟動時產生的。
使用HAProxy的指標
HAProxy的統計報告可以用於監測健康狀況,效能,甚至進行排程決策。HAProxy的資料包括各種規格的計數器和1秒的速率
在本文中,我們將使用HAProxy的資料實現一個有趣的應用程式:一個演示馬拉松應用程式自動縮放的實現。
原理很簡單:對於給定的應用程式,我們可以測量其每秒的請求對於一個給定的資源方面的效能。如果該應用是無狀態的水平縮放,我們就可以在每秒平均N個間隔的頻率下,按比例的縮放應用例項的數目。自動縮放指令碼輪詢HAProxy的統計,基於傳入的請求自動縮放應用例項。
該指令碼不會做任何事情聰明,它只是簡單的獲取當前的RPS(每秒請求數),並用每個應用程式例項目標RPS除以這個數字。該級分的結果是所需的應用例項的數目(或更確切地說,該級分的上限是必需的例項)。
為了演示自動縮放,我們將用3個獨立的marathon應用程式:
- marathon-lb-autoscale - 可通過marathon REST api監控HAProxy和縮放應用的指令碼。
- nginx - 我們的演示應用程式
- siege - 生成HTTP請求的工具
注:Siege是一個壓力測試和評測工具,設計用於WEB開發這評估應用在壓力下的承受能力:可以根據配置對一個WEB站點進行多使用者的併發訪問,記錄每個使用者所有請求過程的相應時間,並在一定數量的併發訪問下重複進行。
讓我們首先執行marathon-lb-autoscale。該應用程式的JSON定義可以在這裡找到。儲存檔案,並啟動它的marathon:
$ wget https://gist.githubusercontent.com/brndnmtthws/2ca7e10b985b2ce9f8ee/raw/66cbcbe171afc95f8ef49b70034f2842bfdb0aca/marathon-lb-autoscale.json
$ dcos marathon app add marathon-lb-autoscale.json
讓我們來看看定義檔案:
"args":[
"--marathon", "http://leader.mesos:8080",
"--haproxy", "http://marathon-lb.marathon.mesos:9090",
"--target-rps", "100",
"--apps", "nginx_10000"
],
注意:如果沒有外部(external)marathon-lb在執行的情況下,可以通過命令啟動它dcos package install marathon-lb。
上面,我們傳遞兩個重要引數:–target-rps告訴marathon-lb-autoscale我們的RPS目標是什麼,–apps的值是一個逗號分隔的多值列表,列表中的每個值是用“_”連線的marathon app 名和服務監聽埠的字串。如果配置成每個應用程式可以向LB暴露多個服務埠,marathon-lb-autoscale將擴充套件應用程式,以滿足所需的例項數的最大公約數。
接下來,我們將啟動我們的nginx測試例項。該應用程式的JSON定義檔案可以在這裡找到。儲存檔案,並啟動:
$ wget https://gist.githubusercontent.com/brndnmtthws/84d0ab8ac057aaacba05/raw/d028fa9477d30b723b140065748e43f8fd974a84/nginx.json
$ dcos marathon app add nginx.json
最後,讓我們進行壓力測試,用於生成HTTP請求。該應用程式的JSON定義檔案可以在這裡找到。儲存檔案,並啟動
$ wget https://gist.githubusercontent.com/brndnmtthws/fe3fb0c13c19a96c362e/raw/32280a39e1a8a6fe2286d746b0c07329fedcb722/siege.json
$ dcos marathon app add siege.json
現在,如果您檢查HAProxy的狀態頁面,你應該看到氣球命中nginx例項:
在“Session rate”部分中,你可以看到我們目前得到每秒約54請求。
下一步,縮放壓力測試應用程式,使我們產生了一堆的HTTP請求:
$ dcos marathon app update /siege instances=15
現在,等待幾分鐘,去喝杯咖啡,茶,鬆餅,牛排或任何你可能做的休閒事情。過幾分鐘你就會發現nginx的應用程式已經被自動擴充套件到可以支撐當前服務流量的數目。
接下來,嘗試修改marathon-lb-autoscale引數(這是實驗記錄在這裡)。試著改變區間,樣本數和其他值,直到達到預期的效果。預設值是相當保守的,這可能會或可能不符合您的期望。它建議您目標RPS安全係數是50%。例如,如果您測量您的應用程式SLA是:在1個CPU和1GiB記憶體的情況下能滿足1500 RPS,那麼你可能希望將目標RPS設定為1000。
注:
1)我的理解是RPS安全係數,是marathon-lb根據系統執行引數生成的預判值,想要保證服務在這個情況下穩定執行,就要將SLA的值進行等比例的下調。
2)SLA是關於網路服務供應商和客戶間的一份合同,其中定義了服務型別、服務質量和客戶付款等術語。SLA概念已被大量企業所採納,作為公司 IT 部門的內部服務。大型企業的 IT 部門都規範了一套服務等級協議,以衡量、確認他們的客戶(企業其他部門的使用者)服務,有時也與外部網路供應商提供的服務進行比較。
就這樣!在到達終點的祝賀。