一. 簡介
Kubernetes 的能力都是通過各種 API 對(duì)象來提供,API 對(duì)象正是我們使用 Kubernetes 的接口,我們正是通過操作這些提供的 API 對(duì)象來使用 Kubernetes 能力的。最常見的就是 kubectl apply
命令。
二. 聲明式
對(duì)于我們使用 Kubernetes API 對(duì)象的方式,一般會(huì)編寫對(duì)應(yīng) API 對(duì)象的 YAML 文件交給 Kubernetes(而不是使用一些命令來直接操作 API)。所謂“聲明式”,指的就是只需要提交一個(gè)定義好的 API 對(duì)象來“聲明”(這個(gè) YAML 文件其實(shí)就是一種“聲明”),表示所期望的最終狀態(tài)是什么樣子就可以了。而如果提交的是一個(gè)個(gè)命令,去指導(dǎo)怎么一步一步達(dá)到期望狀態(tài),這就是“命令式”了。
這意味著 kube-apiserver
在響應(yīng)命令式請(qǐng)求(比如,kubectl replace
)的時(shí)候,一次只能處理一個(gè)寫請(qǐng)求,否則會(huì)有產(chǎn)生沖突的可能。而對(duì)于聲明式請(qǐng)求(比如,kubectl apply
),一次能處理多個(gè)寫操作,并且具備 Merge 能力。
三. “聲明式”與“命令式”區(qū)別
- 在“聲明式API“中,通常具有如下特點(diǎn):
- API包含相對(duì)少量的相對(duì)較小的對(duì)象(資源)
- 這些對(duì)象定義應(yīng)用程序或基礎(chǔ)結(jié)構(gòu)的配置
- 對(duì)象相對(duì)不頻繁地更新
- 通常需要讀取和寫入對(duì)象
- 對(duì)象的主要操作是 CRUD-y (creating, reading, updating and deleting)
- 不需要跨對(duì)象進(jìn)行事務(wù)處理:API 代表期望的狀態(tài),而不是當(dāng)前的狀態(tài)
- “命令式API”中,通常具有如下特點(diǎn):
- 客戶端說“執(zhí)行此操作”,然后在完成后返回一個(gè)同步響應(yīng)
- 客戶端說“執(zhí)行此操作”,然后取回操作ID,并且必須檢查單獨(dú)的 Operation 對(duì)象以確定請(qǐng)求是否完成
- 使用遠(yuǎn)程過程調(diào)用(RPCs)
- 直接存儲(chǔ)大量數(shù)據(jù),例如,每個(gè)對(duì)象大于幾kB,或者大于1000個(gè)對(duì)象。
- 需要高帶寬訪問(持續(xù)每秒10s的請(qǐng)求)
- 存儲(chǔ)最終用戶數(shù)據(jù)(例如圖像,PII 等)或應(yīng)用程序處理的其他大規(guī)模數(shù)據(jù)
- 對(duì)象上的操作不是 CRUD-y 操作
- 該 API 很難建模為對(duì)象
- 選擇了用“操作ID”或“操作對(duì)象”表示待處理的操作
四. API 對(duì)象
4.1 組成結(jié)構(gòu)
一個(gè) API 對(duì)象在 Etcd 里的完整資源路徑,是由:Group(API組)、Version(API版本)和 Resource(API資源類型)
三個(gè)部分組成的。
具體案例如下圖:
可以看出,Kubernetes 里 API 對(duì)象的組織方式,其實(shí)是層層遞進(jìn)的。
4.2 YAML結(jié)構(gòu)
借助之前的yaml文件,參考如下的一個(gè)結(jié)構(gòu):
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: demo-statefulset
spec:
serviceName: "demo-service"
replicas: 3
selector:
matchLabels:
app: demo-nginx
template:
........
在這個(gè) YAML 文件中,StatefulSet
就是這個(gè) API 對(duì)象的資源類型(Resource),apps
就是它的組(Group),v1
就是它的版本(Version)。
4.3 API 檢索流程
對(duì) Resource、Group 和 Version 進(jìn)行檢索,最終定位到API對(duì)象的流程如下:
- 匹配 Group
在陪陪Group時(shí),一般分倆類。
- 核心 API 對(duì)象
對(duì)于 Kubernetes 里的核心 API 對(duì)象,比如:Pod、Node 等,是不需要 Group 的,因?yàn)樗鼈兊?Group 是“”。對(duì)于這些 API 對(duì)象來說,Kubernetes 會(huì)直接在/api
這個(gè)層級(jí)進(jìn)行下一步的匹配過程。 - 非核心 API 對(duì)象
對(duì)于StatefulSet
等非核心 API 對(duì)象來說,Kubernetes 就必須在/apis
這個(gè)層級(jí)里查找它對(duì)應(yīng)的 Group,進(jìn)而根據(jù)“apps”
這個(gè) Group 的名字,找到/apis/apps
。
這些API Group
的分類是以對(duì)象功能為依據(jù)的,比如Deployment
,StatefulSet
就都屬于“apps” 這個(gè) Group。
具體可查看如下這張圖:
匹配 Version
對(duì)于StatefulSet
這個(gè) API 對(duì)象來說,Kubernetes 在apps
這個(gè) Group 下,匹配到的版本號(hào)就是v1
。在 Kubernetes 中,同一種 API 對(duì)象可以有多個(gè)版本,這正是 Kubernetes 進(jìn)行 API 版本化管理的重要手段。這樣,比如在StatefulSet
的開發(fā)過程中,對(duì)于會(huì)影響到用戶的變更就可以通過升級(jí)新版本來處理,從而保證了向后兼容。匹配 Resource
在前面匹配到正確的版本之后,Kubernetes 就知道,要?jiǎng)?chuàng)建的原來是一個(gè)/apis/apps/v1
下的StatefulSet
對(duì)象。
五. 概念拓展
5.1 CRD
CRD 的全稱是 Custom Resource Definition
。它指的就是,允許用戶在 Kubernetes 中添加一個(gè)跟 Pod、Node 類似的、新的 API 資源類型,即:自定義 API 資源。
5.2 ListAndWatch
在 ListAndWatch 機(jī)制下,一旦 APIServer 端有新的實(shí)例被創(chuàng)建、刪除或者更新,Reflector 都會(huì)收到“事件通知”。
ListAndWatch 方法的含義是:
- 首先,通過 APIServer 的 LIST API“獲取”所有最新版本的 API 對(duì)象。
- 然后,再通過 WATCH API 來“監(jiān)聽”所有這些 API 對(duì)象的變化。
六. 總結(jié)
綜上,Kubernetes“聲明式 API”的獨(dú)特之處:
- 首先,所謂“聲明式”,指的就是只需要提交一個(gè)定義好的 API 對(duì)象來“聲明”所期望的狀態(tài)。
- 其次,“聲明式 API”允許有多個(gè) API 寫端,以
PATCH
的方式對(duì) API 對(duì)象進(jìn)行修改,而無需關(guān)心本地原始 YAML 文件的內(nèi)容。 - 最后,基于上面?zhèn)z種能力,Kubernetes 才可以基于對(duì) API 對(duì)象的增、刪、改、查,在完全無需外界干預(yù)的情況下,完成對(duì)“實(shí)際狀態(tài)”和“期望狀態(tài)”的調(diào)諧(Reconcile)過程。
所以“聲明式 API“ 才是 Kubernetes 項(xiàng)目編排能力“賴以生存”的核心所在,PaaS平臺(tái)與這完全沒有可比性。
歡迎收藏個(gè)人博客: Wyatt's Blog ,非常感謝~
Reference
https://docs.openshift.com/container-platform/4.5/rest_api/workloads_apis/workloads-apis-index.html
https://time.geekbang.org/column/article/42493?utm_campaign=guanwang&utm_source=baidu-ad&utm_medium=ppzq-pc&utm_content=title&utm_term=baidu-ad-ppzq-title
https://blog.csdn.net/KevinBetterQ/article/details/104012293
https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/