2 资源类型 Scheme
本节主要讲解 Kubernetes 核心的资源类型 Scheme 的定义和用途。
现在我们知道我们的 yaml 文件是通过 api 的一个转换来发起一个网络请求,那么整个的资源类型他是怎么样在 K8S 当中来定义的呢?
就是平时我们在 yaml 中写的一个 deployment 的资源类型为什么 K8S 能够识别?这些资源类型就是通过 scheme 来定义的
2.1 介绍
当我们操作资源和 apiserver 进行通信的时候,需要根据资源对象类型的 Group、Version、Kind 以及规范定义、编解码等内容构成 Scheme 类型,然后 Clientset 对象就可以来访问和操作这些资源类型了,clientset 的话其实就是一个用来操作 K8S 的客户端,Scheme 的定义主要在 api 子项目之中,源码仓库地址: https://github.com/kubernetes/api ,被同步到 Kubernetes 源码的 staging/src/k8s.io/api 之下。
1.查看 apps/v1 目录结构
# staging/src/k8s.io/api 路径下主要就是对 K8S 一些原始资源的结构体定义
[11:42:44 root@go kubernetes]#tree staging/src/k8s.io/api/apps/v1
staging/src/k8s.io/api/apps/v1
├── doc.go
├── generated.pb.go
├── generated.proto
├── register.go
├── types.go # 定义了 apps.v1 下的一些资源对象的结构体
├── types_swagger_doc_generated.go
└── zz_generated.deepcopy.go
0 directories, 7 files
2.2 types.go 文件
其中 types.go
文件里面就是 apps/v1
这个 GroupVersion
下面所有的资源对象的定义,有 Deployment、DaemonSet、StatefulSet、ReplicaSet 等几个资源对象,比如 Deployment 的结构体定义如下所示:
1.这里我查看 types.go 文件中,这个文件中一般都是 v1 版本的常用 K8S 资源类型,这里我使用 deployment 来做演示
可以看到在 deployment 结构体中有 metav1.TypeMeta
、metav1.ObjectMeta
、DeploymentSpec
、DeploymentStatus
这几个属性
然后这里我在查看 TypeMeta
属性的源代码,可以看到在 typemeta 中就是定义了 group 中的信息apiversion
,Kind
信息
由 TypeMeta、ObjectMeta、DeploymentSpec 以及 DeploymentStatus 4个属性组成,和我们使用 YAML 文件定义的 Deployment 资源对象也是对应的。
所以对应到 yaml 文件中就如下:
apiVersion: apps/v1
kind: Deployment # 源码中 TypeMeta
metadata: # 源码中 ObjectMeta
name: nginx-deploy
namespace: default
spec: # 源码中 DSpec DeploymentSpec
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
其中 apiVersion
与 kind
就是 TypeMeta
属性,metadata 属性就是 ObjectMeta
,spec 属性就是 DeploymentSpec
,当资源部署创建过后也会包含一个 status 的属性,也就是 DeploymentStatus
所以这个属性不需要人为指定,这样就完整的描述了一个资源对象的模型。
并且可以通过下面命令查看到对应的 api group 中有那些资源类型
[13:19:18 root@k8s-master ~]#kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
applications app app.k8s.io/v1beta1 true Application
helmapplications happ application.kubesphere.io/v1alpha1 false HelmApplication
helmapplicationversions happver application.kubesphere.io/v1alpha1 false HelmApplicationVersion
helmcategories hctg application.kubesphere.io/v1alpha1 false HelmCategory
helmreleases hrls application.kubesphere.io/v1alpha1 false HelmRelease
helmrepos hrepo application.kubesphere.io/v1alpha1 false HelmRepo
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v1 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Job
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
clusters cluster.kubesphere.io/v1alpha1 false Cluster
leases coordination.k8s.io/v1 true Lease
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
ingresses ing extensions/v1beta1 true Ingress
flowschemas flowcontrol.apiserver.k8s.io/v1beta1 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta1 false PriorityLevelConfiguration
gateways gateway.kubesphere.io/v1alpha1 true Gateway
nginxes gateway.kubesphere.io/v1alpha1 true Nginx
federatedrolebindings iam.kubesphere.io/v1alpha2 true FederatedRoleBinding
federatedroles iam.kubesphere.io/v1alpha2 true FederatedRole
federatedusers iam.kubesphere.io/v1alpha2 true FederatedUser
globalrolebindings iam.kubesphere.io/v1alpha2 false GlobalRoleBinding
globalroles iam.kubesphere.io/v1alpha2 false GlobalRole
groupbindings iam.kubesphere.io/v1alpha2 false GroupBinding
groups iam.kubesphere.io/v1alpha2 false Group
loginrecords iam.kubesphere.io/v1alpha2 false LoginRecord
rolebases iam.kubesphere.io/v1alpha2 false RoleBase
users iam.kubesphere.io/v1alpha2 false User
workspacerolebindings iam.kubesphere.io/v1alpha2 false WorkspaceRoleBinding
workspaceroles iam.kubesphere.io/v1alpha2 false WorkspaceRole
nodes metrics.k8s.io/v1beta1 false NodeMetrics
pods metrics.k8s.io/v1beta1 true PodMetrics
alertmanagerconfigs monitoring.coreos.com/v1alpha1 true AlertmanagerConfig
alertmanagers monitoring.coreos.com/v1 true Alertmanager
podmonitors monitoring.coreos.com/v1 true PodMonitor
probes monitoring.coreos.com/v1 true Probe
prometheuses monitoring.coreos.com/v1 true Prometheus
prometheusrules monitoring.coreos.com/v1 true PrometheusRule
servicemonitors monitoring.coreos.com/v1 true ServiceMonitor
thanosrulers monitoring.coreos.com/v1 true ThanosRuler
clusterdashboards monitoring.kubesphere.io/v1alpha2 false ClusterDashboard
dashboards monitoring.kubesphere.io/v1alpha2 true Dashboard
ipamblocks network.kubesphere.io/v1alpha1 false IPAMBlock
ipamhandles network.kubesphere.io/v1alpha1 false IPAMHandle
ippools network.kubesphere.io/v1alpha1 false IPPool
namespacenetworkpolicies nsnp network.kubesphere.io/v1alpha1 true NamespaceNetworkPolicy
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
configs nc notification.kubesphere.io/v2beta2 false Config
notificationmanagers nm notification.kubesphere.io/v2beta2 false NotificationManager
receivers nr notification.kubesphere.io/v2beta2 false Receiver
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
resourcequotas quota.kubesphere.io/v1alpha2 false ResourceQuota
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
servicepolicies servicemesh.kubesphere.io/v1alpha2 true ServicePolicy
strategies servicemesh.kubesphere.io/v1alpha2 true Strategy
volumesnapshotclasses snapshot.storage.k8s.io/v1 false VolumeSnapshotClass
volumesnapshotcontents snapshot.storage.k8s.io/v1 false VolumeSnapshotContent
volumesnapshots snapshot.storage.k8s.io/v1 true VolumeSnapshot
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1beta1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment
workspaces tenant.kubesphere.io/v1alpha1 false Workspace
workspacetemplates tenant.kubesphere.io/v1alpha2 false WorkspaceTemplate
像这种结构体的定义的话在 K8S 中他就叫做一个资源对象的模型
2.3 zz_generated.deepcopy.go 文件
上面定义的规范在 Kubernetes 中称为资源类型 Scheme
,此外zz_generated.deepcopy.go
文件是由 deepcopy-gen
工具创建的定义各资源类型 DeepCopyObject()
方法的文件,所有注册到 Scheme 的资源类型都要实现 runtime.Object
接口:
也就是说在我们真正对 K8S 操作的时候很多时候都会去操作我们的 object
// staging/src/k8s.io/apimachinery/pkg/runtime/interface.go
// 也就是说只要是注册到 scheme 中的资源对象,我们都必须去实现这个 object 接口
type Object interface {
GetObjectKind() schema.ObjectKind
DeepCopyObject() Object
}
而在 K8S 中所有的资源类型都包含一个 TypeMeta 类型,而该类型实现了 GetObjectKind()
方法,所以各资源类型只需要实现 DeepCopyObject()
方法即可:
// staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go
func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj }
// GetObjectKind 方法返回的是 schema.ObjectKind 接口
各个资源类型的 DeepCopyObject()
方法也不是手动定义,而是使用 deepcopy-gen
工具命令统一自动生成的,该工具会读取 types.go
文件中的 +k8s:deepcopy-gen
注释,以 Deployment 为例:
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Deployment enables declarative updates for Pods and ReplicaSets.
type Deployment struct {
......
}
然后将自动生成的代码保存到 zz_generated.deepcopy.go
文件中。
2.4 register.go 文件
register.go
文件的主要作用是定义 AddToScheme 函数,将各种资源类型注册到 Clientset 使用的 Scheme 对象中去,由于每个资源自动生成了 DeepCopyObject() 方法,这样资源就实现了 runtime.Object
接口,所以可以注册到 Scheme 中去了。
// 源码路径:staging/src/k8s.io/api/apps/v1/register.go
var (
// TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api.
// localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
localSchemeBuilder = &SchemeBuilder
// 对外暴露的 AddToScheme 方法用于注册该 Group/Verion 下的所有资源类型
AddToScheme = localSchemeBuilder.AddToScheme
)
// Adds the list of known types to the given scheme.
// 将 addKnownTypes 函数中所有的资源对象都注册到 Scheme 中
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&Deployment{},
&DeploymentList{},
&StatefulSet{},
&StatefulSetList{},
&DaemonSet{},
&DaemonSetList{},
&ReplicaSet{},
&ReplicaSetList{},
&ControllerRevision{},
&ControllerRevisionList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
// 源码路径:staging/src/k8s.io/client-go/kubernetes/scheme/register.go
// 新建一个 Scheme,将各类资源对象都添加到该 Scheme
var Scheme = runtime.NewScheme()
// 为 Scheme 中的所有类型创建一个编解码工厂
var Codecs = serializer.NewCodecFactory(Scheme)
// 为 Scheme 中的所有类型创建一个参数编解码工厂
var ParameterCodec = runtime.NewParameterCodec(Scheme)
// 将各 k8s.io/api/<Group>/<Version> 目录下资源类型的 AddToScheme() 方法注册到 SchemeBuilder 中
var localSchemeBuilder = runtime.SchemeBuilder{
......
appsv1.AddToScheme,
appsv1beta1.AddToScheme,
appsv1beta2.AddToScheme,
......
}
var AddToScheme = localSchemeBuilder.AddToScheme
func init() {
v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"})
// 调用 SchemeBuilder 中各资源对象的 AddToScheme() 方法,将它们注册到到 Scheme 对象
utilruntime.Must(AddToScheme(Scheme))
}
将各类资源类型注册到全局的 Scheme 对象
中,这样 Clientset 就可以识别和使用它们了。
apimachinery 子项目主要是 Kubernetes 服务端和客户端项目都共同依赖的一些公共方法、struct、工具类的定义,主要服务于 kubernetes、client-go、apiserver 这三个项目。
2.5 总结
我们现在 types.go 中定义一个资源对象结构体,然后在这个结构体中需要去实现 runtime.Object 这样的接口,在 runtime.Object 中有两个接口,GetObjectKind() schema.ObjectKind
,DeepCopyObject() Object
然后在我面的 register.go 程序中会将当前所有定义的资源对象添加到 AddToScheme
函数中
然后在全局的 clinet-go 把所有的资源对象都添加到全局的一个 scheme 资源当中去,这样就可以通过全局的 scheme 获取到每一个资源对象
我们可以及拿过 scheme 理解为所有资源类型的集合、然后再 scheme 中有多个其他不同的资源、再通过 clientSet 来实现对 scheme 里面的资源类型进行操作