029.核心組件-Controller Manager

一 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密切相關。
clipboard
提示:在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的典型使用場景一般有以下幾種:
  1. 從新調度(Rescheduling):無論想運行1個副本仍是1000個副本,副本控制器都能確保指定數量的副本存在於集羣中,即便發生節點故障或Pod副本被終止運行等意外情況。
  2. 彈性伸縮(Scaling):手動或者經過自動擴容代理修改副本控制器的spec.replicas屬性值,很是容易實現增長或減小副本的數量。
  3. 滾動更新(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的相關控制功能。
clipboard
Node Controller的核心工做流程:
  1. ControllerM anager在啓動時若是設置了--cluster-cidr參數,那麼爲每一個沒有設置Spec.PodCIDR的Node都生成一個CIDR地址,並用該CIDR地址設置節點的Spec.PodCIDR屬性,這樣作的目的是防止不一樣節點的CIDR地址發生衝突。
  2. 逐個讀取Node信息,屢次嘗試修改nodeStatusMap中的節點狀態信息,將該節點信息和Node Controller的nodeStatusMap中保存的節點信息作比較。若是判斷出沒有收到kubelet發送的節點信息、第1次收到節點kubelet發送的節點信息,或在該處理過程當中節點狀態變成非「健康」狀態,則在nodeStatusMap中保存該節點的狀態信息,並用Node Controller所在節點的系統時間做爲探測時間和節點狀態變化時間。若是判斷出在指定時間內收到新的節點信息,且節點狀態發生變化,則在nodeStatusMap中保存該節點的狀態信息,並用Node Controller所在節點的系統時間做爲探測時間和節點狀態變化時間。若是判斷出在指定時間內收到新的節點信息,但節點狀態沒發生變化,則在nodeStatusMap中保存該節點的狀態信息,並用Node Controller所在節點的系統時間做爲探測時間,將上次節點信息中的節點狀態變化時間做爲該節點的狀態變化時間。若是判斷出在某段時間(gracePeriod)內沒有收到節點狀態信息,則設置節點狀態爲「未知」,而且經過API Server保存節點狀態。
  3. 逐個讀取節點信息,若是節點狀態變爲非「就緒」狀態,則將節點加入待刪除隊列,不然將節點從該隊列中刪除。若是節點狀態爲非「就緒」狀態,且系統指定了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數量。
Kubernetes的配額管理是經過Admission Control(准入控制)來控制的,Admission Control當前提供了兩種方式的配額約束,分別是LimitRanger與ResourceQuota。
其中LimitRanger做用於Pod和Container,ResourceQuota則做用於Namespace,限定一個Namespace裏的各種資源的使用總額。

4.2 ResourceQuota Controller工做流程

clipboard
如圖所示,若是在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的關係。
clipboard
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對象的配置只有一個默認值。
注意:該控制器僅關注PVC的建立過程,對更新過程無效。
  • 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拒絕了該請求,該請求就會失敗。
在API Server上設置參數便可定製咱們須要的准入控制鏈,若是啓用多種准入控制選項,則建議設置:在Kubernetes1.9及以前的版本中使用的參數是--admission-control,而且其中的內容是順序相關的;在Kubernetes1.10及以後的版本中,該參數爲--enable-admission-plugins,而且與順序無關。
對Kubernetes 1.10及以上版本設置以下:
  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
相關文章
相關標籤/搜索