Kubernetes 中 fieldsV1 相关介绍
1. 为什么会出现 fieldsV1
Server - Side Apply (SSA)
Kubernetes 1.18 引入了 SSA 机制,用于更精确地管理资源的字段所有权。
managedFields
每个资源对象都有一个 managedFields
字段,记录了每个字段的管理者(例如,哪个客户端或用户修改了该字段)。
fieldsV1
fieldsV1
是 managedFields
的一部分,描述了字段的所有权信息。
2. fieldsV1 的结构
fieldsV1
是一个复杂的结构,描述了资源对象中每个字段的所有权。例如:
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:deployment.kubernetes.io/revision: {}
f:status:
f:conditions:
.: {}
k:{"type":"Available"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
k:{"type":"Progressing"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
f:observedGeneration: {}
f:
表示字段(field)。k:
表示键(key),用于描述 map 或 struct 中的特定键。.: {}
表示该字段本身的所有权。
3. 为什么查到的 YAML 和 API Server 的不一样
默认行为
当你通过 kubectl get
或直接查询 API Server 时,默认会隐藏 managedFields
,因为它是内部元数据,通常对用户不直接有用。
显式查询
如果你通过 client - go
或其他工具直接查询资源对象,managedFields
会被包含在返回的结果中。
YAML 序列化
当你将资源对象序列化为 YAML 时,managedFields
也会被包含在内。
4. 如何隐藏 managedFields
如果你不希望 managedFields
出现在 YAML 中,可以在查询或序列化时将其移除。以下是几种方法:
方法 1:在查询时忽略 managedFields
obj.SetManagedFields(nil) // 移除 managedFields
yaml, err := yamlutil.Marshal(obj)
方法 2:在序列化时过滤 managedFields
type DeploymentWithoutManagedFields struct {
appv1.Deployment `json:",inline"`
ManagedFields []metav1.ManagedFieldsEntry `json:"managedFields,omitempty"`
}
objWithoutFields := &DeploymentWithoutManagedFields{
Deployment: *obj,
}
yaml, err := yamlutil.Marshal(objWithoutFields)
方法 3:使用 kubectl 查询并隐藏 managedFields
kubectl get deployment <deployment - name> -n <namespace> -o yaml --show - managed - fields=false
5. 示例代码
以下是一个完整的示例,展示如何查询 Deployment 并移除 managedFields
:
// 查询 Deployment
obj := &appv1.Deployment{}
err = client.Get(ctx, ctrlclient.ObjectKey{Namespace: task.Namespace, Name: task.TaskName}, obj)
if err != nil {
log.Fatalf("Failed to get Deployment: %v", err)
}
// 移除 managedFields
obj.SetManagedFields(nil)
// 将 Deployment 转换为 YAML
yaml, err := yamlutil.Marshal(obj)
if err != nil {
log.Fatalf("Failed to marshal Deployment to YAML: %v", err)
}
fmt.Println(string(yaml))
6. 总结
fieldsV1
是 Kubernetes 的managedFields
的一部分,用于记录字段的所有权信息。- 默认情况下,
kubectl
会隐藏managedFields
,但通过client - go
查询时会包含它。 - 你可以通过移除
managedFields
来生成与kubectl
一致的 YAML 输出。