Kubernetes如何处理同一资源对应的多个不同API版本
在Kubernetes中,我们可以使用不同的API版本请求资源:
kubectl get roles.v1.rbac.authorization.k8s.io foo -n bar -oyaml
输出如下:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: foo namespace: bar rules: - apiGroups: - "" resources: - endpoints - secrets verbs: - create - get - watch - list - update
kubectl get roles.v1beta1.rbac.authorization.k8s.io foo -n bar -oyaml
低版本集群输出如下:
Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Role apiVersion: rbac.authorization.k8s.io/v1beta1 kind: Role metadata: name: foo namespace: bar rules: - apiGroups: - "" resources: - endpoints - secrets verbs: - create - get - watch - list - update
问题解答
1. 创建资源时使用的API版本是否会对ETCD中存储的对应资源产生影响?
不会。提交资源时使用的任意对外暴露的API版本,都会被kube-apiserver先转换为内部版本完成校验,再转换为ETCD对应的存储版本写入,提交时使用的版本不会影响ETCD内的实际存储内容。
2. 若某资源在新版本API(v1)尚未推出时就已存储,旧版本API(v1beta1)被移除后是否会出现问题?
只要升级集群前已经将ETCD中的存储版本迁移到新版本支持的存储版本就不会有问题。如果未提前完成迁移,旧存储版本不在新版本K8s的支持版本列表中时,apiserver将无法识别ETCD中的存量资源,就会出现异常。
3. 升级到已移除rbac.authorization.k8s.io/v1beta1的Kubernetes v1.22版本,是否会破坏已创建存储的相关资源?
按照官方推荐流程升级不会出现问题。K8s 1.17及之后版本RBAC相关资源的ETCD存储版本已经切换为v1,只要是从1.17及以上版本升级到1.22,ETCD中存储的RBAC资源本身就是v1格式,v1beta1 API接口移除只会影响使用v1beta1版本发起的资源请求操作,不会影响存量存储资源。如果是从1.16及更早版本直接跳升1.22且未提前完成存储版本迁移,可能会出现资源无法识别的问题。
4. Kubernetes中不同API版本之间的资源转换逻辑是如何处理的?
K8s不会维护各个对外API版本之间的两两转换逻辑,而是统一将所有对外API版本(如v1beta1、v1)和内部中间版本做双向转换。
当你使用某个版本提交/请求资源时,apiserver会先把收到的资源转换成内部版本完成校验、逻辑处理,存储时再转换为ETCD对应的存储版本写入;读取流程刚好相反,先把ETCD中读取到的存储版本转成内部版本,再转换为你请求的API版本返回。如果请求的API版本已经被移除,apiserver找不到对应转换逻辑,会直接返回报错。
内容的提问来源于stack exchange,提问作者MichaelAttard

