天天看點

伸縮Kubernetes到2500個節點中遇到的問題和解決方法

Kubernetes自從 1.6

起便号稱可以承載5000個以上的節點,但是從數十到5000的路上,難免會遇到問題。

本片文章即分享Open API在kubernetes 5000之路上的經驗,包括遇到的問題、嘗試解決問題以及找到真正的問題。

遇到的問題以及如何解決

問題一:1 ~ 500個節點之後

問題:

kubectl 有時會出現 timeout(p.s. kubectl -v=6 可以顯示所有API細節指令)

嘗試解決:

  • 一開始以為是kube-apiserver伺服器負載的問題,嘗試增加proxy做replica協助進行負載均衡
  • 但是超過10個備份master的時候,發現問題不是因為kube-apiserver無法承受負載,GKE通過一台32-core VM就可以承載500個節點

原因:

  • 排除以上原因,開始排查master上剩下的幾個服務(etcd、kube-proxy)
  • 開始嘗試調整etcd
  • 通過使用 datadog 檢視etcd吞吐量,發現有異常延遲(latency spiking ~100 ms)
  • 通過 Fio 工具做性能評估,發現隻用到10%的IOPS(Input/Output Per Second),由于寫入延遲(write latency 2ms)降低了性能
  • 嘗試把SSD從網絡硬碟變為每台機器有個local temp drive(SSD)
  • 結果從~100ms —> 200us

問題二:~1000個節點的時候

  • 發現kube-apiserver每秒從etcd上讀取500mb
  • 發現 Fluentd 和Datadog抓取每個節點上資料過于頻繁
  • 調低兩個服務的抓取頻率,網絡性能從500mb/s降低到幾乎沒有
  • etcd小技巧:通過–etcd-servers-overrides可以将Kubernetes Event的資料寫入作為切割,分不同機器處理,如下所示
--etcd-servers-overrides=/events#https://0.example.com:2381;https://1.example.com:2381;https://2.example.com:2381      

問題三:1000 ~ 2000個節點

  • 無法再寫入資料,報錯cascading failure
  • kubernetes-ec2-autoscaler在全部的etcd都停掉以後才回傳問題,并且關閉所有的etcd
  • 猜測是etcd硬碟滿了,但是檢查SSD依舊有很多空間
  • 檢查是否有預設的空間限制,發現有2GB大小限制

解決方法:

  • 在etcd啟動參數中加入–quota-backend-bytes
  • 修改kubernetes-ec2-autoscaler邏輯——如果超過50%出現問題,關閉叢集

各種服務的優化

Kube masters 的高可用

一般來說,我們的架構是一個kube-master(主要的 Kubernetes 服務提供元件,上面有kube-apiserver、kube-scheduler 和kube-control-manager)加上多個slave。但是要達到高可用,要參考一下方式實作:

  • kube-apiserver要設定多個服務,并且通過參數–apiserver-count重新開機并且設定
  • kubernetes-ec2-autoscaler可以幫助我們自動關閉idle的資源,但是這跟Kubernetes scheduler的原則相悖,不過通過這些設定,可以幫助我們盡量集中資源。
{ "kind" : "Policy", "apiVersion" : "v1", "predicates" : [ {"name" : "GeneralPredicates"}, {"name" : "MatchInterPodAffinity"}, {"name" : "NoDiskConflict"}, {"name" : "NoVolumeZoneConflict"}, {"name" : "PodToleratesNodeTaints"} ], "priorities" : [ {"name" : "MostRequestedPriority", "weight" : 1}, {"name" : "InterPodAffinityPriority", "weight" : 2} ] }      

以上為調整kubernetes scheduler範例,通過調高InterPodAffinityPriority的權重,達到我們的目的。更多示範參考

範例

需要注意的是,目前Kubernetes Scheduler Policy并不支援動态切換,需要重新開機kube-apiserver(issue:

41600

)

調整scheduler policy造成的影響

OpenAI使用了

KubeDNS

,但不久後發現——

  • 經常出現DNS查詢不到的情況(随機發生)
  • 超過 ~200QPS domain lookup
  • 嘗試檢視為何有這種狀态,發現有些node上跑了超過10個KuberDNS

解決方法:

  • 由于scheduler policy造成了許多POD的集中
  • 很輕量,容易被配置設定到同一節點上,造成domain lookup的集中
  • 需要修改POD affinity( 相關介紹 ),盡量讓 配置設定到不同的node之上
affinity:
 podAntiAffinity:
 requiredDuringSchedulingIgnoredDuringExecution: - weight: 100
 labelSelector:
 matchExpressions: - key: k8s-app
 operator: In
 values: - kube-dns
 topologyKey: kubernetes.io/hostname      

建立節點時Docker image pulls緩慢的問題

  • 每次新節點建立起來,docker image pull都要花30分鐘
  • 有一個很大的container image Dota ,差不多17GB,影響了整個節點的image pulling
  • 開始檢查kubelet是否有其他image pull選項
  • 在kubelet增加選項–serialize-image-pulls=false來啟動image pulling,讓其他服務可以更早地pull(參考:kubelet 啟動選項
  • 這個選項需要docker storgae切換到overlay2(可以參考 docker教學文章
  • 并且把docker image存放到SSD,可以讓image pull更快一些

補充:source trace

// serializeImagePulls when enabled, tells the Kubelet to pull images one // at a time. We recommend *not* changing the default value on nodes that // run docker daemon with version < 1.9 or an Aufs storage backend. // Issue #10959 has more details. SerializeImagePulls *bool `json:"serializeImagePulls"`      

提高docker image pull的速度

此外,還可以通過以下方式來提高pull的速度

kubelet參數–image-pull-progress-deadline要提高到30mins

docker daemon參數max-concurrent-download調整到10才能多線程下載下傳

網絡性能提升

Flannel性能限制

OpenAI節點間的網絡流量,可以達到10-15GBit/s,但是由于Flannel是以導緻流量會降到 ~2GBit/s

解決方式是拿掉Flannel,使用實際的網絡

  • hostNetwork: true
  • dnsPolicy: ClusterFirstWithHostNet

這裡還有一些

注意事項

需要詳細閱讀

想要簡單易用、生産就緒的Kubernetes?試試好雨Rainbond——以應用的方式包裝Kubernetes,了解和使用更簡單,各種管理流程開箱即用!

好雨Rainbond

(雲幫)是一款以應用為中心的開源PaaS,深度整合基于Kubernetes的容器管理、Service Mesh微服務架構最佳實踐、多類型CI/CD應用建構與傳遞、多資料中心資源管理等技術,為使用者提供雲原生應用全生命周期解決方案,建構應用與基礎設施、應用與應用、基礎設施與基礎設施之間互聯互通的生态體系,滿足支撐業務高速發展所需的靈活開發、高效運維和精益管理需求。

本文轉自kubernetes中文社群-

伸縮Kubernetes到2500個節點中遇到的問題和解決方法

繼續閱讀