k8s的對象管理一(命令式與聲明式API)


官方文檔:https://kubernetes.io/docs/concepts/overview/working-with-objects/object-management/

     https://kubernetes.io/docs/tasks/manage-kubernetes-objects

 

k8s在管理對象(增刪改查資源)時可以有如下三種方式

 

1.幾個關鍵的概念

  • object configuration file / configuration file: A file that defines the configuration for a Kubernetes object. 使用的時候會pass configuration files to kubectl apply. Configuration files are typically stored in source control, such as Git. 點評: 重點在於他就是一個文件,一各定義object的用戶寫的文件。
  • live object configuration / live configuration: The live configuration values of an object, as observed by the Kubernetes cluster. These are kept in the Kubernetes cluster storage, typically etcd.點評:重點在於他是object的"屬性"值,且這些"屬性"值是k8s集群生成,存儲在集群中的。
  • declarative configuration writer / declarative writer: A person or software component that makes updates to a live object. The live writers will make changes to object configuration files and run kubectl apply to write the changes. 點評: 重點在於他是應用於聲明式場景中,表示將被應用到object,從而去改變某些"屬性".

2`方式一:命令式命令(Imperative commands)

顧名思義,首先,他是以下發命令的形式(Imperative)直接操作object,即我命令(run/create/replace)xxx做什么什么....

                  然后,命令的對象是Live object,通過命令的方式(commands)直接指定,即直接在命令行中指定是deployment還是什么,也包括一些參數則用flag

                  最后,被操作的的對象具體變成什么樣子則交給系統了

特點:1)僅需一步就對集群做了修改

例子:創建一個deployment類型的object

kubectl run nginx --image nginx

kubectl create deployment nginx --image nginx

 # kubectl run nginx --image nginx
kubectl run --generator=deployment/apps.v1beta1 is DEPRECATED and will be removed in a future version. Use kubectl create instead.
deployment.apps/nginx created
# kubectl get deployment |grep nginx
nginx                          1         1         1            0           32s

# kubectl get pods|grep nginx
nginx-dbddb74b8-qt7zv                           0/1     ImagePullBackOff   0          86s

 

 

 命令:

1)創建object,例如run(表示要run一個pod,缺省會創建deployment), create:創建指定類型的object,比如deployment

2)更新object,例如edit(直接編輯一個live object的raw configuration), patch: 直接改live object。。。。。

3)刪除object,  例如delete

4)查看pbject,例如get,describe,logs等

 

 

 

方式二:對象配置式命令(Imperative object configuration)

顧名思義,首先,同樣是下發命令(Imperative),即我命令(create/replace...)xxx做什么什么....

                  但是,命令的對象是Individual files(一個文件),文件中的內容是a full definition of the object in YAML or JSON format;整個命令可以指定多個文件,但是每個文件都是獨立的,相當於兩條獨立的操作放在一條命令中,並不會將多個文件合並再操作。

                  最后,被操作的的對象會被系統按照配置文件進行具體操作了

特點:1)只能指定文件名稱,不可以是目錄

           2)可以將想要做的事情以文件的形式存放,方便管理(比如執行前檢查,比如放到git上等)

           3)在使用replace命令的時候需要特別注意: replace命令會將當前obeject的spec完全替換成新的,所謂完全替換意味着會dropping all changes to the object missing from the configuration file(wxy: 意思應該是說如果object已經存在某些spec,但是新配置文件中沒有這方面的信息,那么就直接將這些參數去掉,也就是"全方位的替換")。另外,這種方式不要用在那些spec的更新不依賴配置文件的資源類型中,比如LoadBalancer類型的Services,他的externalIPs字段是由對應的LoadBalancer所更新(wxy:不知道如果就用了會怎樣?)

         ???? 4) 使用create, replace和delete命令時,如果定義的object' configuration已經被記錄到object的configuration里面了,則啥也不會發生;但一旦一個live object被update但還沒來及merge到configuration file中,則如果此時有replace操作,那么上一次update操作丟失,即

1)根據用戶定義的configuration文件創建新資源

2)一個update操作來了

3)又一個帶着新configuration的replace請求來了,那么2)中的update將會lost

 

例子:

#將在這兩個文件中定義的object刪除
kubectl delete -f nginx.yaml -f redis.yaml

 

命令:

除了run?其余和命令式命令相同?

 

方式三:聲明式對象配置(Declarative object configuration)

 https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/

顧名思義,首先,只是聲明(Imperative)一下,即我想要我的object什么什么樣子都定義在配置文件中了;

                  並且,操作的對象是Directories of files(多個文件),所謂的動作就是apply;

                  最后,kubectl會根據情況自動檢測出針對某個object具體是執行什么動作(create,update,delete)。

 

 

例子:

1.當沒有這個資源的時候,apply操作會創建對應的資源,
# kubectl apply -f ./

2.查看該資源的live configuration,發現如下:
  1)生成annotations:  kubectl.kubernetes.io/last-applied-configuration,將configuration file的內容完整記錄下來了中記錄了完整的
  2)configuration file中沒有指定replicas的信息,於是生成后為缺省值1
# kubectl get deployment nginx-deployment -oyaml
# kubectl get -f ./simple_deployment.yaml -oyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx","ports":[{"containerPort":80}]}]}}}}
  creationTimestamp: 2020-05-03T08:46:37Z
spec:
  minReadySeconds: 5
  progressDeadlineSeconds: 600
  replicas: 1

3.使用命令式命令的方式擴容為2
# kubectl scale deployment/nginx-deployment --replicas=2

4.此時並不會更改kubectl.kubernetes.io/last-applied-configuration的內容,因為他就是記錄的apply的configuration file的內容
# kubectl get deployment nginx-deployment -oyaml
...
 annotations:
    deployment.kubernetes.io/revision: "1"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},"spec":{"minReadySeconds":5,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.14.2","name":"nginx","ports":[{"containerPort":80}]}]}}}}
  creationTimestamp: 2020-05-03T08:46:37Z
 ...
  replicas: 2
  
  
5.更改configuration file的內容,刪除一項,修改一項
 # vi ./simple_deployment.yaml
  minReadySeconds: 5     ---刪除
    image: nginx:1.16.2  ---修改
    
    
6.重新執行聲明式命令,然后查看live configuration,發現如下的改變
1)kubectl.kubernetes.io/last-applied-configuration隨着配置文件變更而變更
2)live configuration被以patch的方式進行修改,即:以configuration file為基准修改,他沒提到的保持不變
# kubectl apply -f ./
# kubectl get deployment nginx-deployment -oyaml
...
  annotations:
    deployment.kubernetes.io/revision: "2"
    kubectl.kubernetes.io/last-applied-configuration: |   ---被刷新
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"nginx-deployment","namespace":"default"},"spec":{"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.16.2","name":"nginx","ports":[{"containerPort":80}]}]}}}}
  creationTimestamp: 2020-05-03T08:46:37Z
  ...
  replicas: 2                  ----保持不變
  ...
      - image: nginx:1.16.2    ----被修改

 

 

 

實現原理:

核心思想是apply命令使用的是patch API,該API可以認為是一種update操作,操作的范圍是object的指定字段而不是整個object,具體的工作步驟如下

1.kubectl apply命令(即kubectl)計算patch請求, 計算步驟如下:

   1)計算哪些字段需要被刪除:last-applied-configuration中有的,但是新配置文件(configuration file)中沒有的

   2)計算哪些字段需要添加或者設置的:新配置文件(configuration file)中有,但是與 live configuration中的值不匹配(比如沒有,或者值不同)

   3)設置一個新的last-applied-configuration annotation,使其值與配置文件(configuration file)匹配

   4)將上述 1) 2) 3)得到的結果進行融合,最終得到一個信息的patch請求,並發往API server

 

 

2.向patch API發送請求。

   請求中存放的是"差別"信息,然后API Server會將這些“差別信息”與該object 的live configuration進行合並,合並的過程中,會因為字段的類型不同,而有不同的處理方式:

   1)原生類型:比如 string, integer, or boolean,則直接替換處理;

   2)map(也稱為object)類型:則將其元素或子字段進行合並處理;

   3)list類型:list中的條目可以是原生類型或map類型,則根據1) 和2)分別處理。

   另:  更詳細的處理細節參考官網

 

 

 

 

 

特點:

1)使用kubectl apply命令被稱為"managed by kubectl apply",原因為這是一個管理的命令,包含了create/update/delete操作

2)聲明式對象配置會retains changes made by other writers, even if the changes are not merged back to the object configuration file. 這是因為這種方式使用的是patch API,這種操作只會寫入 observed differences, 而不似replace API 那般,直接替換整個object的配置文件。

3) 不支持與命令式配置文件方式混合使用,這是因為后者的create和replace操作沒有kubectl.kubernetes.io/last-applied-configuration,而這卻恰恰是apply賴以生存的部分。

    經試驗發現,使用create創建,使用apply修改也是可以的,后者的操作會為object的live configuration增加該annotation,只不過會爆出警告,如下:

   

//1.命令式創建object, 此時是沒有annotation的
# kubectl create -f ./simple_deployment.yaml
或
# kubectl create deployment nginx-deployment --image nginx

//2.經過apply,盡管會報錯,但仍會添加annotation,且參數也會依照object configuration file而變更
# kubectl apply -f ./
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps/nginx-deployment configured

 

4)關於刪除那些"managed by kubectl apply"的object:推薦直接使用命令式命令的方式刪除,

      也可以使用聲明式本身的刪除方式:kubectl apply -f <directory/> --prune -l your=label

 =================================


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM