- Kubernetes進階實戰
- 馬永亮
- 3557字
- 2019-03-13 14:20:36
2.1 Kubernetes的核心對象
API Server提供了RESTful風格的編程接口,其管理的資源是Kubernetes API中的端點,用于存儲某種API對象的集合,例如,內置Pod資源是包含了所有Pod對象的集合。資源對象是用于表現集群狀態的實體,常用于描述應于哪個節點進行容器化應用、需要為其配置什么資源以及應用程序的管理策略等,例如,重啟、升級及容錯機制。另外,一個對象也是一種“意向記錄”——一旦創建,Kubernetes就需要一直確保對象始終存在。Pod、Deployment和Service等都是最常用的核心對象。
2.1.1 Pod資源對象
Pod資源對象是一種集合了一到多個應用容器、存儲資源、專用IP及支撐容器運行的其他選項的邏輯組件,如圖2-1所示。換言之,Pod代表著Kubernetes的部署單元及原子運行單元,即一個應用程序的單一運行實例,它通常由共享資源且關系緊密的一個或多個應用容器組成。

圖2-1 Pod通常由一到多個共享網絡和存儲資源的容器組合而成
Kubernetes的網絡模型要求其各Pod對象的IP地址位于同一網絡平面內(同一IP網段),各Pod之間可使用其IP地址直接進行通信,無論它們運行于集群內的哪個工作節點之上,這些Pod對象都像是運行于同一局域網中的多個主機。
讀者可以將每個Pod對象想象成一個邏輯主機,它類似于現實世界中的物理主機或VM(Virtual Machine),運行于同一個Pod對象中的多個進程也類似于物理機或VM上獨立運行的進程。不過,Pod對象中的各進程均運行于彼此隔離的容器中,并于各容器間共享兩種關鍵資源:網絡和存儲卷。
?□網絡(networking):每個Pod對象都會被分配一個集群內專用的IP地址,也稱為Pod IP,同一Pod內部的所有容器共享Pod對象的Network和UTS名稱空間,其中包括主機名、IP地址和端口等。因此,這些容器間的通信可以基于本地回環接口lo進行,而與Pod外的其他組件的通信則需要使用Service資源對象的ClusterIP及其相應的端口完成。
?□存儲卷(volume):用戶可以為Pod對象配置一組“存儲卷”資源,這些資源可以共享給其內部的所有容器使用,從而完成容器間數據的共享。存儲卷還可以確保在容器終止后被重啟,甚至是被刪除后也能確保數據不會丟失,從而保證了生命周期內的Pod對象數據的持久化存儲。
一個Pod對象代表某個應用程序的一個特定實例,如果需要擴展應用程序,則意味著為此應用程序同時創建多個Pod實例,每個實例均代表應用程序的一個運行的“副本”(replica)。這些副本化的Pod對象的創建和管理通常由另一組稱之為“控制器”(Controller)的對象實現,例如,Deployment控制器對象。
創建Pod時,還可以使用Pod Preset對象為Pod注入特定的信息,如ConfigMap、Secret、存儲卷、卷掛載和環境變量等。有了Pod Preset對象,Pod模板的創建者就無須為每個模板顯式提供所有信息,因此,也就無須事先了解需要配置的每個應用的細節即可完成模板定義。這些內容將在后面的章節中予以介紹。
基于期望的目標狀態和各節點的資源可用性,Master會將Pod對象調度至某選定的工作節點運行,工作節點于指向的鏡像倉庫(image registry)下載鏡像,并于本地的容器運行時環境中啟動容器。Master會將整個集群的狀態保存于etcd中,并通過API Server共享給集群的各組件及客戶端。
2.1.2 Controller
Kubernetes集群的設計中,Pod是有生命周期的對象。用戶通過手工創建或由Controller(控制器)直接創建的Pod對象會被“調度器”(Scheduler)調度至集群中的某工作節點運行,待到容器應用進程運行結束之后正常終止,隨后就會被刪除。另外,節點資源耗盡或故障也會導致Pod對象被回收。
但Pod對象本身并不具有“自愈”功能,若是因為工作節點甚至是調度器自身導致了運行失敗,那么它將會被刪除;同樣,資源耗盡或節點故障導致的回收操作也會刪除相關的Pod對象。在設計上,Kubernetes使用“控制器”實現對一次性的(用后即棄)Pod對象的管理操作,例如,要確保部署的應用程序的Pod副本數量嚴格反映用戶期望的數目,以及基于Pod模板來重建Pod對象等,從而實現Pod對象的擴縮容、滾動更新和自愈能力等。例如,某節點發生故障時,相關的控制器會將此節點上運行的Pod對象重新調度到其他節點進行重建。
控制器本身也是一種資源類型,它有著多種實現,其中與工作負載相關的實現如Replication Controller、Deployment、StatefulSet、DaemonSet、DaemonSet和Jobs等,也可統稱它們為Pod控制器。如圖2-2中的Deployment就是這類控制器的代表實現,是目前最常用的管理無狀態應用的Pod控制器。

圖2-2 Replication Controller
Pod控制器的定義通常由期望的副本數量、Pod模板和標簽選擇器(Label Selector)組成。Pod控制器會根據標簽選擇器對Pod對象的標簽進行匹配檢查,所有滿足選擇條件的Pod對象都將受控于當前控制器并計入其副本總數,并確保此數目能夠精確反映期望的副本數。
需要注意的是,在實際的應用場景中,在接收到的請求流量負載顯著低于或接近于已有Pod副本的整體承載能力時,用戶需要手動修改Pod控制器中的期望副本數量以實現應用規模的擴容或縮容。不過,若集群中部署了HeapSter或Prometheus一類的資源指標監控附件時,用戶還可以使用“HorizontalPodAutoscaler”(HPA)計算出合適的Pod副本數量,并自動修改Pod控制器中期望的副本數以實現應用規模的動態伸縮,提高集群資源利用率,如圖2-3所示。

圖2-3 Horizontal Pod Autoscaler
Kubernetes集群中的每個節點都運行著cAdvisor以收集容器及節點的CPU、內存及磁盤資源的利用率指標數據,這些統計數據由Heapster聚合后可通過API Server訪問。HorizontalPodAutoscaler基于這些統計數據監控容器健康狀態并做出擴展決策。
2.1.3 Service
盡管Pod對象可以擁有IP地址,但此地址無法確保在Pod對象重啟或被重建后保持不變,這會為集群中的Pod應用間依賴關系的維護帶來麻煩:前端Pod應用(依賴方)無法基于固定地址持續跟蹤后端Pod應用(被依賴方)。于是,Service資源被用于在被訪問的Pod對象中添加一個有著固定IP地址的中間層,客戶端向此地址發起訪問請求后由相關的Service資源調度并代理至后端的Pod對象。
換言之,Service是“微服務”的一種實現,事實上它是一種抽象:通過規則定義出由多個Pod對象組合而成的邏輯集合,并附帶訪問這組Pod對象的策略。Service對象挑選、關聯Pod對象的方式同Pod控制器一樣,都是要基于Label Selector進行定義,其示意圖如圖2-4所示。

圖2-4 Service對象功能示意圖
Service IP是一種虛擬IP,也稱為Cluster IP,它專用于集群內通信,通常使用專用的地址段,如“10.96.0.0/12”網絡,各Service對象的IP地址在此范圍內由系統動態分配。
集群內的Pod對象可直接請求此類的Cluster IP,例如,圖2-4中來自pod client的訪問請求即可以Service的Cluster IP作為目標地址,但集群網絡屬于私有網絡地址,它們僅在集群內部可達。將集群外部的訪問流量引入集群內部的常用方法是通過節點網絡進行,實現方法是通過工作節點的IP地址和某端口(NodePort)接入請求并將其代理至相應的Service對象的Cluster IP上的服務端口,而后由Service對象將請求代理至后端的Pod對象的Pod IP及應用程序監聽的端口。因此,諸如圖2-4中的External Clients這種來自集群外部的客戶端無法直接請求此Service提供的服務,而是需要事先經由某一個工作節點(如Node Y)的IP地址進行,這類請求需要兩次轉發才能到達目標Pod對象,因此在通信效率上必然存在負面影響。
事實上,NodePort會部署于集群中的每一個節點,這就意味著,集群外部的客戶端通過任何一個工作節點的IP地址來訪問定義好的NodePort都可以到達相應的Service對象。此種場景中,如果存在集群外部的一個負載均衡器,即可將用戶請求負載均衡至集群中的部分或者所有節點。這是一種稱為“LoadBalancer”類型的Service,它通常是由Cloud Provider自動創建并提供的軟件負載均衡器,不過,也可以是由管理員手工配置的諸如F5 Big-IP一類的硬件設備。
簡單來說,Service主要有三種常用類型:第一種是僅用于集群內部通信的ClusterIP類型;第二種是接入集群外部請求的NodePort類型,它工作于每個節點的主機IP之上;第三種是LoadBalancer類型,它可以把外部請求負載均衡至多個Node的主機IP的NodePort之上。此三種類型中,每一種都以其前一種為基礎才能實現,而且第三種類型中的LoadBalancer需要協同集群外部的組件才能實現,并且此外部組件并不接受Kubernetes的管理。
2.1.4 部署應用程序的主體過程
Docker容器技術使得部署應用程序從傳統的安裝、配置、啟動應用程序的方式轉為于容器引擎上基于鏡像創建和運行容器,而Kubernetes又使得創建和運行容器的操作不必再關注其位置,并在一定程度上賦予了它動態擴縮容及自愈的能力,從而讓用戶從主機、系統及應用程序的維護工作中解脫出來。
用到某應用程序時,用戶只需要向API Server請求創建一個Pod控制器,由控制器根據鏡像等信息向API Server請求創建出一定數量的Pod對象,并由Master之上的調度器指派至選定的工作節點以運行容器化應用。此外,用戶一般還需要創建一個具體的Service對象以便為這些Pod對象建立起一個固定的訪問入口,從而使得其客戶端能夠通過其服務名稱或ClusterIP進行訪問,如圖2-5所示。

圖2-5 應用程序簡單的部署示例
API Server的常用客戶端程序是Kubernetes系統自帶的命令行工具kubectl,它通過一眾子命令用于實現集群及相關資源對象的管理操作,并支持直接命令式、命令式配置清單及聲明式配置清單等三種操作方式,特性豐富且功能強大。而需作為集群附件額外部署的Dashboard則提供了基于Web界面的圖形客戶端,它是一個通用目的管理工具,與Kubernetes緊密集成,支持多級別用戶授權,能在一定程度上替代kubectl的大多數操作。
本章后面的篇幅將介紹在部署完成的Kubernetes集群環境中如何快速部署如圖2-5所示的示例應用程序,并簡單說明如何完成對容器化應用的訪問,以及如何進行應用規模的動態伸縮,并借此讓讀者了解kubectl命令的基本功能和用法。
- Learning Scala Programming
- Implementing VMware Horizon 7(Second Edition)
- Ceph Cookbook
- Python數據分析基礎
- Dynamics 365 Application Development
- Vue.js快速入門與深入實戰
- 數據結構習題精解(C語言實現+微課視頻)
- Reactive Programming With Java 9
- Java EE 7 Performance Tuning and Optimization
- C++反匯編與逆向分析技術揭秘(第2版)
- Hands-On Neural Network Programming with C#
- C語言程序設計與應用(第2版)
- 計算機應用基礎項目化教程
- BeagleBone Robotic Projects(Second Edition)
- 深入解析Java編譯器:源碼剖析與實例詳解