k8s patch 的幾種方式

  • 序言
  • JSON Patch
  • JSON Merge Patch
  • JSON Patch 與 JSON Merge Patch 對比
  • Strategic Merge Patch
  • 總結(jié)
  • 參考

序言

在更新 k8s 資源的時候,除了 update 這種方式讥珍,k8s 也提供了 patch 來進(jìn)行資源的更新誉券。

通過 kubectl patch 來更新的時候策州,也提供了不同的更新方式


kubectl patch help

這里的三種方式對應(yīng)的就是 JSON Patch诞丽、JSON Merge Patch 以及 k8s 自定義的 Strategic Merge Patch鹉勒。

今天我們來看下這三種方式分別都是怎么工作的磅轻,讓大家能有一個大概的認(rèn)識珍逸,在選擇方案的時候,能有所幫助聋溜。

因為 Json Patch 和 Json Merge Patch 大家在其他的很多地方也會用到谆膳,因此使用場景會更多,所以會優(yōu)先講解這兩種方式撮躁,我也建議大家先搞懂這兩種方式漱病。

Strategic Merge Patch 只有在更新 k8s 的標(biāo)準(zhǔn)資源的時候才會有(截止今天,不支持自定義資源通過這種方式進(jìn)行更新)把曼,因此放在最后講解杨帽。

Json Patch

Json Patch 是一種比較好理解的方式,當(dāng)你更新 json 文檔的時候嗤军,你可以通過直接指定 'op' 'path' 'value' 來完成注盈,比如如下 patch 數(shù)據(jù)。op 代表了執(zhí)行的操作類型(目前在 RFC 文檔中指定了有六種叙赚,分別是 add老客、remove 、replace震叮、move沿量、copy、test冤荆,具體的可以參見 Json Patch RFC 文檔)朴则,path 指定了你要更新的 key 值,value 代表了被更新后的值。

   [
     { "op": "test", "path": "/a/b/c", "value": "foo" },
     { "op": "remove", "path": "/a/b/c" },
     { "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
     { "op": "replace", "path": "/a/b/c", "value": 42 },
     { "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
     { "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
   ]

我們來看個示例乌妒。
比如原來的 json 數(shù)據(jù)如下:

{
  "title": "Goodbye!",
  "author": {
    "givenName": "John",
    "familyName": "Doe"
  },
  "tags": [
    "example",
    "sample"
  ],
  "content": "This will be unchanged"

通過 JSON Patch 格式來 patch 以下數(shù)據(jù)

[
  { "op": "replace", "path": "/title", "value": "Hello!"},
  { "op": "remove", "path": "/author/familyName"},
  { "op": "add", "path": "/phoneNumber", "value": "+01-123-456-7890"},
  { "op": "replace", "path": "/tags", "value": ["example"]}
]

就會最終變成以下信息

{
  "title": "Hello!",
  "author": {
    "givenName": "John"
  },
  "tags": [
    "example"
  ],
  "content": "This will be unchanged",
  "phoneNumber": "+01-123-456-7890"
}

我們可以對比下兩者之間的差別


diff

可以明顯看出汹想,在 JSON Patch 格式數(shù)據(jù)中對應(yīng)的 remove、replace 以及 add 都在對應(yīng)源 json 文件的位置產(chǎn)生了變化撤蚊。

JSON Merge Patch

如果說 Json Patch 是一系列操作的集合古掏,那么 Json Merge Patch 就是一系列差異的集合。差異就是指 原始 Json 文件 和 目標(biāo) Json 文件 的不同侦啸。

如果是刪除某個字段槽唾,則需要將字段置為 null,如果是修改某個字段光涂,則需要將新的 value 值寫在 對應(yīng)的 key 上庞萍。

比如為了達(dá)到和上面示例類似的效果,通過 Json Merge Patch 在執(zhí)行操作的時候忘闻,對應(yīng)的數(shù)據(jù)如下钝计。

{
  "title": "Hello!",
  "author": {
    "familyName": null
  },
  "phoneNumber": "+01-123-456-7890",
  "tags": [
    "example"
  ]
}

可以看到這里修改了 title 的值,去掉了 author 中的 familyName齐佳,增加了 phoneNumber 以及刪除了 tags 中的 sample私恬。通過這種方式也達(dá)到了相同的結(jié)果。詳細(xì)內(nèi)容亦可參考 JSON Merge Patch RFC 文檔炼吴。

JSON Patch 與 JSON Merge Patch 對比

就我的使用體驗而言本鸣,他們在常規(guī)的使用情況下不分伯仲,但在一些特殊場景場景硅蹦,都會存在一些難以解決的問題荣德。

Json Patch 因為是操作的集合,在并發(fā)的這種場景下提针,有可能就會造成 某個數(shù)組中的值,被增加了多次這種問題曹傀,反觀 Json Merge Patch辐脖,因為它提供的數(shù)組是完整的數(shù)組,因為不會有該問題皆愉。

當(dāng)然 Json Merge Patch 也不是萬能的嗜价,只要觀察示例中使用的文件,就不難發(fā)現(xiàn) Json Merge Patch 存在一些致命的限制幕庐。

  • 刪除某個鍵值久锥,需要在 patch 文件中將對應(yīng)的值置成 null,但是如果我們某個值异剥,確實是需要置成 null瑟由,那就幾乎無解了
  • 數(shù)組需要提供全量的,在很多場景下冤寿,這個是有些讓人難以接受歹苦,比如只有一個很細(xì)小的值青伤,也是需要 提供全量的數(shù)組
  • 不會報錯,無論什么情況殴瘦,都會 patch 成功狠角。在真實使用場景下,還需要做額外的校驗

當(dāng)然在實際場景中蚪腋,我們可以根據(jù)自己的使用場景靈活的來確定使用哪種方式丰歌。

Strategic Merge Patch

這種方式是更新 k8s 資源時,提供的一種特殊的新的類型屉凯,并不是一個標(biāo)準(zhǔn)的協(xié)議立帖。

這種方式其實是基于 JSON Merge Patch 的理念來實現(xiàn)的,但是又可以避免 Json Merge Patch 中的坑神得。比如上面提到的修改數(shù)組需要提供全量數(shù)組的問題厘惦,示例如下。

當(dāng)前集群有一個 deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: patch-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: patch-demo-ctr
        image: nginx
      tolerations:
      - effect: NoSchedule
        key: dedicated
        value: test-team

我們想給這個 deployment 增加一個容器哩簿,這個時候我們創(chuàng)建一個 patch 文件

spec:
  template:
    spec:
      containers:
      - name: patch-demo-ctr-2
        image: redis

執(zhí)行命令宵蕉,進(jìn)行 patch 操作,

kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"

這個時候节榜,再去查看對應(yīng)的 deployment 就會包括 patch 文件中的容器

containers:
- image: redis
  imagePullPolicy: Always
  name: patch-demo-ctr-2
  ...
- image: nginx
  imagePullPolicy: Always
  name: patch-demo-ctr
  ...

我們在上面的操作中所做的 patch 稱為策略性合并 patch(Strategic Merge Patch)羡玛。 在這種情況下,patch 中的列表與現(xiàn)有列表合并宗苍。但是當(dāng)你在列表中使用策略性合并 patch 時稼稿,在某些情況下,列表是替換的讳窟,而不是合并的让歼。

patch 策略由 Kubernetes 源代碼中字段標(biāo)記中的 patchStrategy 鍵的值指定。 例如丽啡,PodSpec 結(jié)構(gòu)體的 Containers 字段的 patchStrategy 為 merge谋右,因此這里的操作是一個合并的操作

type PodSpec struct {
  ...
  Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`

如果我們替換 deployment 中另外一個列表數(shù)據(jù),你就會發(fā)現(xiàn)不同补箍。

  template:
    spec:
      tolerations:
      - effect: NoSchedule
        key: disktype
        value: ssd

執(zhí)行命令改执,將該文件內(nèi)容 patch 到 deployment 中。

kubectl patch deployment patch-demo --patch "$(cat patch-file-containers.yaml)"

we will get that in deployment

...
tolerations:
      - effect: NoSchedule
        key: disktype
        value: ssd
...

請注意坑雅,PodSpec 中的 tolerations 列表被替換辈挂,而不是合并。這是因為 PodSpec 的 tolerations 的字段標(biāo)簽中沒有 patchStrategy 鍵裹粤。所以策略合并 patch 操作使用默認(rèn)的 patch 策略终蒂,也就是 replace。

type PodSpec struct {
  ...
  Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`

總結(jié)

標(biāo)題雖然是 k8s patch 的幾種方式,但是主要還是分析了下 JSON Patch 和 JSON Merge Patch 的不同后豫,因為 k8s 的 Strategy Merge Patch 幾乎就是 JSON Merge Patch 的一個變種悉尾,搞懂了前兩種方式,這種方式也就很容易弄清楚了挫酿。

參考

json patch
json merge patch
Json Patch and Json Merge Patch — Quick Example in Java
JSON Patch and JSON Merge Patch
Update API Objects in Place Using kubectl patch

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末构眯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子早龟,更是在濱河造成了極大的恐慌惫霸,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葱弟,死亡現(xiàn)場離奇詭異壹店,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)芝加,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門硅卢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人藏杖,你說我怎么就攤上這事将塑。” “怎么了蝌麸?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵点寥,是天一觀的道長。 經(jīng)常有香客問我来吩,道長敢辩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任弟疆,我火速辦了婚禮戚长,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘怠苔。我一直安慰自己同廉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布嘀略。 她就那樣靜靜地躺著恤溶,像睡著了一般乓诽。 火紅的嫁衣襯著肌膚如雪帜羊。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天鸠天,我揣著相機(jī)與錄音讼育,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛奶段,可吹牛的內(nèi)容都是我干的饥瓷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼痹籍,長吁一口氣:“原來是場噩夢啊……” “哼呢铆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蹲缠,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤棺克,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后线定,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娜谊,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年斤讥,在試婚紗的時候發(fā)現(xiàn)自己被綠了纱皆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡芭商,死狀恐怖派草,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蓉坎,我是刑警寧澤澳眷,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站蛉艾,受9級特大地震影響钳踊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜勿侯,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一拓瞪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧助琐,春花似錦祭埂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掘譬,卻和暖如春泰演,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葱轩。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工睦焕, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留藐握,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓垃喊,卻偏偏與公主長得像猾普,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子本谜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容