壓力測試是用來檢測系統承載能力的有效手段。在系統規模較小的時候,在一臺空閑的服務器上使用[ab],[wrk],[siege]等工具發起一定量的并發請求即可得到一個初步的測試結果。但在系統復雜度逐步提高,特別是引入了負載均衡,微服務等架構后,單機的壓力測試方案不再可用,企業需要搭建分布式測試集群或者付費使用外部供應商提供的壓力測試服務。
不管是采取自主搭建或是采用外購的手段,都會面臨系統使用率不高以及成本的問題。基于Kubernetes的動態資源調度功能,以及Kubernetes集群的動態伸縮特性,我們可以充分利用集群內的閑置計算資源,在需要進行壓力測試時啟動測試節點,在測試結束后釋放資源給其他業務,甚至通過集群擴容和縮容臨時為壓力測試提供更多的計算資源。
支持分布式部署的壓力測試工具有多款,今天我們將介紹在Kubernetes集群中使用Tsung進行壓力測試的方法。
Tsung
[Tsung]是一款使用[Erlang]開發的分布式壓力測試系統,它支持HTTP,Jabber,MySQL等多種協議,可以用于不同場景的壓力測試。與傳統的針對單一測試目標重復請求的壓測系統不同,Tsung更側重于模擬真實使用場景。測試人員指定新用戶到訪頻率,并設定一系列的模擬操作請求。所有的Slave節點將在Master節點的統一調度下,按照到訪頻率創建虛擬用戶,并發送操作請求。
所有請求的耗時以及錯誤信息將傳回Master節點用于統計和報表。
選擇Tsung主要有三方面的考慮:
- 性能優越。Erlang語言天生就是為高并發網絡系統設計的。合理配置的Tsung集群可以實現100W以上的并發流量。
- 描述式的配置方法。不論簡單還是復雜,Tsung均統一使用XML文件描述整個測試步驟以及各種參數。這樣可以在集群架構保持不變時完成各種測試。
- 模擬真實用戶的測試理念。在真實場景中,用戶會訪問系統的各項功能。只有支持模擬真實用戶的壓力測試系統才能比較準確的反應系統各個部分在壓力下的狀態,找到瓶頸環節。
由于Tsung采取的工作模式是在配置中注明Slave地址,然后由Master連上Slave完成測試,傳統的部署方法是啟動多臺物理機或者虛擬機,分別配置它們。在這種工作模式下,會產生大量的運維工作,同時這些計算資源在不進行測試時處于閑置狀態,降低了硬件使用率。
在Kubernetes中使用容器運行Tsung
利用Kubernetes強大的調度能力,我們可以將Tsung運行在容器當中,動態的啟動和刪除。當需要提高測試規模時,我們僅需要使用[Archon]等已有的工具對集群進行擴容,就可以很方便的一鍵擴容Slave的數量,幾乎沒有帶來任何的運維負擔。
以下是具體的操作流程:
創建Namespace
$ kubectl create namespace tsung
使用StatefulSet部署Tsung Slave
這里不能使用Deployment
,只有使用StatefulSet
才能在為每一個Pod
分配獨立的內部域名,供Master連接。
將以下文件保存為tsung-slave-svc.yaml
apiVersion: v1
kind: Service
metadata:labels:run: tsung-slavename: tsung-slave
spec:clusterIP: Noneselector:run: tsung-slaveports:- port: 22type: ClusterIP
將以下文件保存為tsung-slave.yaml
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:name: tsung-slave
spec:serviceName: "tsung-slave"replicas: 1template:metadata:labels:run: tsung-slavespec:containers:- name: tsungimage: ddragosd/tsung-docker:1.6.0env:- name: SLAVEvalue: "true"
在Kubernetes中創建相應的資源
$ kubectl create -f tsung-slave-svc.yaml --namespace tsung
$ kubectl create -f tsung-slave.yaml --namespace tsung
這里我們設置了StatefulSet
的serviceName
字段,這樣啟動的Pod
在集群內部就可以通過tsung-slave-0.tsung-slave.tsung.svc.cluster.local
這個域名訪問到。
使用StatefulSet部署Tsung Master
與Slave類似,Master節點也要求可以在集群內部通過域名訪問。所以我們依然需要使用StatefulSet
來運行。
將以下文件保存為tsung-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: tsung-config
data:config.xml: |<?xml version="1.0" encoding="utf-8"?><!DOCTYPE tsung SYSTEM "/usr/share/tsung/tsung-1.0.dtd" []><tsung loglevel="warning"><clients><client host="tsung-slave-0.tsung-slave.tsung.svc.cluster.local" /></clients><servers><server host="target" port="8000" type="tcp"/></servers><load><arrivalphase phase="1" duration="1" unit="minute"><users arrivalrate="100" unit="second"/></arrivalphase></load><sessions><session name="es_load" weight="1" type="ts_http"><for from="1" to="10" incr="1" var="counter"><request> <http url="/" method="GET" version="1.1"></http> </request></for></session></sessions></tsung>
將以下文件保存為tsung-master-svc.yaml
apiVersion: v1
kind: Service
metadata:labels:run: tsung-mastername: tsung-master
spec:clusterIP: Noneselector:run: tsung-masterports:- port: 8091sessionAffinity: Nonetype: ClusterIP
將以下文件保存為tsung-master.yaml
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:name: tsung-master
spec:serviceName: "tsung-master"replicas: 1template:metadata:labels:run: tsung-masterspec:containers:- name: tsungimage: ddragosd/tsung-docker:1.6.0env:- name: ERL_SSH_PORTvalue: "22"args:- -k- -f- /tsung/config.xml- -F- startvolumeMounts:- mountPath: /tsungname: config-volumevolumes:- configMap:name: tsung-configname: config-volume
在Kubernetes中創建相應的資源
$ kubectl create -f tsung-config.yaml --namespace tsung
$ kubectl create -f tsung-master-svc.yaml --namespace tsung
$ kubectl create -f tsung-master.yaml --namespace tsung
當Tsung Master的容器被啟動后,它會自動開始運行壓力測試。在上面的列子中,Tsung將向http://target:8000
發起為期1分鐘的壓力測試,在測試期間,每秒鐘產生100個模擬用戶,每個用戶訪問10次目標地址。
我們將Tsung的配置文件用ConfigMap
注入到了Master容器當中,這樣用戶僅需要修改tsung-config.yaml
的內容,就可以方便的定義符合自己要求的測試。在實際使用過程中,用戶可以自主調整測試持續時間,虛擬用戶產生速度,目標地址等參數。用戶還可以通過修改tsung-slave.yaml
中replicas
的數值,并將更多的Slave地址加入到tsung-config.yaml
當中,來獲得更多的測試資源,進一步增加負載量。
在Master的運行參數中,我們使用的-k
參數將使得Master在測試完成后仍處于運行狀態,這樣用戶可以通過8091
端口訪問到測試結果。
$ kubectl port-forward tsung-master-0 -n tsung 8091:8091
之后在本地通過瀏覽器訪問http://localhost:8091
即可打開Tsung內置的報表界面。如下圖所示:
另外-F
參數讓Master使用FQDN
地址訪問Slave節點,這項參數非常關鍵,缺少它將導致Master無法正常連接上Slave。
資源回收
測試結束后,用戶可以使用報表界面查看和保存結果。當所有結果被保存下來之后,可以直接刪除Namespace
完成資源回收。
$ kubectl delete namespace tsung
這樣所有的Tsung相關配置和容器均會被刪除。當下次需要測試時,可以從一個全新的狀態開始新一次測試。
總結
本文主要介紹了在Kubernetes中部署Tsung這款分布式壓力測試系統的方法。其中使用StatefulSet
配合-F
參數的方法,使得Master和Slave可以順利的使用域名找到對方,成功的解決了在容器中運行Tsung會遇到的訪問問題。
原本需要專業的運維工程師投入不少時間才能搭建起來的Tsung測試集群,在Kubernetes中幾乎可以毫不費力的啟動起來,完成測試。這種使用調度器充分利用集群空閑資源,使用后及時釋放供其他系統使用的方法,也充分體現了Kubernetes的優越性。
在下一篇分享中,我們將使用本文所描述的測試系統,對主流的Python WSGI服務器進行壓力測試,用以對比各個服務器的性能指標。希望通過這種實戰演示的方式,幫助大家深入了解Tsung以及Kubernetes。敬請期待。