中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

從零開始入門 K8s | K8s 的應用編排與管理

發布時間:2020-08-15 11:52:26 來源:ITPUB博客 閱讀:152 作者:阿里系統軟件技術 欄目:云計算

從零開始入門 K8s | K8s 的應用編排與管理

作者 | 張振 阿里云高級技術專家

一、資源元信息

1. Kubernetes 資源對象

我們知道,Kubernetes 的資源對象組成:主要包括了 Spec、Status 兩部分。其中 Spec 部分用來描述期望的狀態,Status 部分用來描述觀測到的狀態。
今天我們將為大家介紹 K8s 的另外一個部分,即元數據部分。該部分主要包括了用來識別資源的標簽:Labels, 用來描述資源的注解;Annotations, 用來描述多個資源之間相互關系的 OwnerReference。這些元數據在 K8s 運行中有非常重要的作用。

2. labels

第一個元數據,也是最重要的一個元數據——資源標簽。資源標簽是一種具有標識型的 Key:Value 元數據,如下圖所示,展示了幾個常見的標簽。
前三個標簽都打在了 Pod 對象上,分別標識了對應的應用環境、發布的成熟度和應用的版本。從應用標簽的例子可以看到,標簽的名字包括了一個域名的前綴,用來描述打標簽的系統和工具, 最后一個標簽打在 Node 對象上,還在域名前增加了版本的標識 beta 字符串。
標簽主要用來篩選資源和組合資源,可以使用類似于 SQL 查詢 select,來根據 Label 查詢相關的資源。
從零開始入門 K8s | K8s 的應用編排與管理

3. Selector

最常見的 Selector 就是相等型 Selector。現在舉一個簡單的例子:
假設系統中有四個 Pod,每個 Pod 都有標識系統層級和環境的標簽,我們通過 Tie:front 這個標簽,可以匹配左邊欄的 Pod,相等型 Selector 還可以包括多個相等條件,多個相等條件之間是邏輯”與“的關系。
在剛才的例子中,通過 Tie=front,Env=dev 的 Selector,我們可以篩選出所有 Tie=front,而且 Env=dev 的 Pod,也就是下圖中左上角的 Pod。另外一種 Selector 是集合型 Selector,在例子中,Selector 篩選所有環境是 test 或者 gray 的 Pod。
除了 in 的集合操作外,還有 notin 集合操作,比如 tie notin(front,back),將會篩選所有 tie 不是 front 且不是 back 的 Pod。另外,也可以根據是否存在某 lable 的篩選,如:Selector release,篩選所有帶 release 標簽的 Pod。集合型和相等型的 Selector,也可以用“,”來連接,同樣的標識邏輯”與“的關系。
從零開始入門 K8s | K8s 的應用編排與管理

4. Annotations

另外一種重要的元數據是:annotations。一般是系統或者工具用來存儲資源的非標示性信息,可以用來擴展資源的 spec/status 的描述,這里給了幾個 annotations 的例子:
第一個例子,存儲了阿里云負載器的證書 ID,我們可以看到 annotations 一樣可以擁有域名的前綴,標注中也可以包含版本信息。第二個 annotation存儲了 nginx 接入層的配置信息,我們可以看到 annotations 中包括“,”這樣無法出現在 label 中的特殊字符。第三個 annotations 一般可以在 kubectl apply 命令行操作后的資源中看到, annotation 值是一個結構化的數據,實際上是一個 json 串,標記了上一次 kubectl 操作的資源的 json 的描述。
從零開始入門 K8s | K8s 的應用編排與管理

5. Ownereference

最后一個元數據叫做 Ownereference。所謂所有者,一般就是指集合類的資源,比如說 Pod 集合,就有 replicaset、statefulset,這個將在后序的課程中講到。

集合類資源的控制器會創建對應的歸屬資源。比如:replicaset 控制器在操作中會創建 Pod,被創建 Pod 的 Ownereference 就指向了創建 Pod 的 replicaset,Ownereference 使得用戶可以方便地查找一個創建資源的對象,另外,還可以用來實現級聯刪除的效果。

二、操作演示

這里通過 kubectl 命令去連接我們 ACK 中已經創建好的一個 K8s 集群,然后來展示一下怎么查看和修改 K8s 對象中的元數據,主要就是 Pod 的一個標簽、注解,還有對應的 Ownerference。
首先我們看一下集群里現在的配置情況:
  1. 查看 Pod,現在沒有任何的一個 Pod;
  • kubectl get pods
  1. 然后用事先準備好的一個 Pod 的 yaml,創建一個 Pod 出來;
  • kubectl apply -f pod1.yaml
  • kubectl apply -f pod2.yaml
  1. 現在查看一下 Pod 打的標簽,我們用 --show-labels 這個選項,可以看到這兩個 Pod 都打上了一個部署環境和層級的標簽;
  • kubectl get pods —show-labels
  1. 我們也可以通過另外一種方式來查看具體的資源信息。首先查看 nginx1 第一個 Pod 的一個信息,用 -o  yaml 的方式輸出,可以看到這個 Pod 元數據里面包括了一個 lables 的字段,里面有兩個 lable;
  • kubectl get pods nginx1 -o yaml | less
  1. 現在再想一下,怎么樣對 Pod 已有的 lable 進行修改?我們先把它的部署環境,從開發環境改成測試環境,然后指定 Pod 名字,在環境再加上它的一個值 test ,看一下能不能成功。 這里報了一個錯誤,可以看到,它其實是說現在這個 label 已經有值了;
  • kubectl label pods nginx1 env=test
  1. 如果想覆蓋掉它的話,得額外再加上一個覆蓋的選項。加上之后呢,我們應該可以看到這個打標已經成功了;
  • kubectl label pods nginx1 env=test —overwrite
  1. 我們再看一下現在集群的 lable 設置情況,首先可以看到 nginx1 的確已經加上了一個部署環境 test 標簽;
  • kubectl get pods —show-labels
  1. 如果想要對 Pod 去掉一個標簽,也是跟打標簽一樣的操作,但是 env 后就不是等號了。只加上 label 名字,后面不加等號,改成用減號表示去除 label 的 k:v;
  • kubectl label pods nginx tie-
  1. 可以看到這個 label,去標已經完全成功;
  • kubectl get pods —show-labels
從零開始入門 K8s | K8s 的應用編排與管理
  1. 下面來看一下配置的 label 值,的確能看到 nginx1 的這個 Pod 少了一個 tie=front 的標簽。有了這個 Pod 標簽之后,可以看一下怎樣用 label Selector 進行匹配?首先 label Selector 是通過 -l 這個選項來進行指定的 ,指定的時候,先試一下用相等型的一個 label 來篩選,所以我們指定的是部署環境等于測試的一個 Pod,我們可以看到能夠篩選出一臺;
  • kubectl get pods —show-labels -l env=test
  1. 假如說有多個相等的條件需要指定的,實際上這是一個與的關系,假如說 env 再等于 dev,我們實際上是一個 Pod 都拿不到的;
  • kubectl get pods —show-labels -l env=test,env=dev
  1. 然后假如說 env=dev,但是 tie=front,我們能夠匹配到第二個 Pod,也就是 nginx2;
  • kubectl get pods —show-labels -l env=dev,tie=front
  1. 我們還可以再試一下怎么樣用集合型的 label Selector 來進行篩選。這一次我們還是想要匹配出所有部署環境是 test 或者是 dev 的一個 Pod,所以在這里加上一個引號,然后在括號里面指定所有部署環境的一個集合。這次能把兩個創建的 Pod 都篩選出來;
  • kubectl get pods —show-labels -l ’env in (dev,test)’
  1. 我們再試一下怎樣對 Pod 增加一個注解,注解的話,跟打標是一樣的操作,但是把 label 命令改成 annotate 命令;然后,一樣指定類型和對應的名字。后面就不是加上 label 的 k:v 了,而是加上 annotation 的 k:v。這里我們可以指定一個任意的字符串,比如說加上空格、加上逗號都可以;
  • kubectl annotate pods nginx1 my-annotate=‘my annotate,ok’
  1. 然后,我們再看一下這個 Pod 的一些元數據,我們這邊能夠看到這個 Pod 的元數據里面 annotations,這是有一個 my-annotate 這個 Annotations;
  • kubectl get pods nging1 -o yaml | less
然后我們這里其實也能夠看到有一個 kubectl apply 的時候,kubectl 工具增加了一個 annotation,這也是一個 json 串。
從零開始入門 K8s | K8s 的應用編排與管理
  1. 然后我們再演示一下看 Pod 的 Ownereference 是怎么出來的。原來的 Pod 都是直接通過創建 Pod 這個資源方式來創建的,這次換一種方式來創建:通過創建一個 ReplicaSet 對象來創建 Pod 。首先創建一個 ReplicaSet 對象,這個 ReplicaSet 對象可以具體查看一下;
  • kubectl apply -f rs.yaml
  • kubectl get replicasets  nginx-replicasets -o yaml |less
從零開始入門 K8s | K8s 的應用編排與管理
  1. 我們可以關注一下這個 ReplicaSet 里面 spec 里面,提到會創建兩個 Pod,然后 selector 通過匹配部署環境是 product 生產環境的這個標簽來進行匹配。所以我們可以看一下,現在集群中的 Pod 情況;
  • kubectl get pods
從零開始入門 K8s | K8s 的應用編排與管理
  1. 將會發現多了兩個 Pod,仔細查看這兩個 Pod,可以看到 ReplicaSet 創建出來的 Pod 有一個特點,即它會帶有 Ownereference,然后 Ownereference 里面指向了是一個 replicasets 類型,名字就叫做 nginx-replicasets;
  • kubectl get pods nginx-replicasets-rhd68 -o yaml | less
從零開始入門 K8s | K8s 的應用編排與管理

三、控制器模式

1. 控制循環

控制型模式最核心的就是控制循環的概念。在控制循環中包括了控制器、被控制的系統,以及能夠觀測系統的傳感器,三個邏輯組件。
當然這些組件都是邏輯的,外界通過修改資源 spec 來控制資源,控制器比較資源 spec 和 status,從而計算一個 diff,diff 最后會用來決定執行對系統進行什么樣的控制操作,控制操作會使得系統產生新的輸出,并被傳感器以資源 status 形式上報,控制器的各個組件將都會是獨立自主地運行,不斷使系統向 spec 表示終態趨近。

從零開始入門 K8s | K8s 的應用編排與管理

2. Sensor

控制循環中邏輯的傳感器主要由 Reflector、Informer、Indexer 三個組件構成。
Reflector 通過 List 和 Watch K8s server 來獲取資源的數據。List 用來在 Controller 重啟以及 Watch 中斷的情況下,進行系統資源的全量更新;而 Watch 則在多次 List 之間進行增量的資源更新;Reflector 在獲取新的資源數據后,會在 Delta 隊列中塞入一個包括資源對象信息本身以及資源對象事件類型的 Delta 記錄,Delta 隊列中可以保證同一個對象在隊列中僅有一條記錄,從而避免 Reflector 重新 List 和 Watch 的時候產生重復的記錄。
Informer 組件不斷地從 Delta 隊列中彈出 delta 記錄,然后把資源對象交給 indexer,讓 indexer 把資源記錄在一個緩存中,緩存在默認設置下是用資源的命名空間來做索引的,并且可以被 Controller Manager 或多個 Controller 所共享。之后,再把這個事件交給事件的回調函數
從零開始入門 K8s | K8s 的應用編排與管理
控制循環中的控制器組件主要由事件處理函數以及 worker 組成,事件處理函數之間會相互關注資源的新增、更新、刪除的事件,并根據控制器的邏輯去決定是否需要處理。對需要處理的事件,會把事件關聯資源的命名空間以及名字塞入一個工作隊列中,并且由后續的 worker 池中的一個 Worker 來處理,工作隊列會對存儲的對象進行去重,從而避免多個 Woker 處理同一個資源的情況。
Worker 在處理資源對象時,一般需要用資源的名字來重新獲得最新的資源數據,用來創建或者更新資源對象,或者調用其他的外部服務,Worker 如果處理失敗的時候,一般情況下會把資源的名字重新加入到工作隊列中,從而方便之后進行重試。

3. 控制循環例子-擴容

這里舉一個簡單的例子來說明一下控制循環的工作原理。
ReplicaSet 是一個用來描述無狀態應用的擴縮容行為的資源, ReplicaSet controler 通過監聽 ReplicaSet 資源來維持應用希望的狀態數量,ReplicaSet 中通過 selector 來匹配所關聯的 Pod,在這里考慮 ReplicaSet rsA 的,replicas 從 2 被改到 3 的場景。
從零開始入門 K8s | K8s 的應用編排與管理
首先,Reflector 會 watch 到 ReplicaSet 和 Pod 兩種資源的變化,為什么我們還會 watch pod 資源的變化稍后會講到。發現 ReplicaSet 發生變化后,在 delta 隊列中塞入了對象是 rsA,而且類型是更新的記錄。
Informer 一方面把新的 ReplicaSet 更新到緩存中,并與 Namespace nsA 作為索引。另外一方面,調用 Update 的回調函數,ReplicaSet 控制器發現 ReplicaSet 發生變化后會把字符串的 nsA/rsA 字符串塞入到工作隊列中,工作隊列后的一個 Worker 從工作隊列中取到了 nsA/rsA 這個字符串的 key,并且從緩存中取到了最新的 ReplicaSet 數據。
Worker 通過比較 ReplicaSet 中 spec 和 status 里的數值,發現需要對這個 ReplicaSet 進行擴容,因此 ReplicaSet 的 Worker 創建了一個 Pod,這個 pod 中的 Ownereference 取向了 ReplicaSet rsA。
從零開始入門 K8s | K8s 的應用編排與管理

然后 Reflector Watch 到的 Pod 新增事件,在 delta 隊列中額外加入了 Add 類型的 deta 記錄,一方面把新的 Pod 記錄通過 Indexer 存儲到了緩存中,另一方面調用了 ReplicaSet 控制器的 Add 回調函數,Add 回調函數通過檢查 pod ownerReferences 找到了對應的 ReplicaSet,并把包括 ReplicaSet 命名空間和字符串塞入到了工作隊列中。
ReplicaSet 的 Woker 在得到新的工作項之后,從緩存中取到了新的 ReplicaSet 記錄,并得到了其所有創建的 Pod,因為 ReplicaSet 的狀態不是最新的,也就是所有創建 Pod 的數量不是最新的。因此在此時 ReplicaSet 更新 status 使得 spec 和 status 達成一致。


從零開始入門 K8s | K8s 的應用編排與管理

四、控制器模式總結

1. 兩種 API 設計方法

Kubernetes 控制器模式依賴聲明式的 API。另外一種常見的 API 類型是命令式 API。為什么 Kubernetes 采用聲明式 API,而不是命令式 API 來設計整個控制器呢?
首先,比較兩種 API 在交互行為上的差別。在生活中,常見的命令式的交互方式是家長和孩子交流方式,因為孩子欠缺目標意識,無法理解家長期望,家長往往通過一些命令,教孩子一些明確的動作,比如說:吃飯、睡覺類似的命令。我們在容器編排體系中,命令式 API 就是通過向系統發出明確的操作來執行的。
而常見的聲明式交互方式,就是老板對自己員工的交流方式。老板一般不會給自己的員工下很明確的決定,實際上可能老板對于要操作的事情本身,還不如員工清楚。因此,老板通過給員工設置可量化的業務目標的方式,來發揮員工自身的主觀能動性。比如說,老板會要求某個產品的市場占有率達到 80%,而不會指出要達到這個市場占有率,要做的具體操作細節。
類似的,在容器編排體系中,我們可以執行一個應用實例副本數保持在 3 個,而不用明確的去擴容 Pod 或是刪除已有的 Pod,來保證副本數在三個。


從零開始入門 K8s | K8s 的應用編排與管理

2. 命令式 API 的問題

在理解兩個交互 API 的差別后,可以分析一下命令式 API 的問題。
  • 命令 API 最大的一個問題在于錯誤處理;
在大規模的分布式系統中,錯誤是無處不在的。一旦發出的命令沒有響應,調用方只能通過反復重試的方式來試圖恢復錯誤,然而盲目的重試可能會帶來更大的問題。
假設原來的命令,后臺實際上已經執行完成了,重試后又多執行了一個重試的命令操作。為了避免重試的問題,系統往往還需要在執行命令前,先記錄一下需要執行的命令,并且在重啟等場景下,重做待執行的命令,而且在執行的過程中,還需要考慮多個命令的先后順序、覆蓋關系等等一些復雜的邏輯情況。
  • 實際上許多命令式的交互系統后臺往往還會做一個巡檢的系統,用來修正命令處理超時、重試等一些場景造成數據不一致的問題;
然而,因為巡檢邏輯和日常操作邏輯是不一樣的,往往在測試上覆蓋不夠,在錯誤處理上不夠嚴謹,具有很大的操作風險,因此往往很多巡檢系統都是人工來觸發的。
  • 最后,命令式 API 在處理多并發訪問時,也很容易出現問題;
假如有多方并發的對一個資源請求進行操作,并且一旦其中有操作出現了錯誤,就需要重試。那么最后哪一個操作生效了,就很難確認,也無法保證。很多命令式系統往往在操作前會對系統進行加鎖,從而保證整個系統最后生效行為的可預見性,但是加鎖行為會降低整個系統的操作執行效率。
  • 相對的,聲明式 API 系統里天然地記錄了系統現在和最終的狀態。
不需要額外的操作數據。另外因為狀態的冪等性,可以在任意時刻反復操作。在聲明式系統運行的方式里,正常的操作實際上就是對資源狀態的巡檢,不需要額外開發巡檢系統,系統的運行邏輯也能夠在日常的運行中得到測試和錘煉,因此整個操作的穩定性能夠得到保證。
最后,因為資源的最終狀態是明確的,我們可以合并多次對狀態的修改。可以不需要加鎖,就支持多方的并發訪問。


從零開始入門 K8s | K8s 的應用編排與管理

3. 控制器模式總結

最后我們總結一下:
  1. Kubernetes 所采用的控制器模式,是由聲明式 API 驅動的。確切來說,是基于對 Kubernetes 資源對象的修改來驅動的;
  2. Kubernetes 資源之后,是關注該資源的控制器。這些控制器將異步的控制系統向設置的終態驅近;
  3. 這些控制器是自主運行的,使得系統的自動化和無人值守成為可能;
  4. 因為 Kubernetes 的控制器和資源都是可以自定義的,因此可以方便的擴展控制器模式。特別是對于有狀態應用,我們往往通過自定義資源和控制器的方式,來自動化運維操作。這個也就是后續會介紹的 operator 的場景。
從零開始入門 K8s | K8s 的應用編排與管理

本文總結

這里為大家簡單總結一下本文的主要內容:
  • Kubernetes 資源對象中的元數據部分,主要包括了用來識別資源的標簽:Labels, 用來描述資源的注解;Annotations, 用來描述多個資源之間相互關系的 OwnerReference。這些元數據在 K8s 運行中有非常重要的作用;

  • 控制型模式中最核心的就是控制循環的概念;

  • 兩種 API 設計方法:聲明式 API 和命令式 API ;Kubernetes 所采用的控制器模式,是由聲明式 API 驅動的。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

洛隆县| 常州市| 商河县| 孝义市| 芦山县| 罗甸县| 明光市| 上犹县| 武乡县| 台北市| 武陟县| 濉溪县| 天水市| 福泉市| 潜山县| 东乌| 东海县| 武陟县| 麟游县| 囊谦县| 中方县| 久治县| 灌云县| 龙江县| 金门县| 黑水县| 富蕴县| 清原| 淳化县| 天柱县| 威信县| 沙洋县| 德安县| 华亭县| 樟树市| 长岭县| 衢州市| 视频| 昌乐县| 成安县| 新泰市|