kubectl apply

首先我们需要大概了解 kubectl apply做了什么,分为如下几步:

  1. GET 查询目标 Object
  2. 如果 Object 不存在,则提交到API创建,并且将用户提供的 input 信息放到 新创建的 Object 的 annotations里(key 为 kubectl.kubernetes.io/last-applied-configuration)
  3. 如果 Object 已存在, 先读取到旧的 Object 的 kubectl.kubernetes.io/last-applied-configuration 的值, 然后与当前的做对比, 生成一个 diff (strategic merge patch), 用 PATCH 发给 API Server. 其中 diff 里面也会附带上最新的 kubectl.kubernetes.io/last-applied-configuration.

其中, strategic merge patch 需要单独提一下,它的主要特点就是对于 list 的 update 提供了 patchStrategy 以便对不同的字段做不同的处理.比如我们常见的 Pod 的 containers 列表:

  1. type PodSpec struct {
  2. ...
  3. Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`
  1. PATCH /apis/extensions/v1beta1/namespaces/default/deployments/nginx HTTP/1.1
  2. Host: 127.0.0.1:8080
  3. User-Agent: kubectl/v0.0.0 (linux/amd64) kubernetes/$Format
  4. Content-Length: 246
  5. Accept: application/json
  6. Content-Type: application/strategic-merge-patch+json
  7. Uber-Trace-Id: 5ca3fde0b9f9aaf1:0c0358897c8e0ef8:0f38135280523f87:1
  8. Accept-Encoding: gzip
  9. {"spec":{"template":{"spec":{"$setElementOrder/containers":[{"name":"nginx"}],"containers":[{"$setElementOrder/env":[{"name":"DEMO_GREETING"}],"env":[{"name":"DEMO_GREETING","value":"Hello from the environment#kubectl edit"}],"name":"nginx"}]}}}}