日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(译)An introduction to Kubernetes

發布時間:2023/12/4 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (译)An introduction to Kubernetes 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文:https://www.jeremyjordan.me/kubernetes/(博客園團隊推薦的)

這篇博客文章將對Kubernetes進行介紹,以便您了解該工具背后的動機,含義以及使用方式。在后續文章中,我將討論如何使用更具體的(數據科學)示例來利用Kubernetes增強數據科學工作負載。但是,這有助于您首先了解基本原理-這是本文的重點。

先決條件:我將假設您熟悉Docker等容器技術。如果您沒有構建和運行容器映像的經驗,建議您先熟悉之后,在繼續閱讀本文

總覽

這是我們將在本文中討論的內容。

Kubernetes有什么意義?

Kubernetes通常被描述為容器編排平臺。為了理解確切的含義,它有助于重新審視容器的用途,缺少的內容以及Kubernetes如何填補這一空白。

注意:您還將看到Kubernetes其簡稱numeronym,K8S。這意味著同一件事,只是更容易鍵入。

為什么我們喜歡容器?容器提供了一種輕量級的機制來隔離應用程序的環境。對于給定的應用程序,我們可以指定要安裝的系統配置和庫,而不必擔心與可能在同一臺物理計算機上運行的其他應用程序產生沖突。我們將每個應用程序封裝為容器映像container image)可以在任何機器上可靠地執行*(只要它能夠運行容器映像),從而為我們提供了可移植性,以實現從開發到部署的平穩過渡。此外,由于每個應用程序都是獨立的,無需擔心環境沖突,因此將多個工作負載放置在同一臺物理計算機上并實現更高的資源(內存和CPU)利用率更加容易-最終降低了成本。

缺少的東西?但是,如果您的容器死了怎么辦?甚至更糟的是,如果運行您的容器的計算機發生故障,會發生什么?容器沒有提供容錯(fault tolerance解決方案。或者,如果您有多個需要通信的容器,該如何在容器之間實現聯網?當您旋轉單個容器時,此變化如何?容器網絡(networking?)很容易變成一團糟。最后,假設您的生產環境由多臺機器組成-您如何決定使用哪臺機器來運行容器?

Kubernetes作為容器編排平臺。我們可以使用容器編排平臺解決上述許多問題。

樂團的負責人擁有音樂表演的愿景,并與音樂家溝通,以協調他們個人的樂器演奏,以實現總體愿景。作為系統的架構師,您的工作只是簡單地創作音樂(指定要運行的容器),然后將控制權移交給樂團總監(容器編排平臺)以實現該愿景。

容器編排平臺管理單個容器的整個生命周期,根據需要擴展和關閉資源。如果某個容器意外關閉,編排平臺將通過在其位置啟動另一個容器來作出反應。

最重要的是,編排平臺為應用程序之間的通信提供了一種機制,即使底層的單個容器被創建和銷毀也是如此。

最后,在給定(1)一組要運行的容器工作負載和(2)集群上的一組計算機的情況下,容器協調器將檢查每個容器并確定最佳的計算機來調度該工作負載。要了解為什么這很有價值,請觀看Kelsey Hightower(17:47-20:55)使用俄羅斯方塊示例游戲來說明自動化部署和容器編排之間的區別。

設計原則。

現在我們大致了解了容器編排的動機,讓我們花一些時間來討論Kubernetes背后的動機設計原則。它有助于理解這些原理,以便您可以按預期使用該工具。

陳述式

也許Kubernetes中最重要的設計原則是,我們僅定義系統的期望狀態,并讓Kubernetes自動化工作以確保系統的實際狀態反映這些期望。這使您免于在大多數事物損壞時進行修復的責任;你只需說明你的系統是什么應該看起來像一個理想的狀態。Kubernetes將檢測到系統的實際狀態何時不符合這些期望,它將代表您進行干預以解決問題。這使我們的系統能夠自我修復并對問題做出反應,而無需人工干預。

系統的“狀態”由一組對象定義。每個Kubernetes對象具有(1)一個規范在其中提供所期望的狀態和(2)的狀態反映了對象的當前狀態。Kubernetes維護所有對象規范的列表,并不斷輪詢每個對象,以確保其狀態與規范相等。如果對象無響應,Kubernetes將啟動一個新版本來替換它。如果對象的狀態偏離了規范,Kubernetes將發出必要的命令以將該對象驅動回到其所需狀態。

分布式

對于一定的操作規模,有必要將您的應用程序設計為分布式系統。Kubernetes旨在為此類分布式系統提供基礎設施層,產生干凈的抽象以在一組機器(統稱為集群)之上構建應用程序。更具體地說,Kubernetes提供了一個用于與該集群交互的統一界面,因此您不必擔心與每臺機器進行單獨通信。

解耦

容器開發通常建議單一關注。結果,開發容器化應用程序非常適合微服務架構設計模式,該模式建議“將軟件應用程序設計為可獨立部署的服務套件”。

Kubernetes中提供的抽象自然支持分離服務的思想,該服務可以獨立縮放和更新。這些服務在邏輯上是分開的,并通過定義良好的API進行通信。這種邏輯上的分離使團隊可以更快地將更改部署到生產中,因為每個服務都可以在獨立的發布周期內運行(前提是他們遵守現有的API合約)。

不變的基礎設施

為了從容器和容器編排中獲得最大收益,您應該部署不可變的基礎結構。這是不是應該登錄到計算機上的容器以進行更改(例如,更新庫),而是應該構建新的容器映像,部署新版本并終止舊版本。在項目的生命周期(開發->測試->生產)中跨環境過渡時,您應該使用相同的容器映像,并且只能修改容器映像外部的配置(例如,通過安裝配置文件)。

這一點非常重要,因為容器被設計為短暫的,隨時可以被另一個容器實例替換。如果您的原始容器處于突變狀態(例如,手動配置),但是由于運行狀況檢查失敗而被關閉,則在其位置旋轉的新容器不會反映這些手動更改,并可能破壞您的應用程序。

當您維護不可變的基礎結構時,將應用程序回滾到以前的狀態(例如,如果發生錯誤)也變得更加容易-您可以簡單地更新配置以使用較舊的容器映像。

Kubernetes中的基本對象。

之前,我提到過,我們通過Kubernetes?對象的集合描述了系統的期望狀態。到目前為止,我們對Kubernetes的討論還相對抽象和高層次。在本節中,我們將通過覆蓋Kubernetes中可用的基本對象,深入探討有關如何在Kubernetes上部署應用程序的更多細節。

可以使用YAMLJSON文件定義Kubernetes對象。這些定義對象的文件通常稱為清單(manifests。將這些清單保留在版本控制的存儲庫中是一個好習慣,該存儲庫可作為有關集群上正在運行哪些對象的唯一事實來源。

Pod

pod對象是Kubernetes的基本構建塊,由一個或多個(緊密相關的)的容器,一個共享的網絡層,和共享文件系統的卷。與容器類似,Pods被設計為短暫的-不會期望特定的單個POD會長期存在。

通常,您不會在清單中顯式創建Pod對象,因為使用更高級的組件來為您管理Pod對象通常更簡單。

部署方式

一個部署對象包括由模板和副本數量(模板的多少副本,我們要運行)定義的pods的集合。您可以為副本數設置特定的值,也可以使用單獨的Kubernetes資源(例如,水平Pod自動縮放器)根據系統指標(例如CPU利用率)來控制副本數。

注意:Deployment對象的控制器實際上在內部創建了另一個對象ReplicaSet。但是,這是作為用戶從您那里抽象出來的。

雖然您不能依賴任何一個Pod來無限期地運行,但是您可以依靠集群將始終嘗試使n個Pod可用的事實(其中n由您指定的副本數定義)。?如果我們有一個部署的副本數為10的Deployment,并且其中3個Pod因機器故障而崩潰,那么將安排另外3個Pod在群集中的另一臺計算機上運行。因此,Deployment最適合無狀態應用程序,在這些應用程序中Pod可以隨時更換而不會損壞。

以下YAML文件提供了有關如何定義Deployment對象的帶注釋的示例。在此示例中,我們要運行一個容器的10個實例,該實例通過REST接口提供ML模型。

注意:為了讓Kubernetes知道此工作負載可能有多計算密集型,我們還應該在Pod模板規范中提供資源限制。

部署還允許我們指定當我們有新版本的容器映像時我們希望如何推出更新;這篇博客文章很好地概述了您的不同選擇。如果我們想覆蓋默認值,我們將strategy在object下包含一個附加字段spec。Kubernetes將確保正常關閉運行舊容器映像的Pod并啟動運行新容器映像的新Pod

服務

Kubernetes中的每個Pod都分配有一個唯一的IP地址,我們可以用來與之通信。但是,由于Pod是短暫的,因此很難將流量發送到所需的容器。例如,讓我們考慮上面的“部署”,其中有10Pod運行一個容器,通過REST為機器學習模型提供服務。如果作為部署的一部分運行的Pod集合可以隨時更改,我們如何與服務器可靠地通信?這是服務對象輸入圖片的地方。Kubernetes服務為您提供了一個穩定的端點,即使由于更新,擴展和故障導致確切的基礎Pod發生變化,它也可以用于將流量引導到所需的Pod。服務根據標簽知道應將流量發送到哪個Pod?(鍵值對),我們在Pod元數據中定義。

注意:這篇博客文章很好地解釋了如何實際路由流量。

在此示例中,我們的服務使用標簽將流量發送到所有健康的Pod?app="ml-model"。

以下YAML文件提供了一個示例,說明了我們如何圍繞早期的Deployment示例包裝Service。


Ingress

盡管“服務”使我們可以在穩定的終結點后面公開應用程序,但該終結點僅可用于內部群集通信。如果我們想將應用程序暴露給集群外部的流量,則需要定義一個Ingress對象。

這種方法的好處在于,您可以選擇公開哪些服務。例如,假設除了我們的機器學習模型服務外,我們還有一個UI,該UI利用了模型的預測作為大型應用程序的一部分。我們可能選擇僅使UI可用于公共流量,從而阻止用戶直接查詢服務模型服務。

以下YAML文件為上述示例定義了一個Ingress對象,使UI可以公開訪問。

Job

到目前為止,我已經描述過的Kubernetes對象可以組成可靠的,長期運行的服務。相反,當您要執行離散任務時,Job對象很有用。例如,假設我們想根據前一天收集的信息每天重新訓練模型。每天,我們都希望啟動一個容器來執行預定義的工作負載(例如train.py腳本),然后在培訓結束時關閉它。喬布斯為我們提供了做到這一點的能力!如果由于某種原因我們的容器在完成腳本之前崩潰了,Kubernetes將通過在其位置啟動一個新Pod來完成工作來做出反應。對于Job對象,對象的“所需狀態”是作業的完成。

以下YAML定義了一個用于訓練機器學習模型的示例Job(假設在中定義了訓練代碼train.py)。

注意:此作業規范將僅執行一次訓練。如果我們想每天執行此作業,則可以定義一個CronJob對象。

...還有很多

上面討論的對象當然不是Kubernetes中可用資源類型的詳盡列表。在部署應用程序時,您可能會發現有用的其他一些對象包括:

  • Volume:用于管理安裝在Pod上的目錄

  • Secret:用于存儲敏感憑證

  • NameSpace:用于分隔群集上的資源

  • ConfigMap:用于指定要作為文件掛載的應用程序配置值

  • HorizontalPodAutoscaler:用于基于現有Pod的當前資源利用率擴展部署

  • StatefulSet:與Deployment類似,但適用于需要運行有狀態應用程序的情況

怎么樣?Kubernetes control plane(控制平面)。

至此,您可能想知道Kubernetes如何能夠采用我們所有的對象規范并在集群上實際執行這些工作負載。在本節中,我們將討論組成Kubernetes 控制平面的組件,這些組件控制如何在集群上執行,監視和維護工作負載。

在深入研究之前,重要的是區分集群上的兩類計算機:

  • 一個master node主節點包含了大部分,這使得我們的控制平面,我們將在下面討論的組件。在大多數中等大小的集群中,您只有一個主節點,盡管可以有多個主節點來實現高可用性。如果您使用云提供商的托管Kubernetes服務,則它們通常會抽象化主節點,而您不必進行管理或為此付費。

  • 一個worker node工作節點是實際運行我們的應用程序工作負載的機器。可以針對集群上的不同類型的工作負載量身定制多種不同的計算機類型。例如,您可能具有一些GPU優化的節點以進行更快的模型訓練,然后使用CPU優化的節點進行服務。定義對象規格時,可以指定有關將工作負載分配給哪種機器的首選項。

現在,讓我們深入了解主節點上的主要組件。與Kubernetes通信以提供新的或更新的對象規范時,您正在與API服務器進行通信。

更具體地說,API服務器驗證更新對象的請求,并充當有關集群當前狀態的問題的統一接口。但是,集群的狀態存儲在etcd(分布式鍵值存儲)中。我們將使用etcd來保存有關以下信息:集群配置,對象規范,對象狀態,集群上的節點以及分配對象在哪些節點上運行。

注意:etcd是我們控制平面中唯一的有狀態組件,所有其他組件都是無狀態的。

說到應該在哪里運行對象,調度程序scheduler?負責確定這一點!調度程序將詢問API服務器(然后將與etcd通信)尚未分配給計算機的對象。然后,調度程序將確定這些對象應分配給哪些機器,并將回復API服務器以反映此分配(該分配將傳播到etcd)。

我們將在本文中討論的主節點上的最后一個組件是controller-manager,它通過API服務器監視集群的狀態,以查看集群的當前狀態是否符合我們的期望狀態。如果實際狀態與我們的期望狀態不同,則控制器管理器將通過API服務器進行更改,以嘗試將集群驅動到期望狀態。控制器管理器由一組控制器controllers定義,每個負責管理集群上特定資源類型的對象。在非常高的級別上,控制器將監視存儲在etcd中的特定資源類型(例如,部署),并為應運行的Pod創建規范以實現對象的所需狀態。然后,控制者有責任確保這些吊艙在運行時保持健康,并在需要時關閉。

總結到目前為止我們所涵蓋的內容...

接下來,讓我們討論在工作程序節點上運行的控制平面組件。我們的工作程序節點上可用的大多數資源都花在了運行我們的實際應用程序上,但是我們的節點確實需要知道他們應該運行哪些Pod,以及如何與其他計算機上的Pod通信。我們將討論的控制平面的兩個最后組成部分恰好涵蓋了這兩個方面。

kubelet作為一個節點的“代理人”,其與API服務器進行通信,以查看哪些容器工作量被分配到節點。然后,它負責旋轉Pod以運行這些分配的工作負載。當節點首次加入集群時,kubelet負責向API服務器宣布節點的存在,以便調度程序可以為其分配容器。

最后,kube-proxy使容器能夠跨集群上的各個節點相互通信。該組件處理所有網絡問題,例如如何將流量轉發到適當的Pod。

希望到這一點,您應該能夠開始了解Kubernetes集群中事物的運行方式。所有組件都通過API服務器進行交互,我們將群集的狀態存儲在etcd中。有多種組件(通過API服務器)寫入etcd,以對集群進行更改,并且集群上的節點(通過API服務器)偵聽etcd,以查看其應運行的Pod。

整個系統的設計使故障對整個群集的影響最小。例如,如果我們的主節點發生故障,那么我們的應用程序都不會立即受到影響;在新的主節點上線之前,我們將無法對集群進行任何進一步的更改。

什么時候不應該使用Kubernetes?

與每項新技術一樣,你會花費一些時間,您了解它是如何工作的,以及它如何應用于您正在構建的應用程序時。問“我真的需要Kubernetes嗎?”是一個合理的問題。因此,我將嘗試提供一些答案可能為否的示例情況。

  • 您可以在單臺計算機上運行工作負載。(Kubernetes可以看作是構建分布式系統的平臺,但是如果不需要,則不應構建分布式系統!)

  • 您的計算需求不多。(在本例中,用于編排框架的計算相對較高!)

  • 您不需要高可用性,并且可以容忍停機時間。

  • 您不會想到對已部署的服務進行大量更改。

  • 您已經擁有一個滿意的有效工具棧。

  • 您擁有一個單體架構,不打算將其分成微服務。(這可以回到原本打算使用的工具的狀態。)

  • 您閱讀了這篇文章,并認為“這很復雜”而不是“這很有用”。

  • 參考:
  • 朱莉婭·埃文斯(Julia Evans)-Kubernetes很酷的原因(https://jvns.ca/blog/2017/10/05/reasons-kubernetes-is-cool/)

  • 朱莉婭·埃文斯(Julia Evans)-我對Kubernetes的一些了解(Julia的雜志對我的視覺解釋Kubernetes控制平面有很大的啟發)(https://jvns.ca/blog/2017/06/04/learning-about-kubernetes/)

總結

以上是生活随笔為你收集整理的(译)An introduction to Kubernetes的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。