Kubernetes: kubectl apply是如何達到宣告式管理?

閱讀時間約 8 分鐘

前言

在 Kubernetes 中,kubectl apply 是一種用於部署資源物件的指令,它與宣告式管理密切相關,包括可以使用kubectl apply 在 Kubernetes 中創建、更新或刪除物件。

而宣告式管理是一種資源管理模式,透過宣告一份資源的定義檔(YAML/JSON),直接將定義檔提供給叢集,由叢集自行分析與判斷該如何部署資源。

所以宣告式管理的好處就是只需要告知我想要系統達到「甚麼狀態」就好,剩下的由系統自動幫你完成,也不必關心系統如何達到該狀態。

如何部署資源物件

首先先撰寫資源的yaml定義檔案

範例:nginx.yaml

apiVersion: v1
kind: Pod
metadata:
name: myweb
labels:
type : web-server
spec:
containers:
- name: nginx
image: nginx:latest

並在當前目錄(或附上完整檔案路徑)執行kubectl apply指令

kubectl apply -f nginx.yaml

當執行指令時發生了甚麼事?

kubectl apply 在決定要進行哪些更改之前會考慮本地配置文件the local configuration file、即時配置設定(a live object configuration)以及最後應用配置(the last applied configuration)

在後台,kubernetes 中會生成一個即時配置設定live object configuration,被kubernetes叢集即時觀察著,通常儲存在kubernetes的etcd內。

我們可以使用kubectl get指令將剛剛部屬的pod的live object configuration列印出來。

kubectl get pod -f nginx -o yaml > nginx_LiveObject.yaml

顯示nginx_LiveObject.yaml內容

apiVersion: v1
kind: Pod
metadata:
labels:
type: web-server
name: myweb
spec:
containers:
- image: nginx:latest
name: nginx
status:
conditions:
- lastProbeTime: null
status: "True"
type: Initialized

可以發現這個即時配置設定與我們在本地創建的文件幾乎一致,但它會包含該資源物件狀態的更多信息,存放在status中。


那當我們對本地配置文件yaml檔案進行更動修改刪除時,kubernetes叢集要怎麼知道我們是kubectl apply一個新的資源物件還是對現有資源進行更動呢?

本地配置文件的 YAML 版本會轉換為 JSON 格式,然後存儲為最後應用配置(the last applied configuration)

{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"labels": {
"type": "web-server"
},
"name": "myweb"
},
"spec": {
"containers": [
{
"image": "nginx:latest",
"name": "nginx"
}
]
}
}

那這個最後應用配置(the last applied configuration)其實會藏在即時配置設定(a live object configuration)的Metadata裡面,以annotations的方式儲存。

顯示nginx_LiveObject.yaml內容

apiVersion: v1
kind: Pod
metadata:
name: myweb
labels:
type: web-server
annotations:
# ...
# This is the json representation of simple_deployment.yaml
# It was written by kubectl apply when the object was created
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Pod",
"metadata":{"labels":{"type":"web-server"},"name":"myweb"},
"spec": {"containers": [{"image": "nginx:latest","name": "nginx"}]}}
spec:
containers:
- image: nginx:latest
name: nginx
status:
conditions:
- lastProbeTime: null
status: "True"
type: Initialized

假設我們本地配置文件the local configuration file中刪除了一個內容,比如label中的type被刪除了。當我們運行 kubectl apply 命令時,kubernetes叢集看到最後應用配置(the last applied configuration)有一個label,但它不存在於本地配置文件the local configuration file中。

這意味著需要從即時配置設定live object configuration中刪除label中的type。

總結

宣告式管理是一種管理方法,其中您描述系統或資源的期望狀態,而不必關心實際如何達到該狀態。kubectl apply 命令在 Kubernetes 中實現了這種宣告式管理方式,以下是執行指令時的運作流程:

  1. 建立或讀取描述檔案: 使用者創建一個描述檔案(YAML 或 JSON 格式),其中包含您想要在 Kubernetes 中創建或修改的資源的規格。
  2. 使用 kubectl apply: 您執行 kubectl apply -f <檔案名稱> 命令,指定剛創建的資源描述檔案。
  3. 對比當前狀態: Kubernetes 的control plane接收描述檔案並解析其中的資源規格。它將這些規格與實際在集群中運行的資源進行比較。
  4. 檢測差異: control plane檢測描述檔案(本地配置文件the local configuration file)中的資源規格與實際狀態(最後應用配置the last applied configuration即時配置設定live object configuration)之間的差異。
  5. 執行變更: 基於差異的比較,Kubernetes control plane會自動執行必要的操作,以使集群的實際狀態接近您描述的期望狀態,包括創建、更新或刪除資源。
  6. 更新註解: 在執行變更時,kubectl apply 會將描述檔案的內容記錄為實際資源的一個註解(annotations),稱為 kubectl.kubernetes.io/last-applied-configuration,幫助後續kubernetes叢集管理的比較和回滾。


如果你喜歡這篇文章歡迎幫我按愛心鼓勵一下喔!~閱讀愉快!

# Vocus的程式碼好像會把縮排全部吃掉==,yaml/json格式可能有跑版...

17會員
34內容數
歡迎來到「Marcos的方格子」!目前在「Marcos談科技」撰寫在職涯上學習到的知識,在「Marcos談書」分享我在日常的閱讀和心得,歡迎您的到來!!
留言0
查看全部
發表第一個留言支持創作者!