kubectl apply
首先我们需要大概了解 kubectl apply做了什么,分为如下几步:
- GET 查询目标 Object
- 如果 Object 不存在,则提交到API创建,并且将用户提供的 input 信息放到 新创建的 Object 的 annotations里(key 为 kubectl.kubernetes.io/last-applied-configuration)
- 如果 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 列表:
type PodSpec struct {
...
Containers []Container `json:"containers" patchStrategy:"merge" patchMergeKey:"name" ...`
PATCH /apis/extensions/v1beta1/namespaces/default/deployments/nginx HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: kubectl/v0.0.0 (linux/amd64) kubernetes/$Format
Content-Length: 246
Accept: application/json
Content-Type: application/strategic-merge-patch+json
Uber-Trace-Id: 5ca3fde0b9f9aaf1:0c0358897c8e0ef8:0f38135280523f87:1
Accept-Encoding: gzip
{"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"}]}}}}