• k8s的对象管理二(详解path与RFC7386)


    一:概述:

    根据(一)的kubectl命令可以发现,资源的更新可以是命令式的也可以是声明式的,

    所谓命令式的,顾名思义就是我直接设置某个字段是什么样子的

    所谓声明式的,顾名思义就是我想让某个字段是什么样子的

    二者的执行对应到真正调用后端的api时是有差别的,前者是直接replace,后者则是商量着来,有可能直接replace也有可能merge(见。。。。)

    所以,接下来我们一起从API的角度来探讨下replace和patch的区别

    二:资源更新(update)的两种方式

    参考官网;https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#podspec-v1-core

    想对指定资源进行更新操作,API server给我们提供了两种形式的api,分别如下

    1. Replace

       这种方式是将当前资源的spec替换为指定的。这是一个read-then-write的操作,而且因为如果在read 和 write之间资源有发生变化,那么就会发生乐观锁的失败,所以这个操作是安全的。

       注;replace操作中ResourceStatus 会被系统忽略,并不会被更新,若想更新这个字段,则必须触发那些会引起该状态变化的行为才行。也就是说有,甭想通过replace命令直接更新状态,只有通过让相应的事件发生,才能间接的刷新对应的状态。

    常用的replace API有:

    2.Patch

    这种方式是对指定的spec字段应用一个"变更"操作,所谓的应用是指将"变更"合并到每一个filed上,合并的过程中会根据filed类型的不同或是替换(replace),或是合并(merge).

    patch操作不会引发乐观锁失败,只有最后一次写生效。如果你无法读取object的完整状态或者不希望乐观所失败,那么就推荐你使用Patch操作。

    当你Patching的是复杂的类型如arrays, map,那么具体的patch是如何被应用到每个filed上的,则取决于每个字段的

    三:详解Patch操作

    可能是替换当前值,也可能是与当前值进行合并,具体要根据k8s的源码以及????而定,见下个章节
    一:patch API缺省情况下执行的是是"strategic merge patch",即是一种按照field在源码中定义的策略属性进行的patch操作,具体是什么策略呢?
    这个策略被定义在 Kubernetes的源码中,以filed的tag的形式存在,具体为key等于patchStrategy那个tag
    type PodSpec struct {
      ...
      Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`
    }
    解析:
    1.patchStrategy的vlaue可以取值merge或replace,缺省为replace,即如果源码中没有这个类型的tag,则表示这个filed在patch的时候是替换操作

    获取这个field的策略,则通过api(???什么api)来得知

    二:除了缺省的"strategic merge patch",patch API还支持在调用API的时候指定type参数来决定怎么patch,具体如下
    1.JSON merge patch
    用法(k8s):
      命令行:  --type merge
      API: "Content-Type:merge-patch+json"
      特点:如果想要更新一个list,你的patch request中必须囊括了整个list,因为他会将行list完全替换掉旧的list
    原理(RFC 7386):

    2.JSON patch
    用法(k8s):
      命令行:  --type json
      API: "Content-Type:json-patch+json"
      特点:如果想要更新一个list,你的patch request中必须囊括了整个list,因为他会将行list完全替换掉旧的list
    原理(RFC 7386):

    另外,对于缺省"strategic merge patch"方式,相当于
    命令行:  --type strategic
    API: "Content-Type:strategic-merge-patch+json"
     
    三:JSON merge patch和JSON patch的用法
    1.JSON Patch
    这种类型的patch操作要求Patch请求以["op","path","value"]三元组的形式来定义
    "op": operation,代表要执行怎样的操作,可以是"add", "remove", "replace", "move" 和 "copy"
    "path":被操作对象的位置, 表示处于json文件的哪个位置的fragment,通俗的说就是json格式下的逻辑位置
    "value": 用于操作的值
    具体工作原理用如下例子阐述:
    例1:
    1)一个object的json形式描述文件如下
    {
      "users" : [
        { "name" : "Alice" , "email" : "alice@example.org" },
        { "name" : "Bob" , "email" : "bob@example.org" }
      ]
    }

    2)patch请求的json形式描述如下:

    [
        {
            "op" : "replace" ,                 ---我要做"替换"操作  
            "path" : "/users/0/email" ,        ---替换的对象是users数组的第1个元素的email字段
            "value" : "alice@wonderland.org"   ---要替换成的值是"alic...."
        },
        {
            "op" : "add" ,                     ---我要做"添加"操作 
            "path" : "/users/-" ,              ---增加的对象是users数组的下一级,即称为user的一个元素
            "value" : {                        ---增加的值是一个{...}
                "name" : "Christine", 
                "email" : "christine@example.org"
            }
        }
    ]
    3)patch后得到的结果如下:
    {
        "users" : [
            { "name" : "Alice" , "email" : "alice@wonderland.org" },      --被替换
            { "name" : "Bob" , "email" : "bob@example.org" },            --没变  
            { "name" : "Christine" , "email" : "christine@example.org" }  --新增的
        ]
    }
    1.JSON Merge Patch
    这种类型的patch操作的Patch请求描述的是"变化信息"即"changed version of a JSON document"
    具体工作原理用如下例子阐述:
    例2:
    1)一个object的json形式描述文件如下
    {
        "a": "b",
        "c": {
            "d": "e",
            "f": "g"
        }
    }
    2)patch请求的json形式描述如下:
    {
        "a":"z",   ---我想让a变成z
        "c": {     ---我想让c的f变成null(代表删除)
            "f": null
        }
    }
    3)patch后得到的结果如下:
    {
        "a": "z",
        "c": {
            "d": "e",
        }
    }
    特点:
    1.无法将值设置成null,因为在这里设置成null意味着删除
    2.操作array比较麻烦,因为你必须全部写下,否则就会将旧array完全替换成新的,并不会发生"合并"
    3.执行patch操作后,永远不会报错
    wxy:
    另外,kubectl patch命令是一个直接的调用patch api的操作,即直接将patch的内容作为patch request调用api
         而kubectl apply则隐含了先计算patch request的内容,然后再调用patch api
  • 相关阅读:
    linuxshell中"2>&1"含义
    Java中正数与负数操作>>、>>>的区别
    jsp el表达式
    struct2常用标签
    shell正则表达式
    IPV6学起来很费力?你看看,也就这样简单吧!
    STP、RSTP、MSTP合集思维导图
    HCIE之路--ISIS思维导图
    佛祖保佑,永不宕机! 永无BUG!
    震惊!ARP安全竟然还可以这样配置?
  • 原文地址:https://www.cnblogs.com/shuiguizi/p/12823071.html
Copyright © 2020-2023  润新知