Kubernetes编程——client-go基础—— ObjectMeta
ObjectMeta
https://github.com/kubernetes/apimachinery/blob/release-1.27/pkg/apis/meta/v1/types.go
我理解意思是说:在 Kubernetes 中,ObjectMeta 是一个结构体,用于表示资源对象的元数据,例如 Pod、Service 和 Deployment 等。ObjectMeta 结构体包含了以下字段:
-
- Name:资源对象的名称。
- Namespace:资源对象所属的命名空间。
- Labels:带有键值对的标签,用于标识和选择资源对象。
- Annotations:带有键值对的注释,用于提供关于资源对象的附加信息。
- OwnerReferences:指向拥有当前资源对象的其他资源对象的引用。
- CreationTimestamp:资源对象的创建时间戳。
- Finalizers:资源对象的终结器列表,控制资源对象的生命周期。
ObjectMeta 使得 Kubernetes 可以管理和维护资源对象的元数据信息,从而更好地管理和调度这些对象。
出自:https://github.com/kubernetes/apimachinery/blob/release-1.27/pkg/apis/meta/v1/types.go
// ObjectMeta is metadata that all persisted resources must have, which includes all objects // users must create. type ObjectMeta struct { // Name must be unique within a namespace. Is required when creating resources, although // some resources may allow a client to request the generation of an appropriate name // automatically. Name is primarily intended for creation idempotence and configuration // definition. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names // +optional Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"` // GenerateName is an optional prefix, used by the server, to generate a unique // name ONLY IF the Name field has not been provided. // If this field is used, the name returned to the client will be different // than the name passed. This value will also be combined with a unique suffix. // The provided value has the same validation rules as the Name field, // and may be truncated by the length of the suffix required to make the value // unique on the server. // // If this field is specified and the generated name exists, the server will return a 409. // // Applied only if Name is not specified. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency // +optional GenerateName string `json:"generateName,omitempty" protobuf:"bytes,2,opt,name=generateName"` // Namespace defines the space within which each name must be unique. An empty namespace is // equivalent to the "default" namespace, but "default" is the canonical representation. // Not all objects are required to be scoped to a namespace - the value of this field for // those objects will be empty. // // Must be a DNS_LABEL. // Cannot be updated. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces // +optional Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"` // Deprecated: selfLink is a legacy read-only field that is no longer populated by the system. // +optional SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"` // UID is the unique in time and space value for this object. It is typically generated by // the server on successful creation of a resource and is not allowed to change on PUT // operations. // // Populated by the system. // Read-only. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids // +optional UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"` // An opaque value that represents the internal version of this object that can // be used by clients to determine when objects have changed. May be used for optimistic // concurrency, change detection, and the watch operation on a resource or set of resources. // Clients must treat these values as opaque and passed unmodified back to the server. // They may only be valid for a particular resource or set of resources. // // Populated by the system. // Read-only. // Value must be treated as opaque by clients and . // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency // +optional ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"` // A sequence number representing a specific generation of the desired state. // Populated by the system. Read-only. // +optional Generation int64 `json:"generation,omitempty" protobuf:"varint,7,opt,name=generation"` // CreationTimestamp is a timestamp representing the server time when this object was // created. It is not guaranteed to be set in happens-before order across separate operations. // Clients may not set this value. It is represented in RFC3339 form and is in UTC. // // Populated by the system. // Read-only. // Null for lists. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional CreationTimestamp Time `json:"creationTimestamp,omitempty" protobuf:"bytes,8,opt,name=creationTimestamp"` // DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This // field is set by the server when a graceful deletion is requested by the user, and is not // directly settable by a client. The resource is expected to be deleted (no longer visible // from resource lists, and not reachable by name) after the time in this field, once the // finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. // Once the deletionTimestamp is set, this value may not be unset or be set further into the // future, although it may be shortened or the resource may be deleted prior to this time. // For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react // by sending a graceful termination signal to the containers in the pod. After that 30 seconds, // the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, // remove the pod from the API. In the presence of network partitions, this object may still // exist after this timestamp, until an administrator or automated process can determine the // resource is fully terminated. // If not set, graceful deletion of the object has not been requested. // // Populated by the system when a graceful deletion is requested. // Read-only. // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata // +optional DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"` // Number of seconds allowed for this object to gracefully terminate before // it will be removed from the system. Only set when deletionTimestamp is also set. // May only be shortened. // Read-only. // +optional DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"` // Map of string keys and values that can be used to organize and categorize // (scope and select) objects. May match selectors of replication controllers // and services. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels // +optional Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"` // Annotations is an unstructured key value map stored with a resource that may be // set by external tools to store and retrieve arbitrary metadata. They are not // queryable and should be preserved when modifying objects. // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations // +optional Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"` // List of objects depended by this object. If ALL objects in the list have // been deleted, this object will be garbage collected. If this object is managed by a controller, // then an entry in this list will point to this controller, with the controller field set to true. // There cannot be more than one managing controller. // +optional // +patchMergeKey=uid // +patchStrategy=merge OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"` // Must be empty before the object is deleted from the registry. Each entry // is an identifier for the responsible component that will remove the entry // from the list. If the deletionTimestamp of the object is non-nil, entries // in this list can only be removed. // Finalizers may be processed and removed in any order. Order is NOT enforced // because it introduces significant risk of stuck finalizers. // finalizers is a shared field, any actor with permission can reorder it. // If the finalizer list is processed in order, then this can lead to a situation // in which the component responsible for the first finalizer in the list is // waiting for a signal (field value, external system, or other) produced by a // component responsible for a finalizer later in the list, resulting in a deadlock. // Without enforced ordering finalizers are free to order amongst themselves and // are not vulnerable to ordering changes in the list. // +optional // +patchStrategy=merge Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"` // Tombstone: ClusterName was a legacy field that was always cleared by // the system and never used. // ClusterName string `json:"clusterName,omitempty" protobuf:"bytes,15,opt,name=clusterName"` // ManagedFields maps workflow-id and version to the set of fields // that are managed by that workflow. This is mostly for internal // housekeeping, and users typically shouldn't need to set or // understand this field. A workflow can be the user's name, a // controller's name, or the name of a specific apply path like // "ci-cd". The set of fields is always in the version that the // workflow used when modifying the object. // // +optional ManagedFields []ManagedFieldsEntry `json:"managedFields,omitempty" protobuf:"bytes,17,rep,name=managedFields"` }
在 JSON 或 YAML 中,这些字段位于 metadata 字段中。deployment 对象为例,metav1.ObjectMeta 中存储了如下信息:
metadata: namespace: default name: example
通常来说, metadata 字段中存储了各种元信息,包括 名字、命名空间、资源版本(不是API组版本)、各种时间戳以及一些通用的标签和注解,它们都是 ObjectMeta 的一部分。
client-go 中的代码通常不直接对 ObjectMeta 字段进行读写操作。ObjectMeta 字段的值是由 Kubernetes 系统自动生成和管理的,用于确保整个系统的一致性和正确性。
在 ObjectMeta 中,resourceVersion 是用来跟踪对象在 Kubernetes 集群中的版本信息的重要字段。每个对象的 ObjectMeta 对应着 etcd 中的一个键,而 resourceVersion 的值正是来自于 etcd。resourceVersion 字段用于比较和解决并发更新的冲突,确保更新操作是基于最新的数据。
import ( "fmt" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" ) func main() { // 创建 Kubernetes 客户端 clientset, _ := kubernetes.NewForConfig(config) // 获取 Pod 的元数据 pod, _ := clientset.CoreV1().Pods("default").Get(context.TODO(), "my-pod", metav1.GetOptions{}) // 检查当前资源版本 fmt.Println("Current Resource Version:", pod.ObjectMeta.ResourceVersion) // 修改 Pod 对象 pod.ObjectMeta.Labels["new-label"] = "new-value" // ... // 更新 Pod 对象 updatedPod, _ := clientset.CoreV1().Pods("default").Update(context.TODO(), pod, metav1.UpdateOptions{}) fmt.Println("Updated Resource Version:", updatedPod.ObjectMeta.ResourceVersion) // ... }
在上面的示例中,我们首先读取了 Pod 对象的元数据,然后可以检查它的当前 resourceVersion。接下来,我们对 Pod 对象进行修改,然后将其更新回 Kubernetes 集群,并获取更新后的 resourceVersion。
需要注意的是,由于 resourceVersion 是由 Kubernetes 系统自动管理的,我们不应该手动修改或设置它。我们只能读取它,或通过更新对象将其自动更新。
总而言之,resourceVersion 是 Kubernetes 系统中用于确保数据一致性和正确性的重要字段之一。client-go 中的代码通常不会直接对 ObjectMeta 进行读写操作,但可以通过读取和更新对象来间接操作 resourceVersion 的值。