閱讀834 返回首頁    go 人物


基於Kubernetes的分布式壓力測試方案

壓力測試是用來檢測係統承載能力的有效手段。在係統規模較小的時候,在一台空閑的服務器上使用abwrksiege等工具發起一定量的並發請求即可得到一個初步的測試結果。但在係統複雜度逐步提高,特別是引入了負載均衡,微服務等架構後,單機的壓力測試方案不再可用,企業需要搭建分布式測試集群或者付費使用外部供應商提供的壓力測試服務。

不管是采取自主搭建或是采用外購的手段,都會麵臨係統使用率不高以及成本的問題。基於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-slave
  name: tsung-slave
spec:
  clusterIP: None
  selector:
    run: tsung-slave
  ports:
  - port: 22
  type: ClusterIP

將以下文件保存為tsung-slave.yaml

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: tsung-slave
spec:
  serviceName: "tsung-slave"
  replicas: 1
  template:
    metadata:
      labels:
        run: tsung-slave
    spec:
      containers:
      - name: tsung
        image: ddragosd/tsung-docker:1.6.0
        env:
        - name: SLAVE
          value: "true"

在Kubernetes中創建相應的資源

$ kubectl create -f tsung-slave-svc.yaml --namespace tsung
$ kubectl create -f tsung-slave.yaml --namespace tsung

這裏我們設置了StatefulSetserviceName字段,這樣啟動的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-master
  name: tsung-master
spec:
  clusterIP: None
  selector:
    run: tsung-master
  ports:
  - port: 8091
  sessionAffinity: None
  type: ClusterIP

將以下文件保存為tsung-master.yaml

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: tsung-master
spec:
  serviceName: "tsung-master"
  replicas: 1
  template:
    metadata:
      labels:
        run: tsung-master
    spec:
      containers:
      - name: tsung
        image: ddragosd/tsung-docker:1.6.0
        env:
        - name: ERL_SSH_PORT
          value: "22"
        args:
        - -k
        - -f
        - /tsung/config.xml
        - -F
        - start
        volumeMounts:
        - mountPath: /tsung
          name: config-volume
      volumes:
      - configMap:
          name: tsung-config
        name: 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將向https://target:8000發起為期1分鍾的壓力測試,在測試期間,每秒鍾產生100個模擬用戶,每個用戶訪問10次目標地址。

我們將Tsung的配置文件用ConfigMap注入到了Master容器當中,這樣用戶僅需要修改tsung-config.yaml的內容,就可以方便的定義符合自己要求的測試。在實際使用過程中,用戶可以自主調整測試持續時間,虛擬用戶產生速度,目標地址等參數。用戶還可以通過修改tsung-slave.yamlreplicas的數值,並將更多的Slave地址加入到tsung-config.yaml當中,來獲得更多的測試資源,進一步增加負載量。

在Master的運行參數中,我們使用的-k參數將使得Master在測試完成後仍處於運行狀態,這樣用戶可以通過8091端口訪問到測試結果。

$ kubectl port-forward tsung-master-0 -n tsung 8091:8091

之後在本地通過瀏覽器訪問https://localhost:8091即可打開Tsung內置的報表界麵。如下圖所示:

tsung_report

另外-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。敬請期待。

最後更新:2017-06-29 09:02:11

  上一篇:go  Spring cloud--服務注冊和服務發現-Eureka 的使用
  下一篇:go  樹莓派使用 DHT11 溫濕度傳感器