Kubernetes v1.27 新特性一覽

張晉濤發表於2023-05-09

大家好,我是張晉濤。

Kubernetes v1.27 是 2023 年的第一個大版本更新,包含了近 60 項主要的更新。 而 1.26 只有 37 項,所以這個版本可以說是一個變化非常顯著的版本了。

其中 18 個增強功能正在進入 Alpha 階段,29 個將升級到 Beta 階段,而另外 13 個則將升級到穩定版。

儘管這個版本中包含了這麼多的特性變更,但值得一提的是,這個版本應該算是第一個完全按照即定流程,恪守每個 deadline 的版本。
之前的版本中,每次都或多或少會有一些變數,不過這也從側面可以看到 release team 做了很多幕後的工作。

我每期的 「k8s生態週報」都有一個叫上游進展的部分,所以很多值得關注的內容在之前的文章中已經發過了。
這篇中我會再額外介紹一些之前未涵蓋的,和之前介紹過的值得關注的內容。

我們一起來具體看看吧!

SeccompDefault 達到 Stable

如果想要預設使用 seccomp profile,則必須在每個想要使用它的節點上為 kubelet 啟用 --seccomp-default 選項。
如果啟用了該選項,則 kubelet 將預設使用由容器執行時定義的 RuntimeDefault seccomp profile,而不是使用 Unconfined(禁用seccomp)模式。“

預設配置檔案旨在提供強大的安全性設定,並保留工作負載功能。
容器執行時的不同釋出版本之間可能存在不同的預設配置檔案。

印象裡很早之前 Docker 的配置檔案就因為修補安全漏洞而調整過。

Pod 排程就緒機制達到 Beta

這個功能實際上是從 Kubernetes v1.26 開始增加的。是 KEP 3521 的第一部分。

首先我們來簡單的回顧一下 Pod 的建立過程。

當 client 透過 kube-apiserver 建立成功 Pod 資源後,kube-scheduler 會去檢查尚未被排程的 Pod,然後為其進行排程,分配 Node。之後 Node 獲取到排程到該 Node 上的 Pod 然後進行建立。
這裡省略了很多細節,但其他的部分與我們此處要介紹的內容關係不太大,就不展開了。

根據上述的過程,我們可以發現,在 Pod 建立成功後,其實就預設該 Pod 是可以被排程了,kube-scheduler 就應該開始工作了。

但在實際的場景中,Pod 通常還會需要一些其他的資源,最典型的比如儲存。在一些環境中,這些資源是需要預先進行建立的,
尤其是在一些雲廠商的場景中,還需要檢查使用者賬戶中是否還有餘額可以用於建立雲盤等

一但前置的依賴無法滿足,假如 kube-scheduler 已經完成了 Pod 的排程,那麼 kubelet 側就會處於嘗試建立 Pod ,但失敗的情況。

這個 KEP 的出現就可以很好的解決這個問題,增加了一個 Pod 是否準備好被排程的機制。
如果前置依賴不滿足,那麼 Pod 就無需被排程,這也不會消耗資源。kube-scheduler 和 kubelet 都無需進行處理。
待條件滿足,Pod 再被排程和建立即可。

這個機制我個人感覺還是挺好的,甚至我可以有更靈活的策略來控制應用的副本。
比如在大流量,需要動態擴容的場景下,我可以利用此機制預先建立一些 Pod 資源以及準備好它的依賴,
甚至可以在 Node 上準備好映象等。當需要增加副本時,直接標記 Pod 可被排程,

使用時,透過配置 Pod 的 .spec.schedulingGates 即可。

新增 NodeLogQuery 特性 - KEP-2258

我們通常最習慣使用 kubectl logs 命令來獲取 Kubernetes 叢集中執行的應用的日誌,也可以透過給它傳遞一些引數來調整它的過濾範圍。

比如:kubectl logs job/hello 來指定獲取 hello 這個 job 的日誌;也可以增加 -l / --selector='' 來基於 label 進行過濾。

但這並沒有擴充套件到 Node 級別的日誌,無法直接獲取到某個 Node 上的全部日誌,要想得到這個結果需要寫一段很複雜的 Shell 來完成。

當前 Kubernetes 社群已經逐漸提供了更多 Node 除錯工具,旨在為除錯 Node 故障提供統一體驗,並更好地支援極簡作業系統。透過 KEP 2258: add node log query by LorbusChris · Pull Request #96120 · kubernetes/kubernetes ,我們現在可以遠端獲取底層 Node 日誌。與容器日誌記錄一樣,這是Kubelet API的一部分。

對於Linux系統,它查詢journald;對於Windows系統,則查詢事件日誌(Event Log)。目前還沒有專門針對此功能的 kubectl 命令,但可以使用如下命令進行嘗試:

(MoeLove) ➜ kubectl get --raw "/api/v2/nodes/$NODE_NAME/proxy/logs/?query=kubelet

基於 CEL 的 Admission Control

對 Kubernetes 中的 Adminssion Control 感興趣的小夥伴可以看看我之前的文章:理清 Kubernetes 中的准入控制(Admission Controller) | MoeLove

Kubernetes 在 v1.26 增加了一項很重要的特性,那就是允許使用 CEL 進行 Admission Control,具體內容可以參考我之前寫的文章:
Kubernetes v1.26 新特性一覽 | MoeLove

其中引入了一個新的資源 ValidatingAdmissionPolicy ,使用起來如下:

apiVersion: admissionregistration.k8s.io/v1alpha1
 kind: ValidatingAdmissionPolicy
 metadata:
   name: "demo-policy.moelove.info"
 Spec:
   failurePolicy: Fail
   matchConstraints:
     resourceRules:
     - apiGroups:   ["apps"]
       apiVersions: ["v1"]
       operations:  ["CREATE", "UPDATE"]
       resources:   ["deployments"]
   validations:
     - expression: "object.spec.replicas <= 2"

但是在當時也只是實現了 KEP-3488 的一部分。

在這個 PR 中是在實現 Authz 的部分,這允許用 CEL 表示式編寫複雜的 admission control 規則,
放置在宣告式資源中,而不是構建和部署 webhook。

雖然 admission webhook 一直是我們靈活的與第三方工具整合的基石,但是對於新使用者來說,它們有很多複雜性,新的 CEL 系統有望接管僅需要對預設規則進行小修改的簡單獨立案例。

以前,表示式上下文會公開有關當前請求和目標資源的資訊,現在透過這個 PR 可以在授權層中動態檢查 RBAC 許可權。
一些有用的地方可能是使用 RBAC 進行每個欄位的更新許可權,允許 RBAC 檢查特定物件而不使用 resourceNames 系統,
或基於請求者身份限制對程式敏感欄位(例如 finalizers )的訪問而無需生成複雜的 RBAC 策略。

例如:

authorizer.group('').resource('pods').namespace('default').check('create').allowed()
authorizer.path('/healthz').check('GET').allowed()
authorizer.requestResource.check('my-custom-verb').allowed()

本次還加入了#115973,該功能允許在失敗時作為主要操作發出審計日誌事件,或者如果需要更多資料,可以編寫一個或多個CEL表示式,以提供詳細的值,
這些值將傳送到審計子系統。

這既可以在開發新策略時提供強大的除錯選項,也可以進行執行時分析。
其他 CEL admission 特性包括成本檢查,以防止您使用所有這些新功能意外拒絕服務自己的 kube-apiserver,以及改進的型別檢查。

總的來說,基於 CEL 的 admission 處理有了很多新的功能,希望進一步將 webhook 推入到一個有限的用例空間中(防止濫用)。

Pod In-place 原地伸縮能力

這個功能允許在不重啟 Pod 的情況下,更新 Pod 的 resources 配置。

經過 4 年的規劃和至少 2 年的開發,在 Kubernetes v1.27 中終於推出了 Pod 的就地資源縮放的第一版。
這個PR實現了核心縮放功能和一些相關的API處理。
主要功能非常簡單,現在可以在現有容器上編輯 resources 配置,而不會導致 API 錯誤。

在看到縮放請求後,Kubelet 會立即採取行動並檢查節點是否有足夠的資源來滿足新的請求。
如果是這樣,它將 Status.Resize 欄位設定為 InProgress,並繼續進行 CRI 呼叫和其他內部更新。

如果新的大小不合適,將啟動其他狀態流,但總體目標相同,即嘗試在可能的情況下提供請求的更改。
還有一個新的 per-resource 縮放策略欄位,可以設定為 RestartNotRequired(預設值)表示不需要重新啟動(但某些執行時仍然可能需要這樣做),
或設定為 Restart 以強制關閉和重新啟動容器(例如具有需要重新計算-Xmx 堆大小標誌的 Java 應用)。

現在缺少一個顯著的特性是基於縮放的驅逐。目前,Kubelet 不會自動處理它,但如果外部系統執行 Pod 刪除,它將適當地作出反應。

儘管現在還處於比較早期的階段,但至少我們看到了它的變化,期待後續的演進。

一些廢棄提醒

不再提供的API版本:

  • Kubeadm v1beta2,可以使用 kubeadm config migrate 遷移到 v1beta3
  • resource.k8s.io/v1alpha1.PodScheduling :請使用 resource.k8s.io/v1alpha2.PodSchedulingContext
  • DynamicResourceManagement v1alpha1:請使用 v1alpha2
  • CSIStorageCapacity:storage.k8s.io/v1beta1:請使用 v1。

已棄用,在下一個版本釋出之前實現替代方案:

  • seccomp.security.alpha.kubernetes.io/podcontainer.seccomp.security.alpha.kubernetes.io annotations :請改用 securityContext.seccompProfile 欄位。
  • SecurityContextDeny 准入外掛。
  • service.kubernetes.io/topology-aware-hints annotations:請改用 service.kubernetes.io/topology-mode

已刪除

  • Feature gates:

    • IPv6DualStack
    • ExpandCSIVolumes
    • ExpandInUsePersistentVolumes
    • ExpandPersistentVolumes
    • ControllerManagerLeaderMigration
    • CSI Migration
    • CSIInlineVolume
    • EphemeralContainers
    • LocalStorageCapacityIsolation
    • NetworkPolicyEndPort
    • StatefulSetMinReadySeconds
    • IdentifyPodOS
    • DaemonSetUpdateSurge
  • appProtocol: kubernetes.io/grpc.
  • kube-apiserver 引數: --master-service-namespace.
  • CLI 引數: --enable-taint-manager--pod-eviction-timeout.
  • kubelet 引數: --container-runtime, --master-service-namespace.
  • Azure disk in-tree storage plugin.
  • AWS kubelet credential provider: 使用 ecr-credential-provider.
  • Metrics:

    • node_collector_evictions_numbernode_collector_evictions_total 替換
    • scheduler_e2e_scheduling_duration_secondsscheduler_scheduling_attempt_duration_seconds 替換

以上就是 Kubernetes v1.27 版本中我認為主要值得關注的部分。下次再見!


歡迎訂閱我的文章公眾號【MoeLove】

TheMoeLove

相關文章