2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

如何用 Kubernetes 管理超過(guò) 2500 個(gè)節(jié)點(diǎn)的集群

 xujin3 2018-06-10

接收程序員的 8 點(diǎn)技術(shù)早餐

譯者|夏天
校對(duì)|郭維
出處丨 K8sMeetup 中國(guó)社區(qū)

兩年來(lái),我們一直在使用 Kubernetes 進(jìn)行深度學(xué)習(xí)方面的研究。雖然我們大量的 workloads 可以直接運(yùn)行在云虛擬機(jī)上,但是因?yàn)?Kubernetes 目前仍在快速迭代,而且擁有比較好的擴(kuò)展性,也沒(méi)有過(guò)多的約束,因此 Kubernetes 成為了我們最理想的集群管理工具。目前,我們已經(jīng)有好幾個(gè)正在運(yùn)行的 Kubernetes 集群了(有些運(yùn)行在云虛擬機(jī)上,有些則直接運(yùn)行在物理機(jī)上)。其中最大的一個(gè)集群運(yùn)行在 Azure 上,由 D15v2 和 NC24 兩種類(lèi)型的虛擬機(jī)組成,目前已經(jīng)超過(guò) 2500 個(gè)節(jié)點(diǎn)。

在達(dá)到 2500 節(jié)點(diǎn)規(guī)模的過(guò)程中,許多的系統(tǒng)組件都出現(xiàn)了問(wèn)題,包括 etcd,Kube Master,Docker 拉取鏡像,網(wǎng)絡(luò),Kube DNS,機(jī)器上的 ARP 緩存。接下來(lái)將分享我們所遇到的問(wèn)題和解決方案,希望對(duì)大家有所幫助。

 etcd  

在集群中添加了超過(guò) 500 個(gè)節(jié)點(diǎn)的時(shí)候,我們的研究人員發(fā)現(xiàn)使用 kubectl 操作集群的時(shí)候會(huì)發(fā)生超時(shí)的情況。于是我們嘗試添加更多的 Kube Master 節(jié)點(diǎn)(運(yùn)行 kube-apiserver 的節(jié)點(diǎn))。這樣做臨時(shí)解決了這個(gè)問(wèn)題,但當(dāng)我們添加了 10 個(gè) Master 節(jié)點(diǎn)后,我們發(fā)現(xiàn)這只是在表面上解決問(wèn)題,并沒(méi)有找到這個(gè)問(wèn)題的根本原因(作為對(duì)比,GKE 只使用了一臺(tái) 32 核的虛擬機(jī)作為 Master 就能管理 500 個(gè)節(jié)點(diǎn)。

etcd 存儲(chǔ)了 Kubernetes 集群的所有狀態(tài)數(shù)據(jù),因此我們強(qiáng)烈懷疑是 etcd 集群出現(xiàn)了問(wèn)題。通過(guò)查看 Datadog,我們發(fā)現(xiàn)雖然我們的每臺(tái)機(jī)器都使用了支持 5000 IOPS 的 P30 SSD,但是運(yùn)行了 etcd 的 DS15v2 虛擬機(jī)的寫(xiě)延遲在某些時(shí)間段猛增至數(shù)百毫秒。

這么高的寫(xiě)延遲阻塞了整個(gè)集群!

在使用 fio 進(jìn)行性能測(cè)試之后,我們發(fā)現(xiàn) etcd 的 I/O 性能只能達(dá)到 I/O 上限的 10% 左右 。這主要是因?yàn)閱未螌?xiě)延遲為 2ms,而 etcd 又使用了串行 I/O,導(dǎo)致 I/O 之間的延遲疊加(latency-bound)。

然后,我們將每個(gè)節(jié)點(diǎn)上的 etcd 的目錄從網(wǎng)絡(luò)磁盤(pán)移到本地 SSD 磁盤(pán)上。移動(dòng)之后,寫(xiě)延遲降低到了 200 微秒,etcd 終于正常了。

我們的集群一直運(yùn)行良好,直到我們?cè)黾拥搅?1000 個(gè)節(jié)點(diǎn)。這個(gè)時(shí)候我們?cè)俅伟l(fā)現(xiàn) etcd 出現(xiàn)了很高的延遲。這一次,我們注意到 kube-apiservers 從 etcd 讀取數(shù)據(jù)的速度超過(guò)了 500MB/s。我們搭建了 Prometheus 用于監(jiān)控 kube-apiservers,還設(shè)置了  --audit-log-path--audit-log-maxbackup 選項(xiàng)來(lái)保存更多的日志數(shù)據(jù)。通過(guò)日志,我們發(fā)現(xiàn)了許多慢查詢請(qǐng)求和大量的對(duì) Events 的 List API 的請(qǐng)求。

我們找到了問(wèn)題的根本原因,我們發(fā)現(xiàn)部分程序會(huì)頻繁去 kube-apiservers 查詢各種信息(比如 Fluentd 和 Datdog 會(huì)去 kube-apiservers 查詢每個(gè)節(jié)點(diǎn)信息)。我們修改了這些程序的設(shè)置,降低它們對(duì) kube-apiservers 的查詢頻率,然后 kube-apiservers 的負(fù)載就降下來(lái)了:

etcd 的出口速度從 500MB/s 左右降低到了接近 0MB/s(上圖中負(fù)值表示出口速度)

另一個(gè)有效的改動(dòng)是把 Kubernetes Events 存儲(chǔ)在一個(gè)單獨(dú)的 etcd 集群里,這樣對(duì) Events 的操作就不會(huì)影響到主 etcd 集群的正常工作。要想能做到這一點(diǎn),我們只需要將這 --etcd-servers-overrides 設(shè)置為

另一個(gè)超過(guò) 1000 節(jié)點(diǎn)后的故障是觸發(fā)了 etcd 的硬盤(pán)存儲(chǔ)上限(默認(rèn)是 2GB), 于是 etcd 不再接受寫(xiě)請(qǐng)求。這直接導(dǎo)致了一連串的問(wèn)題:所有 kube node 的健康檢查都失敗了,我們的 autoscaler 決定刪除所有的 workers。于是我們通過(guò) etcd 的  --quota-backend-bytes 增大了存儲(chǔ)大小。另外還讓 autoscaler 支持基礎(chǔ)(sanity)檢查,在發(fā)現(xiàn)要終止集群里超過(guò) 50% 的 workers 的時(shí)候,放棄這個(gè)操作。

Kube Master

我們?cè)谕慌_(tái)機(jī)器上安裝了 kube-apiserver,kube-controller-manager 和 kube-scheduler processes。為了高可用,我們一直有至少兩個(gè) masters,并將 --apiserver-count 設(shè)置為我們正在運(yùn)行的 apiservers 數(shù)量(否則 Prometheus 可能會(huì)混淆這些實(shí)例)。

我們主要使用 Kubernetes 作為批量調(diào)度系統(tǒng),并依靠 autoscaler 動(dòng)態(tài)地伸縮我們的集群。這使我們可以顯著地降低空閑節(jié)點(diǎn)的成本,在快速迭代的同時(shí)提供低延遲。默認(rèn)的 kube-scheduler 策略是將負(fù)載均勻分散在節(jié)點(diǎn)之間,但這與我們的期望相悖,我們希望可以終止未使用的節(jié)點(diǎn),同時(shí)也可以快速調(diào)度大的 pod。所以我們切換到下面的策略:

我們使用 KubeDNS 實(shí)現(xiàn)服務(wù)發(fā)現(xiàn),但是在我們使用新的調(diào)度策略后,很快它就出現(xiàn)了一些可靠性問(wèn)題。我們發(fā)現(xiàn)故障只在 KubeDNS 的 Pods 中出現(xiàn)。在新的調(diào)度規(guī)則影響下,有些機(jī)器上運(yùn)行了十多個(gè) KubeDNS 實(shí)例,這就導(dǎo)致了這些機(jī)器成為了熱點(diǎn),它們收到的 DNS 查詢超過(guò)了 200 QPS(這是 Azure 虛擬機(jī)對(duì) DNS 查詢的上限值)。

Docker 拉取鏡像

我們的 Dota 項(xiàng)目剛開(kāi)始運(yùn)行在 Kubernetes 上的時(shí)候,一旦它開(kāi)始擴(kuò)容,我們就注意到一些新的節(jié)點(diǎn)上有很多 Pods 處于 Pending 狀態(tài),而且持續(xù)很長(zhǎng)時(shí)間。Dota 的鏡像大小為 17GB,把這個(gè)鏡像拉取到一個(gè)新的節(jié)點(diǎn)上需要大約 30 分鐘的時(shí)間。因此我們知道了 Dota 的 Pod 處于 Pending 的原因,但是同一個(gè)節(jié)點(diǎn)上的其他比較小的 Pod 也出現(xiàn)了相同的情況。

隨著調(diào)查的深入,我們發(fā)現(xiàn) kubelet 的 --serialize-image-pulls 默認(rèn)為 true,這意味著拉取 Dota 鏡像的時(shí)候,其他鏡像的拉取都會(huì)被阻塞住。把這個(gè)選項(xiàng)修改為 false 需要讓 Docker 使用 overlay2 文件系統(tǒng)而不是 AUFS。為了加快拉取速度,我們把 Docker 的根存儲(chǔ)目錄遷移到了機(jī)器的本地 SSD 上,就像 etcd 那樣。

在優(yōu)化了拉取速度之后,我們?nèi)匀话l(fā)現(xiàn) Pods 出現(xiàn)了奇怪的錯(cuò)誤:error message: rpc error: code = 2 desc = net/http: request canceled。由于進(jìn)度不足,Kubelet 和 Docker 的日志里也指出了鏡像拉取被取消了。我們究其根源,發(fā)現(xiàn)當(dāng)有很多積壓的鏡像拉取任務(wù),或者有些大鏡像花費(fèi)很長(zhǎng)的時(shí)間都沒(méi)有完成拉取和解壓工作的時(shí)候,就會(huì)出現(xiàn)這種錯(cuò)誤。為了解決這個(gè)問(wèn)題,我們將 Kubelet 的 --image-pull-progress-deadline 設(shè)置為 30 分鐘, 并且設(shè)置了 Docker 的 max-concurrent-downloads 為 10。(第二個(gè)選項(xiàng)不會(huì)加速大鏡像的解壓工作,但是可以讓拉取鏡像的工作并行執(zhí)行 。)

我們最后的 Docker 鏡像拉取問(wèn)題源自 Google Container Registry。默認(rèn)情況下, Kubelet 會(huì)自動(dòng)從 gcr.io 拉取一個(gè)特殊的鏡像(可由 --pod-infra-container-image 控制),這個(gè)鏡像用于啟動(dòng)新的容器。如果拉取失敗,這個(gè)節(jié)點(diǎn)就不能啟動(dòng)任何 Pod 。由于我們的節(jié)點(diǎn)沒(méi)有公網(wǎng) IP,只能通過(guò) NAT 訪問(wèn) gcr.io,一旦超過(guò)了單個(gè) IP 的配額上限,就會(huì)拉取失敗。為了解決這個(gè)問(wèn)題,我們通過(guò)預(yù)加載鏡像直接將鏡像部署到機(jī)器上。通過(guò)  docker image save -o /opt/preloaded_docker_images.tardocker image load -i /opt/preloaded_docker_images.tar 完成這個(gè)工作。為了提升性能,我們對(duì)其他公共鏡像比如 OpenAI-internal 和 Dota 鏡像也做了相同的事情。

聯(lián)   網(wǎng)

隨著我們的實(shí)驗(yàn)越來(lái)越大,我們的系統(tǒng)也逐漸變成了重度依賴網(wǎng)絡(luò)的復(fù)雜的分布式系統(tǒng)。當(dāng)我們第一次開(kāi)始分布式實(shí)驗(yàn)的時(shí)候,立即就發(fā)現(xiàn)了我們的網(wǎng)絡(luò)不是很好。機(jī)器之間的吞吐量大約在 10-15Gbit/s, 但是我們基于 Flannel 的 Pods 之間的最大吞吐量?jī)H僅只有 2Gbit/s。

Machine Zone 的公開(kāi)性能測(cè)試也顯示了類(lèi)似的結(jié)果,這意味著這個(gè)問(wèn)題未必是由配置不好導(dǎo)致的,很有可能是我們的環(huán)境中隱藏了一些問(wèn)題(機(jī)器上的 Flannel 應(yīng)該不會(huì)增加這么大的開(kāi)銷(xiāo))。

為了解決這個(gè)問(wèn)題,用戶可以使用兩個(gè)不同的設(shè)置來(lái)讓 Pods 繞過(guò) Flannel 的網(wǎng)絡(luò):hostNetwork 設(shè)置為 true,dnsPolicy 設(shè)置為 ClusterFirstWithHostNet(在做這件事情之前請(qǐng)先閱讀 Kubernetes 中的警告)。

ARP 緩存

雖然我們優(yōu)化了 DNS 的 Pods,但是 DNS 解析仍然時(shí)不時(shí)地出點(diǎn)問(wèn)題。有一天,一位工程師報(bào)告說(shuō),他用 nc -v 連接 Redis 服務(wù)器時(shí),花費(fèi)了超過(guò) 30 秒才成功建立連接。我們深入這個(gè)問(wèn)題一直到內(nèi)核的 ARP 棧。初步調(diào)查顯示 Redis Pod 所在節(jié)點(diǎn)的網(wǎng)絡(luò)出現(xiàn)了嚴(yán)重錯(cuò)誤:連接任意端口都會(huì)掛起好幾秒,而且本地的 dnsmasq 沒(méi)有任何 DNS 記錄,dig 只是打印了一個(gè)奇怪的錯(cuò)誤信息:socket.c:1915: internal_send: 127.0.0.1#53: Invalid argument。dmesg 的日志反而有用的多:neighbor table overflow!這表示 ARP 已經(jīng)用完了緩存空間。ARP 是用來(lái)映射 IPv4 地址到一個(gè)物理地址的(比如 MAC 地址)。幸運(yùn)的是,只需要在 /etc/sysctl.conf 中設(shè)置幾個(gè)選項(xiàng)就能輕松解決這個(gè)問(wèn)題:

這個(gè)修改在 HPC 集群中非常常見(jiàn),而此時(shí)在 Kubernetes 中這個(gè)選項(xiàng)也非常重要,因?yàn)槊總€(gè) Pod 都有自己的 IP,而每個(gè) IP 都需要占用 ARP 緩存空間。

參考文獻(xiàn)

https://blog./scaling-kubernetes-to-2500-nodes/?utm_source=digg

本文由【K8sMeetup 中國(guó)社區(qū)】授權(quán)轉(zhuǎn)載,微信號(hào)【kuberneteschina】。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多