GKE中kubectl get导出YAML与kubectl apply提交YAML的差异原因咨询
Service配置本地提交与集群返回YAML差异问题解答
1. 涉及的Kubernetes核心概念
这里涉及的核心概念包括:
- 声明式API:Kubernetes的核心交互模式,用户只需要提交期望的资源状态,由集群负责收敛到最终状态
- 资源规约(Spec)与状态(Status):所有Kubernetes资源对象都分为两部分,Spec存储用户定义的期望配置,Status存储集群实际运行的实时状态
- 默认值填充(Defaulting):API服务器的准入控制环节能力,对用户未显式定义的可选字段自动填充集群默认值
- 准入控制器(Admission Controller):API服务器处理资源创建请求的中间环节,可对资源对象进行校验、修改、补充元数据等操作
2. 两份YAML产生巨大差异的原因
你本地编写提交的YAML是仅包含自定义配置的最小化声明文件,仅填写了必要的期望配置字段;而从集群拉取的YAML是完整的资源对象,除了你提交的配置外,还包含了集群自动补充的全部内容,差异主要来自几个部分:
- 你未显式声明的可选字段被填充了集群默认值,比如未指定
type时默认填充ClusterIP,未指定sessionAffinity时默认填充None - 集群自动分配的动态字段值,比如ClusterIP、NodePort、LoadBalancer类型的公网IP等
- 准入控制器自动注入的标签、注解,比如云厂商的资源标识、集群管理相关的元数据
- 控制器更新的Status字段,包含资源的实际运行状态、关联资源信息等,这部分是本地YAML完全不会包含的内容
3. 底层的运行逻辑
整个流程的底层逻辑如下:
- 本地执行
kubectl apply提交Service YAML时,客户端先做基础格式校验,将请求发送到Kubernetes API服务器 - API服务器依次执行鉴权、授权操作,确认你有创建Service的权限
- 请求进入准入控制环节,首先执行可变准入控制:对未显式声明的字段填充默认值,由集群内置或额外部署的准入控制器注入必要的标签、注解,修改不符合规则的配置
- 校验通过后,API服务器将完整的资源对象(含填充的默认值、注入的元数据)持久化存储到etcd中
- 对应的Service控制器、云厂商控制器(如果是LoadBalancer类型)等组件监听到资源创建事件,按照Spec配置分配资源、更新关联对象,同时将实际运行状态回写到资源的Status字段中
- 你执行
kubectl get service拉取配置时,API服务器直接从etcd中返回包含全量字段、最新Status的完整资源对象,和你本地的最小化YAML就会产生明显差异
4. 该现象是GKE特有,还是所有K8s集群都会出现?
该现象是所有标准Kubernetes集群的通用能力,并非GKE特有。GKE作为托管集群会额外注入一些谷歌云相关的专属注解、标签,或者调整部分默认配置值,但是核心的默认值填充、Status字段更新、元数据注入逻辑是所有Kubernetes集群的标准逻辑,即使是本地用kubeadm、kind搭建的单节点测试集群也会出现相同的现象。
5. 可通过哪些资料学习相关概念?
可参考的学习资料包括:
- Kubernetes官方文档的核心概念章节、API参考文档、准入控制器相关文档
- 《Kubernetes权威指南》《Kubernetes源码剖析》等书籍中关于API机制、资源对象生命周期的相关章节
- Kubernetes社区官方发布的设计文档、原理讲解类技术内容
内容的提问来源于stack exchange,提问作者Rakib
相关产品推荐
相关产品推荐

