需求
物理計算節點有限,難以測試網絡組件的性能滿不滿足5000節點集群需求,在開發測試階段知道網絡插件的性能至關重要。因此使用kubemark來模擬計算節點,都知道使用kubemark需要一個真實的k8s集群和一個kubemark集群。真實的k8s集群已搭建完畢,下面需要搭建kubemark虛擬集群。並在虛擬集群中替換自己客制化的組件。
安裝kubemark集群
參考k8s官方文檔(鏈接1):
https://github.com/kubernetes/community/blob/452f681d92d98d6d62dfb24fbc9c8da10935632c/contributors/devel/sig-scalability/kubemark-setup-guide.md
如果以上鏈接打不開可以先到https://github.com/kubernetes/community/頁面,在搜索欄里輸入kubemark進行搜索,應該能找到。
構建kubemark鏡像
你可以下載已經編譯好的鏡像,也可以自己編譯代碼
docker pull staging-k8s.gcr.io/kubemark:latest
如果你下載不了,那么感謝偉大的網友ss104301,可以在https://hub.docker.com/網站找到kubemark鏡像,用命令docker pull ss104301/kubemark 下載鏡像即可。但是如果你需要定制化kubemark那么就需要自己編譯kubemark鏡像。編譯自己的kubemark鏡像不像想象中那么復雜,按照鏈接1給出的三個步驟即可順利的編譯,這三個步驟在此重復一下:
- i. 下載kurbernetes源碼
下載和external-cluster一致的kubernetes release版本,我下載的是kubernetes-release-1.14.zip這個文件。里面已經包含了vendor目錄,無需自己再下載第三方庫 - ii. 編譯kubemark二進制文件
設置好GOPATH環境變量,然后執行命令./hack/build-go.sh cmd/kubemark/ cp $GOPATH/src/k8s.io/kubernetes/_output/bin/kubemark $GOPATH/src/k8s.io/kubernetes/cluster/images/kubemark/
- iii. 構建kubemark鏡像
這里Dockerfile中寫明該鏡像From debian:jessie, 我從debian官網中看到debian:jessie就是debian8,然后到https://hub.docker.com/中找到匹配的版本鏡像下載到本地並用命令docker tag打上標簽debian:jessie, 然后運行上面的命令就能編譯出staging-k8s.gcr.io/kubemark:latest本地鏡像。注意,編譯的環境要求能連外網。cd $GOPATH/src/k8s.io/kubernetes/cluster/images/kubemark/ make build
- iv. 推送kubemark鏡像
docker tag staging-k8s.gcr.io/kubemark:latest {{kubemark_image_registry}}/kubemark:{{kubemark_image_tag}} docker push {{kubemark_image_registry}}/kubemark:{{kubemark_image_tag}}
創建hollow節點
- 創建namespace, configmap 和 secret
文章開頭提到kubemark方案需要一個真實的k8s集群,這里kubemark使用該集群的config.注意--from-file后面最好放決對路徑,否則會在命令執行的當前找配置文件。或者到文件所在的目錄下執行命令。
kubectl create ns kubemark
kubectl create configmap node-configmap -n kubemark --from-literal=content.type="test-cluster"
kubectl create secret generic kubeconfig --type=Opaque --namespace=kubemark --from-file=kubelet.kubeconfig=path/to/kubeletcfg --from-file=kubeproxy.kubeconfig=path/to/kubeproxycfg
我的環境用的配置文件路徑分別是/etc/kubernetes/kubelet.kubeconfig和/etc/kubernetes/kube-proxy.kubeconfig,這里要仔細核對,不要填錯了。
- 用yaml文件創建hollow節點
可以參考官方模板(鏈接2)
https://github.com/kubernetes/community/blob/452f681d92d98d6d62dfb24fbc9c8da10935632c/contributors/devel/sig-scalability/hollow-node_simplified_template.yaml
注意: - 參數 {{numreplicas}} 表示的是kubemark集群中hollow節點的數量
- 參數 {{numreplicas}}, {{kubemark_image_registry}} 和{{kubemark_image_tag}} 需要根據你的實際情況填寫,其他不需要填寫
- 你的真實集群要有足夠的資源來運行 {{numreplicas}} 數量的 hollow-node pods
最后,用命令創建hollow-node pods就可以了
kubectl create -f hollow-node_simplified_template.yaml
hollow節點排錯
查看hollow-node pods,看出並不正常
describe其中一個pod,發現報錯"NetworkPlugin cni failed to set up pod "hollow-node-pvp57_kubemark" network: Voyage:Error making request to create endpoint". 這是因為,我們的真實節點使用的是自定義的網絡插件voyage,而下載的鏡像是沒有這個組件的。怎么辦呢?一步一步來。
清除網絡插件配置,使hollow-node pods能運行起來
因為目前external-cluster使用的是CNI網絡模式,而kubemark集群中並沒有該網絡插件,因此,我先把網絡調試調整成hostonly模式,修改/etc/kurbenetes/kubelet文件中的KUBELET_ARGS配置,使--network-plugin值為空重啟kubelet,重新創建kubemark集群。但集群還是起不來,查看各個相關pod的log
[root@k8s-master kubernetes]# kubectl log -n kubemark hollow-node-48wb8 hollow-proxy
可以看出,找不到kubelet配置文件中的ssl認證文件,這時需要修改hollow-node_simplified_template.yaml添加volume共享配置
volumes:
- name: sslconfig-volume
hostPath:
path: /etc/kubernetes/ssl/
...
volumeMounts:
- name: sslconfig-volume
mountPath: /etc/kubernetes/ssl/
然后重新創建,hollow-node pod終於Running起來了,但是查看節點信息,並沒有多出來節點。再次查看hollow-node pod的log, 報錯如下:
I0331 08:37:56.990844 7 kubelet_node_status.go:72] Attempting to register node hollow-node-c229t
E0331 08:37:56.991809 7 kubelet_node_status.go:94] Unable to register node "hollow-node-c229t" with API server: nodes "hollow-node-c229t" is forbidden: node "k8s-master" is not allowed to modify node "hollow-node-c229t"
E0331 08:37:56.997823 7 kubelet.go:2246] node "hollow-node-c229t" not found
E0331 08:37:57.298099 7 kubelet.go:2246] node "hollow-node-c229t" not found
經查看,是證書的問題,因為我們的external-cluster開啟了驗證,因此要給每個follow-node指定一個證書。RC改變為使用statefulset,因為這樣pod的名稱是有一定的規律的,方便證書的生產。后面會附上修改的hollow-node.yaml文件。
編譯e2e
還是到編譯kubemark的目錄,設置好GOPATH環境變量。然后輸入命令 make WHAT="test/e2e/e2e.test" ,就在_output/bin目錄中生成了e2e.test二進制文件。
測試性能
這里需要先安裝ginkgo和gomega,生成kubeconfig文件:kubectl config view -o yaml >> /root/.kube/config . 然后引用上面編譯好的e2e二進制文件
_output/bin/e2e.test --kube-master=10.27.244.161 --host=http://10.27.244.161:8080 --ginkgo.focus=":Performance]" --provider=local --kubeconfig=/etc/kubernetes/kubelet.kubeconfig --num-nodes=2 --v=3 > performance.log
然后查看 "pods creation" 關鍵字來看創建花費的時間。
修改kubemark網絡插件
kubemark使用的網絡組件是默認的fake cri networking,叫做kubernetes.io/no-op.因此一般情況下不需要部署網絡插件,虛擬節點上的容器也會得到一個IP. 但是如果你需要測試自己的網絡插件的性能,那么就需要修改kubemark源代碼,在hollow_kubelet.go文件中的GetHollowKubeletConfig函數中添加f.ContainerRuntimeOptions.NetworkPluginName = "cni"
即可。注意編譯的時候需要先把_output文件夾刪除,否則不生效。但是注意,當使用自己的網絡插件時,可能需要修改kubelet/dockershim/docker_sandbox.go中的getIPFromPlugin函數。根據插件的不同獲取插件指定的IP,否則kubectl查看到的Pod的IP是hollow-node的IP。
網絡插件的進程也需要有hollow-node pod在啟動時帶起來,讓網絡插件守護進程跑在虛擬節點pod里,監聽kubelet的調用。其實虛擬節點上的kubelet進程也是被hollow-node pod啟動時帶起來的。
修改虛擬節點的資源配置
kubemark創建的hollow-node使用的是cadvisor_fake.go中的默認資源值例如FakeNumCores(CPU核數),FakeMemoryCapacity(內存大小)等等。如果需要修改就修改這里或者引用這些數值的地方,然后重新編譯。
屏蔽PreStop處理代碼
因為kubemark創建的pod是不真實調用docker-cri接口的,也就是說並沒有真實的pod被創建出來。當pod銷毀時有PreStop事件需要處理的話,那么會crash,所以需要屏蔽kubelet/kuberuntime/kuberuntime_container.go中的函數executePreStopHook處理PreStop的代碼。