介紹
Kubernetes是一個強大的開源系統,最初由Google開發,並得到Cloud Native Computing Foundation(CNCF)的支持,用於在叢集環境中管理容器化應用程序。它旨在提供更好的方法來管理相關的、分佈式的組件和服務,跨越各種基礎設施。如果您想了解更多關於Kubernetes的信息,請探索以下指南。如果您正在尋找受管理的Kubernetes主機服務,請查看我們為增長而打造的簡單、受管理的Kubernetes服務。
在本指南中,我們將討論什麼是Kubernetes,一些Kubernetes的基本概念。我們將討論系統的架構、它解決的問題,以及它用於處理容器化部署和擴展的模型。
什麼是Kubernetes?
Kubernetes,在其基本水平上,是一個用於在機器叢集上運行和協調容器化應用程序的系統。它是一個設計用來完全管理容器化應用程序和服務的生命周期的平台,使用提供可預測性、可擴展性和高可用性的方法。
作為 Kubernetes 用戶,您可以定義應用程序運行的方式,以及它們應該如何與其他應用程序或外部世界進行交互。您可以將服務進行擴展或縮減,執行優雅的滾動更新,並在不同版本的應用程序之間切換流量,以測試功能或回滾有問題的部署。Kubernetes 提供了界面和可組合的平台基元,讓您以高度靈活、強大和可靠的方式定義和管理應用程序。
Kubernetes 架構
要理解 Kubernetes 如何提供這些功能,有助於對其在高層次上的設計和組織方式有所了解。Kubernetes 可以被視為一個分層構建的系統,每一個更高的層次都在抽象化下一層中找到的複雜性。
在其基礎上,Kubernetes 將單個物理或虛擬機器通過共享網絡聚合成一個集群,以便在每台服務器之間進行通信,無論是物理還是虛擬機器。這個 Kubernetes 集群是配置所有 Kubernetes 組件、功能和工作負載的物理平台。
Kubernetes 集群中的機器都被賦予了 Kubernetes 生態系統中的角色。一台服務器(在高可用性部署中可能是一小組服務器)充當 主 服務器。這台服務器通過為用戶和客戶端暴露 Kubernetes API,健康檢查其他服務器,決定最佳的工作分配方式(稱為“調度”),並協調其他組件之間的通信(有時稱為容器編排)來充當集群的門戶和大腦。主服務器是與集群進行主要接觸的點,負責大部分 Kubernetes 提供的集中式邏輯。
集群中的其他機器被指定為 節點:負責使用本地和外部資源接受和運行工作負載的服務器。為了幫助隔離、管理和靈活性,Kubernetes 在 容器 中運行應用程序和服務,因此每個節點都需要配備容器運行時(如 Docker 或 rkt)。節點從主服務器接收工作指令,並相應地創建或銷毀容器,調整網絡規則以適當地路由和轉發流量。
如上所述,應用程式和服務本身在容器內的集群上運行。底層組件確保應用程式的期望狀態與集群的實際狀態相匹配。使用者通過與主要的 Kubernetes API 伺服器直接通信或使用客戶端和庫來與集群互動。要啟動應用程式或服務,需要提交一個以 JSON 或 YAML 定義要創建什麼以及如何管理的聲明計劃。然後,主伺服器接受計劃並通過檢查系統的需求和當前狀態來決定如何在基礎設施上運行它。根據指定計劃運行的這組用戶定義的應用程式代表 Kubernetes 的最終層。
主伺服器組件
如上所述,主伺服器充當 Kubernetes 集群的主要控制平面。它作為管理員和使用者的主要接觸點,還為相對不複雜的工作節點提供了許多集群範圍的系統。總的來說,主伺服器上的組件共同工作,接受用戶請求,確定最佳的工作負載容器調度方式,驗證客戶端和節點,調整集群範圍的網絡,以及管理擴展和健康檢查責任。
這些組件可以安裝在單台機器上,也可以分佈在多台伺服器上。我們將在本節中研究與 Kubernetes 集群的主控伺服器相關的每個獨立組件。
etcd
Kubernetes 運行所需的基本組件之一是一個全球可用的配置存儲。由 CoreOS 團隊(操作系統)開發的etcd項目是一個輕量級的、分佈式鍵值存儲,可以配置為跨多個節點擴展。
Kubernetes 使用 etcd
存儲配置數據,這些數據可被集群中的每個節點訪問。這可用於服務發現,並可幫助組件根據最新信息進行配置或重新配置自身。它還通過提供簡單的 HTTP/JSON API 來幫助維護集群狀態,例如領導者選舉和分佈式鎖定。
與控制平面中的大多數其他組件一樣,etcd
可以配置在單個主控伺服器上,或者在生產情況下分佈在多台機器上。唯一的要求是它必須對每台 Kubernetes 機器都可通過網絡訪問。
kube-apiserver
其中最重要的主服務之一是 API 伺服器。這是整個叢集的主要管理點,因為它允許使用者配置 Kubernetes 的工作負載和組織單位。它還負責確保 etcd
存儲和已部署容器的服務詳細信息一致。它充當各種組件之間的橋樑,以維護叢集健康狀態並傳播信息和命令。
API 伺服器實現了一個 RESTful 介面,這意味著許多不同的工具和庫可以輕鬆地與其通信。一個名為 kubectl 的客戶端可作為從本地計算機與 Kubernetes 叢集交互的默認方法。
kube-controller-manager
控制器管理器是一個通用服務,負責許多職責。主要地,它管理不同的控制器,調節叢集的狀態,管理工作負載生命週期並執行常規任務。例如,複製控制器確保 pod 的副本(相同的副本)數量與當前在叢集上部署的數量匹配。這些操作的詳細信息寫入 etcd
,其中控制器管理器通過 API 伺服器觀察更改。
當發生變化時,控制器會讀取新資訊並執行程序,以滿足所需的狀態。這可能涉及應用程式的擴展或縮減,調整端點等。
kube-scheduler
實際將工作負載分配給集群中特定節點的過程是調度器。該服務會讀取工作負載的操作需求,分析當前的基礎架構環境,並將工作負載放置在可接受的節點上。
調度器負責跟蹤每個主機上的可用容量,以確保工作負載不會超出可用資源。調度器必須知道每台伺服器上已分配給現有工作負載的總容量以及資源。
cloud-controller-manager
Kubernetes可以部署在許多不同的環境中,並且可以與各種基礎架構提供者進行交互,以了解和管理集群中資源的狀態。儘管Kubernetes使用資源的通用表示形式,例如可附加的儲存和負載平衡器,但它需要一種方法將這些映射到非同質雲提供者提供的實際資源。
雲控制器管理器充當了將 Kubernetes 與具有不同功能、特性和 API 的提供商進行交互的”黏合劑”,同時在內部保持相對通用的構造。這使得 Kubernetes 能夠根據從雲提供商獲取的信息更新其狀態信息,根據系統中需要的變更調整雲資源,並創建和使用其他雲服務來滿足提交給集群的工作需求。
節點伺服器元件
在 Kubernetes 中,通過運行容器執行工作的伺服器稱為節點。節點伺服器具有與主元件通信、配置容器網絡和運行分配給它們的實際工作負載所必需的一些要求。
A Container Runtime
每個節點必須擁有的第一個組件是容器運行時。通常,這個要求是通過安裝和運行Docker來滿足的,但也有其他選擇,如rkt和runc。
容器运行时负责启动和管理容器,即在相对隔离但轻量级操作环境中封装的应用程序。集群中的每个工作单元,在基本层面上都是作为一个或多个容器来实现的,这些容器必须被部署。每个节点上的容器运行时是最终运行提交到集群的工作负载中所定义的容器的组件。
kubelet
与集群组的每个节点的主要接触点是一个名为kubelet的小型服务。该服务负责将信息传递到控制平面服务,以及与etcd
存储交互,读取配置详情或写入新值。
kubelet
服务与主控组件通信,进行集群认证并接收命令和工作。工作以清单的形式接收,其中定义了工作负载和操作参数。然后,kubelet
进程负责在节点服务器上维护工作状态。它控制容器运行时以根据需要启动或销毁容器。
kube-proxy
管理單個主機子網路並使服務可用於其他組件,需要在每個節點伺服器上運行一個名為 kube-proxy 的小型代理服務。該流程將請求轉發到正確的容器,可以進行基本的負載平衡,通常負責確保網絡環境是可預測和可訪問的,但在適當的情況下是隔離的。
Kubernetes物件和工作負載
雖然容器是部署容器化應用程序的基礎機制,但Kubernetes在容器界面上使用額外的抽象層,提供了伸縮性、復原性和生命周期管理功能。用戶不是直接管理容器,而是定義並與由Kubernetes物件模型提供的各種基元組成的實例進行交互。我們將在下面介紹可以用來定義這些工作負載的不同類型的物件。
Pods
A pod is the most basic unit that Kubernetes deals with. Containers themselves are not assigned to hosts. Instead, one or more tightly coupled containers are encapsulated in an object called a pod.
A pod generally represents containers that should be controlled as a single application. Pods consist of containers that operate closely together, share a life cycle, and should always be scheduled on the same node. They are managed entirely as a unit and share their environment, volumes, and IP space. In spite of their containerized implementation, you should generally think of pods as a single, monolithic application to best conceptualize how the cluster will manage the pod’s resources and scheduling.
通常,Pod 包含滿足工作負載一般目的的主要容器,以及可選的一些輔助容器,這些容器有助於執行與主要應用密切相關的任務。這些是受益於在自己的容器中運行和管理的程序,但與主要應用程序緊密關聯。例如,一個 Pod 可能有一個容器運行主要應用程序服務器,還有一個輔助容器,在外部存儲庫檢測到變更時,將文件下載到共享文件系統中。通常不建議在 Pod 級別上進行水平擴展,因為有其他更適合此任務的更高級別對象。
通常,用戶不應該自行管理 Pod,因為它們不提供應用程序通常所需的某些功能(如複雜的生命周期管理和擴展)。相反,鼓勵用戶與使用 Pod 或 Pod 模板作為基本組件但實現額外功能的更高級別對象一起工作。
複製控制器和複製集
在使用 Kubernetes 時,通常不是單獨管理單個 Pod,而是管理相同的、複製的 Pod 群組。這些從 Pod 模板創建,並且可以通過稱為複製控制器和複製集的控制器進行水平擴展。
A replication controller is an object that defines a pod template and control parameters to scale identical replicas of a pod horizontally by increasing or decreasing the number of running copies. This is an easy way to distribute load and increase availability natively within Kubernetes. The replication controller knows how to create new pods as needed because a template that closely resembles a pod definition is embedded within the replication controller configuration.
複製控制器負責確保部署在集群中的Pod數量與其配置中的Pod數量相匹配。如果Pod或底層主機失敗,控制器將啟動新的Pod來進行補償。如果控制器配置中的副本數量發生變化,控制器將啟動或終止容器以匹配所需的數量。複製控制器還可以執行滾動更新,逐個將一組Pod升級到新版本,從而將對應用程序可用性的影響降到最低。
複製集是對複製控制器設計的一種迭代,具有更大的靈活性,控制器可以更好地識別其應管理的Pod。由於複製集具有更大的副本選擇能力,它們開始取代複製控制器,但無法像複製控制器那樣進行滾動更新以將後端循環到新版本。相反,複製集應該用於提供該功能的其他更高級別的單元內。
與Pod一樣,複製控制器和複製集都很少直接使用。儘管它們建立在Pod設計的基礎上,以增加水平擴展和可靠性保證,但它們缺少一些在更複雜對象中找到的精細的生命週期管理能力。
部署
部署是直接创建和管理的最常见工作负载之一。 部署使用复制集作为构建模块,为其中添加了灵活的生命周期管理功能。
虽然使用复制集构建的部署可能看起来重复了复制控制器提供的功能,但部署解决了滚动更新实现中存在的许多问题。 使用复制控制器更新应用程序时,用户需要提交一个新的复制控制器计划,以替换当前的控制器。 当使用复制控制器时,像跟踪历史记录、在更新期间从网络故障中恢复以及回滚错误更改这样的任务要么很困难,要么由用户负责。
部署是一种高级对象,旨在简化复制的Pod的生命周期管理。 通过更改配置,可以轻松修改部署,Kubernetes将调整复制集,管理不同应用程序版本之间的过渡,并可选择自动维护事件历史记录和撤消功能。 由于这些特性,部署很可能是您最频繁使用的Kubernetes对象类型。
有状态集
有狀態集是專門的 Pod 控制器,提供排序和唯一性保證。主要用於在部署順序、持久數據或穩定網絡方面有特殊需求時提供更精細的控制。例如,有狀態集通常與數據導向應用程序(如需要訪問相同卷的數據庫)相關聯,即使重新調度到新節點,它們也需要訪問相同的卷。
有狀態集通過為每個 Pod 創建唯一的基於數字的名稱來提供穩定的網絡標識符,即使需要將 Pod 移動到另一個節點,這個標識符也會持續存在。同樣,持久存儲卷可以在重新調度時與 Pod 轉移。這些卷在 Pod 被刪除後仍然存在,以防止意外數據丟失。
在部署或調整規模時,有狀態集根據其名稱中的編號標識符執行操作。這提供了更大的可預測性和對執行順序的控制,這在某些情況下非常有用。
守護進程集
守護進程集是另一種特殊形式的 Pod 控制器,它在集群中的每個節點上運行一個 Pod 的副本(如果指定,也可以是子集)。這在部署幫助執行維護並為 Kubernetes 節點本身提供服務的 Pod 時最為有用。
例如,收集和轉發日誌、聚合指標和運行增強節點本身功能的服務是常見的守護進程集的候選項。由於守護進程集通常提供基本服務並且需要在整個系統中運行,它們可以繞過Pod調度限制,防止其他控制器將Pod分配給特定主機。例如,由於其獨特的責任,主服務器經常配置為無法進行正常的Pod調度,但是守護進程集可以覆蓋Pod層面的限制,以確保重要服務正在運行。
工作和Cron工作
到目前為止,我們描述的工作負載都假定具有長期運行的類似服務的生命周期。Kubernetes使用稱為工作的工作負載提供基於任務的工作流程,其中運行的容器預計在完成工作後的某個時間內成功退出。如果您需要執行一次性或批處理作業,則工作非常有用,而不是運行持續服務。
在工作中建構的是cron工作。像是在 Linux 和類 Unix 系統上的傳統 cron
守護程序一樣,透過 Kubernetes 的 cron 工作提供了一個介面,可以按照排程運行工作。Cron 工作可以用來安排工作在未來執行,或定期、定期地執行。Kubernetes cron 工作基本上是對經典的 cron 行為的重新實現,使用集群作為平台,而不是單個操作系統。
其他 Kubernetes 組件
除了您可以在集群上運行的工作負載之外,Kubernetes 還提供了一些其他抽象,幫助您管理應用程序、控制網絡並實現持久性。我們將在這裡討論一些比較常見的例子。
Kubernetes 服務
到目前為止,我們一直在使用“服務”這個術語,按照傳統的 Unix-like 觀點:用於表示長期運行的進程,通常是網絡連接的,能夠回應請求。但是,在 Kubernetes 中,服務是一個作為基本內部負載均衡器和代理人的組件,用於 pod。服務將執行相同功能的 pod 邏輯集合組合在一起,以將它們呈現為單個實體。
這使您能夠部署一個能夠跟踪並路由到特定類型的所有後端容器的服務。內部使用者只需要知道服務提供的穩定端點。同時,服務抽象允許您根據需要擴展或替換後端工作單元。一個服務的 IP 地址保持穩定,無論它路由到的 pods 如何更改。通過部署一個服務,您可以輕鬆獲得可發現性並簡化您的容器設計。
每當您需要向另一個應用程序或外部使用者提供對一個或多個 pods 的訪問時,您應該配置一個服務。例如,如果您有一組正在運行 Web 伺服器的 pods,應該從互聯網訪問,服務將提供必要的抽象。同樣地,如果您的 Web 伺服器需要存儲和檢索數據,您會想要配置一個內部服務,讓它們可以訪問您的數據庫 pods。
儘管服務默認僅可使用內部可路由的 IP 地址,但可以通過選擇幾種策略之一來在集群外部提供服務。 NodePort 配置通過在每個節點的外部網絡界面上打開一個靜態端口來工作。對外端口的流量將自動路由到適當的 pods,使用內部集群 IP 服務。
或者,LoadBalancer 服務類型創建一個外部負載均衡器,通過雲提供商的 Kubernetes 負載均衡器集成來路由到服務。雲控制器管理器將創建適當的資源並使用內部服務地址進行配置。
卷和持久卷
在許多容器化環境中,可靠地共享數據並保證其在容器重新啟動時可用是一項挑戰。容器運行時通常提供一些機制來將存儲附加到容器,以使其在容器的生命周期之外持久存在,但實現通常缺乏靈活性。
為了解決這個問題,Kubernetes 使用自己的卷抽象,允許數據被所有容器在一個 pod 內共享,並保持可用直到 pod 被終止。這意味著緊密耦合的 pods 可以輕鬆共享文件,而無需複雜的外部機制。 pod 內的容器失敗不會影響對共享文件的訪問。一旦 pod 被終止,共享卷就會被銷毀,因此它不適用於真正的持久數據。
持久卷是一種用於抽象更健壯存儲的機制,不與 pod 的生命周期綁定。相反,它們允許管理員為集群配置存儲資源,用戶可以為他們運行的 pods 請求並聲明。一旦一個 pod 使用完一個持久卷,卷的回收策略決定了卷是否保留到手動刪除或立即刪除數據。持久數據可用於防範基於節點的故障,並分配比本地可用的更大量的存儲空間。
標籤和註釋
A Kubernetes organizational abstraction related to, but outside of the other concepts, is labeling. A label in Kubernetes is a semantic tag that can be attached to Kubernetes objects to mark them as a part of a group. These can then be selected for when targeting different instances for management or routing. For instance, each of the controller-based objects use labels to identify the pods that they should operate on. Services use labels to understand the backend pods they should route requests to.
標籤被賦予為簡單的鍵-值對。每個單元可以擁有多個標籤,但每個單元只能有一個每個鍵的條目。通常,”name” 鍵被用作通用標識符,但您還可以通過其他標準(如開發階段、公共可訪問性、應用程序版本等)進行對對象的分類。
註釋是一種類似的機制,允許您將任意鍵-值信息附加到對象上。雖然標籤應該用於與選擇標準匹配有用的語義信息,但註釋更自由形式,可以包含結構不太嚴謹的數據。通常,註釋是向對象添加豐富元數據的一種方式,但對於選擇目的並不有用。
結論
Kubernetes 是一個令人振奮的項目,它允許用戶在高度抽象的平台上運行可擴展、高可用的容器化工作負載。儘管 Kubernetes 的架構和一系列內部組件一開始可能讓人感到困惑,但它們的強大、靈活性和健壯的功能集在開源世界和雲原生開發領域中無與倫比。通過了解基本構建塊如何配合,您可以開始設計系統,充分利用平台的能力來運行和管理大規模的工作負載,打造出令人驚嘆的雲原生應用程式。
Source:
https://www.digitalocean.com/community/tutorials/an-introduction-to-kubernetes