Kubernetes API 概念
Kubernetes API 是一個基於資源 (RESTful) 的程式化介面,透過 HTTP 提供。它支援透過標準 HTTP 動詞 (POST、PUT、PATCH、DELETE、GET) 擷取、建立、更新與刪除主要資源。
對於某些資源,API 包含額外的子資源,允許細緻的授權 (例如 Pod 詳細資訊與日誌擷取的個別檢視),並且可以接受與提供不同表示形式的資源,以方便或提高效率。
Kubernetes 透過監看支援資源上的高效變更通知
在 Kubernetes API 中,監看是一個動詞,用於追蹤 Kubernetes 中物件的變更作為串流。它用於有效偵測變更。
Kubernetes 也提供一致的清單操作,以便 API 用戶端可以有效地快取、追蹤與同步資源的狀態。您可以線上檢視API 參考,或繼續閱讀以了解一般 API 的相關資訊。
Kubernetes API 術語
Kubernetes 通常利用常見的 RESTful 術語來描述 API 概念
- 資源類型是在 URL 中使用的名稱 (
pods
、namespaces
、services
) - 所有資源類型都有具體的表示形式 (其物件綱要),稱為種類
- 資源類型的執行個體清單稱為集合
- 資源類型的單一執行個體稱為資源,通常也代表一個物件
- 對於某些資源類型,API 包含一個或多個子資源,這些子資源表示為資源下方的 URI 路徑
大多數 Kubernetes API 資源類型都是物件 – 它們代表叢集上概念的具體執行個體,例如 Pod 或命名空間。少數 API 資源類型是虛擬的,因為它們通常代表物件上的操作,而不是物件,例如權限檢查 (使用具有 SubjectAccessReview
JSON 編碼主體的 POST 到 subjectaccessreviews
資源),或 Pod 的 eviction
子資源 (用於觸發API 起始的驅逐)。
物件名稱
您可以透過 API 建立的所有物件都有唯一的物件名稱,以允許冪等建立與擷取,但虛擬資源類型可能沒有唯一的名稱,如果它們不可擷取,或不依賴冪等性。在命名空間中,一次只能有一個給定種類的物件具有給定的名稱。但是,如果您刪除物件,您可以建立具有相同名稱的新物件。有些物件不是命名空間範圍的 (例如:節點),因此它們的名稱在整個叢集中必須是唯一的。
API 動詞
幾乎所有物件資源類型都支援標準 HTTP 動詞 - GET、POST、PUT、PATCH 與 DELETE。Kubernetes 也使用自己的動詞,這些動詞通常以小寫字母撰寫,以區分它們與 HTTP 動詞。
Kubernetes 使用術語 list 來描述傳回資源的集合,以區分擷取單一資源,這通常稱為 get。如果您傳送帶有 ?watch
查詢參數的 HTTP GET 請求,Kubernetes 將其稱為 watch 而不是 get (請參閱高效變更偵測以取得更多詳細資訊)。
對於 PUT 請求,Kubernetes 內部將其分類為 create 或 update,根據現有物件的狀態而定。update 與 patch 不同;patch 的 HTTP 動詞是 PATCH。
資源 URI
所有資源類型都是叢集範圍的 (/apis/GROUP/VERSION/*
) 或命名空間範圍的 (/apis/GROUP/VERSION/namespaces/NAMESPACE/*
)。命名空間範圍的資源類型將在其命名空間刪除時刪除,並且對該資源類型的存取由命名空間範圍的授權檢查控制。
注意:核心資源使用 /api
而不是 /apis
,並省略 GROUP 路徑區段。
範例
/api/v1/namespaces
/api/v1/pods
/api/v1/namespaces/my-namespace/pods
/apis/apps/v1/deployments
/apis/apps/v1/namespaces/my-namespace/deployments
/apis/apps/v1/namespaces/my-namespace/deployments/my-deployment
您也可以存取資源集合 (例如:列出所有節點)。以下路徑用於擷取集合與資源
叢集範圍的資源
GET /apis/GROUP/VERSION/RESOURCETYPE
- 傳回資源類型的資源集合GET /apis/GROUP/VERSION/RESOURCETYPE/NAME
- 傳回資源類型下具有 NAME 的資源
命名空間範圍的資源
GET /apis/GROUP/VERSION/RESOURCETYPE
- 傳回跨所有命名空間的資源類型所有執行個體的集合GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE
- 傳回 NAMESPACE 中資源類型所有執行個體的集合GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME
- 傳回 NAMESPACE 中具有 NAME 的資源類型執行個體
由於命名空間是叢集範圍的資源類型,您可以使用 GET /api/v1/namespaces
擷取所有命名空間的清單 (「集合」),並使用 GET /api/v1/namespaces/NAME
擷取特定命名空間的詳細資訊。
- 叢集範圍的子資源:
GET /apis/GROUP/VERSION/RESOURCETYPE/NAME/SUBRESOURCE
- 命名空間範圍的子資源:
GET /apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME/SUBRESOURCE
每個子資源支援的動詞會因物件而異 - 請參閱API 參考以取得更多資訊。無法跨多個資源存取子資源 - 如果有必要,通常會使用新的虛擬資源類型。
HTTP 媒體類型
透過 HTTP,Kubernetes 支援 JSON 與 Protobuf 線路編碼。
依預設,Kubernetes 以JSON 序列化傳回物件,使用 application/json
媒體類型。雖然 JSON 是預設值,但用戶端可以請求 YAML 回應,或使用更有效率的二進位Protobuf 表示法,以在規模上獲得更好的效能。
Kubernetes API 實作標準 HTTP 內容類型協商:傳遞具有 GET
呼叫的 Accept
標頭將請求伺服器嘗試以您偏好的媒體類型傳回回應。如果您想要在 PUT
或 POST
請求中以 Protobuf 將物件傳送至伺服器,您必須適當地設定 Content-Type
請求標頭。
如果您請求可用的媒體類型,API 伺服器會傳回具有適當 Content-Type
的回應;如果您請求的媒體類型都不受支援,API 伺服器會傳回 406 Not acceptable
錯誤訊息。所有內建資源類型都支援 application/json
媒體類型。
JSON 資源編碼
Kubernetes API 預設使用 JSON 來編碼 HTTP 訊息主體。
例如
列出叢集上的所有 Pod,不指定偏好的格式
GET /api/v1/pods
200 OK Content-Type: application/json … JSON encoded collection of Pods (PodList object)
透過將 JSON 傳送到伺服器來建立 Pod,並請求 JSON 回應。
POST /api/v1/namespaces/test/pods Content-Type: application/json Accept: application/json … JSON encoded Pod object
200 OK Content-Type: application/json { "kind": "Pod", "apiVersion": "v1", … }
YAML 資源編碼
Kubernetes 也支援 application/yaml
媒體類型用於請求和回應。YAML
可以用於定義 Kubernetes 清單和 API 互動。
例如
以 YAML 格式列出叢集上的所有 Pod
GET /api/v1/pods Accept: application/yaml
200 OK Content-Type: application/yaml … YAML encoded collection of Pods (PodList object)
透過將 YAML 編碼的資料傳送到伺服器來建立 Pod,並請求 YAML 回應
POST /api/v1/namespaces/test/pods Content-Type: application/yaml Accept: application/yaml … YAML encoded Pod object
200 OK Content-Type: application/yaml apiVersion: v1 kind: Pod metadata: name: my-pod …
Kubernetes Protobuf 編碼
Kubernetes 使用信封包裝器來編碼 Protobuf 回應。該包裝器以 4 位元組的魔術數字開頭,以幫助識別磁碟或 etcd 中的內容為 Protobuf(而不是 JSON)。4 位元組的魔術數字資料之後是一個 Protobuf 編碼的包裝器訊息,它描述了底層物件的編碼和類型。在 Protobuf 包裝器訊息中,內部物件資料使用 Unknown 的 raw
欄位記錄(詳見 IDL)。
例如
以 Protobuf 格式列出叢集上的所有 Pod。
GET /api/v1/pods Accept: application/vnd.kubernetes.protobuf
200 OK Content-Type: application/vnd.kubernetes.protobuf … JSON encoded collection of Pods (PodList object)
透過將 Protobuf 編碼的資料傳送到伺服器來建立 Pod,但請求 JSON 回應。
POST /api/v1/namespaces/test/pods Content-Type: application/vnd.kubernetes.protobuf Accept: application/json … binary encoded Pod object
200 OK Content-Type: application/json { "kind": "Pod", "apiVersion": "v1", ... }
您可以將這兩種技術結合使用,並使用 Kubernetes 的 Protobuf 編碼與任何支援它的 API 互動,無論是讀取還是寫入。只有某些 API 資源類型與 Protobuf 相容。
包裝器格式如下
A four byte magic number prefix:
Bytes 0-3: "k8s\x00" [0x6b, 0x38, 0x73, 0x00]
An encoded Protobuf message with the following IDL:
message Unknown {
// typeMeta should have the string values for "kind" and "apiVersion" as set on the JSON object
optional TypeMeta typeMeta = 1;
// raw will hold the complete serialized object in protobuf. See the protobuf definitions in the client libraries for a given kind.
optional bytes raw = 2;
// contentEncoding is encoding used for the raw data. Unspecified means no encoding.
optional string contentEncoding = 3;
// contentType is the serialization method used to serialize 'raw'. Unspecified means application/vnd.kubernetes.protobuf and is usually
// omitted.
optional string contentType = 4;
}
message TypeMeta {
// apiVersion is the group/version for this type
optional string apiVersion = 1;
// kind is the name of the object schema. A protobuf definition should exist for this object.
optional string kind = 2;
}
注意
接收到application/vnd.kubernetes.protobuf
回應但不符合預期前綴的用戶端應拒絕該回應,因為未來版本可能需要以不相容的方式更改序列化格式,並且將透過更改前綴來實現。與 Kubernetes Protobuf 的相容性
並非所有 API 資源類型都支援 Kubernetes 的 Protobuf 編碼;具體來說,Protobuf 不適用於定義為CustomResourceDefinitions 或透過聚合層提供的資源。
作為用戶端,如果您可能需要使用擴充類型,您應該在請求的 Accept
標頭中指定多個內容類型,以支援回退到 JSON。例如
Accept: application/vnd.kubernetes.protobuf, application/json
CBOR 資源編碼
Kubernetes v1.32 [alpha]
(預設啟用:false)啟用 CBORServingAndStorage
功能閘道 後,所有內建資源類型以及 CustomResourceDefinition 定義的所有資源的請求和回應主體,都可以編碼為 CBOR 二進制資料格式。如果個別聚合 API 伺服器中啟用了 CBOR,則在聚合層也支援 CBOR。
當請求主體包含單個 CBOR 編碼資料項目 時,用戶端應在 Content-Type
HTTP 請求標頭中指示 IANA 媒體類型 application/cbor
,當準備接受回應中的 CBOR 編碼資料項目時,應在 Accept
HTTP 請求標頭中指示。當回應主體包含 CBOR 編碼物件時,API 伺服器將在 Content-Type
HTTP 回應標頭中使用 application/cbor
。
如果 API 伺服器使用 CBOR 編碼其對 watch 請求的回應,則回應主體將是 CBOR 序列,並且 Content-Type
HTTP 回應標頭將使用 IANA 媒體類型 application/cbor-seq
。序列的每個條目(如果有的話)都是單個 CBOR 編碼的 watch 事件。
除了現有的 application/apply-patch+yaml
媒體類型用於 YAML 編碼的伺服器端套用配置之外,啟用 CBOR 的 API 伺服器將接受 application/apply-patch+cbor
媒體類型用於 CBOR 編碼的伺服器端套用配置。對於 application/json-patch+json
或 application/merge-patch+json
,或 application/strategic-merge-patch+json
,沒有支援的 CBOR 等效項。
有效率地偵測變更
Kubernetes API 允許用戶端對物件或集合發出初始請求,然後追蹤自該初始請求以來的變更:一個 watch。用戶端可以傳送 list 或 get,然後發出後續的 watch 請求。
為了使這種變更追蹤成為可能,每個 Kubernetes 物件都有一個 resourceVersion
欄位,表示該資源在底層持久層中儲存的版本。當檢索資源集合(命名空間或叢集範圍)時,來自 API 伺服器的回應包含一個 resourceVersion
值。用戶端可以使用該 resourceVersion
來啟動針對 API 伺服器的 watch。
當您傳送 watch 請求時,API 伺服器會回應變更串流。這些變更詳細列出了在您指定為 watch 請求參數的 resourceVersion
之後發生的操作(例如 create、delete 和 update)的結果。整體 watch 機制允許用戶端獲取當前狀態,然後訂閱後續變更,而不會遺漏任何事件。
如果用戶端 watch 斷線,則該用戶端可以從最後返回的 resourceVersion
啟動新的 watch;用戶端也可以執行新的 get / list 請求並重新開始。有關更多詳細資訊,請參閱 資源版本語義。
例如
列出給定命名空間中的所有 Pod。
GET /api/v1/namespaces/test/pods --- 200 OK Content-Type: application/json { "kind": "PodList", "apiVersion": "v1", "metadata": {"resourceVersion":"10245"}, "items": [...] }
從資源版本 10245 開始,接收任何影響 *test* 命名空間中 Pod 的 API 操作(例如 create、delete、patch 或 update)的通知。每個變更通知都是一個 JSON 文件。HTTP 回應主體(以
application/json
提供)由一系列 JSON 文件組成。GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245 --- 200 OK Transfer-Encoding: chunked Content-Type: application/json { "type": "ADDED", "object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...} } { "type": "MODIFIED", "object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "11020", ...}, ...} } ...
給定的 Kubernetes 伺服器只會保留有限時間的變更歷史記錄。預設情況下,使用 etcd 3 的叢集會保留過去 5 分鐘內的變更。當請求的 watch 操作因該資源的歷史版本不可用而失敗時,用戶端必須透過識別狀態碼 410 Gone
來處理這種情況,清除其本地快取,執行新的 get 或 list 操作,並從返回的 resourceVersion
開始 watch。
對於訂閱集合,Kubernetes 用戶端程式庫通常為此 list-then-watch 邏輯提供某種形式的標準工具。(在 Go 用戶端程式庫中,這稱為 Reflector
,位於 k8s.io/client-go/tools/cache
套件中。)
Watch 書籤
為了減輕短歷史視窗的影響,Kubernetes API 提供了一個名為 BOOKMARK
的 watch 事件。這是一種特殊的事件,用於標記用戶端請求的所有變更都已傳送,直到給定的 resourceVersion
為止。表示 BOOKMARK
事件的文件是請求所請求的類型,但僅包含 .metadata.resourceVersion
欄位。例如
GET /api/v1/namespaces/test/pods?watch=1&resourceVersion=10245&allowWatchBookmarks=true
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10596", ...}, ...}
}
...
{
"type": "BOOKMARK",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "12746"} }
}
作為用戶端,您可以透過將 allowWatchBookmarks=true
查詢參數設定為 watch 請求來請求 BOOKMARK
事件,但您不應假設書籤會以任何特定間隔返回,用戶端也不能假設 API 伺服器即使在請求時也會傳送任何 BOOKMARK
事件。
串流列表
Kubernetes v1.32 [beta]
(預設啟用:true)在大型叢集上,檢索某些資源類型的集合可能會導致控制平面上資源使用量(主要是 RAM)顯著增加。為了減輕影響並簡化 list + watch 模式的使用者體驗,Kubernetes v1.32 將允許請求初始狀態(先前透過 list 請求請求)作為 watch 請求一部分的功能升級為 beta 版。
在用戶端,可以透過在 watch 請求中指定 sendInitialEvents=true
作為查詢字串參數來請求初始狀態。如果設定,API 伺服器會以合成的初始事件(類型為 ADDED
)開始 watch 串流,以建構所有現有物件的完整狀態,然後是 BOOKMARK
事件(如果透過 allowWatchBookmarks=true
選項請求)。書籤事件包含同步到的資源版本。在傳送書籤事件後,API 伺服器會像任何其他 watch 請求一樣繼續。
當您在查詢字串中設定 sendInitialEvents=true
時,Kubernetes 也要求您將 resourceVersionMatch
設定為 NotOlderThan
值。如果您在查詢字串中提供了 resourceVersion
而沒有提供值或根本沒有提供,這將被解釋為請求 *一致性讀取*;當狀態至少同步到從請求開始處理時的一致性讀取時刻時,會傳送書籤事件。如果您指定 resourceVersion
(在查詢字串中),則當狀態至少同步到提供的資源版本時,會傳送書籤事件。
範例
一個範例:您想要 watch Pod 的集合。對於該集合,目前的資源版本為 10245,並且有兩個 Pod:foo
和 bar
。然後傳送以下請求(透過使用 resourceVersion=
設定空資源版本來明確請求 *一致性讀取*)可能會導致以下事件序列
GET /api/v1/namespaces/test/pods?watch=1&sendInitialEvents=true&allowWatchBookmarks=true&resourceVersion=&resourceVersionMatch=NotOlderThan
---
200 OK
Transfer-Encoding: chunked
Content-Type: application/json
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "8467", "name": "foo"}, ...}
}
{
"type": "ADDED",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "5726", "name": "bar"}, ...}
}
{
"type": "BOOKMARK",
"object": {"kind": "Pod", "apiVersion": "v1", "metadata": {"resourceVersion": "10245"} }
}
...
<followed by regular watch stream starting from resourceVersion="10245">
回應壓縮
Kubernetes v1.16 [beta]
(預設啟用:true)APIResponseCompression
是一個選項,允許 API 伺服器壓縮 get 和 list 請求的回應,從而減少網路頻寬並提高大型叢集的效能。自 Kubernetes 1.16 以來,它預設為啟用,並且可以透過在 API 伺服器的 --feature-gates
標誌中包含 APIResponseCompression=false
來停用。
API 回應壓縮可以顯著減小回應的大小,尤其是對於大型資源或集合。例如,Pod 的 list 請求可以返回數百 KB 甚至 MB 的資料,具體取決於 Pod 的數量及其屬性。透過壓縮回應,可以節省網路頻寬並減少延遲。
要驗證 APIResponseCompression
是否正常運作,您可以向 API 伺服器傳送帶有 Accept-Encoding
標頭的 get 或 list 請求,並檢查回應大小和標頭。例如
GET /api/v1/pods
Accept-Encoding: gzip
---
200 OK
Content-Type: application/json
content-encoding: gzip
...
content-encoding
標頭指示回應已使用 gzip
壓縮。
以區塊檢索大型結果集
Kubernetes v1.29 [stable]
(預設啟用:true)在大型叢集上,檢索某些資源類型的集合可能會導致非常大的回應,這可能會影響伺服器和用戶端。例如,一個叢集可能擁有數萬個 Pod,每個 Pod 大約相當於 2 KiB 的編碼 JSON。跨所有命名空間檢索所有 Pod 可能會導致非常大的回應 (10-20MB) 並消耗大量伺服器資源。
Kubernetes API 伺服器支援將單個大型集合請求分解為許多較小區塊的能力,同時保持總請求的一致性。每個區塊可以循序返回,這既減少了請求的總大小,又允許面向使用者的用戶端逐步顯示結果,以提高回應速度。
您可以請求 API 伺服器透過使用頁面(Kubernetes 稱之為 *區塊*)來處理 list 以提供單個集合。要以區塊檢索單個集合,集合的請求支援兩個查詢參數 limit
和 continue
,並且所有 list 操作的回應欄位 continue
都會在集合的 metadata
欄位中返回。用戶端應使用 limit
指定他們希望在每個區塊中接收的最大結果數,伺服器將在結果中返回最多 limit
個資源,並且如果集合中還有更多資源,則包含 continue
值。
作為 API 用戶端,您可以然後將此 continue
值傳遞給 API 伺服器在下一個請求中,以指示伺服器返回下一頁(*區塊*)結果。透過繼續直到伺服器返回空 continue
值,您可以檢索整個集合。
與 watch 操作類似,continue
令牌會在短時間後(預設為 5 分鐘)過期,如果無法返回更多結果,則返回 410 Gone
。在這種情況下,用戶端將需要從頭開始或省略 limit
參數。
例如,如果叢集上有 1,253 個 Pod,並且您想要一次接收 500 個 Pod 的區塊,請按如下方式請求這些區塊
列出叢集上的所有 Pod,每次檢索最多 500 個 Pod。
GET /api/v1/pods?limit=500 --- 200 OK Content-Type: application/json { "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion":"10245", "continue": "ENCODED_CONTINUE_TOKEN", "remainingItemCount": 753, ... }, "items": [...] // returns pods 1-500 }
繼續先前的呼叫,檢索接下來的 500 個 Pod 集。
GET /api/v1/pods?limit=500&continue=ENCODED_CONTINUE_TOKEN --- 200 OK Content-Type: application/json { "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion":"10245", "continue": "ENCODED_CONTINUE_TOKEN_2", "remainingItemCount": 253, ... }, "items": [...] // returns pods 501-1000 }
繼續先前的呼叫,檢索最後 253 個 Pod。
GET /api/v1/pods?limit=500&continue=ENCODED_CONTINUE_TOKEN_2 --- 200 OK Content-Type: application/json { "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion":"10245", "continue": "", // continue token is empty because we have reached the end of the list ... }, "items": [...] // returns pods 1001-1253 }
請注意,集合的 resourceVersion
在每個請求中保持不變,表示伺服器正在向您顯示 Pod 的一致快照。版本 10245
之後建立、更新或刪除的 Pod 將不會顯示,除非您在沒有 continue
令牌的情況下發出單獨的 list 請求。這允許您將大型請求分解為較小的區塊,然後對完整集合執行 watch 操作,而不會遺漏任何更新。
remainingItemCount
是集合中未包含在此回應中的後續項目數。如果 list 請求包含標籤或欄位選擇器,則剩餘項目數未知,並且 API 伺服器不會在其回應中包含 remainingItemCount
欄位。如果 list 已完成(因為它未分塊,或者因為這是最後一個區塊),則沒有更多剩餘項目,並且 API 伺服器不會在其回應中包含 remainingItemCount
欄位。remainingItemCount
的預期用途是估計集合的大小。
集合
在 Kubernetes 術語中,您從 list 獲得的回應是一個 *集合*。但是,Kubernetes 為不同類型資源的集合定義了具體的種類。集合的種類名稱以資源種類命名,並附加 List
。
當您查詢 API 以獲取特定類型時,該查詢返回的所有項目都是該類型。例如,當您 list 服務時,集合回應的 kind
設定為 ServiceList
;該集合中的每個項目都代表一個單獨的服務。例如
GET /api/v1/services
{
"kind": "ServiceList",
"apiVersion": "v1",
"metadata": {
"resourceVersion": "2947301"
},
"items": [
{
"metadata": {
"name": "kubernetes",
"namespace": "default",
...
"metadata": {
"name": "kube-dns",
"namespace": "kube-system",
...
在 Kubernetes API 中定義了數十種集合類型(例如 PodList
、ServiceList
和 NodeList
)。您可以從 Kubernetes API 文件中獲取有關每種集合類型的更多資訊。
某些工具,例如 kubectl
,表示 Kubernetes 集合機制的方式與 Kubernetes API 本身略有不同。由於 kubectl
的輸出可能包含來自 API 層多個 list 操作的回應,因此 kubectl
使用 kind: List
表示項目列表。例如
kubectl get services -A -o yaml
apiVersion: v1
kind: List
metadata:
resourceVersion: ""
selfLink: ""
items:
- apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2021-06-03T14:54:12Z"
labels:
component: apiserver
provider: kubernetes
name: kubernetes
namespace: default
...
- apiVersion: v1
kind: Service
metadata:
annotations:
prometheus.io/port: "9153"
prometheus.io/scrape: "true"
creationTimestamp: "2021-06-03T14:54:14Z"
labels:
k8s-app: kube-dns
kubernetes.io/cluster-service: "true"
kubernetes.io/name: CoreDNS
name: kube-dns
namespace: kube-system
注意
請記住,Kubernetes API 沒有名為 List
的 kind
。
kind: List
是一個用戶端、內部實作細節,用於處理可能屬於不同物件種類的集合。避免在自動化或其他程式碼中依賴 kind: List
。
以表格形式接收資源
當您執行 kubectl get
時,預設輸出格式是特定資源類型的一個或多個實例的簡單表格表示形式。過去,用戶端需要重現 kubectl
中實作的表格和描述輸出,以執行簡單的物件列表。該方法的一些限制包括處理某些物件時的複雜邏輯。此外,API 聚合或第三方資源提供的類型在編譯時是未知的。這表示必須為用戶端無法識別的類型提供通用實作。
為了避免上述潛在的限制,用戶端可以請求物件的表格表示形式,將列印的特定細節委派給伺服器。Kubernetes API 實作了標準 HTTP 內容類型協商:傳遞包含 application/json;as=Table;g=meta.k8s.io;v=v1
值的 Accept
標頭以及 GET
呼叫,將請求伺服器以表格內容類型返回物件。
例如,以表格格式列出叢集上的所有 Pod。
GET /api/v1/pods
Accept: application/json;as=Table;g=meta.k8s.io;v=v1
---
200 OK
Content-Type: application/json
{
"kind": "Table",
"apiVersion": "meta.k8s.io/v1",
...
"columnDefinitions": [
...
]
}
對於控制平面不知道自訂表格定義的 API 資源類型,API 伺服器會返回預設表格回應,其中包含資源的 name
和 creationTimestamp
欄位。
GET /apis/crd.example.com/v1alpha1/namespaces/default/resources
---
200 OK
Content-Type: application/json
...
{
"kind": "Table",
"apiVersion": "meta.k8s.io/v1",
...
"columnDefinitions": [
{
"name": "Name",
"type": "string",
...
},
{
"name": "Created At",
"type": "date",
...
}
]
}
並非所有 API 資源類型都支援表格回應;例如,CustomResourceDefinitions 可能未定義欄位到表格的映射,並且 擴充核心 Kubernetes API 的 APIService 可能根本不提供表格回應。如果您正在實作使用表格資訊且必須針對所有資源類型(包括擴充功能)工作的用戶端,則應發出在 Accept
標頭中指定多個內容類型的請求。例如
Accept: application/json;as=Table;g=meta.k8s.io;v=v1, application/json
資源刪除
當您 delete 資源時,這會分兩個階段進行。
- 最終確定
- 移除
{
"kind": "ConfigMap",
"apiVersion": "v1",
"metadata": {
"finalizers": ["url.io/neat-finalization", "other-url.io/my-finalizer"],
"deletionTimestamp": nil,
}
}
當用戶端首次傳送 delete 以請求移除資源時,.metadata.deletionTimestamp
會設定為目前時間。一旦設定了 .metadata.deletionTimestamp
,作用於 finalizer 的外部控制器可以隨時以任何順序開始執行其清理工作。
finalizer 之間不強制執行順序,因為這會引入 .metadata.finalizers
卡住的重大風險。
.metadata.finalizers
欄位是共用的:任何具有權限的角色都可以重新排序它。如果 finalizer 列表按順序處理,則可能會導致以下情況:列表中第一個 finalizer 的組件正在等待列表中稍後 finalizer 的組件產生的某些訊號(欄位值、外部系統或其他),從而導致死鎖。
在沒有強制排序的情況下,finalizer 可以自由地在彼此之間排序,並且不易受到列表中排序變更的影響。
一旦最後一個 finalizer 被移除,資源就會實際從 etcd 中移除。
強制刪除
Kubernetes v1.32 [alpha]
(預設啟用:false)注意
如果與資源強制刪除相關的工作負載依賴於正常的刪除流程,則可能會破壞該工作負載,因此可能會產生叢集破壞的後果。透過啟用刪除選項 ignoreStoreReadErrorWithClusterBreakingPotential
,使用者可以對無法解密/損壞的資源執行不安全的強制 delete 操作。此選項位於 ALPHA 功能閘道之後,預設情況下處於停用狀態。為了使用此選項,叢集運營商必須透過設定命令列選項 --feature-gates=AllowUnsafeMalformedObjectDeletion=true
來啟用該功能。
注意
執行強制 delete 操作的使用者必須具有對給定資源執行 delete 和 unsafe-delete-ignore-read-errors 動詞的權限。如果資源由於 a) 轉換錯誤(例如:解密失敗)或 b) 物件無法解碼而無法從儲存體成功檢索,則該資源被視為已損壞。API 伺服器首先嘗試正常刪除,如果因 *損壞的資源* 錯誤而失敗,則會觸發強制刪除。強制 delete 操作是不安全的,因為它忽略 finalizer 約束並跳過先決條件檢查。
此選項的預設值為 false
,這保持了向後相容性。對於 ignoreStoreReadErrorWithClusterBreakingPotential
設定為 true
的 delete 請求,欄位 dryRun
、gracePeriodSeconds
、orphanDependents
、preconditions
和 propagationPolicy
必須保持未設定狀態。
注意
如果使用者對其他可讀資源發出ignoreStoreReadErrorWithClusterBreakingPotential
設定為 true
的 delete 請求,則 API 伺服器會中止請求並顯示錯誤。單一資源 API
Kubernetes API 動詞 get、create、update、patch、delete 和 proxy 僅支援單一資源。這些支援單一資源的動詞不支援在有序或無序列表或交易中一起提交多個資源。
當用戶端(包括 kubectl)作用於一組資源時,用戶端會發出一系列單一資源 API 請求,然後在需要時聚合回應。
相比之下,Kubernetes API 動詞 list 和 watch 允許獲取多個資源,而 deletecollection 允許刪除多個資源。
欄位驗證
Kubernetes 始終驗證欄位的類型。例如,如果 API 中的欄位定義為數字,則您不能將該欄位設定為文字值。如果欄位定義為字串陣列,則您只能提供陣列。某些欄位允許您省略它們,其他欄位是必填的。從 API 請求中省略必填欄位是一個錯誤。
如果您發出的請求帶有額外欄位,即叢集控制平面無法識別的欄位,則 API 伺服器的行為會更複雜。
預設情況下,API 伺服器會從收到的輸入中刪除它無法識別的欄位(例如,PUT
請求的 JSON 主體)。
在兩種情況下,API 伺服器會刪除您在 HTTP 請求中提供的欄位。
這些情況是
- 該欄位無法識別,因為它不在資源的 OpenAPI 綱要中。(此規則的一個例外是 CRD,它們明確選擇不透過
x-kubernetes-preserve-unknown-fields
修剪未知欄位)。 - 該欄位在物件中重複。
對無法識別或重複欄位的驗證
Kubernetes v1.27 [stable]
(預設啟用:true)從 1.25 開始,當您使用可以提交資料的 HTTP 動詞(POST
、PUT
和 PATCH
)時,物件中無法識別或重複的欄位會透過伺服器上的驗證來偵測。可能的驗證等級為 Ignore
、Warn
(預設)和 Strict
。
忽略
- API 伺服器成功處理請求,就像沒有設定錯誤欄位一樣,刪除所有未知和重複的欄位,並且不指示它已這樣做。
警告
- (預設)API 伺服器成功處理請求,並向用戶端報告警告。警告使用
Warning:
回應標頭傳送,為每個未知或重複的欄位新增一個警告項目。有關警告和 Kubernetes API 的更多資訊,請參閱部落格文章 Warning: Helpful Warnings Ahead。 嚴格
- 當 API 伺服器偵測到任何未知或重複的欄位時,會拒絕請求並顯示 400 Bad Request 錯誤。來自 API 伺服器的回應訊息指定了 API 伺服器偵測到的所有未知或重複的欄位。
欄位驗證等級由 fieldValidation
查詢參數設定。
注意
如果您提交的請求指定了無法識別的欄位,並且由於另一個原因(例如,請求為已知欄位提供了字串值,而 API 期望整數值)也無效,則 API 伺服器會回應 400 Bad Request 錯誤,但不會提供有關未知或重複欄位的任何資訊(僅提供它首先遇到的致命錯誤)。
在這種情況下,無論您請求的欄位驗證等級為何,您始終會收到錯誤回應。
向伺服器提交請求的工具(例如 kubectl
)可能會設定與 API 伺服器預設使用的 Warn
驗證等級不同的預設值。
kubectl
工具使用 --validate
標誌來設定欄位驗證等級。它接受值 ignore
、warn
和 strict
,同時也接受值 true
(相當於 strict
)和 false
(相當於 ignore
)。kubectl 的預設驗證設定為 --validate=true
,這表示嚴格的伺服器端欄位驗證。
當 kubectl 無法連線到具有欄位驗證的 API 伺服器(Kubernetes 1.27 之前的 API 伺服器)時,它將回退到使用用戶端驗證。用戶端驗證將在未來版本的 kubectl 中完全移除。
注意
在 Kubernetes 1.25 之前,kubectl --validate
用於切換用戶端驗證的開關,作為布林標誌。Dry-run
Kubernetes v1.19 [stable]
(預設啟用:true)當您使用可以修改資源的 HTTP 動詞(POST
、PUT
、PATCH
和 DELETE
)時,您可以在 *dry run* 模式下提交請求。Dry run 模式有助於評估請求通過典型的請求階段(準入鏈、驗證、合併衝突)直到將物件持久化到儲存體。請求的回應主體盡可能接近非 dry-run 回應。Kubernetes 保證 dry-run 請求不會持久化到儲存體或產生任何其他副作用。
發出 dry-run 請求
Dry-run 是透過設定 dryRun
查詢參數觸發的。此參數是一個字串,作為列舉使用,唯一接受的值為
- [未設定值]
- 允許副作用。您可以使用查詢字串(例如
?dryRun
或?dryRun&pretty=true
)請求此選項。回應是最終將被持久化的物件,如果請求無法完成,則為錯誤。 All
- 每個階段都像往常一樣執行,除了防止副作用的最終儲存階段。
當您設定 ?dryRun=All
時,任何相關的準入控制器都會執行,驗證準入控制器會檢查請求的後變更,合併在 PATCH
上執行,欄位會預設,並且會發生綱要驗證。變更不會持久化到底層儲存體,但仍會將最終將被持久化的物件以及正常狀態碼返回給使用者。
如果請求的非 dry-run 版本將觸發具有副作用的準入控制器,則請求將會失敗,而不是冒不必要的副作用的風險。所有內建準入控制外掛程式都支援 dry-run。此外,準入 webhook 可以在其 配置物件 中宣告它們沒有副作用,方法是將其 sideEffects
欄位設定為 None
。
注意
如果 webhook 實際上確實具有副作用,則應將sideEffects
欄位設定為 "NoneOnDryRun"。如果 webhook 也被修改為理解 AdmissionReview 中的 DryRun
欄位,並防止在任何標記為 dry-run 的請求上產生副作用,則此變更適用。以下是使用 ?dryRun=All
的 dry-run 請求範例
POST /api/v1/namespaces/test/pods?dryRun=All
Content-Type: application/json
Accept: application/json
回應看起來與非 dry-run 請求相同,但某些產生欄位的值可能有所不同。
產生值
物件的某些值通常在物件持久化之前產生。重要的是不要依賴 dry-run 請求設定的這些欄位的值,因為這些值在 dry-run 模式下可能與發出真實請求時的值不同。其中一些欄位是
name
:如果設定了generateName
,name
將具有唯一的隨機名稱creationTimestamp
/deletionTimestamp
:記錄建立/刪除時間UID
:唯一識別物件並隨機產生(非確定性)resourceVersion
:追蹤物件的持久化版本- 任何由變更準入控制器設定的欄位
- 對於
Service
資源:kube-apiserver 指派給 Service 物件的 Port 或 IP 位址
Dry-run 授權
Dry-run 和非 dry-run 請求的授權是相同的。因此,要發出 dry-run 請求,您必須被授權發出非 dry-run 請求。
例如,要對 Deployment 執行 dry-run patch,您必須被授權執行該 patch。以下是 Kubernetes RBAC 的規則範例,該規則允許 patch Deployment
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["patch"]
請參閱 授權概觀。
更新現有資源
Kubernetes 提供了幾種更新現有物件的方法。您可以閱讀 選擇更新機制 以了解哪種方法最適合您的用例。
您可以使用 HTTP PUT 覆寫(update)現有資源 - 例如 ConfigMap。對於 PUT 請求,用戶端有責任指定 resourceVersion
(從正在更新的物件中獲取)。Kubernetes 使用該 resourceVersion
資訊,以便 API 伺服器可以偵測遺失的更新並拒絕用戶端過時的請求。如果資源已變更(用戶端提供的 resourceVersion
已過時),則 API 伺服器會返回 409 Conflict
錯誤回應。
用戶端可以傳送指示給 API 伺服器以 patch 現有資源,而不是傳送 PUT 請求。如果用戶端想要進行的變更不是以現有資料為條件的,則 patch 通常是合適的。需要有效偵測遺失更新的用戶端應考慮使其請求以現有的 resourceVersion
為條件(HTTP PUT 或 HTTP PATCH),然後處理發生衝突時所需的任何重試。
Kubernetes API 支援四種不同的 PATCH 操作,由其對應的 HTTP Content-Type
標頭確定
application/apply-patch+yaml
- 伺服器端套用 YAML(基於 YAML 的 Kubernetes 特定擴充功能)。所有 JSON 文件都是有效的 YAML,因此您也可以使用此媒體類型提交 JSON。有關更多詳細資訊,請參閱 伺服器端套用序列化。
對於 Kubernetes 而言,如果物件不存在,則這是 create 操作,如果物件已存在,則這是 patch 操作。 application/json-patch+json
- JSON Patch,如 RFC6902 中定義。JSON patch 是一系列在資源上執行的操作;例如
{"op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ]}
。
對於 Kubernetes 而言,這是 patch 操作。使用
application/json-patch+json
的 patch 可以包含條件來驗證一致性,如果未滿足這些條件,則允許操作失敗(例如,避免遺失更新)。 application/merge-patch+json
- JSON 合併修補(Merge Patch),如 RFC7386 中所定義。JSON 合併修補本質上是資源的部分表示法。提交的 JSON 會與目前的資源合併以建立一個新的資源,然後儲存這個新的資源。
對於 Kubernetes 而言,這是 patch 操作。 application/strategic-merge-patch+json
- 策略性合併修補(Strategic Merge Patch,Kubernetes 特定的擴充功能,基於 JSON)。策略性合併修補是 JSON 合併修補的自訂實作。您只能將策略性合併修補與內建 API 或已針對其提供特殊支援的聚合 API 伺服器搭配使用。您無法將
application/strategic-merge-patch+json
用於任何使用 CustomResourceDefinition 定義的 API。注意
Kubernetes 的伺服器端套用機制已取代策略性合併修補。
Kubernetes 的 伺服器端套用 功能允許控制平面追蹤新建立物件的受管欄位。伺服器端套用為管理欄位衝突提供清晰的模式,提供伺服器端的 套用 和 更新 操作,並取代 kubectl apply
的用戶端功能。
對於伺服器端套用,如果物件尚不存在,Kubernetes 會將請求視為 建立,否則視為 修補。對於在 HTTP 層級使用 PATCH 的其他請求,邏輯 Kubernetes 操作始終是 修補。
請參閱 伺服器端套用 以取得更多詳細資訊。
選擇更新機制
HTTP PUT 以取代現有資源
更新(HTTP PUT
)操作實作簡單且彈性,但有缺點
- 您需要處理物件的
resourceVersion
在您的用戶端讀取物件和嘗試寫回物件之間發生變更的衝突。Kubernetes 始終會偵測到衝突,但您身為用戶端作者需要實作重試。 - 如果您在本地解碼物件(例如,使用 client-go,您可能會收到您的用戶端不知道如何處理的欄位 - 然後在更新過程中捨棄它們),您可能會意外捨棄欄位。
- 如果物件上存在大量爭用(即使在您未嘗試編輯的欄位或欄位集上),您也可能難以傳送更新。對於較大的物件和具有許多欄位的物件,問題會更嚴重。
使用 JSON 修補的 HTTP PATCH
修補 更新很有幫助,因為
- 由於您只傳送差異,因此您在
PATCH
請求中需要傳送的資料較少。 - 您可以進行依賴現有值的變更,例如將特定欄位的值複製到註解中。
- 與 更新 (HTTP
PUT
) 不同,即使不相關的欄位經常變更,您的變更也可以立即發生):您通常不需要重試。- 如果您想格外小心以避免遺失更新,您可能仍然需要指定
resourceVersion
(以符合現有物件) - 在發生錯誤時,最好還是編寫一些重試邏輯。
- 如果您想格外小心以避免遺失更新,您可能仍然需要指定
- 您可以使用測試條件來仔細制定特定的更新條件。例如,如果現有值符合您的預期,您可以遞增計數器而無需讀取它。即使物件自您上次寫入以來已以其他方式變更,您也可以在沒有遺失更新風險的情況下執行此操作。(如果測試條件失敗,您可以退回到讀取目前的值,然後寫回變更後的數字)。
然而
- 您需要更多本地(用戶端)邏輯來建置修補;如果您有 JSON 修補的程式庫實作,甚至專門針對 Kubernetes 進行 JSON 修補,這會非常有幫助。
- 身為用戶端軟體的作者,您在建置修補(HTTP 請求本文)時需要小心,不要捨棄欄位(操作順序很重要)。
使用伺服器端套用的 HTTP PATCH
伺服器端套用有一些明顯的優點
- 單次往返:它很少需要先發出
GET
請求。- 您仍然可以偵測到非預期變更的衝突
- 如果適當,您可以選擇強制覆寫衝突
- 用戶端實作很容易製作。
- 您可以毫不費力地獲得原子性的建立或更新操作(類似於某些 SQL 方言中的
UPSERT
)。
然而
- 伺服器端套用完全不適用於依賴物件目前值的欄位變更。
- 您只能將更新套用至物件。Kubernetes HTTP API 中的某些資源不是物件(它們沒有
.metadata
欄位),而伺服器端套用僅與 Kubernetes 物件相關。
資源版本
資源版本是識別伺服器物件內部版本的字串。用戶端可以使用資源版本來判斷物件何時變更,或在取得、列出和監看資源時表達資料一致性需求。資源版本必須由用戶端視為不透明,並以未修改的方式傳回伺服器。
您不得假設資源版本是數字或可排序的。API 用戶端只能比較兩個資源版本是否相等(這表示您不得比較資源版本的大小關係)。
metadata 中的 resourceVersion
欄位
用戶端可以在資源中找到資源版本,包括來自 監看 的回應串流中的資源,或在使用 list 列舉資源時。
v1.meta/ObjectMeta - 資源執行個體的 metadata.resourceVersion
識別執行個體上次修改時的資源版本。
v1.meta/ListMeta - 資源集合(對 list 的回應)的 metadata.resourceVersion
識別建構集合時的資源版本。
查詢字串中的 resourceVersion
參數
get、list 和 watch 操作支援 resourceVersion
參數。從 v1.19 版開始,Kubernetes API 伺服器也支援 list 請求上的 resourceVersionMatch
參數。
API 伺服器會根據您請求的操作以及 resourceVersion
的值,以不同的方式解譯 resourceVersion
參數。如果您設定 resourceVersionMatch
,則這也會影響比對的發生方式。
get 和 list 的語意
對於 get 和 list,resourceVersion
的語意如下
get
resourceVersion 未設定 | resourceVersion="0" | resourceVersion="{0 以外的值}" |
---|---|---|
最新版本 | 任何版本 | 不早於 |
list
從 v1.19 版開始,Kubernetes API 伺服器支援 list 請求上的 resourceVersionMatch
參數。如果您同時設定 resourceVersion
和 resourceVersionMatch
,則 resourceVersionMatch
參數會決定 API 伺服器如何解譯 resourceVersion
。
當在 list 請求上設定 resourceVersion
時,您應始終設定 resourceVersionMatch
參數。但是,請準備好處理回應的 API 伺服器不知道 resourceVersionMatch
並忽略它的情況。
除非您有強烈的一致性要求,否則使用 resourceVersionMatch=NotOlderThan
和已知的 resourceVersion
是較佳的選擇,因為與讓 resourceVersion
和 resourceVersionMatch
未設定相比,它可以實現更好的效能和叢集可擴展性,後者需要仲裁讀取才能提供服務。
在未設定 resourceVersion
的情況下設定 resourceVersionMatch
參數是無效的。
下表說明具有 resourceVersion
和 resourceVersionMatch
各種組合的 list 請求的行為
resourceVersionMatch 參數 | 分頁參數 | resourceVersion 未設定 | resourceVersion="0" | resourceVersion="{0 以外的值}" |
---|---|---|---|---|
未設定 | limit 未設定 | 最新版本 | 任何版本 | 不早於 |
未設定 | limit=<n>,continue 未設定 | 最新版本 | 任何版本 | 精確 |
未設定 | limit=<n>,continue=<token> | Continue 權杖,精確 | 無效,視為 Continue 權杖,精確 | 無效,HTTP 400 Bad Request |
resourceVersionMatch=Exact | limit 未設定 | 無效 | 無效 | 精確 |
resourceVersionMatch=Exact | limit=<n>,continue 未設定 | 無效 | 無效 | 精確 |
resourceVersionMatch=NotOlderThan | limit 未設定 | 無效 | 任何版本 | 不早於 |
resourceVersionMatch=NotOlderThan | limit=<n>,continue 未設定 | 無效 | 任何版本 | 不早於 |
注意
如果您的叢集 API 伺服器不接受resourceVersionMatch
參數,則行為與您未設定它的情況相同。get 和 list 語意的含義是
- 任何版本
- 傳回任何資源版本的資料。最新的可用資源版本是首選,但不要求強烈的一致性;可以提供任何資源版本的資料。請求可能會傳回比用戶端先前觀察到的資源版本還要舊很多的資料,尤其是在高可用性組態中,由於分割或過時的快取。無法容忍此情況的用戶端不應使用此語意。
- 最新版本
- 傳回最新資源版本的資料。傳回的資料必須一致(詳細資訊:從 etcd 透過仲裁讀取提供服務)。對於 etcd v3.4.31+ 和 v3.5.13+,Kubernetes 1.32 從監看快取提供「最新」讀取:API 伺服器內部的內部記憶體儲存區,用於快取和鏡像到 etcd 中持久保存的資料狀態。Kubernetes 請求進度通知以維持快取與 etcd 持久層的一致性。Kubernetes 版本 v1.28 到 v1.30 也支援此功能,雖然作為 Alpha 版本,但不建議用於生產環境,並且在 v1.31 版本之前預設未啟用。
- 不早於
- 傳回至少與提供的
resourceVersion
一樣新的資料。最新的可用資料是首選,但可以提供任何不早於提供的resourceVersion
的資料。對於向接受resourceVersionMatch
參數的伺服器發出的 list 請求,這保證集合的.metadata.resourceVersion
不早於請求的resourceVersion
,但不保證該集合中任何項目的.metadata.resourceVersion
。 - 精確
- 傳回與提供的確切資源版本對應的資料。如果提供的
resourceVersion
不可用,伺服器會以 HTTP 410 "Gone" 回應。對於向接受resourceVersionMatch
參數的伺服器發出的 list 請求,這保證集合的.metadata.resourceVersion
與您在查詢字串中請求的resourceVersion
相同。該保證不適用於該集合中任何項目的.metadata.resourceVersion
。 - Continue 權杖,精確
- 傳回初始分頁 list 呼叫的資源版本的資料。傳回的 continue 權杖 負責追蹤初始分頁 list 之後的所有分頁 list 呼叫的初始提供資源版本。
注意
當您 list 資源並收到集合回應時,回應會包含集合的 list metadata 以及該集合中每個項目的 object metadata。對於在集合回應中找到的個別物件,.metadata.resourceVersion
追蹤該物件上次更新的時間,而不是物件在提供服務時的最新程度。當使用 resourceVersionMatch=NotOlderThan
且設定了 limit 時,用戶端必須處理 HTTP 410 "Gone" 回應。例如,用戶端可能會使用較新的 resourceVersion
重試,或退回到 resourceVersion=""
。
當使用 resourceVersionMatch=Exact
且 limit
未設定時,用戶端必須驗證集合的 .metadata.resourceVersion
是否與請求的 resourceVersion
相符,並處理不相符的情況。例如,用戶端可能會退回到設定了 limit
的請求。
watch 的語意
對於 watch,資源版本的語意如下
watch
resourceVersion 未設定 | resourceVersion="0" | resourceVersion="{0 以外的值}" |
---|---|---|
取得狀態並從最新版本開始 | 取得狀態並從任何版本開始 | 從精確版本開始 |
這些 watch 語意的含義是
- 取得狀態並從任何版本開始
- 從任何資源版本開始 watch;最新的可用資源版本是首選,但不要求。允許任何起始資源版本。watch 可能會從比用戶端先前觀察到的資源版本還要舊很多的資源版本開始,尤其是在高可用性組態中,由於分割或過時的快取。無法容忍此明顯倒帶的用戶端不應使用此語意啟動 watch。為了建立初始狀態,watch 會從針對在起始資源版本存在的所有資源執行個體的合成 "Added" 事件開始。所有後續的監看事件都是針對在 watch 開始的資源版本之後發生的所有變更。
注意
以此方式初始化的監看可能會傳回任意過時的資料。請在使用此語意之前檢閱它,並盡可能優先選擇其他語意。 - 取得狀態並從最新版本開始
- 從最新的資源版本開始 watch,該版本必須是一致的(詳細資訊:從 etcd 透過仲裁讀取提供服務)。為了建立初始狀態,watch 會從針對在起始資源版本存在的所有資源執行個體的合成 "Added" 事件開始。所有後續的監看事件都是針對在 watch 開始的資源版本之後發生的所有變更。
- 從精確版本開始
- 從精確的資源版本開始 watch。監看事件是針對提供的資源版本之後的所有變更。與「取得狀態並從最新版本開始」和「取得狀態並從任何版本開始」不同,watch 不會從針對提供的資源版本的合成 "Added" 事件開始。用戶端假定已經擁有起始資源版本的初始狀態,因為用戶端提供了資源版本。
"410 Gone" 回應
伺服器不需要提供所有較舊的資源版本,如果用戶端請求的 resourceVersion
比伺服器保留的版本還舊,則可能會傳回 HTTP 410 (Gone)
狀態碼。用戶端必須能夠容忍 410 (Gone)
回應。請參閱 有效偵測變更 以取得有關如何在監看資源時處理 410 (Gone)
回應的詳細資訊。
如果您請求的 resourceVersion
超出適用限制,則根據請求是否從快取提供服務,API 伺服器可能會回覆 410 Gone
HTTP 回應。
無法使用的資源版本
伺服器不需要提供無法辨識的資源版本。如果您請求 list 或 get API 伺服器無法辨識的資源版本,則 API 伺服器可能會
- 短暫等待資源版本變成可用,然後在提供的資源版本在合理的時間內未變成可用時,逾時並傳回
504 (Gateway Timeout)
; - 回覆
Retry-After
回應標頭,指示用戶端應等待多少秒才能重試請求。
如果您請求 API 伺服器無法辨識的資源版本,kube-apiserver 還會使用 "資源版本過大" 訊息來識別其錯誤回應。
如果您對無法辨識的資源版本發出 watch 請求,API 伺服器可能會無限期地等待(直到請求逾時)資源版本變成可用。