序言
對軟件系統(tǒng)而言看疗,性能測試通常包括兩部分澡屡,一是制造合適的負載,二是在負載條件下進行合理的觀測。
定義觀測對象
任何系統(tǒng)都是有性能邊界的旬陡,保證性能需要成本鸭丛、人力褥傍、時間裂问,不可能無休止地亦或是全方位地要求性能指標。
開發(fā)軟件系統(tǒng)的目的是為了更好的服務(wù)用戶张峰,用戶對系統(tǒng)有品質(zhì)要求泪蔫。影響到用戶品質(zhì)要求的性能指標是主要的、核心的指標喘批,其它的是次要的指標(比如程序員拍腦袋想的指標)撩荣。因此,在進行性能測試之前饶深,定義哪些指標會影響到用戶品質(zhì)要求是必須的工作餐曹,哪怕定義的指標不全面。盲目進行性能測試得到的通常是毫無意義的結(jié)果敌厘。
通常云廠商使用SLA(服務(wù)等級協(xié)議)來概括用戶對系統(tǒng)的品質(zhì)要求台猴。遺憾的是,由于Kubernetes的復(fù)雜性俱两,截止至2019.5.18饱狂,各大云廠商都沒有提供可以最終公布的SLA。
Kubernetes社區(qū)提供了一些SLI(服務(wù)等級指標)和SLO(服務(wù)等級目標)指導(dǎo)系統(tǒng)性能測試宪彩、分析休讳,詳見跳轉(zhuǎn)地址。這些指標間接地描述了Kubernetes系統(tǒng)服務(wù)品質(zhì)毯焕,是性能測試重點關(guān)注的指標衍腥。
除此之外,Master機器的CPU纳猫、Memory等指標,以及ETCD的ioutil等指標也會對Kubernetes服務(wù)造成明顯影響竹捉,因此同樣應(yīng)當納入性能測試的觀測范圍芜辕。
制造集群負載
- 便宜的負載
社區(qū)資料表明Kubernetes可以支持5000臺Node、15萬Pod的集群良好運行块差。這意味著侵续,驗證這一說法至少應(yīng)該制造5000臺Node倔丈、15萬Pod的負載。然而獲得5000臺真實機器的使用權(quán)很貴状蜗,長期占用這么多機器用于Kubernetes的開發(fā)測試是不科學(xué)的需五。因此,社區(qū)開發(fā)了kubemark
和Virtual Kubelet
等工具用于模擬真實Node轧坎,使用少量機器也可以制造出足夠大的負載宏邮。在小米的測試過程中,20臺真實機器可以模擬3000臺Node缸血、10萬個Pod的負載情況蜜氨。 - 多樣的負載
在實際運行環(huán)境中,真實負載情況是多種多樣的捎泻,不同的負載可能對系統(tǒng)的性能指標有不同的影響飒炎,在測試過程中模擬多種負載情況是必要的。為了方便模擬多樣的負載情況笆豁,性能測試提供負載的程序可配置性應(yīng)當盡可能強郎汪。在早期的Kubernetes代碼中,性能測試程序的各項參數(shù)寫死在代碼中闯狱,要修改Kubernetes源碼重新編譯后怒竿,拷貝到測試環(huán)境,才能修改一次測試參數(shù)扩氢。測試過程十分痛苦耕驰。
因此社區(qū)開發(fā)了perf-test/clusterloader2,可配置性極強录豺,并且配備了相應(yīng)的性能指標觀測代碼朦肘,十分推薦。
工具使用說明
Kubernetes性能測試的前置要求:
- 準備運行良好的Kubernetes集群
本文接下來介紹性能測試工具kubemark和perf-test/clusterloader2双饥。
kubemark
kubemark是閹割版的kubelet媒抠,除了不調(diào)用CRI接口之外(即不調(diào)用Docker,直接返回)咏花,其它行為和kubelet基本一致趴生。
編譯
- 編譯二進制
下載kubernetes源碼,執(zhí)行make WHAT='cmd/kubemark'
- 編譯鏡像
編譯docker鏡像的腳本在test/kubemark/start-kubemark.sh中昏翰,因為要涉及到一些代碼改造苍匆,在此不作說明。
使用步驟
- 標記真實Node
1.設(shè)置Taint
假設(shè)Node名字是mytestnode
棚菊,執(zhí)行以下命令設(shè)置Taint浸踩。
kubectl taint nodes mytestnode role=real:NoSchedule
設(shè)置Taint的目的在于,避免壓力測試的Pod調(diào)度至真實Node上统求。
2.設(shè)置Label
假設(shè)Node名字是mytestnode
检碗,執(zhí)行以下命令設(shè)置Label据块。
kubectl label nodes mytestnode role=real
- 配置kubeconfig
apiVersion: v1
kind: Config
users:
- name: kubelet
user: {}
clusters:
- name: kubemark
cluster:
server: http://10.114.25.172:8083 #替換成你自己的APIServer地址
contexts:
- context:
cluster: kubemark
user: kubelet
name: kubemark-context
current-context: kubemark-context
假如上述kubeconfig保存在/home/mi/.kube/config
,執(zhí)行以下命令創(chuàng)建secret
kubectl create secret generic kubeconfig --from-file=kubelet.kubeconfig=/home/mi/.kube/config
- 創(chuàng)建kubemark Pod
執(zhí)行以下腳本運行kubemark:
curl -L https://gist.githubusercontent.com/Betula-L/fef068ef7e914aa4a52113ac81fc6517/raw/77abf3f9b234274e33435597dec079ef46300324/kubemark.yaml | kubectl apply -f -
注意事項
- kubemark版本盡量和master版本一致
- 上述說明只適用沒有開啟認證授權(quán)的master
clusterloader2
運行要求
- master節(jié)點開放ssh服務(wù)
- 測試啟動時刻所有Node處于Ready狀態(tài)(包括hollow node)
編譯
下載pert-tests項目折剃,運行${perf-tests}/clusterloader2/run-e2e.sh
或者如下腳本編譯二進制文件另假。
CLUSTERLOADER_ROOT=${perf-tests}
cd ${CLUSTERLOADER_ROOT}/ && go build -o clusterloader './cmd/'
使用步驟
- 設(shè)置環(huán)境變量
# kube config for kubernetes api
KUBE_CONFIG=${HOME}/.kube/config
# Provider setting
# Supported provider for xiaomi: local, kubemark, lvm-local, lvm-kubemark
PROVIDER='kubemark'
# SSH config for metrics' collection
KUBE_SSH_KEY_PATH=$HOME/.ssh/id_rsa
MASTER_SSH_IP=10.142.43.51
MASTER_SSH_USER_NAME=root
# Clusterloader2 testing strategy config paths
# It supports setting up multiple test strategy. Each testing strategy is individual and serial.
TEST_CONFIG='configs/examples/density/config.yaml'
# Clusterloader2 testing override config paths
# It supports setting up multiple override config files. All of override config files will be applied to each testing strategy.
# OVERRIDE_CONFIG='testing/density/override/200-nodes.yaml'
# Log config
REPORT_DIR='./reports'
LOG_FILE='logs/tmp.log'
填充上述腳本內(nèi)容,并使用source
命令設(shè)置好Linux環(huán)境變量
- 運行clusterloader2
$CLUSTERLOADER_BIN --kubeconfig=$KUBE_CONFIG \
--provider=$PROVIDER \
--masterip=$MASTER_SSH_IP --mastername=$MASTER_SSH_USER_NAME \
--testconfig=$TEST_CONFIG \
--report-dir=$REPORT_DIR \
--alsologtostderr 2>&1 | tee $LOG_FILE
# --testoverrides="${OVERRIDE_CONFIG:-}" \
按上述命令運行clusterloader2怕犁,其中CLUSTERLOADER_BIN
是編譯好的clusterloader2二進制文件位置边篮,其它參數(shù)是設(shè)置好的環(huán)境變量。
測試說明
pert-tests只是性能測試框架因苹,具體的性能測試策略需要用戶自己通過配置文件定義苟耻。
以kubernetes density測試為例,解釋clusterloader2的測試過程及其結(jié)果扶檐。
density測試策略
- 啟動若干個觀測程序
在測試策略配置文件中凶杖,所有的Measurement都是用于采集數(shù)據(jù)的觀測程序。perf-tests提供了十幾個Measurement款筑,density測試使用了其中5個智蝠,包括APIResponsiveness
、SaturationPodStartupLatency
奈梳、WaitForRunningSaturationRCs
杈湾、SchedulingThroughput
、PodStartupLatency
攘须。 - 系統(tǒng)調(diào)度吞吐測試
kubernetes認為每個Node運行30個Pod是機器正常負載情況漆撞。一次性發(fā)布#node*30
個Pod用于測試集群的調(diào)度吞吐性能,可以說明“系統(tǒng)發(fā)生大規(guī)模故障后于宙,從零到正常負載所需恢復(fù)時間”浮驳,調(diào)度吞吐量定義如下:
?? ? ? ? ?調(diào)度吞吐量=一段較長時間內(nèi)最大可以發(fā)布的Pod數(shù)量/總發(fā)布時間
值得注意的是,clusterloader2不是簡單地使用一個rc創(chuàng)建#node*30
個Pod捞魁,因為kubernetes對系統(tǒng)的使用有一些基本假設(shè)至会,包括“每個namespace的Pod數(shù)量不超過3000”,“每個node的Pod數(shù)量不能超過110”等谱俭。為了滿足這些基本假設(shè)奉件,clusterloader2在創(chuàng)建rc時,做了不少的特殊處理昆著。 - Pod啟動e2e耗時測試
為了說明Pod啟動e2e耗時县貌,在不刪除“調(diào)度吞吐測試”負載的基礎(chǔ)上,進行l(wèi)atency測試宣吱。
latency測試策略是每隔0.2秒創(chuàng)建一個pod窃这,根據(jù)pod創(chuàng)建過程中產(chǎn)生的timestamp和event,計算出Pod啟動過程中征候,每個階段的耗時和總e2e耗時杭攻。如果調(diào)度吞吐量<5pods/s
,則創(chuàng)建Pod的時間間隔應(yīng)當設(shè)置大于0.2s疤坝。
目前l(fā)atency測試存在精度問題兆解,因為kubernetes event存儲的時間是RFC3339,導(dǎo)致部分階段的耗時精度只到秒跑揉,對性能分析價值不大锅睛。
density測試策略
測試結(jié)果
- stdout/stderr
整個性能測試過程以及部分測試結(jié)果會打印到stdout中,如果按本文所述方法運行clusterloader2历谍,打印結(jié)果會保存一份至${LOG_FILE}
现拒。
調(diào)度吞吐量結(jié)果:
Jan 9 13:55:47.876: INFO: E2E startup time for 10500 pods: 28m40.333662404s
Jan 9 13:55:47.876: INFO: Throughput (pods/s) during cluster saturation phase: 6.1034675
^[[1mSTEP^[[0m: Printing Pod to Node allocation data
Jan 9 13:55:47.884: INFO: Density Pods: 10500 out of 10500 created, 10500 running, 0 pending, 0 waiting, 0 inactive, 0 terminating, 0 unknown, 0 runningButNotReady
Pod啟動e2e耗時結(jié)果:
Jan 9 14:09:31.598: INFO: perc50: 1614, perc90: 2241, perc99: 2541
Jan 9 14:09:31.598: INFO: Approx throughput: 7486.052881923156 pods/min
- report文件夾
詳細的性能測試結(jié)果clusterloader2收集在report文件夾下,如果按本文方法運行望侈,則結(jié)果存放在{$REPORT_DIR}
中印蔬。因為涉及到的性能測試結(jié)果非常多,本文不在此一一列舉脱衙。目前Kubernetes性能分析最主要的性能指標如下:- APIServer Restful API響應(yīng)時間 - APIResponsiveness
- Pod 啟動總耗時 - PodStartupLatency
- Scheduler調(diào)度性能 - SchedulingThroughput, SchedulingMetrics
- ETCD指標 - EtcdMetrics