校内 实训网站 建设方案,网站结构如何优化,宣传片影视拍摄公司,域名有免费的吗欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)#xff1a;https://github.com/zq2599/blog_demos 本篇概览
本文是《Kubernetes对象深入学习》系列的第三篇#xff0c;主要内容是关于对象属性的知识点#xff0c;关于对象属性#xff0c;先通过一个具体…欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码)https://github.com/zq2599/blog_demos 本篇概览
本文是《Kubernetes对象深入学习》系列的第三篇主要内容是关于对象属性的知识点关于对象属性先通过一个具体实例来建立第一印象在kubernetes环境执行命令kubectl get pod kube-apiserver-hedy -n kube-system -o yaml可以看到指定pod的基本信息注意pod名请根据您自己环境的实际情况调整内容如下图 上图中黄色箭头2和3之间的大片区域都是对象属性对应在kubernetes源码中接口是metav1.Object实现是metav1.ObjectMeta来看pod的数据结构源码内嵌了metav1.ObjectMeta其他资源也是同样的套路
// 1. 代码生成器来生成runtime.Object接口的实现
// k8s:deepcopy-gen:interfacesk8s.io/apimachinery/pkg/runtime.Object// Pod is a collection of containers, used as either input (create, update) or as output (list, get).
type Pod struct {// 2. 这样就实现了schema.ObjectKind接口metav1.TypeMeta// 3. 这样就实现了metav1.Object接口// optionalmetav1.ObjectMeta// Spec defines the behavior of a pod.// optionalSpec PodSpec// Status represents the current information about a pod. This data may not be up// to date.// optionalStatus PodStatus
}
以上是从使用的角度了解属性接下来深入属性相关的源码学习
接口metav1.Object
先看接口metav1.Object的源码可见前面咱们看到的annonationslabels等等信息在metav1.Object中都有Get方法获取也有Set方法来设置
type Object interface {GetNamespace() stringSetNamespace(namespace string)GetName() stringSetName(name string)GetGenerateName() stringSetGenerateName(name string)GetUID() types.UIDSetUID(uid types.UID)GetResourceVersion() stringSetResourceVersion(version string)GetGeneration() int64SetGeneration(generation int64)GetSelfLink() stringSetSelfLink(selfLink string)GetCreationTimestamp() TimeSetCreationTimestamp(timestamp Time)GetDeletionTimestamp() *TimeSetDeletionTimestamp(timestamp *Time)GetDeletionGracePeriodSeconds() *int64SetDeletionGracePeriodSeconds(*int64)GetLabels() map[string]stringSetLabels(labels map[string]string)GetAnnotations() map[string]stringSetAnnotations(annotations map[string]string)GetFinalizers() []stringSetFinalizers(finalizers []string)GetOwnerReferences() []OwnerReferenceSetOwnerReferences([]OwnerReference)GetClusterName() stringSetClusterName(clusterName string)GetManagedFields() []ManagedFieldsEntrySetManagedFields(managedFields []ManagedFieldsEntry)
}接口的实现metav1.ObjectMeta
前面看到接口定义是一堆Get和Set方法这里再来了解这些Get和Set方法在实现中返回了哪些内容又设置了哪些内容先看结构体定义与前面截图中的pod的meta信息是能对应上的
type ObjectMeta struct {Name string json:name,omitempty protobuf:bytes,1,opt,namenameGenerateName string json:generateName,omitempty protobuf:bytes,2,opt,namegenerateNameNamespace string json:namespace,omitempty protobuf:bytes,3,opt,namenamespaceSelfLink string json:selfLink,omitempty protobuf:bytes,4,opt,nameselfLinkUID types.UID json:uid,omitempty protobuf:bytes,5,opt,nameuid,casttypek8s.io/kubernetes/pkg/types.UIDResourceVersion string json:resourceVersion,omitempty protobuf:bytes,6,opt,nameresourceVersionGeneration int64 json:generation,omitempty protobuf:varint,7,opt,namegenerationCreationTimestamp Time json:creationTimestamp,omitempty protobuf:bytes,8,opt,namecreationTimestampDeletionTimestamp *Time json:deletionTimestamp,omitempty protobuf:bytes,9,opt,namedeletionTimestampDeletionGracePeriodSeconds *int64 json:deletionGracePeriodSeconds,omitempty protobuf:varint,10,opt,namedeletionGracePeriodSecondsLabels map[string]string json:labels,omitempty protobuf:bytes,11,rep,namelabelsAnnotations map[string]string json:annotations,omitempty protobuf:bytes,12,rep,nameannotationsOwnerReferences []OwnerReference json:ownerReferences,omitempty patchStrategy:merge patchMergeKey:uid protobuf:bytes,13,rep,nameownerReferencesFinalizers []string json:finalizers,omitempty patchStrategy:merge protobuf:bytes,14,rep,namefinalizersClusterName string json:clusterName,omitempty protobuf:bytes,15,opt,nameclusterNameManagedFields []ManagedFieldsEntry json:managedFields,omitempty protobuf:bytes,17,rep,namemanagedFields
}那么接口实现的方法其内容就不言而喻了对结构体中相关字段的Get和Set具体代码如下图所示唯一要注意的是GetObjectMeta方法返回的是结构体自己 现在源码已经了解接下来要看使用场景
使用场景 对象属性是非常重要的在官方资料中明确规定MetaData中的一些字段是所有资源类型必须要有的如下图所示 如下图在kubernetes源码中搜索各种常见资源的定义ObjectMeta是必不可少的上一篇学到的TypeMeta也同样一定会有 再打开client-go库的源码看看client-go如何使用ObjectMeta通过单元测试可以看到官方的标准用法如下图创建对象的操作在单元测试中随处可见一样离不开ObjectMeta 看到这里咱们把对象属性的源码和使用场景都看过了是不是本章可以结束了不就是一堆get和set方法嘛以后想读写哪个字段调用该字段对应的get和set方法就行了呗 我的建议是您先别离开还有个重要内容即将呈现那是官方的馈赠那是很实用的工具
实用工具meta.Accessor
试想一个场景开发一个函数此函数不关注资源对象的具体类型例如可能是pod也可能是deployment只想获取这个对象的一些meta信息例如namespace、label等这个函数如何实现呢看过前面的内容后其实聪明的您应该能想到ObjectMeta是嵌入到各个资源数据结构中的所以这些资源对象都算是实现了meta1.Object接口了只要能把对象转换成meta1.Object接口上述函数就能做出来了和资源关系密切client-go库自然也会遇到上述场景所以库中已经封装好了这个函数源码如下所示
func Accessor(obj interface{}) (metav1.Object, error) {switch t : obj.(type) {case metav1.Object:return t, nilcase metav1.ObjectMetaAccessor:if m : t.GetObjectMeta(); m ! nil {return m, nil}return nil, errNotObjectdefault:return nil, errNotObject}
}这个meta.Accessor方法很实用来看client-go是怎么使用的如下图在从本地缓存中取得资源列表时无需关注资源类型也能得到对象的namespace、labels等字段的信息因此这个ListAllByNamespace方法就更加通用了各种资源都能用这个方法来获取 下面这个MetaNamespaceIndexFunc方法在client-go库中是被高频使用的源码如下很简单任何资源类型都能用这个方法得到其namespace也是借用了meta.Accessor来无视资源类型
// MetaNamespaceIndexFunc is a default index function that indexes based on an objects namespace
func MetaNamespaceIndexFunc(obj interface{}) ([]string, error) {meta, err : meta.Accessor(obj)if err ! nil {return []string{}, fmt.Errorf(object has no meta: %v, err)}return []string{meta.GetNamespace()}, nil
}Unstructured的使用场景也会用到meta.Accessor方法
meta.Accessor方法还有一处比较典型使用就是利用Unstructured对象创建对象先来看看什么是UnstructuredUnstructured是个map在创建Deployment、Pod等对象的时候除了使用Deployment、Pod等特定的数据结构还可以直接用Unstructured对象作为创建的参数这样写出的代码更有通用性以下是个代码片段用来创建Deployment对象可见通过map就能完成Deployment资源的创建那个Create方法的入参就是Unstructured deploymentRes : schema.GroupVersionResource{Group: apps, Version: v1, Resource: deployments}deployment : unstructured.Unstructured{Object: map[string]interface{}{apiVersion: apps/v1,kind: Deployment,metadata: map[string]interface{}{name: demo-deployment,},spec: map[string]interface{}{replicas: 2,selector: map[string]interface{}{matchLabels: map[string]interface{}{app: demo,},},template: map[string]interface{}{metadata: map[string]interface{}{labels: map[string]interface{}{app: demo,},},spec: map[string]interface{}{containers: []map[string]interface{}{{name: web,image: nginx:1.12,ports: []map[string]interface{}{{name: http,protocol: TCP,containerPort: 80,},},},},},},},},}// Create Deploymentfmt.Println(Creating deployment...)result, err : client.Resource(deploymentRes).Namespace(apiv1.NamespaceDefault).Create(context.TODO(), deployment, metav1.CreateOptions{})进入Create方法内部看看如下图所示这个Create方法可以用来创建多种资源类型但使用了meta.Accessor无需知道资源类型也能得到资源名称 至此对象属性的学习就完成了相信您对metav1.Object和metav1.ObjectMeta都有了深入的理解也会有动手写代码试试的冲动实战一直是欣宸原创的招牌这里也不会缺席碍于篇幅限制本篇就只聊理论下一篇咱们实战走起写代码体验对象属性的操作
你不孤单欣宸原创一路相伴
Java系列Spring系列Docker系列kubernetes系列数据库中间件系列DevOps系列