OpenStack Rally 質量評估與自動化測試利器
目錄
文章目錄
問題描述
需求實現 Rally 擴充套件外掛的緣起是因為希望通過 Rally 來自動化測試 Octavia 專案的穩定性以及評估大規模 LB 工作負載對自身雲平臺的效能影響,所以下述的內容主要記錄了在 Rally(stable/0.12)Benchmark Engine/Task Framework 中實現 Octavia Plugin 的方式。
Rally 簡介
OpenStack Rally 是一個自動化測試工具,社群希望通過 Rally 來解答 “How does OpenStack work at scale?(如何規模化執行 OpenStack)” 的問題。為了實現這一目的,Rally 被設計成集自動化部署、功能驗證、效能測試和分析報告於一體,作為 OpenStack CI/CD 系統中的基礎工具,幫助使用者不斷提高系統的 SLA(服務等級協議)、效能和穩定性。
簡而言之,Rally 能夠幫助使用者完成整個 OpenStack 平臺或者某個單一元件功能的壓力測試,幫助使用者驗證和評估穩定系統工作負載的規模。
應用場景
應用案例
- 自動化測試、分析,評估新引入的程式碼如何影響雲平臺的效能;
- 自動化測試、分析新引入的程式碼是否完美相容雲平臺功能清單;
- 評估不同的部署方式如何影響雲平臺的效能,以此得出效能峰值最高的雲平臺部署架構;
- 評估不同硬體裝置對雲平臺的效能影響,以此得出效能峰值最高的雲平臺硬體設施;
更多案例,請瀏覽官方文件:https://docs.openstack.org/rally/latest/overview/overview.html#who-is-using-rally
Rally 安裝
下載原始碼:
git clone https://github.com/openstack/rally.git
安裝專案:
cd rally && ./install_rally.sh
NOTE:建議在沙盒環境安裝
Rally 使用
本篇以自動化測試為例,使用 Rally 自動化完成雲平臺功能的壓力測試。
Step 1. 建立 Deploy
這裡我們使用 Existing Cloud,所以 deploy file 如下:
# vim ~/existing.json
{
"openstack": {
"auth_url": "http://172.18.22.222/identity",
"region_name": "RegionOne",
"endpoint_type": "public",
"admin": {
"username": "admin",
"password": "admin",
"tenant_name": "admin"
},
"https_insecure": false,
"https_cacert": ""
}
}
執行 deployment 執行進行建立及檢視:
$ rally deployment create --filename=~/existing.json --name=existing
$ rally deployment list
+--------------------------------------+----------------------------+----------+------------------+--------+
| uuid | created_at | name | status | active |
+--------------------------------------+----------------------------+----------+------------------+--------+
| 97f7ccce-76dc-4af0-8583-f1a15be56c99 | 2018-10-25T03:22:11.399523 | existing | deploy->finished | * |
+--------------------------------------+----------------------------+----------+------------------+--------+
Existing Cloud deployment status 為 deploy->finished
則表示正常。
驗證是否成功對接 OpenStack 雲平臺:
$ rally deployment check
--------------------------------------------------------------------------------
Platform openstack:
--------------------------------------------------------------------------------
Available services:
+-------------+----------------+-----------+
| Service | Service Type | Status |
+-------------+----------------+-----------+
| __unknown__ | block-storage | Available |
| __unknown__ | compute_legacy | Available |
| __unknown__ | placement | Available |
| __unknown__ | volumev2 | Available |
| __unknown__ | volumev3 | Available |
| cinder | volume | Available |
| glance | image | Available |
| keystone | identity | Available |
| neutron | network | Available |
| nova | compute | Available |
| octavia | load-balancer | Available |
+-------------+----------------+-----------+
列印 Available services 表示正常對接。
Step 2. 自動化執行 Task
Rally 自動化執行 Task 的功能依賴於 Task file,Task file 描述了任務的內容和執行任務所必須要的引數。Rally 自身就提供非常完善的 Task file sample,滿足了大部分的測試需求,在路徑 rally/samples/tasks/scenarios
下檢視。
[[email protected] rally]# cd ../samples/tasks/scenarios/
[[email protected] scenarios]# ll
total 100
drwxr-xr-x 2 root root 4096 Oct 25 10:43 authenticate
drwxr-xr-x 2 root root 4096 Oct 25 10:43 ceilometer
drwxr-xr-x 2 root root 4096 Oct 25 10:43 cinder
drwxr-xr-x 2 root root 4096 Oct 25 10:43 designate
drwxr-xr-x 2 root root 4096 Oct 25 10:43 dummy
drwxr-xr-x 2 root root 90 Oct 25 10:43 ec2
drwxr-xr-x 2 root root 4096 Oct 25 10:43 glance
drwxr-xr-x 2 root root 4096 Oct 25 10:43 gnocchi
drwxr-xr-x 3 root root 4096 Oct 25 10:43 heat
drwxr-xr-x 2 root root 142 Oct 25 10:43 ironic
drwxr-xr-x 2 root root 4096 Oct 25 10:43 keystone
drwxr-xr-x 3 root root 4096 Oct 25 10:43 magnum
drwxr-xr-x 2 root root 4096 Oct 25 10:43 manila
drwxr-xr-x 2 root root 4096 Oct 25 10:43 mistral
drwxr-xr-x 2 root root 56 Oct 25 10:43 monasca
drwxr-xr-x 2 root root 4096 Oct 25 10:43 murano
drwxr-xr-x 2 root root 8192 Oct 25 18:20 neutron
drwxr-xr-x 2 root root 8192 Oct 25 10:43 nova
drwxr-xr-x 2 root root 50 Oct 26 15:07 octavia
drwxr-xr-x 2 root root 4096 Oct 25 10:43 quotas
-rw-r--r-- 1 root root 452 Oct 25 10:43 README.rst
drwxr-xr-x 2 root root 124 Oct 25 10:43 requests
drwxr-xr-x 3 root root 4096 Oct 25 10:43 sahara
drwxr-xr-x 2 root root 98 Oct 25 10:43 senlin
drwxr-xr-x 2 root root 4096 Oct 25 10:43 swift
drwxr-xr-x 2 root root 4096 Oct 25 10:43 vm
drwxr-xr-x 2 root root 234 Oct 25 10:43 watcher
drwxr-xr-x 2 root root 50 Oct 25 10:43 workload
drwxr-xr-x 2 root root 116 Oct 25 10:43 zaqar
這裡我們以 Nova 的 boot-and-delete-server 為例,直接使用 Task file:rally/samples/tasks/scenarios/nova/boot-and-delete.json
來頻繁建立和刪除雲主機。
rally task start ~/rally/samples/tasks/scenarios/nova/boot-and-delete.json
Step 3. 生成並檢視測試報告
$ rally task report 5b24ef46-6061-443a-be14-dab1e5cdf51a --out output.html
使用瀏覽器開啟 output.html 即可檢視 Report 的內容。
Report 中展示了 Task 描述、SLA(服務質量協議)、Durations(任務持續時間)、Task Details 和執行成功率等用於評估效能引數的有效資訊。
Rally 架構
上圖是 Rally 的總體架構,描述了 Rally 的組成結構、資料流和 OpenStack 的呼叫方式。
- Deploy Engine:儲存部署所需要的憑證(credentials)資訊,以外掛的形式整合第三方自動化部署工具(e.g. Devstack, Fuel, etc.),提供自動化部署能力。
- Verification:通過呼叫 Tempest(基於 unittest 的功能測試框架)來驗證雲平臺的功能清單。
- Benchmark Engine/Task Engine:是一個通用的測試用例外掛框架,允許使用者編寫引數化的 Plugin 實現以及對應的 Task File(YAML/JSON)來滿足自定義功能、效能測試需求,使用這種通用的方式來生成真實的使用者負載。
Rally 最初被設計成一種不需要 Daemon 的 CLI-Driver,這使 Rally 非常易於使用和開發。但通常 OpenStack Projects 總是以 “as-a-Service” 來實現的,所以現在社群也提出了 RaaS 的理念,並付諸於行動(work in progress)。
上圖描述了 “Rally-as-a-Service” 和 “Rally-as-an-APP” 兩種形式的實現架構,顯然兩者在實現上的區別主要在於是否具有 Daemon 以及相應的 HTTP、RPC Invoke,也就是所謂的是否實現了泛 “Service” 化。實際上,對於使用者而言無需太過於關心上層的呼叫方式,使用者只需關心 Rally Core 的 Benchmark Engine/Task Framework 的應用。所以本文采用的是更為成熟、簡單以及常用的 “Rally-as-an-APP” 模式。
Rally Plugin 分析與實現
程式入口
依舊從 setup.cfg 切入:
[entry_points]
console_scripts =
rally = rally.cli.main:main
rally-manage = rally.cli.manage:main
可見 Rally 只有 rally
和 rally-manage
兩個啟動指令碼,其中 rally-manage
主要用於列印 Version 資訊、程式編譯以及比較重要的資料庫版本控制 3 個功能,不過這些功能至 0.10.0 之後都被移植到了rally
中,rally-manage
也被標記為了 deprecated
:
`rally-manage db <command>` was deprecated since 0.10.0 version and is going to be removed soon. Please use `rally db <command>`.
所以我們重點要關注的程式入口還是 rally = rally.cli.main:main
。
# file: ~/rally/rally/cli/main.py
"""CLI interface for Rally."""
from __future__ import print_function
import sys
from rally.cli import cliutils
from rally.cli.commands import db
from rally.cli.commands import deployment
from rally.cli.commands import env
from rally.cli.commands import plugin
from rally.cli.commands import task
from rally.cli.commands import verify
categories = {
"db": db.DBCommands,
"env": env.EnvCommands,
"deployment": deployment.DeploymentCommands,
"plugin": plugin.PluginCommands,
"task": task.TaskCommands,
"verify": verify.VerifyCommands
}
def main():
return cliutils.run(sys.argv, categories)
if __name__ == "__main__":
sys.exit(main())
- cliutils module:實現了常見的 CLI 呼叫的封裝
- db/env/deployment/plugin/task/verify modules:每個 module 對應一個 rally 子命令 API 的呼叫封裝
下文以 rally task start
子命令為例。
執行 rally task start 的 UML
從上述 UML 分析得出,當 Rally 執行一個任務時主要進行了以下工作:
- 載入、解析 Task File 並以統一的形式(TaskConfig Object)返回,TaskConfig 中包含了:
- benchmark scenarios name
- benchmark scenarios args
- runner type
- runner args
- 基於 TaskConfig 生成 TaskEngine Object,TaskEngine 是執行 benchmark scenarios 的物件,所謂的 benchmark scenarios 就是實際 Plugin Class/Method 實現的程式碼邏輯
- 基於 TaskConfig 生成 Runner Object,Runner 設定了執行 Task 程序拓撲(總數、併發數)
顯然,開發者需要關心的主要有兩點:
- task file 的定義
- benchmark scenarios 的實現
最後
最後總結一下完成實現所需要解決的幾個問題:
- 如何通過 Task file 的 benchmark scenario name 載入指定的 Plugin Class/Method?
- 如何傳入 Task file 中定義的 args 到 Plugin Class/Method?
- 如何返回 Octavia REST API 的 client?