Kubernetes的介紹
【編者的話】Kubernetes是一個強大的開源系統,最初由谷歌開發,用於在叢集環境中管理容器化應用程式。它的目標是提供更好的方法來管理不同基礎設施之間的相關分散式元件和服務。
在本指南中,我們將討論一些Kubernetes的基本概念。我們將討論系統的體系結構、它解決的問題,以及它用來處理容器部署和擴充套件的模型。
Kubernetes是什麼?
在基本級別上,Kubernetes是一個用於跨機器叢集執行和協調容器應用程式的系統。它是一個平臺,旨在通過提供可預測性、可伸縮性和高可用性的方法,完全管理容器化應用程式和服務的生命週期。
作為Kubernetes使用者,您可以定義應用程式的執行方式,以及它們與其他應用程式或外部互動的方式。您可以向上或向下擴充套件服務、執行優雅的滾動更新、不同版本應用程式的流量切換,以測試特性或回滾問題部署。Kubernetes提供了介面和可組合的平臺基元,允許您以高度的靈活性、強大性和可靠性定義和管理應用程式。
Kubernetes架構
要理解Kubernetes是如何提供這些功能的,瞭解它是如何在高層次上設計和組織的是很有幫助。Kubernetes可以被視為一個以層(layer)為單位的系統,每個更高層抽象出更低層次的複雜性。
在其基礎上,Kubernetes使用共享網路將單個物理或虛擬機器組合到一個叢集中,以便在每個伺服器之間進行通訊。這個叢集是配置所有Kubernetes元件、功能和工作負載的物理平臺。
叢集中的機器在Kubernetes生態系統中每個都有一個角色。一個伺服器(或高度可用部署中的一個小組)充當主伺服器。這個伺服器充當叢集的閘道器和大腦,它為使用者和客戶機公開API,檢查其他伺服器的健康狀況,決定如何最好地分割和分配工作(稱為“排程”),以及協調其他元件之間的通訊。主伺服器充當與叢集的主要接觸點,並負責Kubernetes提供的大部分集中邏輯。
叢集中的其他機器被指定為節點:伺服器負責使用本地和外部資源接受和執行工作負載。為了幫助實現隔離、管理和靈活性,Kubernetes在容器中執行應用程式和服務,因此每個節點都需要配備一個容器執行時(比如Docker或rkt)。節點從主伺服器接收工作指令,並相應地建立或銷燬容器,調整網路規則以適當路由和轉發流量。
如上所述,應用程式和服務本身在容器內的叢集上執行。底層元件確保應用程式的期望狀態與叢集的實際狀態匹配。使用者通過直接與主API伺服器或與客戶機和庫通訊與叢集進行互動。要啟動應用程式或服務,需要以JSON或YAML的形式提交宣告性計劃,定義要建立什麼以及應該如何管理它。然後,主伺服器獲取計劃,通過檢查系統的需求和當前狀態,確定如何在基礎設施上執行它。這組根據指定計劃執行的使用者定義應用程式代表了Kubernetes的最後一層。
主伺服器元件
如上所述,主伺服器充當Kubernetes叢集的主要控制平面。 它是管理員和使用者的主要聯絡點,也為相對不復雜的工作節點提供了許多叢集範圍的系統。 總體而言,主伺服器上的元件協同工作以接受使用者請求,確定排程工作負載容器,驗證客戶端和節點,調整群集範圍網路以及管理擴充套件和執行狀況檢查職責的最佳方法。
這些元件可以安裝在一臺機器上,也可以分佈在多個伺服器上。在本節中,我們將研究與主伺服器相關的每個單獨元件。
ETCD
Kubernetes需要執行的基本元件之一是全域性可用的配置儲存。 由CoreOS團隊開發的etcd專案是一個輕量級的分散式鍵值儲存,可以配置為跨越多個節點。
Kubernetes使用etcd來儲存可以由叢集中的每個節點訪問的配置資料。 這可用於服務發現,並可幫助元件根據最新資訊配置或重新配置自身。 它還有助於通過領導者選舉和分散式鎖定等功能維護群集狀態。 通過提供簡單的HTTP / JSON API,用於設定或檢索值的介面非常簡單。
與控制平面中的大多數其他元件一樣,etcd可以在單個主伺服器上配置,或者在生產方案中,可以在多臺計算機之間分配。 唯一的要求是每個Kubernetes機器都可以訪問網路。
KUBE-API伺服器
最重要的主服務之一是API伺服器。 這是整個群集的主要管理點,因為它允許使用者配置Kubernetes的工作負載和組織單位。 它還負責確保etcd儲存和已部署容器的服務詳細資訊一致。 它充當各種元件之間的橋樑,以維護叢集健康並傳播資訊和命令。
API伺服器實現RESTful介面,這意味著許多不同的工具和庫可以很容易地與它通訊。 名為kubectl的客戶端可用作從本地計算機與Kubernetes叢集互動的預設方法。
KUBE-控制器管理器
控制器管理器是一項具有許多職責的通用服務。它主要管理不同的控制器,用於管理叢集狀態,管理工作負載生命週期以及執行例行任務。例如,複製控制器可確保為pod定義的副本數(相同副本)與當前在群集上部署的數量相匹配。這些操作的詳細資訊將寫入etcd,其中控制器管理器通過API伺服器監視更改。
當看到更改時,控制器讀取新資訊並實現滿足所需狀態的過程。這可能涉及向上或向下擴充套件應用程式,調整端點等。
KUBE-排程
實際將工作負載分配給叢集中特定節點的過程是排程程式。此服務讀取工作負載的操作要求,分析當前的基礎結構環境,並將工作放在可接受的節點上。
排程程式負責跟蹤每臺主機上的可用容量,以確保未排程超出可用資源的工作負載。排程程式必須知道總容量以及已分配給每臺伺服器上現有工作負載的資源。
雲控制器管理器
Kubernetes可以部署在許多不同的環境中,並且可以與各種基礎架構提供商進行互動,以瞭解和管理叢集中的資源狀態。雖然Kubernetes使用可附加儲存和負載平衡器等資源的通用表示,但它需要一種方法將這些表示對映到非同類雲提供商提供的實際資源。
雲控制器管理器充當粘合劑,允許Kubernetes使提供者具有不同的功能,特性和API,同時在內部維護相對通用的構造。這允許Kubernetes根據從雲提供商收集的資訊更新其狀態資訊,在系統中需要更改時調整雲資源,以及建立和使用其他雲服務以滿足提交到群集的工作要求。
節點伺服器元件
在Kubernetes中,通過執行容器執行工作的伺服器稱為節點。 節點伺服器有一些要求,這些要求是與主元件通訊,配置容器網路以及執行分配給它們的實際工作負載所必需的。
一個容器執行時
每個節點必須具有的第一個元件是容器執行時。通常,通過安裝和執行Docker可以滿足此要求,但也可以使用rkt和runc等替代方案。
容器執行時負責啟動和管理容器,應用程式封裝在相對隔離但輕量級的操作環境中。叢集上的每個工作單元在其基本級別上實現為必須部署的一個或多個容器。每個節點上的容器執行時是最終執行提交到叢集的工作負載中定義的容器的元件。
kubelet
每個節點與群集組的主要聯絡點是一個名為kubelet的小型服務。該服務負責向控制平面服務中繼資訊,以及與etcd儲存互動以讀取配置細節或寫入新值。
kubelet服務與主元件通訊以向叢集進行身份驗證並接收命令和工作。以清單的形式接收工作,該清單定義工作量和操作引數。然後,kubelet程序負責維護節點伺服器上的工作狀態。它控制容器執行時根據需要啟動或銷燬容器。
KUBE-代理
為了管理單個主機子網並使服務可用於其他元件,在每個節點伺服器上執行一個名為kube-proxy的小型代理服務。此過程將請求轉發到正確的容器,可以進行原始負載平衡,並且通常負責確保網路環境是可預測和可訪問的,但在適當時隔離。
Kubernetes物件和工作量
雖然容器是用於部署應用程式的底層機制,但Kubernetes在容器介面上使用了額外的抽象層來提供擴充套件,彈性和生命週期管理功能。使用者不是直接管理容器,而是定義由Kubernetes物件模型提供的各種基元組成的例項並與之互動。我們將介紹可用於定義下面這些工作負載的不同型別的物件。
Pods
pod是Kubernetes處理的最基本單位。容器本身未分配給主機。相反,一個或多個緊密耦合的容器被封裝在稱為pod的物件中。
pod通常表示應作為單個應用程式控制的一個或多個容器。 Pod由密集操作的容器組成,共享生命週期,並且應始終安排在同一節點上。它們完全作為一個單元進行管理,並共享其環境,數量和IP空間。儘管它們是容器化的實現,但您通常應該將pod視為一個單一的整體應用程式,以便最好地概念化叢集如何管理pod的資源和排程。
通常,pod包含滿足工作負載一般用途的主容器,以及可選的一些幫助密切相關任務的幫助容器。這些程式受益於在自己的容器中執行和管理,但與主應用程式緊密相關。例如,當外部儲存庫中檢測到更改時,pod可能有一個執行主應用程式伺服器的容器和一個幫助容器將檔案下拉到共享檔案系統。通常不鼓勵在pod級別進行水平縮放,因為還有其他更高級別的物件更適合該任務。
通常,使用者不應自行管理pod,因為它們不提供應用程式中通常需要的某些功能(如複雜的生命週期管理和擴充套件)。相反,鼓勵使用者使用更高級別的物件,這些物件使用pod或pod模板作為基本元件,但實現其他功能。
複製控制器和複製集
通常,在與Kubernetes合作時,不是使用單個pod,而是管理相同,複製的pod組。這些是從pod模板建立的,可以通過稱為複製控制器和複製集的控制器進行水平擴充套件。
複製控制器是一個物件,它定義pod模板和控制引數,以通過增加或減少執行副本的數量來水平擴充套件pod的相同副本。這是在Kubernetes中本地分配負載和增加可用性的簡單方法。複製控制器知道如何根據需要建立新的pod,因為複製控制器配置中嵌入了與pod定義非常相似的模板。
複製控制器負責確保群集中部署的pod數量與其配置中的pod數量相匹配。如果pod或底層主機出現故障,控制器將啟動新的pod以進行補償。如果控制器配置中的副本數量發生更改,控制器將啟動或終止容器以匹配所需的數字。複製控制器還可以執行滾動更新,將一組pod逐個滾動到新版本,從而最大限度地降低對應用程式可用性的影響。
複製集是複製控制器設計的迭代,在控制器識別其要管理的pod方面具有更大的靈活性。複製集開始取代複製控制器,因為它們具有更強的副本選擇功能,但它們無法進行滾動更新以將後端迴圈到新版本,如複製控制器。相反,複製集旨在用於提供該功能的其他更高級別單元內部。
與pod一樣,複製控制器和複製集很少是您直接使用的單元。雖然它們基於pod設計以增加水平擴充套件和可靠性保證,但它們缺少一些在更復雜的物件中發現的細粒度生命週期管理功能。
部署
部署是直接建立和管理的最常見工作負載之一。部署使用複製集作為構建塊,為混合新增靈活的生命週期管理功能。
雖然使用複製集構建的部署可能會複製複製控制器提供的功能,但部署解決了滾動更新實現中存在的許多難點。使用複製控制器更新應用程式時,使用者需要為將替換當前控制器的新複製控制器提交計劃。使用複製控制器時,跟蹤歷史記錄,在更新期間從網路故障中恢復以及回滾不良更改等任務要麼很困難,要麼由使用者負責。
部署是一個高階物件,旨在簡化複製pod的生命週期管理。通過更改配置可以輕鬆修改部署,Kubernetes將調整副本集,管理不同應用程式版本之間的轉換,並可選擇自動維護事件歷史記錄和撤消功能。由於這些功能,部署可能是您最常使用的Kubernetes物件型別。
有狀態集
有狀態集是專門的pod控制器,提供排序和唯一性保證。首先,當您有與部署順序,持久資料或穩定網路相關的特殊要求時,這些用於進行更細粒度的控制。例如,有狀態集通常與面向資料的應用程式相關聯,如資料庫,即使重新安排到新節點,也需要訪問相同的卷。
有狀態集通過為每個pod建立唯一的,基於數字的名稱來提供穩定的網路識別符號,即使將pod移動到另一個節點也會持久存在。同樣,當需要重新安排時,可以使用pod傳輸持久儲存卷。即使在刪除pod後,卷仍然存在,以防止意外資料丟失。
在部署或調整比例時,有狀態集根據其名稱中的編號識別符號執行操作。這提供了更高的可預測性和對執行順序的控制,這在某些情況下很有用。
守護程序集
守護程式集是另一種特殊形式的pod控制器,它在叢集中的每個節點上執行pod的副本(如果指定,則為子集)。在部署有助於執行維護併為節點本身提供服務的pod時,這通常很有用。
例如,收集和轉發日誌,聚合度量以及執行增加節點本身功能的服務是守護程序集的流行候選者。由於守護程式集通常提供基本服務並且在整個機群中都需要,因此它們可以繞過pod排程限制,從而阻止其他控制器將pod分配給某些主機。例如,由於其獨特的職責,主伺服器經常被配置為不可用於正常的pod排程,但是守護程序集能夠逐個pod地覆蓋限制以確保基本服務正在執行。
job和cron jobs
到目前為止,我們所描述的工作負載都假定為長期執行,類似服務的生命週期。 Kubernetes使用稱為作業的工作負載來提供更多基於任務的工作流,其中執行的容器在完成工作後的一段時間後會成功退出。如果您需要執行一次性或批量處理而不是執行連續服務,則作業非常有用。
以工作為基礎的是cron工作。與Linux上的傳統cron守護程式和按計劃執行指令碼的類Unix系統一樣,Kubernetes中的cron作業提供了一個用於執行具有排程元件的作業的介面。 Cron作業可用於安排作業在將來執行或定期重複執行。 Kubernetes cron作業基本上是對經典cron行為的重新實現,使用叢集作為平臺而不是單個作業系統。
其他Kubernetes元件
除了可以在群集上執行的工作負載之外,Kubernetes還提供了許多其他抽象,可幫助您管理應用程式,控制網路和啟用永續性。我們將在這裡討論一些更常見的例子。
服務
到目前為止,我們一直在使用傳統的類似於Unix的術語“服務”:表示長期執行的程序,通常是網路連線的,能夠響應請求。但是,在Kubernetes中,服務是一個元件,充當基本內部負載平衡器和pod的大使。服務將執行相同功能的pod的邏輯集合組合在一起,以將它們顯示為單個實體。
這允許您部署可以跟蹤和路由到特定型別的所有後端容器的服務。內部消費者只需要瞭解服務提供的穩定端點。同時,服務抽象允許您根據需要擴充套件或替換後端工作單元。無論其路由到的pod的變化如何,服務的IP地址都保持穩定。通過部署服務,您可以輕鬆獲得可發現性並簡化容器設計。
每當您需要為一個或多個pod提供對另一個應用程式或外部使用者的訪問許可權時,您應該配置一項服務。例如,如果您有一組執行Web伺服器的pod應該可以從Internet訪問,則服務將提供必要的抽象。同樣,如果您的Web伺服器需要儲存和檢索資料,您可能希望配置內部服務以授予它們訪問資料庫窗格的許可權。
雖然預設情況下服務只能使用內部可路由的IP地址,但只要選擇多種策略之一,就可以在群集外部使用它們。 NodePort配置通過在每個節點的外部網路介面上開啟靜態埠來工作。到外部埠的流量將使用內部群集IP服務自動路由到相應的Pod。
或者,LoadBalancer服務型別使用雲提供程式的Kubernetes負載均衡器整合建立外部負載均衡器以路由到服務。雲控制器管理器將建立適當的資源並使用內部服務服務地址對其進行配置。
儲存卷和持久儲存卷
在許多容器化環境中,可靠地共享資料並保證容器重啟之間的可用性是一項挑戰。容器執行時通常提供一些機制來將儲存連線到容器,該容器持續超出容器的生命週期,但實現通常缺乏靈活性。
為了解決這個問題,Kubernetes使用自己的卷抽象,允許資料由pod中的所有容器共享,並在pod終止之前保持可用。這意味著緊密耦合的pod可以輕鬆共享檔案而無需複雜的外部機制。 pod中的容器故障不會影響對共享檔案的訪問。 pod終止後,共享卷被破壞,因此它不是真正持久資料的好解決方案。
持久卷是一種機制,用於抽象與pod生命週期無關的更強大的儲存。相反,它們允許管理員為群集配置儲存資源,使用者可以請求並宣告正在執行的Pod。使用持久卷完成pod後,卷的回收策略將確定是否保留卷,直到手動刪除或立即刪除資料。永續性資料可用於防止基於節點的故障,並分配比本地可用的儲存量更大的儲存量。
標籤和註釋
與其他概念相關但與其他概念無關的Kubernetes組織抽象是標記。 Kubernetes中的標籤是一個語義標籤,可以附加到Kubernetes物件上,以將它們標記為組的一部分。然後,可以在針對管理或路由的不同例項進行選擇時選擇這些。例如,每個基於控制器的物件使用標籤來標識它們應該操作的pod。服務使用標籤來理解他們應該將請求路由到的後端pod。
標籤以簡單的鍵值對的形式給出。每個單元可以有多個標籤,但每個單元每個鍵只能有一個條目。通常,“名稱”鍵用作通用識別符號,但您還可以通過開發階段,公共可訪問性,應用程式版本等其他標準對物件進行分類。
註釋是一種類似的機制,允許您將任意鍵值資訊附加到物件。雖然標籤應該用於將pod與選擇標準匹配的語義資訊,但註釋更自由,並且可以包含更少的結構化資料。通常,註釋是一種向物件新增豐富元資料的方法,這對於選擇目的沒有幫助。
結論
Kubernetes是一個令人興奮的專案,它允許使用者在高度抽象的平臺上執行可伸縮的、高度可用的容器化工作負載。雖然Kubernetes的體系結構和內部元件集乍一看可能令人生畏,但它們的功能、靈活性和健壯的特性集在開源領域是無與倫比的。通過了解基本構建塊是如何組合在一起的,您可以開始設計系統,充分利用平臺的功能來按比例執行和管理工作負載。