背景資料
在Kubernetes架構圖中可以看到,節點(Node)是一個由管理節點委托運作任務的worker。 它能運作一個或多個Pods,節點(Node)提供了運作容器環境所需要的所有必要條件,在Kubernetes之前版本中叫做Minion。

相關結構體
通過下面這張圖可以看到在Kubernetes中節點(Node)的相關結構體資訊:
• 結構體Node:表示Kubernetes中的節點,在節點上面運作POD。
• 結構體NodeSpec:存放節點的屬性資訊。
1. 屬性PodCIDR:表示這個節點上面POD可以使用的IP範圍。
2. 屬性ExternalID:這是一個已經被放棄使用的屬性。
3. 屬性ProviderID:當節點是公有雲廠商提供的雲主機時,這個屬性表示公有雲系統中對雲主機的唯一辨別,格式為:<ProviderName>://<ProviderSpecificNodeID>
4. 屬性Unschedulable:這是一個布爾型變量,預設是false。如果為true的時候,表示這個節點不能被Kubernetes進行排程,也就是Kubernetes不能在這個節點上建立新的POD,但是不會改變這個節點上已經建立的POD。當要對節點進行維護,那麼就可以将這個節點的Unschedulable變量設定成true,然後對節點進行維護操作。可以通過下面指令來修改這個屬性:
這裡面有一個例外,就是如果使用daemonSet控制器來建立POD的時候,不會關心Unschedulable這個屬性是否被設定成了true,這是因為daemonSet控制器認為任何節點上的daemonSet POD都是必須要建立的,同這個屬性無關。
• 結構體NodeStatus:存放節點目前狀态資訊。
1. 屬性Capacity:存放節點上所有資源總量
2. 屬性Allocatable:存放節點上可以被排程使用的可用資源數量
3. 屬性Phase:存放節點目前所處在什麼階段,一共有三個取值,分别是“Pending”、“Running”和“Terminated”,分别表示如下階段:
1) Pending:表示節點已經被添加到Kubernetes叢集中,但是還沒有被Kubernetes進行配置
2) Running:表示節點已經被Kubernetes配置完成,可以由Kubernetes進行排程使用
3) Terminated:表示節點已經從Kubernetes叢集中被删除掉了
• 結構體NodeCondition:存放節點健康狀況。
1. 屬性Type:節點健康狀況類型,包括Ready、OutOfDisk、MemoryPressure、DiskPressure和NetworkUnavailable,分别表示:
1) Ready:表示節點是健康的,可以随時在上面建立POD
2) OutOfDisk:表示這個節點沒有空閑的磁盤空間了,已經不能在上面建立POD了
3) MemoryPressure:表示這個節點上可用記憶體已經很少了
4) DiskPressure:表示這個節點上可用磁盤空間已經很少了
5) NetworkUnavailable:表示這個節點上網絡沒有被正确配置
2. 屬性Status:表示某種類型健康狀況的目前狀态,目前隻有True、False和Unknown,在kubernetes将來版本中還會繼續添加新的狀态。
1) True:表示目前類型的健康狀況确實存在
2) False:表示目前類型的健康狀況不存在
3) Unknown:表示kubernetes無法确定目前類型的健康狀況是否存在
3. 屬性LastHeartbeatTime:表示上一次更新狀态的時間
4. 屬性LastTransitionTime:表示上一次狀态變化的時間
5. 屬性Reason:表示上一次狀态變化的簡單原因
6. 屬性Message:表示上一次狀态變化的詳細原因
• 結構體AttachedVolume:存放挂載到節點上的資料卷資訊。
1. 屬性Name:挂載到節點上資料卷的名稱
2. 屬性DevicePath:挂載到節點上資料卷的有效路徑
• 結構體NodeStats:存放節點的統計資料。
1. 屬性NodeName:表示這個節點名稱。
2. 屬性SystemContainers:這是一個數組型變量,存放這個節點上所有系統容器的統計資訊,這裡系統容器指的是以Daemon狀态運作的kubelet和docker容器。
3. 屬性StartTime:表示開始對節點進行統計的時間。
4. 屬性CPU:表示CPU相關的統計資料。
5. 屬性Memory:表示記憶體相關的統計資料
6. 屬性Network:表示網絡相關的統計資料。
7. 屬性Fs:表示Kubernetes子產品使用檔案系統相關的統計資料。
8. 屬性Runtime:表示使用者容器運作時的統計資料。
新特性
在Kubernetes1.4中,結構體NodeCondition新增了一個健康狀況類型DiskPressure,用來表示這個節點上可用磁盤空間已經很少了。
新增了這個健康狀況類型DiskPressure後,在兩個方面會提升Kubernetes的使用:
1. 可以在排程POD的時候進行參考,如果節點上确實發生了DiskPressure這件事,那麼就會由scheduler子產品将POD排程到其他節點上。
2. 可以在控制節點的時候進行參考,如果節點上确實發生了DiskPressure這件事,那麼就會由kubelet子產品回收這個節點上的所有POD,将這些POD驅逐到其他節點上。
下面介紹kubelet子產品在控制節點的時候是如何參考使用DiskPressure的,這就需要更細緻的分析結構體NodeStats中的五個屬性:
1. 屬性CPU:表示CPU相關的統計資料。這個屬性對應結構體CPUStats:
其中屬性Time表示統計資料更新時間,屬性UsageNanoCores表示節點上所有CPU在采樣視窗内的使用量,屬性UsageCoreNanoSeconds表示節點上所有CPU曆史使用總量。
2. 屬性Memory:表示記憶體相關的統計資料。這個屬性對應結構體MemoryStats:
其中屬性Time表示統計資料更新時間,屬性AvailableBytes表示可以使用的記憶體總量,屬性UsageBytes表示已經被配置設定的記憶體大小,屬性WorkingSetBytes表示已經被使用的記憶體大小,已經被使用的記憶體大小<=已經被配置設定的記憶體大小,也就是說屬性WorkingSetBytes<=UsageBytes,屬性RSSBytes表示匿名緩存和swap緩存(包括linux transparent huge pages)大小,屬性PageFaults表示次要記憶體缺頁錯誤數,屬性MajorPageFaults表示主要記憶體缺頁錯誤數。
什麼叫錯缺頁錯誤:
節點上實體記憶體是有限,但是應用程式的使用需求是無限的,作業系統為了解決這個沖突,使用了虛拟記憶體的設計。簡單的描述就是,給應用程式一個與實體記憶體無關的虛拟位址空間,并提供一套映射機制,将虛拟位址映射到實體記憶體。當然應用程式是不知道有這個映射機制存在的,他唯一需要做的就是盡情的使用自己的虛拟位址空間。作業系統提供的映射機制是運作時動态進行虛拟位址和實體位址之間的映射的,當一個虛拟位址沒有對應的實體記憶體時候,映射機制就配置設定實體記憶體,建構映射表,滿足應用程式的需求,這個過程就叫缺頁錯誤。與直接通路實體記憶體不同,缺頁錯誤過程大部分是由軟體完成的,消耗時間比較久,是以是影響性能的一個關鍵名額。Linux把缺頁錯誤又進一步分為次要缺頁錯誤和主要缺頁錯誤。前面提到的配置設定實體記憶體,建構映射表過程可以看做是次要缺頁錯誤。主要缺頁錯誤是由swap機制引入的,對于swap情況,位址映射好了後,還需要從外部存儲讀取資料,這個過程涉及到IO操作,耗時更久。
3. 屬性Network:表示網絡相關的統計資料。這個屬性對應結構體NetworkStats:
其中屬性Time表示統計資料更新時間,屬性RxBytes表示接收到的位元組數,屬性RxErrors表示接收錯誤數,屬性TxBytes表示發送出去的位元組數,屬性TxErrors表示發送錯誤數。
4. 屬性Fs:表示Kubernetes子產品使用檔案系統相關的統計資料。這個屬性對應結構體FsStats:
在kubernetes1.4中新增加了InodesFree和Inodes這兩個屬性。其中屬性AvailableBytes表示檔案系統可以使用的存儲空間大小,屬性CapacityBytes表示檔案系統存儲空間總量,屬性UsedBytes表示使用檔案系統上特定任務所占用的存儲空間大小,是以UsedByte并不等于CapacityBytes-AvailableBytes,屬性InodesFree表示檔案系統上空閑inode數量,屬性Inodes表示檔案系統上inode總量。
什麼是inode:
檔案儲存在硬碟上,硬碟的最小存儲機關叫做"扇區"。每個扇區儲存512位元組。作業系統讀取硬碟的時候,不會一個個扇區地讀取,這樣效率太低,而是一次性連續讀取多個扇區,即一次性讀取一個"塊"。這種由多個扇區組成的"塊",是檔案存取的最小機關。"塊"的大小,最常見的是4KB,即連續八個扇區組成一個塊。檔案資料都儲存在"塊"中,那麼很顯然,我們還必須找到一個地方儲存檔案的元資訊,比如檔案的建立者、檔案的建立日期、檔案的大小等等。這種儲存檔案元資訊的區域就叫做inode,中文稱作"索引節點"。
5. 屬性Runtime:表示使用者容器運作時的統計資料。這個屬性對應結構體RuntimeStats:
其中屬性ImageFs對應結構體FsStats,這個屬性表示檔案系統上容器使用鏡像所占用空間的統計資料。對于節點來說可以有兩種檔案系統,一種是root檔案系統,提供給kubelet存放日志、提供資料卷等使用;一種是image檔案系統,提供給容器存儲鏡像、讀寫操作使用。image檔案系統可以就是root檔案系統,也可以是單獨提供給容器鏡像使用的檔案系統,預設情況下就是root檔案系統。
在Kubernetes1.4之前版本中隻有MemoryPressure這個健康狀況類型,對應節點上結構體MemoryStats的AvailableBytes屬性。在Kubernetes1.4中,結構體NodeCondition新增了一個健康狀況類型DiskPressure,其實這個DiskPressure就對應root檔案系統和image檔案系統。更具體的說,就是對應root檔案系統中和image檔案系統的AvailableBytes屬性和inodesFree屬性。
當滿足DiskPressure發生的條件時,kubelet子產品回收這個節點上的所有POD,将這些POD驅逐到其他節點上。這需要在啟動kubelet子產品時增加eviction相關的參數,比如
--eviction-hard:表示立即進行POD資源回收,并将POD驅逐到其他空閑節點上
--eviction-soft:表示先觀察一段時間,之後進行POD資源回收,并将POD驅逐到其他空閑節點上
--eviction-soft-grace-period:表示觀察時長
下面是kubelet子產品設定使用DiskPressure的例子:
1. --eviction-hard="nodefs.available<1Gi,nodefs.inodesFree<1,imagefs.available<10Gi,imagefs.inodesFree<10"
當節點上root檔案系統可用空間小于1G或者空閑inode數小于1,或者當節點上image檔案系統可用空間小于10G或者空閑inode數小于10,那麼就會設定DiskPressure為true,kubelet子產品接口會立即回收這個節點上的POD,并将POD驅逐到其他空閑節點上。
1. --eviction-soft="nodefs.available<1.5Gi,nodefs.inodesFree<10,imagefs.available<20Gi,imagefs.inodesFree<100"
2.
3. --eviction-soft-grace-period="nodefs.available=1m,imagefs.available=2m"