一 Controller Manager原理
1.1 Controller Manager概述
一般來說,智能系統和自動系統通常會通過一個“控制系統”來不斷修正系統的作業狀態,在Kubernetes集群中,每個Controller都是這樣的一個“控制系統”,它們通過API Server提供的(List-Watch)介面實時監控集群中特定資源的狀態變化,當發生各種故障導致某資源物件的狀態發生變化時,Controller會嘗試將其狀態調整為期望的狀態, 比如當某個Node意外宕機時,Node Controller會及時發現此故障并執行自動化修復流程,確保集群始終處于預期的作業狀態,Controller Manager是Kubernetes中各種Controller的管理者,是集群內部的管理控制中心,也是Kubernetes自動化功能的核心, Controller Manager內部包含Replication Controller、Node Controller、ResourceQuota Controller、Namespace Controller、ServiceAccount Controller、Token Controller、Service Controller及Endpoint Controller這8種Controller,每種Controller都負責一種特定資源的控制流程,而Controller Manager正是這些Controller的核心管理者, 提示:ServiceAccount Controller與Token Controller是與安全相關的兩個控制器,并且與ServiceAccount、Token密切相關,
提示:在Kubernetes集群中與Controller Manager協調的另一個組件是Kubernetes Scheduler,它的作用是將待調度的Pod(包括通過API Server新創建的Pod及RC為補足副本而創建的Pod等)通過一些復雜的調度流程計算出最佳目標節點,然后系結到該節點上,
二 Replication Controller
2.1 Replication Controller(副本控制器)作用
Replication Controller的核心作用是確保在任何時候集群中某個RC關聯的Pod副本數量都保持預設值,如果發現Pod的副本數量超過預期值,則Replication Controller會銷毀一些Pod副本;反之,Replication Controller會自動創建新的Pod副本,直到符合條件的Pod副本數量達到預設值, 注意:只有當Pod的重啟策略是Always時(RestartPolicy=Always),Replication Controller才會管理該Pod的操作(例如創建、銷毀、重啟等), 在通常情況下,Pod物件被成功創建后不會消失,唯一的例外是當Pod處于succeeded或failed狀態的時間過長(超時引數由系統設定)時,該Pod會被系統自動回收,管理該Pod的副本控制器將在其他作業節點上重新創建、運行該Pod副本, RC中的Pod模板就像一個模具,模具制作出來的東西一旦離開模具,它們之間就再也沒關系了,同樣,一旦Pod被創建完畢,無論模板如何變化,甚至換成一個新的模板,也不會影響到已經創建的Pod了, 此外,Pod可以通過修改它的標簽來脫離RC的管控,該方法可以用于將Pod從集群中遷移、資料修復等除錯, 對于被遷移走的Pod,RC會自動創建一個新的副本替換被遷移的副本, 注意:洗掉一個RC不會影響它所創建的Pod, 如果想洗掉一個被RC所控制的Pod,則需要將該RC的副本數(Replicas)屬性設定為0,這樣所有的Pod副本就都會被自動洗掉, 提示:建議不要越過RC直接創建Pod,因為Replication Controller會通過RC管理Pod副本,實作自動創建、補足、替換、洗掉Pod副本,這樣能提高系統的容災能力,減少由于節點崩潰等意外狀況造成的損失,即使應用程式只用到一個Pod副本,也強烈建議使用RC來定義Pod, Replication Controller的作用總結如下:- 確保在當前集群中有且僅有N個Pod實體,N是在RC中定義的Pod副本數量,
- 通過調整RC的spec.replicas屬性值來實作系統擴容或者縮容,
- 通過改變RC中的Pod模板(主要是鏡像版本)來實作系統的滾動升級,
2.2 Replication Controller(副本控制器)場景
Replication Controller的典型使用場景通常有如下幾種:- 重新調度(Rescheduling):不管想運行1個副本還是1000個副本,副本控制器都能確保指定數量的副本存在于集群中,即使發生節點故障或Pod副本被終止運行等意外狀況,
- 彈性伸縮(Scaling):手動或者通過自動擴容代理修改副本控制器的spec.replicas屬性值,非常容易實作增加或減少副本的數量,
- 滾動更新(RollingUpdates):副本控制器被設計成通過逐個替換Pod的方式來輔助服務的滾動更新,推薦的方式是創建一個只有一個副本的新RC,若新RC副本數量加1,則舊RC的副本數量減1,直到這個舊RC的副本數量為0,然后洗掉該舊RC,通過上述模式,即使在滾動更新的程序中發生了不可預料的錯誤,Pod集合的更新也都在可控范圍內,在理想情況下,滾動更新控制器需要將準備就緒的應用考慮在內,并保證在集群中任何時刻都有足夠數量的可用Pod,
三 Node Controller
3.1 Node Controller作用
kubelet行程在啟動時通過API Server注冊自身的節點資訊,并定時向API Server匯報狀態資訊,API Server在接收到這些資訊后,會將這些資訊更新到etcd中,在etcd中存盤的節點資訊包括節點健康狀況、節點資源、節點名稱、節點地址資訊、作業系統版本、Docker版本、kubelet版本等, 節點健康狀況包含“就緒”(True)“未就緒”(False)和“未知”(Unknown)三種,3.2 Node Controller作業流程
Node Controller通過API Server實時獲取Node的相關資訊,實作管理和監控集群中的各個Node的相關控制功能,
Node Controller的核心作業流程:
- ControllerM anager在啟動時如果設定了--cluster-cidr引數,那么為每個沒有設定Spec.PodCIDR的Node都生成一個CIDR地址,并用該CIDR地址設定節點的Spec.PodCIDR屬性,這樣做的目的是防止不同節點的CIDR地址發生沖突,
- 逐個讀取Node資訊,多次嘗試修改nodeStatusMap中的節點狀態資訊,將該節點資訊和Node Controller的nodeStatusMap中保存的節點資訊做比較,如果判斷出沒有收到kubelet發送的節點資訊、第1次收到節點kubelet發送的節點資訊,或在該處理程序中節點狀態變成非“健康”狀態,則在nodeStatusMap中保存該節點的狀態資訊,并用Node Controller所在節點的系統時間作為探測時間和節點狀態變化時間,如果判斷出在指定時間內收到新的節點資訊,且節點狀態發生變化,則在nodeStatusMap中保存該節點的狀態資訊,并用Node Controller所在節點的系統時間作為探測時間和節點狀態變化時間,如果判斷出在指定時間內收到新的節點資訊,但節點狀態沒發生變化,則在nodeStatusMap中保存該節點的狀態資訊,并用Node Controller所在節點的系統時間作為探測時間,將上次節點資訊中的節點狀態變化時間作為該節點的狀態變化時間,如果判斷出在某段時間(gracePeriod)內沒有收到節點狀態資訊,則設定節點狀態為“未知”,并且通過API Server保存節點狀態,
- 逐個讀取節點資訊,如果節點狀態變為非“就緒”狀態,則將節點加入待洗掉佇列,否則將節點從該佇列中洗掉,如果節點狀態為非“就緒”狀態,且系統指定了CloudProvider,則Node Controller呼叫CloudProvider查看節點,若發現節點故障,則洗掉etcd中的節點資訊,并洗掉和該節點相關的Pod等資源的資訊,
四 ResourceQuota Controller
4.1 ResourceQuota Controller作用
ResourceQuota Controller,即資源配額管理,資源配額管理確保了指定的資源物件在任何時候都不會超量占用系統物理資源,避免了由于某些業務行程的設計或實作的缺陷導致整個系統運行紊亂甚至意外宕機,對整個集群的平穩運行和穩定性有非常重要的作用, 目前Kubernetes支持如下三個層次的資源配額管理,- 容器級別,可以對CPU和Memory進行限制,
- Pod級別,可以對一個Pod內所有容器的可用資源進行限制,
- Namespace級別,為Namespace(多租戶)級別的資源限制,包括:
- Pod數量;
- Replication Controller數量;
- Service數量;
- ResourceQuota數量;
- Secret數量;
- 可持有的PV數量,
4.2 ResourceQuota Controller作業流程
如圖所示,如果在Pod定義中同時宣告了LimitRanger,則用戶通過API Server請求創建或修改資源時,Admission Control會計算當前配額的使用情況,如果不符合配額約束,則創建物件失敗,
對于定義了ResourceQuota的Namespace,ResourceQuota Controller組件則負責定期統計和生成該Namespace下的各類物件的資源使用總量,統計結果包括Pod、Service、RC、Secret和PersistentVolume等物件實體個數,以及該Namespace下所有Container實體所使用的資源量(目前包括CPU和記憶體),然后將這些統計結果寫入etcd的resourceQuotaStatusStorage目錄(resourceQuotas/status)下,寫入resourceQuotaStatusStorage的內容包含Resource名稱、配額值(ResourceQuota物件中spec.hard域下包含的資源的值)、當前使用值(ResourceQuota Controller統計出來的值),隨后這些統計資訊被Admission Control使用,以確保相關Namespace下的資源配額總量不會超過ResourceQuota中的限定值,
五 Namespace Controller
5.1 Namespace Controller作用
用戶通過API Server可以創建新的Namespace并將其保存在etcd中,Namespace Controller定時通過API Server讀取這些Namespace的資訊,如果Namespace被API標識為優雅洗掉(通過設定洗掉期限實作,即設定DeletionTimestamp屬性),則將該NameSpace的狀態設定成Terminating并保存到etcd中,同時Namespace Controller洗掉該Namespace下的ServiceAccount、RC、Pod、Secret、PersistentVolume、ListRange、ResourceQuota和Event等資源物件, 在Namespace的狀態被設定成Terminating后,由Admission Controller的NamespaceLifecycle插件來阻止為該Namespace創建新的資源,同時,在Namespace Controller洗掉該Namespace中的所有資源物件后,Namespace Controller對該Namespace執行finalize操作,洗掉Namespace的spec.finalizers域中的資訊,如果Namespace Controller觀察到Namespace設定了洗掉期限,同時Namespace的spec.finalizers域值是空的,那么Namespace Controller將通過API Server洗掉該Namespace資源,六 Service Controller與Endpoints Controller
6.1 Service Controller與Endpoints Controller作用
如下所示為Service、Endpoints與Pod的關系,
Endpoints表示一個Service對應的所有Pod副本的訪問地址,Endpoints Controller就是負責生成和維護所有Endpoints物件的控制器,
Endpoints Controller負責監聽Service和對應的Pod副本的變化,如果監測到Service被洗掉,則洗掉和該Service同名的Endpoints物件,如果監測到新的Service被創建或者修改,則根據該Service資訊獲得相關的Pod串列,然后創建或者更新Service對應的Endpoints物件,如果監測到Pod的事件,則更新它所對應的Service的Endpoints物件(增加、洗掉或者修改對應的Endpoint條目),
每個Node的kube-proxy行程會使用Endpoints物件,kube-proxy行程獲取每個Service的Endpoints,實作了Service的負載均衡功能,
因此Service Controller的作用,它其實是屬于Kubernetes集群與外部的云平臺之間的一個介面控制器,Service Controller監聽Service的變化,如果該Service是一個LoadBalancer型別的Service(externalLoadBalancers=true),則Service Controller確保在外部的云平臺上該Service對應的LoadBalancer實體被相應地創建、洗掉及更新路由轉發表(根據Endpoints的條目),
七 Admission Control
7.1 Admission Control概述
Admission Control配備了一個準入控制器的插件串列,發送給API Server的任何請求都需要通過串列中每個準入控制器的檢查,檢查不通過,則API Server拒絕此呼叫請求,此外,準入控制器插件能夠修改請求引數以完成一些自動化任務,比如ServiceAccount這個控制器插件,7.2 可配置創建串列
當前可配置的準入控制器插件如下,- AlwaysAdmit:已棄用,允許所有請求,
- AlwaysPullImages:在啟動容器之前總是嘗試重新下載鏡像,這對于多租戶共享一個集群的場景非常有用,系統在啟動容器之前可以保證總是使用租戶的密鑰去下載鏡像,如果不設定這個控制器,則在Node上下載的鏡像的安全性將被削弱,只要知道該鏡像的名稱,任何人便都可以使用它們了,
- AlwaysDeny:已棄用,禁止所有請求,用于測驗,
- DefaultStorageClass:會關注PersistentVolumeClaim資源物件的創建,如果其中沒有包含任何針對特定Storage class的請求,則為其指派指定的Storage class,在這種情況下,用戶無須在PVC中設定任何特定的Storage class就能完成PVC的創建了,如果沒有設定默認的Storage class,該控制器就不會進行任何操作;如果設定了超過一個的默認Storage class,該控制器就會拒絕所有PVC物件的創建申請,并回傳錯誤資訊,因此需要確保Storage class物件的配置只有一個默認值,
- DefaultTolerationSeconds:針對沒有設定容忍node.kubernetes.io/not-ready:NoExecute或者node.alpha.kubernetes.io/unreachable:NoExecute的Pod,設定5min的默認容忍時間,
- DenyExecOnPrivileged:已棄用,攔截所有想在Privileged Container上執行命令的請求,如果你的集群支持Privileged Container,又希望限制用戶在這些Privileged Container上執行命令,那么強烈推薦使用它,其功能已被合并到DenyEscalatingExec中,
- DenyEscalatingExec:攔截所有exec和attach到具有特權的Pod上的請求,如果你的集群支持運行有escalated privilege權限的容器,又希望限制用戶在這些容器內執行命令,那么強烈推薦使用它,
- EventReateLimit:Alpha版本,用于應對事件密集情況下對API Server造成的洪水攻擊,
- ExtendedResourceToleration:如果需要創建帶有特定資源(例如GPU、FPGA等)的獨立節點,則可能會對節點進行Taint處理來進行特別配置,該控制器能夠自動為申請這些特別資源的Pod加入Toleration定義,無須人工干預,
- ImagePolicyWebhook:這個插件將允許后端的一個Webhook程式來完成Admission Controller的功能,ImagePolicyWebhook需要使用一個組態檔(通過kube-API Server的啟動引數--admission-control-config-file設定)定義后端Webhook的引數,目前是Alpha版本的功能,
- Initializers:Alpha,用于為動態準入控制提供支持,通過修改待創建資源的元資料來完成對該資源的修改,LimitPodHardAntiAffinityTopology:該插件啟用了Pod的反親和性調度策略設定,在設定親和性策略引數requiredDuringSchedulingRequiredDuringExecution時要求將topologyKey的值設定為“kubernetes.io/hostname”,否則Pod會被拒絕創建,
- LimitRanger:這個插件會監控進入的請求,確保請求的內容符合在Namespace中定義的LimitRange物件里的資源限制,如果要在Kubernetes集群中使用LimitRange物件,則必須啟用該插件才能實施這一限制,LimitRanger還能用于為沒有設定資源請求的Pod自動設定默認的資源請求,該插件會為default命名空間中的所有Pod設定0.1CPU的資源請求,
- MutatingAdmissionWebhook:Beta,這一插件會變更符合要求的請求的內容,Webhook以串行的方式順序執行,
- NamespaceAutoProvision:這一插件會檢測所有進入的具備命名空間的資源請求,如果其中參考的命名空間不存在,就會自動創建命名空間,
- NamespaceExists:這一插件會檢測所有進入的具備命名空間的資源請求,如果其中參考的命名空間不存在,就會拒絕這一創建程序,
- NamespaceLifecycle:如果嘗試在一個不存在的Namespace中創建資源物件,則該創建請求將被拒絕,當洗掉一個Namespace時,系統將會洗掉該Namespace中的所有物件,包括Pod、Service等,并阻止洗掉default、kube-system和kube-public這三個命名空間,
- NodeRestriction:該插件會限制kubelet對Node和Pod的修改行為,為了實作這一限制,kubelet必須使用system:nodes組中用戶名為system:node:<nodeName>的Token來運行,符合條件的kubelet只能修改自己的Node物件,也只能修改分配到各自Node上的Pod物件,在Kubernetes1.11以后的版本中,kubelet無法修改或者更新自身Node的taint屬性,在Kubernetes1.13以后,這一插件還會阻止kubelet洗掉自己的Node資源,并限制對有kubernetes.io/或k8s.io/前綴的標簽的修改,
- OnwerReferencesPermissionEnforcement:在該插件啟用后,一個用戶要想修改物件的metadata.ownerReferences,就必須具備delete權限,該插件還會保護物件的metadata.ownerReferences[x].blockOwnerDeletion欄位,用戶只有在對finalizers子資源擁有update權限的時候才能進行修改,
- PersistentVolumeLabel:棄用,這一插件自動根據云供應商(例如GCE或AWS)的定義,為PersistentVolume物件加入region或zone標簽,以此來保障PersistentVolume和Pod同處一區,如果插件不為PV自動設定標簽,則需要用戶手動保證Pod和其加載卷的相對位置,該插件正在被Cloudcontrollermanager替換,從Kubernetes1.11版本開始默認被禁止,
- PodNodeSelector:該插件會讀取命名空間的annotation欄位及全域配置,來對一個命名空間中物件的節點選擇器設定默認值或限制其取值,
- PersistentVolumeClaimResize:該插件實作了對PersistentVolumeClaim發起的resize請求的額外校驗,
- PodPreset:該插件會使用PodSelector選擇Pod,為符合條件的Pod進行注入,
- PodSecurityPolicy:在創建或修改Pod時決定是否根據Pod的securitycontext和可用的PodSecurityPolicy對Pod的安全策略進行控制,
- PodTolerationRestriction:該插件首先會在Pod和其命名空間的Toleration中進行沖突檢測,如果其中存在沖突,則拒絕該Pod的創建,它會把命名空間和Pod的Toleration進行合并,然后將合并的結果與命名空間中的白名單進行比較,如果合并的結果不在白名單內,則拒絕創建,如果不存在命名空間級的默認Toleration和白名單,則會采用集群級別的默認Toleration和白名單,
- Priority:這一插件使用priorityClassName欄位來確定優先級,如果沒有找到對應的PriorityClass,該Pod就會被拒絕,
- ResourceQuota:用于資源配額管理目的,作用于Namespace,該插件攔截所有請求,以確保在Namespace上的資源配額使用不會超標,推薦在Admission Control引數串列中將這個插件排最后一個,以免可能被其他插件拒絕的Pod被過早分配資源,
- SecurityContextDeny:這個插件將在Pod中定義的SecurityContext選項全部失效,SecurityContext在Container中定義了作業系統級別的安全設定(uid、gid、capabilities、SELinux等),在未設定PodSecurityPolicy的集群中建議啟用該插件,以禁用容器設定的非安全訪問權限,
- ServiceAccount:這個插件將ServiceAccount實作了自動化,如果想使用ServiceAccount物件,那么強烈推薦使用它,
- StorageObjectInUseProtection:這一插件會在新創建的PVC或PV中加入kubernetes.io/pvc-protection或kubernetes.io/pv-protection的finalizer,如果想要洗掉PVC或者PV,則直到所有finalizer的作業都完成,洗掉動作才會執行,
- ValidatingAdmissionWebhook:在Kubernetes1.8中為Alpha版本,在Kubernetes1.9中為Beta版本,該插件會針對符合其選擇要求的請求呼叫校驗Webhook,目標Webhook會以并行方式運行;如果其中任何一個Webhook拒絕了該請求,該請求就會失敗,
1 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultsStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota對Kubernetes 1.9及以下版本設定如下:
1 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,CalidatingAdmissionWebhook,ResourceQuota
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/125309.html
標籤:Linux
上一篇:作業系統-信號量臨界區保護
下一篇:想問下有什么辦法可以實作???
