蘭州優(yōu)化網(wǎng)站媒體資源網(wǎng)
#作者:程宏斌
文章目錄
- 準入控制器(Admission Controllers)
- 準入控制插件
- 準入控制擴展點
- 準入控制階段
- 為什么需要準入控制器?
- 怎么關(guān)閉準入控制器?
- 哪些插件是默認啟用的?
- 準入控制器的作用
準入控制器(Admission Controllers)
準入控制器是一段代碼,它會在請求通過認證和鑒權(quán)之后、對象被持久化之前攔截到達 API 服務(wù)器的請求。
Kubernetes 的若干重要功能都要求啟用一個準入控制器,以便正確地支持該特性。 因此,沒有正確配置準入控制器的 Kubernetes API 服務(wù)器是不完整的,它無法支持你所期望的所有特性。
準入控制插件
準入控制器是 Kubernetes API 服務(wù)器中的代碼, 用于檢查請求中到達的數(shù)據(jù),以修改資源。
準入控制器適用于創(chuàng)建、刪除或修改對象的請求。 準入控制器也可以阻止自定義動作,例如通過 API 服務(wù)器代理連接到 Pod 的請求。 準入控制器不會(也不能)阻止讀取(get、watch 或 list)對象的請求, 這是因為讀取操作會繞過準入控制層。
準入控制器機制可以執(zhí)行驗證(Validating) 和/或變更(Mutating) 操作。 變更(Mutating)控制器可以為正在修改的資源修改數(shù)據(jù);驗證(Validating)控制器則不行。
Kubernetes 1.33 中的準入控制器由下面的列表組成, 并編譯進 kube-apiserver 可執(zhí)行文件,并且只能由集群管理員配置。
準入控制擴展點
在完整的列表中,有三個特殊的控制器: MutatingAdmissionWebhook、 ValidatingAdmissionWebhook 和 ValidatingAdmissionPolicy。 前兩個 Webhook 控制器分別執(zhí)行在 API 中所配置的變更和驗證準入控制 Webhook。 而 ValidatingAdmissionPolicy 提供了一種在 API 中嵌入聲明式驗證代碼的方式,無需依賴任何外部 HTTP 調(diào)用。
你可以使用這三個準入控制器來定制準入時的集群行為。
準入控制階段
準入控制過程分為兩個階段。第一階段,運行變更準入控制器。第二階段,運行驗證準入控制器。 再次提醒,某些控制器既是變更準入控制器又是驗證準入控制器。
如果兩個階段之一的任何一個控制器拒絕了某請求,則整個請求將立即被拒絕,并向最終用戶返回錯誤。
最后,除了對對象進行變更外,準入控制器還可能有其它副作用:將相關(guān)資源作為請求處理的一部分進行變更。 增加配額用量就是一個典型的示例,說明了這樣做的必要性。 此類用法都需要相應(yīng)的回收或回調(diào)過程,因為任一準入控制器都無法確定某個請求能否通過所有其它準入控制器。
為什么需要準入控制器?
Kubernetes 的多個重要特性需要按順序啟用某個準入控制器才能正確支持對應(yīng)的特性。 因此,如果 Kubernetes API 服務(wù)器未正確配置相應(yīng)的準入控制器集, 那么這種 API 服務(wù)器將是不完整的,并且無法支持你所期望的所有特性。
如何啟用一個準入控制器?
Kubernetes API 服務(wù)器的 enable-admission-plugins 標志接受一個(以逗號分隔的)準入控制插件列表, 這些插件會在集群修改對象之前被調(diào)用。
例如,下面的命令啟用 NamespaceLifecycle 和 LimitRanger 準入控制插件:
kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger …
說明:
根據(jù)你 Kubernetes 集群的部署方式以及 API 服務(wù)器的啟動方式,你可能需要以不同的方式應(yīng)用設(shè)置。 例如,如果將 API 服務(wù)器部署為 systemd 服務(wù),你可能需要修改 systemd 單元文件; 如果以自托管方式部署 Kubernetes,你可能需要修改 API 服務(wù)器的清單文件。
怎么關(guān)閉準入控制器?
Kubernetes API 服務(wù)器的 disable-admission-plugins 標志,會將傳入的(以逗號分隔的) 準入控制插件列表禁用,即使是默認啟用的插件也會被禁用。
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny …
哪些插件是默認啟用的?
要查看哪些插件是被啟用的:
kube-apiserver -h | grep enable-admission-plugins
在 Kubernetes 1.33 中,默認啟用的插件有:
CertificateApproval, CertificateSigning, CertificateSubjectRestriction, DefaultIngressClass, Defaul
準入控制器的作用
AlwaysAdmit
特性狀態(tài): Kubernetes v1.13 [deprecated]
類別:驗證。
該準入控制器允許所有的 Pod 進入集群。此插件已被棄用,因其行為與沒有準入控制器一樣。
AlwaysDeny
特性狀態(tài): Kubernetes v1.13 [deprecated]
類別:驗證。
拒絕所有的請求。由于它沒有實際意義,已被棄用。
AlwaysPullImages
該準入控制器會修改每個新創(chuàng)建的 Pod,將其鏡像拉取策略設(shè)置為 Always。 這在多租戶集群中是有用的,這樣用戶就可以放心,他們的私有鏡像只能被那些有憑證的人使用。 如果沒有這個準入控制器,一旦鏡像被拉取到節(jié)點上,任何用戶的 Pod 都可以通過已了解到的鏡像的名稱 (假設(shè) Pod 被調(diào)度到正確的節(jié)點上)來使用它,而不需要對鏡像進行任何鑒權(quán)檢查。 啟用這個準入控制器之后,啟動容器之前必須拉取鏡像,這意味著需要有效的憑證。
CertificateApproval
類別:驗證。
此準入控制器獲取審批 CertificateSigningRequest 資源的請求并執(zhí)行額外的鑒權(quán)檢查, 以確保針對設(shè)置了 spec.signerName 的 CertificateSigningRequest 資源而言, 審批請求的用戶有權(quán)限對證書請求執(zhí)行 審批 操作。
有關(guān)對 CertificateSigningRequest 資源執(zhí)行不同操作所需權(quán)限的詳細信息, 請參閱證書簽名請求。
CertificateSigning
類別:驗證。
此準入控制器監(jiān)視對 CertificateSigningRequest 資源的 status.certificate 字段的更新請求, 并執(zhí)行額外的鑒權(quán)檢查,以確保針對設(shè)置了 spec.signerName 的 CertificateSigningRequest 資源而言, 簽發(fā)證書的用戶有權(quán)限對證書請求執(zhí)行 簽發(fā) 操作。
有關(guān)對 CertificateSigningRequest 資源執(zhí)行不同操作所需權(quán)限的詳細信息, 請參閱證書簽名請求。
CertificateSubjectRestriction
類別:驗證。
此準入控制器監(jiān)視 spec.signerName 被設(shè)置為 kubernetes.io/kube-apiserver-client 的 CertificateSigningRequest 資源創(chuàng)建請求,并拒絕所有將 “group”(或 “organization attribute”) 設(shè)置為 system:masters 的請求。
DefaultIngressClass
類別:變更。
該準入控制器監(jiān)測沒有請求任何特定 Ingress 類的 Ingress 對象創(chuàng)建請求,并自動向其添加默認 Ingress 類。 這樣,沒有任何特殊 Ingress 類需求的用戶根本不需要關(guān)心它們,他們將被設(shè)置為默認 Ingress 類。
當(dāng)未配置默認 Ingress 類時,此準入控制器不執(zhí)行任何操作。如果有多個 Ingress 類被標記為默認 Ingress 類, 此控制器將拒絕所有創(chuàng)建 Ingress 的操作,并返回錯誤信息。 要修復(fù)此錯誤,管理員必須重新檢查其 IngressClass 對象,并僅將其中一個標記為默認 (通過注解 “ingressclass.kubernetes.io/is-default-class”)。 此準入控制器會忽略所有 Ingress 更新操作,僅處理創(chuàng)建操作。
關(guān)于 Ingress 類以及如何將 Ingress 類標記為默認的更多信息,請參見 Ingress 頁面。
DefaultStorageClass
類別:變更。
此準入控制器監(jiān)測沒有請求任何特定存儲類的 PersistentVolumeClaim 對象的創(chuàng)建請求, 并自動向其添加默認存儲類。 這樣,沒有任何特殊存儲類需求的用戶根本不需要關(guān)心它們,它們將被設(shè)置為使用默認存儲類。
當(dāng)默認的 StorageClass 不存在時,此準入控制器不執(zhí)行任何操作。如果將多個存儲類標記為默認存儲類, 而且你之后在未設(shè)置 storageClassName 的情況下創(chuàng)建 PersistentVolumeClaim, Kubernetes 將使用最近創(chuàng)建的默認 StorageClass。 當(dāng)使用指定的 volumeName 創(chuàng)建 PersistentVolumeClaim 時,如果在應(yīng)用任意默認的 StorageClass 之后, 靜態(tài)卷的 storageClassName 與 PersistentVolumeClaim 上的 storageClassName 不匹配, 則 PersistentVolumeClaim 保持在 Pending 狀態(tài)。 此準入控制器會忽略所有 PersistentVolumeClaim 更新操作,僅處理創(chuàng)建操作。
關(guān)于持久卷申領(lǐng)和存儲類,以及如何將存儲類標記為默認, 請參見持久卷頁面。
DefaultTolerationSeconds
類別:變更。
此準入控制器基于 k8s-apiserver 的輸入?yún)?shù) default-not-ready-toleration-seconds 和 default-unreachable-toleration-seconds 為 Pod 設(shè)置默認的容忍度,以容忍 notready:NoExecute 和 unreachable:NoExecute 污點 (如果 Pod 尚未容忍 node.kubernetes.io/not-ready:NoExecute 和 node.kubernetes.io/unreachable:NoExecute 污點的話)。 default-not-ready-toleration-seconds 和 default-unreachable-toleration-seconds 的默認值是 5 分鐘。
DenyServiceExternalIPs
類別:驗證。
此準入控制器拒絕新的 Service 中使用字段 externalIPs。 此功能非常強大(允許網(wǎng)絡(luò)流量攔截),并且無法很好地受策略控制。 啟用后,集群用戶將無法創(chuàng)建使用 externalIPs 的新 Service,也無法在現(xiàn)有 Service 對象上為 externalIPs 添加新值。 externalIPs 的現(xiàn)有使用不受影響,用戶可以在現(xiàn)有 Service 對象上從 externalIPs 中刪除值。
大多數(shù)用戶根本不需要此特性,集群管理員應(yīng)考慮將其禁用。 確實需要使用此特性的集群應(yīng)考慮使用一些自定義策略來管理 externalIPs 的使用。 此準入控制器默認被禁用。
PodTopologyLabels
特性狀態(tài): Kubernetes v1.33 []
類型:變更
PodTopologyLabels 準入控制器變更所有綁定到節(jié)點的 pod 的 pods/binding 子資源, 添加與所綁定節(jié)點相匹配的拓撲標簽。 這使得節(jié)點拓撲標簽可以作為 Pod 標簽使用,并且可以通過 Downward API 提供給運行中的容器。 由于此控制器而可用的標簽是 topology.kubernetes.io/region 和 topology.kubernetes.io/zone 標簽。
{{ }}
如果有任何變更的準入 Webhook 添加或修改了 pods/binding 子資源的標簽, 這些變更將由于此控制器傳播到 Pod 標簽,覆蓋具有沖突鍵的標簽。 {{ }}
當(dāng) PodTopologyLabelsAdmission 特性門控被啟用時,才能啟用此準入控制器。
EventRateLimit
特性狀態(tài): Kubernetes v1.13 [alpha]
類別:驗證。
此準入控制器緩解了請求存儲新事件時淹沒 API 服務(wù)器的問題。集群管理員可以通過以下方式指定事件速率限制:
啟用 EventRateLimit 準入控制器;
在通過 API 服務(wù)器的命令行標志 --admission-control-config-file 設(shè)置的文件中, 引用 EventRateLimit 配置文件
可以在配置中指定的限制有四種類型:
- Server:API 服務(wù)器收到的所有(創(chuàng)建或修改)Event 請求共享一個桶。
- Namespace:每個名字空間都對應(yīng)一個專用的桶。
- User:為每個用戶分配一個桶。
- SourceAndObject:根據(jù)事件的來源和涉及對象的各種組合分配桶。
下面是一個針對此配置的 eventconfig.yaml 示例:
apiVersion: eventratelimit.admission.k8s.io/v1alpha1
kind: Configuration
limits:
- type: Namespace
qps: 50
burst: 100
cacheSize: 2000
- type: User
qps: 10
burst: 50
此準入控制器默認被禁用。
ExtendedResourceToleration
類別:變更。
此插件有助于創(chuàng)建帶有擴展資源的專用節(jié)點。 如果運維人員想要創(chuàng)建帶有擴展資源(如 GPU、FPGA 等)的專用節(jié)點,他們應(yīng)該以擴展資源名稱作為鍵名, 為節(jié)點設(shè)置污點。 如果啟用了此準入控制器,會將此類污點的容忍度自動添加到請求擴展資源的 Pod 中, 用戶不必再手動添加這些容忍度。
此準入控制器默認被禁用。
ImagePolicyWebhook
類別:驗證。
ImagePolicyWebhook 準入控制器允許使用后端 Webhook 做出準入決策。
此準入控制器默認被禁用。
LimitPodHardAntiAffinityTopology
類別:驗證。
此準入控制器拒絕定義了 AntiAffinity 拓撲鍵的任何 Pod (requiredDuringSchedulingRequiredDuringExecution 中的 kubernetes.io/hostname 除外)。
此準入控制器默認被禁用。
LimitRanger
類別:變更和驗證。
此準入控制器會監(jiān)測傳入的請求,并確保請求不會違反 Namespace 中 LimitRange 對象所設(shè)置的任何約束。 如果你在 Kubernetes 部署中使用了 LimitRange 對象,則必須使用此準入控制器來執(zhí)行這些約束。 LimitRanger 還可以用于將默認資源請求應(yīng)用到?jīng)]有設(shè)定資源約束的 Pod; 當(dāng)前,默認的 LimitRanger 對 default 名字空間中的所有 Pod 都設(shè)置 0.1 CPU 的需求。
MutatingAdmissionWebhook
類別:變更。
此準入控制器調(diào)用任何與請求匹配的變更(Mutating) Webhook。匹配的 Webhook 將被順序調(diào)用。 每一個 Webhook 都可以自由修改對象。
MutatingAdmissionWebhook,顧名思義,僅在變更階段運行。
如果由此準入控制器調(diào)用的 Webhook 有副作用(如:減少配額), 則它 必須 具有協(xié)調(diào)系統(tǒng),因為不能保證后續(xù)的 Webhook 和驗證準入控制器都會允許完成請求。
如果你禁用了 MutatingAdmissionWebhook,那么還必須使用 --runtime-config 標志禁止 admissionregistration.k8s.io/v1 組/版本中的 MutatingWebhookConfiguration, 二者都是默認啟用的。
NamespaceAutoProvision
類別:變更。
此準入控制器會檢查針對名字空間域資源的所有傳入請求,并檢查所引用的名字空間是否確實存在。 如果找不到所引用的名字空間,控制器將創(chuàng)建一個名字空間。 此準入控制器對于不想要求名字空間必須先創(chuàng)建后使用的集群部署很有用。
NamespaceExists
類別:驗證。
此準入控制器檢查針對名字空間作用域的資源(除 Namespace 自身)的所有請求。 如果請求引用的名字空間不存在,則拒絕該請求。
NamespaceLifecycle
類別:驗證。
該準入控制器禁止在一個正在被終止的 Namespace 中創(chuàng)建新對象,并確保針對不存在的 Namespace 的請求被拒絕。該準入控制器還會禁止刪除三個系統(tǒng)保留的名字空間,即 default、 kube-system 和 kube-public。
Namespace 的刪除操作會觸發(fā)一系列刪除該名字空間中所有對象(Pod、Service 等)的操作。 為了確保這個過程的完整性,我們強烈建議啟用這個準入控制器。
NodeRestriction
類別:驗證。
該準入控制器限制了某 kubelet 可以修改的 Node 和 Pod 對象。 為了受到這個準入控制器的限制,kubelet 必須使用在 system:nodes 組中的憑證, 并使用 system:node:<nodeName>
形式的用戶名。 這樣,kubelet 只可修改自己的 Node API 對象,只能修改綁定到自身節(jié)點的 Pod 對象。
不允許 kubelet 更新或刪除 Node API 對象的污點。
NodeRestriction 準入插件可防止 kubelet 刪除其 Node API 對象, 并對前綴為 kubernetes.io/ 或 k8s.io/ 的標簽的修改對 kubelet 作如下限制:
- 禁止 kubelet 添加、刪除或更新前綴為 node-restriction.kubernetes.io/ 的標簽。 這類前綴的標簽時保留給管理員的,用以為 Node 對象設(shè)置標簽以隔離工作負載,而不允許 kubelet 修改帶有該前綴的標簽。
- 允許 kubelet 添加、刪除、更新以下標簽:
kubernetes.io/hostname
kubernetes.io/arch
kubernetes.io/os
beta.kubernetes.io/instance-type
node.kubernetes.io/instance-type
failure-domain.beta.kubernetes.io/region(已棄用)
failure-domain.beta.kubernetes.io/zone(已棄用)
topology.kubernetes.io/region
topology.kubernetes.io/zone
kubelet.kubernetes.io/ 為前綴的標簽
node.kubernetes.io/ 為前綴的標簽
以 kubernetes.io 或 k8s.io 為前綴的所有其他標簽都限制 kubelet 使用,并且將來可能會被 NodeRestriction 準入插件允許或禁止。
將來的版本可能會增加其他限制,以確保 kubelet 具有正常運行所需的最小權(quán)限集。
OwnerReferencesPermissionEnforcement
類別:驗證。
此準入控制器保護對對象的 metadata.ownerReferences 的訪問,以便只有對該對象具有 delete 權(quán)限的用戶才能對其進行更改。 該準入控制器還保護對 metadata.ownerReferences[x].blockOwnerDeletion 對象的訪問, 以便只有對所引用的 屬主(owner) 的 finalizers 子資源具有 update 權(quán)限的用戶才能對其進行更改。
PersistentVolumeClaimResize
特性狀態(tài): Kubernetes v1.24 [stable]
類別:驗證。
此準入控制器檢查傳入的 PersistentVolumeClaim 調(diào)整大小請求,對其執(zhí)行額外的驗證檢查操作。
建議啟用 PersistentVolumeClaimResize 準入控制器。除非 PVC 的 StorageClass 明確地將 allowVolumeExpansion 設(shè)置為 true 來顯式啟用調(diào)整大小。 否則,默認情況下該準入控制器會阻止所有對 PVC 大小的調(diào)整。
PodNodeSelector
特性狀態(tài): Kubernetes v1.5 [alpha]
類別:驗證。
此準入控制器通過讀取名字空間注解和全局配置,來為名字空間中可以使用的節(jié)點選擇器設(shè)置默認值并實施限制。
此準入控制器默認被禁用。
PodSecurity
特性狀態(tài): Kubernetes v1.25 [stable]
類別:驗證。
PodSecurity 準入控制器在新 Pod 被準入之前對其進行檢查, 根據(jù)請求的安全上下文和 Pod 所在名字空間允許的 Pod 安全性標準的限制來確定新 Pod 是否應(yīng)該被準入。
PodSecurity 取代了一個名為 PodSecurityPolicy 的舊準入控制器。
PodTolerationRestriction
特性狀態(tài): Kubernetes v1.7 [alpha]
類別:變更和驗證。
準入控制器 PodTolerationRestriction 檢查 Pod 的容忍度與其名字空間的容忍度之間是否存在沖突。 如果存在沖突,則拒絕 Pod 請求。 控制器接下來會將名字空間的容忍度合并到 Pod 的容忍度中, 根據(jù)名字空間的容忍度白名單檢查所得到的容忍度結(jié)果。 如果檢查成功,則將接受 Pod 請求,否則拒絕該請求。
如果 Pod 的名字空間沒有任何關(guān)聯(lián)的默認容忍度或容忍度白名單, 則使用集群級別的默認容忍度或容忍度白名單(如果有的話)。
名字空間的容忍度通過注解鍵 scheduler.alpha.kubernetes.io/defaultTolerations 來設(shè)置。可接受的容忍度可以通過 scheduler.alpha.kubernetes.io/tolerationsWhitelist 注解鍵來添加。
優(yōu)先級
類別:變更和驗證。
優(yōu)先級準入控制器使用 priorityClassName 字段并用整型值填充優(yōu)先級。 如果找不到優(yōu)先級,則拒絕 Pod。
ResourceQuota
類別:驗證。
此準入控制器會監(jiān)測傳入的請求,并確保它不違反任何一個 Namespace 中的 ResourceQuota 對象中列舉的約束。如果你在 Kubernetes 部署中使用了 ResourceQuota, 則必須使用這個準入控制器來強制執(zhí)行配額限制。
RuntimeClass
類別:變更和驗證。
如果你所定義的 RuntimeClass 包含 Pod 開銷, 這個準入控制器會檢查新的 Pod。 被啟用后,此準入控制器會拒絕所有已經(jīng)設(shè)置了 overhead 字段的 Pod 創(chuàng)建請求。 對于配置了 RuntimeClass 并在其 .spec 中選定 RuntimeClass 的 Pod, 此準入控制器會根據(jù)相應(yīng) RuntimeClass 中定義的值為 Pod 設(shè)置 .spec.overhead。
ServiceAccount
類別:變更和驗證。
此準入控制器實現(xiàn)了 ServiceAccount 的自動化。強烈推薦為 Kubernetes 項目啟用此準入控制器。 如果你打算使用 Kubernetes 的 ServiceAccount 對象,你應(yīng)啟用這個準入控制器。
關(guān)于 kubernetes.io/enforce-mountable-secrets 注解:盡管注解的名稱表明它只涉及 Secret 的掛載, 但其執(zhí)行范圍也擴展到 Pod 上下文中 Secret 的其他使用方式。 因此,確保所有引用的 Secret 在 ServiceAccount 中被正確指定是至關(guān)重要的。
StorageObjectInUseProtection
類別:變更。
StorageObjectInUseProtection 插件將 kubernetes.io/pvc-protection 或 kubernetes.io/pv-protection 終結(jié)器(finalizers)添加到新創(chuàng)建的持久卷申領(lǐng)(PVC) 或持久卷(PV)中。如果用戶嘗試刪除 PVC/PV,除非 PVC/PV 的保護控制器移除終結(jié)器, 否則 PVC/PV 不會被刪除。有關(guān)更多詳細信息, 請參考保護使用中的存儲對象。
TaintNodesByCondition
類別:變更。
該準入控制器為新創(chuàng)建的節(jié)點添加 NotReady 和 NoSchedule 污點。 這些污點能夠避免一些競態(tài)條件的發(fā)生,而這類競態(tài)條件可能導(dǎo)致 Pod 在更新節(jié)點污點以準確反映其所報告狀況之前,就被調(diào)度到新節(jié)點上。
ValidatingAdmissionPolicy
類別:驗證。
此準入控制器針對傳入的匹配請求實現(xiàn) CEL 校驗。當(dāng) validatingadmissionpolicy 和 admissionregistration.k8s.io/v1alpha1 特性門控組/版本被啟用時, 此特性被啟用。如果任意 ValidatingAdmissionPolicy 失敗,則請求失敗。
ValidatingAdmissionWebhook
類別:驗證。
此準入控制器調(diào)用與請求匹配的所有驗證性 Webhook。 匹配的 Webhook 將被并行調(diào)用。如果其中任何一個拒絕請求,則整個請求將失敗。 該準入控制器僅在驗證(Validating)階段運行;與 MutatingAdmissionWebhook 準入控制器所調(diào)用的 Webhook 相反,它調(diào)用的 Webhook 不可以變更對象。
如果以此方式調(diào)用的 Webhook 有其它副作用(如:減少配額),則它必須具有協(xié)調(diào)機制。 這是因為無法保證后續(xù)的 Webhook 或其他驗證性準入控制器都允許請求完成。
如果你禁用了 ValidatingAdmissionWebhook,還必須通過 --runtime-config 標志來禁用 admissionregistration.k8s.io/v1 組/版本中的 ValidatingWebhookConfiguration 對象。
推薦使用的準入控制器默認情況下都處于啟用狀態(tài)
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-apiserver/#options