我是靠谱客的博主 激昂火,最近开发中收集的这篇文章主要介绍【博客554】k8s 中的 Client-Side Apply 和 Server-Side Applyk8s 中的 Client-Side Apply 和 Server-Side Apply,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

k8s 中的 Client-Side Apply 和 Server-Side Apply

背景

如果你经常与 kubectl 打交道,那相信你一定见过 kubectl.kubernetes.io/last-applied-configuration annotation,以及那神烦的 managedFields,像这样:

kubectl get pods hello -oyaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"creationTimestamp":null,"labels":{"run":"hello"},"name":"hello","namespace":"default"},"spec":{"containers":[{"image":"nginx","name":"hello","resources":{}}],"dnsPolicy":"ClusterFirst","restartPolicy":"Always"},"status":{}}
  creationTimestamp: "2022-05-28T07:28:51Z"
  labels:
    run: hello
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
        f:labels:
          .: {}
          f:run: {}
....
    manager: kubectl
    operation: Update
    time: "2022-05-28T07:28:51Z"
....

由这两个字段,引出本文的两位主角,Client-Side Apply(以下简称CSA)和 Server-Side Apply(以下简称SSA)

kubectl.kubernetes.io/last-applied-configuration: 是使用 kubectl apply 进行 Client-Side Apply 时,由 kubectl 自行填充的。
managedFields: 则是由 kubectl apply 的增强功能—— Server-Side Apply 的引入而添加。

1、kubectl apply 最初始的样子——Client-Side Apply

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

由此可见,last-applied-configuration 体现的是一种 ownership 的关系,表示哪些字段是由 kubectl 管理,它是 kubectl apply 时,计算 patch 报文的依据。

其实这种合并方式也称为:three way merge

2、kubectl apply 升级版——Server-Side Apply

在这里插入图片描述

kubectl apply --server-side=true -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-server-side-apply
data:
  a: "a"
  b: "b"
EOF

部署成功后,查看对象会发现该对象中不再存在 last-applied-configuration:

configmap/test-server-side-apply serverside-applied
kubectl get cm test-server-side-apply -oyaml
apiVersion: v1
data:
  a: a
  b: b
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-11T01:49:55Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:data:
        f:a: {}
        f:b: {}
    manager: kubectl
    operation: Apply
    time: "2022-12-11T01:49:55Z"
  name: test-server-side-apply
  namespace: default

如果你没能看到 managedFields 字段,可以加上 --show-managed-fields 参数:kubectl get cm test-server-side-apply -oyaml --show-managed-fields

失去 last-applied-configuration 后,表达 ownership 的任务就落入了新引入的字段管理机制(field management)手中。根据以上输出的 yaml 的 metadata.managedFields 字段,我们不难得出它想表达的含义:该 configmap 中 data.a 和 data.b 字段都是由 kubectl 来管理的。

“ 字段管理(field management) ”机制追踪对象字段的变化。当一个字段值改变时,其所有权从当前管理器(manager)转移到施加变更的管理器。当尝试将新配置应用到一个对象时,如果字段有不同的值,且由其他管理器管理, 将会引发 冲突 。冲突引发警告信号:此操作可能抹掉其他协作者的修改。冲突可以被刻意忽略,这种情况下,值将会被改写,所有权也会发生转移

SSA 中使用了字段管理机制来追踪对象的变化,当 apply 改变一个字段时,而恰巧该字段被其他用户声明了 ownership,此时会发生冲突。这可以防止一个管理者不小心覆盖掉其他用户设置的值。举个例子:如果修改我们刚刚通过SSA 创建的 test-server-side-applyconfigmap,并且手动设置管理者为 test(通过–field-manager 字段),此时 kubectl 会拒绝我们的提交,提示冲突:

kubectl apply --server-side=true --field-manager="test" -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-server-side-apply
data:
  a: "a"
  b: "c" 
EOF

error: Apply failed with 1 conflict: conflict with "kubectl": .data.b
Please review the fields above--they currently have other managers. Here
are the ways you can resolve this warning:
* If you intend to manage all of these fields, please re-run the apply
  command with the `--force-conflicts` flag.
* If you do not intend to manage all of the fields, please edit your
  manifest to remove references to the fields that should keep their
  current managers.
* You may co-own fields by updating your manifest to match the existing
  value; in this case, you'll become the manager if the other manager(s)
  stop managing the field (remove it from their configuration).
See http://k8s.io/docs/reference/using-api/api-concepts/#conflicts

从 kubectl 返回的提示,我们可以得知当冲突发生的时我们有三种选择:

  • 覆盖前值,成为当前字段的唯一管理者——通过增加 --force-conflicts flag
  • 不覆盖前值,放弃管理权——在本次配置中,把修改的字段删掉(本例中是 data.b)
  • 不覆盖前值,成为共享管理者——把冲突值改成和服务器对象一致

此时如果我们手动设置管理者为 kubectl则可以成功:

kubectl apply --server-side=true --field-manager="kubectl" -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-server-side-apply
data:
  a: "a"
  b: "c" 
EOF
configmap/test-server-side-apply serverside-applied

3、Server-Side Apply 的优点

在这里插入图片描述

最后

以上就是激昂火为你收集整理的【博客554】k8s 中的 Client-Side Apply 和 Server-Side Applyk8s 中的 Client-Side Apply 和 Server-Side Apply的全部内容,希望文章能够帮你解决【博客554】k8s 中的 Client-Side Apply 和 Server-Side Applyk8s 中的 Client-Side Apply 和 Server-Side Apply所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部