1. 程式人生 > >用DCOS和marathon-lb實現服務發現和負載均衡:第二部分

用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應用程式:

  1. marathon-lb-autoscale - 可通過marathon REST api監控HAProxy和縮放應用的指令碼。
  2. nginx - 我們的演示應用程式
  3. 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 部門都規範了一套服務等級協議,以衡量、確認他們的客戶(企業其他部門的使用者)服務,有時也與外部網路供應商提供的服務進行比較。

就這樣!在到達終點的祝賀。