K8s 1.14 發佈了,Release Note 該怎麼讀?

本文由張磊、心貴、臨石、徙遠、衷源、潯鳴等同窗聯合撰寫。linux

Kubernetes 1.14.0 Release 已經於 3 月 25 日正式發佈。相信你也已經注意到,相比於1.13 和 1.12 版本,此次發佈包含的重要變很是多,其對應的 Release Note 的篇幅長度也創下了「新高」。git

面對這樣一份「海量信息」的 Release Note,咱們該如何從這份文檔裏進行高效的信息過濾和挖掘,幫助團隊更精準、快速的梳理出此次發佈最主要的技術脈絡呢?github

在本篇文章中,咱們將 1.14 的Release Note 按照主題進行了從新概括和梳理,按照類別對重要變動進行了技術剖析和討論。但願這種「分類解讀」的方式,可以幫助你們更好的理解 1.14 這個發佈的核心內容。數據庫

Windows Node 正式生產可用

隨着1.14的發佈,Kubernetes 對windows節點的生產級支持無疑是一個重要的里程碑。具體來講,1.14 版本針對 Windows 作了大量加強;windows

  • Pod:Pod內支持 readiness 和 liveness 探針;支持進程隔離和 volume 共享的多容器 Pod;Pod 支持原生configmap 和 sercret;Pod 支持emptyDir;支持對 Pod 進行資源配額等;可是像優雅刪除、Termination message、Privileged Containers、HugePages、Pod 驅逐策略等部分特性還未在 1.14 版本提供;
  • Service:支持服務環境變量提供 DNS 解析;支持 NodePort、ClusterIP、LoadBalancer、Headless service;暫不支持 Pod 的 hostnetwork 模式;
  • 常規 Workload controller:RS、deployment、statefulset、daemonset、job、cronjob 均支持 windows 容器;
  • 除此以外,支持 Pod 和 container 維度的metrics、HPA、「kubectl exec」、調度搶佔、resource quotas、CNI 網絡支持等多種特性讓 windows workload 更加雲原生;因爲 windows 的特殊兼容性,目前 host OS 的版本必須和容器鏡像 OS 版本一致,1.14 版本支持 win server 2019;將來版本中會考慮使用 Hyper-V 隔離機制來解決版本兼容性問題。

而伴隨着 Windows 容器的生態正在慢慢壯大,可以在生產級別支持 Windows 節點的容器服務開始見諸各大雲廠商。阿里雲容器服務(ACK)近期已經推出了 Windows Container 的支持,提供了 linux/windows 應用混合部署的統一管理能力。網絡

參見:Support for Windows Nodes is Graduating to Stable (#116 )架構

本地持久化數據卷(Local PV) 正式可用

長期以來,可以讓 Kubernetes 直接用宿主機的本地存儲設備(好比:本地 SSD 硬盤)來提供持久化數據卷(即:Local PV 功能),一直是社區裏很是強烈的一個訴求。這個緣由很容易理解:相對於遠程存儲(網絡存儲),Local PV 在時延性、易用性、穩定性和費用上具備獨特的優點,尤爲是對於相關特性比較敏感的應用,如數據庫應用和搜索引擎應用來講,有着重要的意義。less

而在 1.14 中,Local PV 終於正式宣佈 GA,爲雲上的持久化存儲選擇增長了一種重要的的可能。運維

不過,必需要明確的是, 選擇使用 Local PV,也意味着用戶必須本身承擔一些潛在的風險,這包括:分佈式

  • 目前社區的開源方案沒法動態建立卷
  • 調度器須要由額外的調度邏輯工做,以確保調度的節點能夠分配出足夠的磁盤容量
  • 容錯性差,若是 Pod 正在運行的宿主機宕機或者磁盤發生異常,那麼它的持久化卷裏的信息可能丟失

第一個問題,能夠經過好比阿里雲的 local-volume-provisioner 實現本地 SSD Nvme 實例自動建立數據捲來解決,但對於容錯性和健壯性的問題,就是比較棘手的了。

參見:Durable Local Storage Management is Now GA (#121)

Pod 優先級與搶佔機制穩定可用

Kubernetes 裏的任務優先級(priority)和搶佔機制(preemption)的目的十分明確:保證高優先級的任務能夠在須要的時候經過搶佔低優先級任務的方式獲得運行。

這其中,優先級定義了一個 Pod 在集羣中的重要程度,這個重要程度體現且僅體如今兩個地方:

(1)高優先級的Pod 在調度階段更容易被優先調度(K8s 採用隊列調度模型),注意這裏並不保證高優先級 Pod 永遠被優先調度,實際影響調度順序的因素有不少;

(2)在集羣總體負載較高時,若是出現高優先級 Pod 沒法被調度的狀況(集羣中沒有知足條件的 Node 供 Pod 運行),K8s 會啓動搶佔機制,經過搶佔已經運行的低優先級的 Pod 的方式,讓高優先級的 Pod 能夠運行起來。搶佔機制即是在這裏引入的。

搶佔機制指當調度器發現某個Pod(如 Pod-A)沒法在集羣中找到合適的節點部署時(全部節點 Predicates 所有失敗),會試圖經過刪除一些優先級低於 Pod-A 的 Pod 來「騰出空間」部署 Pod-A,這樣 Pod-A 就能夠被調度了。這樣一個「看似簡單」的需求在分佈式環境中實施起來有不少細節,例如:如何決定刪除哪一個節點的哪些 Pod、如何保證爲 Pod-A 騰出的空間不被其它 Pod 佔用、如何保證 Pod-A 不被餓死(Starvation)、如何處理有親和性需求的 Pod 調度約束、是否須要支持跨節點 Preemption 以支持某些特定的約束(例如某 Failure Domain 的反親和約束)等等。

參見:Pod Priority and Preemption in Kubernetes (#564)

你必定要知道什麼是 Pod Ready++

在 1.14 版本以前,Kubernetes 判斷一個 Pod 是否 Ready,就是檢查這個 Pod 的容器是否所有正常運行。可是這裏有個問題,那就是容器或者說裏面的主進程 Ready,並不必定意味着這個應用副本就必定是就緒的。爲了確認 Pod 確實能夠正常可用,咱們但願給它增長一些外部指標(好比,該 Pod 須要的 Service,DNS,存儲等服務所有就緒),來反應這個Pod是否「真正」Ready。

這個特性,就是1.14 裏一個叫作「Pod Readiness Gates」、也叫作 Pod Ready ++ 的特性。它爲pod的「Ready 狀態」 提供了一個很是強大的擴展點。須要注意的是,用戶須要編寫一個外部控制器(Controller)來爲這個Pod Readiness Gates 字段對應的指標設置值。

參見:Pod Ready++ (#580)

Kubernetes 原生應用管理能力

1.14以後,Kubernetes 項目自己開始具有了原生的應用管理能力,這其中最重要的一個功能,就是 Kustomize。

Kustomize 容許用戶從一個基礎 YAML 文件,經過 overlay 的方式生成最終部署應用所需的 YAML 文件,而不是像 Helm 那樣經過字符串替換的方式來直接修改基礎 YAML 文件(模板)。這樣,在一個用戶經過 overlay 生成新的 YAML 文件的同時,其餘用戶能夠徹底不受影響的使用任何一個基礎 YAML 或者某一層生成出來的 YAML 。這使得每個用戶,均可以經過 fork/modify/rebase 這樣 Git 風格的流程來管理海量的 YAML 文件。這種 PATCH 的思想跟 Docker 鏡像是很是相似的,它既規避了「字符串替換」對 YAML 文件的入侵,也不須要用戶學習蹩腳的 DSL 語法(好比 Lua)。

在1.14以後,Kustomize 已經成爲了 kubectl 的一個內置命令。不難看到,Kubernetes 社區正在探索一種 Helm 以外的、更加 Kubernetes 原生的應用管理方法。具體效果如何,咱們不妨拭目以待。

參見:Added Kustomize as a subcommand in kubectl (#73033, @Liujingfang1)

用戶友好度進一步提高

隨着你們對 Kubernetes 愈來愈熟悉,對 kubectl 依賴也愈來愈強烈,需求也愈來愈多樣化。而在 1.14 中,kubectl 着重在如下幾個方面,提高用戶體驗,增強對平常運維能力的支持。

  • 以前 kubectl cp 操做每次只能 copy 一個文件,沒辦法使用通配符拷貝一批文件,很是不方便。在 1.14 中,螞蟻金服的工程師提交了一個拷貝操做的通配符功能,方便對容器中的文件進行操做。
  • 以往,用戶一般沒法方便的知道本身被管理員經過 RBAC 配置的權限到底有哪些。而從 v1.14 開始,用戶能夠經過 kubectl auth can-i --list --namespace=ns1 來查看本身在 ns1 這個 namespace 下能夠訪問哪些資源 (好比 Pod,Service 等),並有哪些操做的權限(好比 Get,List,Patch,Delete 等)了。
  • Kubernetes 用戶須要刪除的 API 資源,每每分散在多個 namespace 中,刪除很是不方便。在 v1.14 新版本中,用戶終於能夠藉助於 kubectl delete xxx --all-namespaces 來進行統一的刪除操做了(這裏 XXX 能夠是 Pod,Services,Deployment,自定義的 CRD 等等),而且還能夠配合 -l--field-selector 能夠更精確地刪除知足特定條件的資源。

    穩定性進一步提高

    和以前每一個版本同樣,Kubernetes 的新版本發佈對穩定性和可靠性加強的關注一直是重中之重,下面咱們列舉出一些值得注意的修復和升級。

    • 在作 Pod 驅逐時,會優先嚐試使用優雅刪除模式,而不是暴力刪除 etcd 內的 Pod 數據。這個修復可以使被驅逐的 Pod 更加優雅的退出。
    • Kubelet 要重建 Pod 的容器時,若是舊容器是 unknown 狀態,如今 Kubelet 會首先嚐試 Stop 容器。這避免了一個 Pod 的同一個容器申明會有多個實例同時運行的風險。
    • 在大規模集羣中,節點由於個別Pod使用了大量磁盤 IO,可能會致使節點頻繁的在Ready/NotReady狀態之間變化。這種狀態會引發大規模的、不可預期的 Pod Eviction,致使線上故障。螞蟻金服的工程師針對 Docker 環境下的這個問題提交了修復,建議你們也排查一下其它運行時的集羣裏是否有一樣的問題。
    • 當 Kubelet 在壓力較大狀況下,可能會發生 Kubelet 的 Pod 生命週期事件消費頻次弱於事件產生頻次,致使負責這個事件的 Channel 被佔滿,這種狀況持續一段時間後會直接致使 Kubelet 死鎖。阿里巴巴的工程師針對修這個問題提交了修復。

    大規模場景下的性能提高與優化

    在 Kubernetes 的主幹功能日趨穩定以後,社區已經開始更多的關注大規模場景下 Kubernetes 項目會暴露出來的各類各樣的問題。在 v1.14 中,Kubernetes 社區從面向最終用戶的角度作出了不少優化,好比:

    • kubectl 在實現中會順序遍歷 APIServer 暴露出的所有資源的 Group/Version/Kind,直到查找到須要處理的資源。這種遍歷方式致使了用戶在大規模集羣下使用 kubectl 的性能體驗受到很大影響。在 v1.14 版本中,kubectl 的順序遍歷行爲終於改成了並行,極大地提高了 kubectl 的使用體驗(通過測試,性能指標提高了 10 倍以上)。
    • 在 1.14 中,APIServer 裏的一個重要變動,是對單次 PATCH 請求內容裏的操做個數作出了限制,不能超過10000個,不然就不處理此請求。這樣作的目的,是防止 APIServer 由於處理海量的甚至是惡意 PATCH 請求致使整個集羣癱瘓。這也其實也是社區的 CVE-2019-1002100 主要的修復方法。
    • Kubernetes 的 Aggregated API 容許 k8s 的開發人員編寫一個自定義服務,並把這個服務註冊到 k8s 的 API 裏面像原生 API 同樣使用。在這個狀況下,APIServer 須要將用戶自定義 API Spec 與原生的 API Spec 歸併起來,這是一個很是消耗 CPU 的性能痛點。而在 v1.14 中,社區大大優化了這個操做的速率,極大地提高了APIServer 歸併 Spec 的性能(提高了不止十倍)。

    文章中涉及的相關連接

           github.com/Liujingfang…

    • 用戶友好度:

    #72641github.com/kubernetes/…

    #64820github.com/kubernetes/…

    #73716github.com/kubernetes/…

    • 穩定性:

    #72730github.com/kubernetes/…

    #73802github.com/kubernetes/…

    #74389github.com/kubernetes/…

    #72709github.com/kubernetes/…

    • 大規模場景下的性能提高與優化:

    #73345github.com/kubernetes/…

    #74000github.com/kubernetes/…

    #71223github.com/kubernetes/…

    公衆號:金融級分佈式架構(Antfin_SOFA)

    相關文章
    相關標籤/搜索