You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未加--save-config执行kubectl create:为何Service有字段管理器而ServiceAccount无

ServiceAccount创建时kubectl create无managedFields的原因

在CAPI集群中,使用kubectl apply和kubectl create创建Service(或Pod)时,二者的managedFields几乎一致(仅存在last-applied-configuration这类预期差异),但ServiceAccount的表现却截然不同——kubectl create创建的ServiceAccount完全没有managedFields,而kubectl apply创建的则包含明确的字段管理器记录。


Service(或Pod)的创建对比

kubectl create 结果

$ k get svc my-service -oyaml --show-managed-fields
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2024-01-26T18:40:15Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:internalTrafficPolicy: {}
        f:ports:
          .: {}
          k:{"port":80,"protocol":"TCP"}:
            .: {}
            f:port: {}
            f:protocol: {}
            f:targetPort: {}
        f:selector: {}
        f:sessionAffinity: {}
        f:type: {}
    manager: kubectl-create
    operation: Update
    time: "2024-01-26T18:40:15Z"
  name: my-service
  namespace: default
  resourceVersion: "548809"
  uid: 7d57743d-9b8d-4f04-850b-7ca6d5e1347a
spec:
  clusterIP: 172.19.186.161
  clusterIPs:
  - 172.19.186.161
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    app.kubernetes.io/name: MyApp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

kubectl apply 结果

$ k get svc my-service -oyaml --show-managed-fields
apiVersion: v1
kind: Service
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"my-service","namespace":"default"},"spec":{"ports":[{"port":80,"protocol":"TCP","targetPort":9376}],"selector":{"app.kubernetes.io/name":"MyApp"}}}
  creationTimestamp: "2024-01-26T18:41:00Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
      f:spec:
        f:internalTrafficPolicy: {}
        f:ports:
          .: {}
          k:{"port":80,"protocol":"TCP"}:
            .: {}
            f:port: {}
            f:protocol: {}
            f:targetPort: {}
        f:selector: {}
        f:sessionAffinity: {}
        f:type: {}
    manager: kubectl-client-side-apply
    operation: Update
    time: "2024-01-26T18:41:00Z"
  name: my-service
  namespace: default
  resourceVersion: "548931"
  uid: 8a378bcc-b70e-441b-8b55-463f7700e1f3
spec:
  clusterIP: 172.19.141.7
  clusterIPs:
  - 172.19.141.7
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 9376
  selector:
    app.kubernetes.io/name: MyApp
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}

结果:二者的managedFields结构几乎一致,仅存在kubectl-client-side-apply管理器添加的last-applied-configuration注解差异。


ServiceAccount的创建对比

kubectl create 结果

$ k get sa -oyaml --show-managed-fields
apiVersion: v1
items:
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    creationTimestamp: "2024-01-24T15:11:24Z"
    name: build-robot
    namespace: default
    resourceVersion: "7337504"
    uid: e2414d28-d897-4099-ac5d-699c89835615
  secrets:
  - name: build-robot-token-77p6d 

kubectl apply 结果

$ k get sa -oyaml --show-managed-fields
apiVersion: v1
items:
- apiVersion: v1
  kind: ServiceAccount
  metadata:
    annotations:
      kubectl.kubernetes.io/last-applied-configuration: |
        {"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"build-robot","namespace":"default"}}
    creationTimestamp: "2024-01-24T15:10:55Z"
    managedFields:
    - apiVersion: v1
      fieldsType: FieldsV1
      fieldsV1:
        f:secrets:
          .: {}
          k:{"name":"build-robot-token-8rqgq"}: {}
      manager: kube-controller-manager
      operation: Update
      time: "2024-01-24T15:10:55Z"
    - apiVersion: v1
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            .: {}
            f:kubectl.kubernetes.io/last-applied-configuration: {}
      manager: kubectl-client-side-apply
      operation: Update
      time: "2024-01-24T15:10:55Z"
    name: build-robot
    namespace: default
    resourceVersion: "7337399"
    uid: 0bac2513-844f-4526-b374-3642bdf26838
  secrets:
  - name: build-robot-token-8rqgq 

结果:kubectl create创建的ServiceAccount完全没有managedFields条目,而kubectl apply创建的则包含kubectl-client-side-apply和kube-controller-manager两个字段管理器的记录。


原因分析

  1. 字段管理器的设置逻辑差异
    对于Service、Pod这类常规资源,kubectl create在调用Kubernetes API时会明确设置fieldManager=kubectl-create参数,API Server会根据这个参数生成对应的managedFields条目,记录该资源的初始创建者。
    但针对ServiceAccount资源,部分版本的kubectl create sa命令使用了特殊的客户端逻辑,未在API请求中携带fieldManager参数。API Server在接收未指定fieldManager的创建请求时,不会生成managedFields条目。

  2. kube-controller-manager的后续处理
    ServiceAccount创建后,kube-controller-manager会自动为其生成关联的Token Secret并更新资源。

    • 对于kubectl apply创建的ServiceAccount,由于初始请求携带了fieldManager=kubectl-client-side-apply,API Server已经生成了managedFields,后续控制器的更新会以kube-controller-manager作为字段管理器添加新的条目。
    • 对于kubectl create创建的ServiceAccount,因为没有初始的managedFields,控制器的更新也不会触发managedFields的生成,最终导致该资源完全没有字段管理器记录。
  3. 版本或集群配置影响
    部分较新的kubectl版本已经修复了这个问题,kubectl create sa会正确设置fieldManager参数,但在CAPI集群使用的特定版本中可能仍存在此行为差异。


内容的提问来源于stack exchange,提问作者subtleseeker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:35:14