zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    网友谈:Dictionary.ContainsKey和List.BinarySearch哪个效率高
    C# WinForm 中在窗口标题栏上加按钮
    将Txt文件转换成dataset[原创]
    四个常见的排序算法[原创]
    改版后的groupbox[原创]
    转 五种提高 SQL 性能的方法
    转 牢记!SQL Server数据库开发的二十一条军规(SQL收藏)
    源码详解Java的反射机制
    java多线程采集+线程同步
    jQgrid API
  • 原文地址:https://www.cnblogs.com/shuiguizi/p/12776761.html
Copyright © 2011-2022 走看看