介绍Kubernetes API

282 阅读11分钟

Kuberenetes API Diagram

Kubernetes API

Kubernetes API 是 Kubernetes 集群中的核心组件,它提供了一种标准化的方式来与集群进行交互和管理。Kubernetes API 允许用户通过 RESTful 接口与集群中的各种资源进行交互,包括 Pods、Services、Deployments、ConfigMaps 等。

以下是 Kubernetes API 的一些关键特性和功能:

  1. 统一接口:Kubernetes API 提供了一个统一的接口来管理和操作集群中的资源。无论是部署应用程序、扩展集群、管理网络、配置存储,还是进行监控和日志记录,都可以通过 Kubernetes API 来完成。
  2. RESTful 设计:Kubernetes API 遵循 RESTful 设计原则,使用 HTTP 协议进行通信,并使用标准的 HTTP 方法(GET、POST、PUT、DELETE)来执行操作。资源对象以 JSON 格式进行表示和传输。
  3. 资源管理:通过 Kubernetes API,用户可以创建、更新和删除各种资源对象。可以使用 API 来定义和管理应用程序的副本数量、容器的配置、服务的访问方式等。
  4. 声明式配置:Kubernetes API 支持声明式配置,用户可以通过创建资源对象的 YAML 或 JSON 文件来描述期望的状态。Kubernetes 控制器将根据配置文件中的定义自动调整集群状态,以使集群状态与期望状态保持一致。
  5. 自定义资源定义(Custom Resource Definitions,CRDs):Kubernetes API提供了 CRD 机制,允许用户定义自定义资源类型。CRD 允许用户扩展 Kubernetes API,引入新的资源类型和控制器,以适应特定的业务需求。

以Deployment资源类型为例,分析K8S的资源定义

// https://github1s.com/kubernetes/kubernetes/blob/master/pkg/apis/apps/types.go#L355
    // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

    // Deployment provides declarative updates for Pods and ReplicaSets.
    type Deployment struct {
    	metav1.TypeMeta
    	// +optional
    	metav1.ObjectMeta

    	// Specification of the desired behavior of the Deployment.
    	// +optional
    	Spec DeploymentSpec

    	// Most recently observed status of the Deployment.
    	// +optional
    	Status DeploymentStatus
    }

TypeMeta

TypeMeta 是 Kubernetes API 对象中的一个字段,用于描述该对象的类型信息。它包含两个字段:apiVersion 和 kind。

apiVersion 字段指定了 Kubernetes API 的版本,它用于标识该对象所属的 API 版本。例如,apiVersion: v1 表示该对象属于 Kubernetes 的 v1 版本 API。

kind 字段表示该对象的类型或种类。它用于指示该对象所代表的资源类型。例如,kind: Pod 表示该对象是一个 Pod 类型的资源。

TypeMeta 的作用是提供关于对象类型的元数据信息,使得 Kubernetes API Server 能够正确解析和处理请求。通过查看 TypeMeta 字段,Kubernetes 可以确定对象的 API 版本和类型,从而选择正确的处理逻辑和验证规则。

TypeMeta定义Kubernetes API 对象的规范类型元数据,它是确保对象在与 API Server 进行交互时被正确识别和处理的重要组成部分。

定义中GroupVersionKind

TypeMeta定义中GroupVersionKind分别表示:

  • Group: 指定资源所属组
  • Kind: 指定资源的类型或类别
  • Version: 指定资源对应API的版本
// https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/group_version.go#L86
    // GroupVersionKind unambiguously identifies a kind.  It doesn't anonymously include GroupVersion
    // to avoid automatic coercion.  It doesn't use a GroupVersion to avoid custom marshalling
    //
    // +protobuf.options.(gogoproto.goproto\_stringer)=false
    type GroupVersionKind struct {
    Group   string `json:"group" protobuf:"bytes,1,opt,name=group"`
    Version string `json:"version" protobuf:"bytes,2,opt,name=version"`
    Kind    string `json:"kind" protobuf:"bytes,3,opt,name=kind"`
    }

以下是Deployment的GVK定义:

    Group: "apps"
    Version: "v1"
    Kind: "Deployment"

GroupVersionResource

在 Kubernetes 中,"Resource" 字段用于指定资源的名称,以其复数形式和小写形式表示。它表示所引用的实际资源,在API中需要使用这个字段作为请求资源的类型

    Group: "apps"
    Version: "v1"
    Resource: "deployments"

ObjectMeta

ObjectMeta包括资源实例的名称(name), 所属命名空间(namespace), 标签(labels), annotation(内部标签)

// https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L111-L121
type ObjectMeta struct {
	Name string `json:"name,omitempty" protobuf:"bytes,1,opt,name=name"`
	GenerateName string `json:"generateName,omitempty" protobuf:"bytes,2,opt,name=generateName"`
	Namespace string `json:"namespace,omitempty" protobuf:"bytes,3,opt,name=namespace"`
	SelfLink string `json:"selfLink,omitempty" protobuf:"bytes,4,opt,name=selfLink"`
	UID types.UID `json:"uid,omitempty" protobuf:"bytes,5,opt,name=uid,casttype=k8s.io/kubernetes/pkg/types.UID"`
	ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,6,opt,name=resourceVersion"`
	CreationTimestamp Time `json:"creationTimestamp,omitempty" protobuf:"bytes,8,opt,name=creationTimestamp"`
        Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`
...
  • Name: 代表资源名称
  • Namespace: 代表资源所属命名空间
  • Labels: 代表给资源打的标签

DeploymentSpec

DeploymentSpec用于提供给用户创建配置,用户可以按需求设置replicas、selector、Pod的Template

Spec is the object configuration, include replica, podTemplate

    // DeploymentSpec is the specification of the desired behavior of the Deployment.
    type DeploymentSpec struct {
    	// Number of desired pods. This is a pointer to distinguish between explicit
    	// zero and not specified. Defaults to 1.
    	// +optional
    	Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`

    	// Label selector for pods. Existing ReplicaSets whose pods are
    	// selected by this will be the ones affected by this deployment.
    	// It must match the pod template's labels.
    	Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,2,opt,name=selector"`

    	// Template describes the pods that will be created.
    	// The only allowed template.spec.restartPolicy value is "Always".
    	Template v1.PodTemplateSpec `json:"template" protobuf:"bytes,3,opt,name=template"`

    	// The deployment strategy to use to replace existing pods with new ones.
    	// +optional
    	// +patchStrategy=retainKeys
    	Strategy DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"`

    	// Minimum number of seconds for 

DeploymentStatus

DeploymentStatus用于表示资源在集群中的当前实际状态

    type DeploymentStatus struct {
    	// The generation observed by the deployment controller.
    	// +optional
    	ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`

    	// Total number of non-terminated pods targeted by this deployment (their labels match the selector).
    	// +optional
    	Replicas int32 `json:"replicas,omitempty" protobuf:"varint,2,opt,name=replicas"`

    	// Total number of non-terminated pods targeted by this deployment that have the desired template spec.
    	// +optional
    	UpdatedReplicas int32 `json:"updatedReplicas,omitempty" protobuf:"varint,3,opt,name=updatedReplicas"`

    	// readyReplicas is the number of pods targeted by this Deployment with a Ready Condition.
    	// +optional
    	ReadyReplicas int32 `json:"readyReplicas,omitempty" protobuf:"varint,7,opt,name=readyReplicas"`

    	// Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.
    	// +optional
    	AvailableReplicas int32 `json:"availableReplicas,omitempty" protobuf:"varint,4,opt,name=availableReplicas"`

    	// Total number of unavailable pods targeted by this deployment. This is the total number of
    	// pods that are still required for the deployment to have 100% available capacity. They may
    	// either be pods that are running but not yet available or pods that still have not been created.
    	// +optional
    	UnavailableReplicas int32 `json:"unavailableReplicas,omitempty" protobuf:"varint,5,opt,name=unavailableReplicas"`

根据资源定义规范,声明一个Deployment类型的资源

// https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kubectl/pkg/cmd/create/create_deployment.go#L220
    func (o *CreateDeploymentOptions) createDeployment() *appsv1.Deployment {
    labels := map[string]string{"app": o.Name}
    selector := metav1.LabelSelector{MatchLabels: labels}
    namespace := ""
    if o.EnforceNamespace {
    namespace = o.Namespace
    }

          deploy := &appsv1.Deployment{
          	TypeMeta: metav1.TypeMeta{
                    APIVersion: appsv1.SchemeGroupVersion.String(), 
                    Kind: "Deployment"
                  },
          	ObjectMeta: metav1.ObjectMeta{
          		Name:      o.Name,
          		Labels:    labels,
          		Namespace: namespace,
          	},
          	Spec: appsv1.DeploymentSpec{
          		Replicas: &o.Replicas,
          		Selector: &selector,
          		Template: corev1.PodTemplateSpec{
          			ObjectMeta: metav1.ObjectMeta{
          				Labels: labels,
          			},
          			Spec: o.buildPodSpec(),
          		},
          	},
          }
  • APIVersion: 设置api version
  • Kind: 设置资源类型
  • Name: 设置资源的名称
  • Labels: 为资源添加label
  • Namespace: 设置资源所属命名空间
  • Replicas: 设置pod的副本数量
  • Selector: 设置资源的标签选择器,用于过滤查询资源使用
  • Template: 配置Pod的template模块

查询集群支持的资源类型

    ➜  golang k 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
    aplogconfs                                     appprotect.f5.com/v1beta1           true         APLogConf
    appolicies                                     appprotect.f5.com/v1beta1           true         APPolicy
    apusersigs                                     appprotect.f5.com/v1beta1           true         APUserSig
    apdoslogconfs                                  appprotectdos.f5.com/v1beta1        true         APDosLogConf
    apdospolicies                                  appprotectdos.f5.com/v1beta1        true         APDosPolicy
    dosprotectedresources             pr           appprotectdos.f5.com/v1beta1        true         DosProtectedResource
    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
    selfsubjectreviews                             authentication.k8s.io/v1            false        SelfSubjectReview
    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/v2                      true         HorizontalPodAutoscaler
    cronjobs                          cj           batch/v1                            true         CronJob
    jobs                                           batch/v1                            true         Job
    certificatesigningrequests        csr          certificates.k8s.io/v1              false        CertificateSigningRequest
    ingressclassparameterses                       configuration.konghq.com/v1alpha1   true         IngressClassParameters
    kongclusterplugins                kcp          configuration.konghq.com/v1         false        KongClusterPlugin
    kongconsumergroups                kcg          configuration.konghq.com/v1beta1    true         KongConsumerGroup
    kongconsumers                     kc           configuration.konghq.com/v1         true         KongConsumer
    kongingresses                     ki           configuration.konghq.com/v1         true         KongIngress
    kongplugins                       kp           configuration.konghq.com/v1         true         KongPlugin
    tcpingresses                                   configuration.konghq.com/v1beta1    true         TCPIngress
    udpingresses                                   configuration.konghq.com/v1beta1    true         UDPIngress
    leases                                         coordination.k8s.io/v1              true         Lease
    endpointslices                                 discovery.k8s.io/v1                 true         EndpointSlice
    events                            ev           events.k8s.io/v1                    true         Event
    dnsendpoints                                   externaldns.nginx.org/v1            true         DNSEndpoint
    flowschemas                                    flowcontrol.apiserver.k8s.io/v1     false        FlowSchema
    prioritylevelconfigurations                    flowcontrol.apiserver.k8s.io/v1     false        PriorityLevelConfiguration
    globalconfigurations              gc           k8s.nginx.org/v1                    true         GlobalConfiguration
    policies                          pol          k8s.nginx.org/v1                    true         Policy
    transportservers                  ts           k8s.nginx.org/v1                    true         TransportServer
    virtualserverroutes               vsr          k8s.nginx.org/v1                    true         VirtualServerRoute
    virtualservers                    vs           k8s.nginx.org/v1                    true         VirtualServer
    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
    poddisruptionbudgets              pdb          policy/v1                           true         PodDisruptionBudget
    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
    csidrivers                                     storage.k8s.io/v1                   false        CSIDriver
    csinodes                                       storage.k8s.io/v1                   false        CSINode
    csistoragecapacities                           storage.k8s.io/v1                   true         CSIStorageCapacity
    storageclasses                    sc           storage.k8s.io/v1                   false        StorageClass
    volumeattachments                              storage.k8s.io/v1                   false        VolumeAttachment
  • name 表示资源类型的名称
  • short name 表示资源类型的简写
  • api version 表示资源api所属组和版本
  • namespaced 表示资源是否为namespaced范围的资源
  • kind 表示资源类型

我们可以通过kubectl的-v参数获取API url的信息

    ➜  golang kg deploy -v 8 
    I0324 16:47:40.921694 1522072 loader.go:395] Config loaded from file:  /home/going/.kube/config
    I0324 16:47:40.930139 1522072 round_trippers.go:463] GET <https://127.0.0.1:46219/apis/apps/v1/namespaces/default/deployments?limit=500>
    I0324 16:47:40.930183 1522072 round_trippers.go:469] Request Headers:
    I0324 16:47:40.930195 1522072 round_trippers.go:473]     Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
    I0324 16:47:40.930205 1522072 round_trippers.go:473]     User-Agent: kubectl/v1.28.5 (linux/amd64) kubernetes/e78a4be
    I0324 16:47:40.943334 1522072 round_trippers.go:574] Response Status: 200 OK in 13 milliseconds
    I0324 16:47:40.943381 1522072 round_trippers.go:577] Response Headers:
    I0324 16:47:40.943393 1522072 round_trippers.go:580]     Audit-Id: 8d82fd9c-12cf-4d86-b6a2-23a6c069198a
    I0324 16:47:40.943401 1522072 round_trippers.go:580]     Cache-Control: no-cache, private
    I0324 16:47:40.943408 1522072 round_trippers.go:580]     Content-Type: application/json
    I0324 16:47:40.943416 1522072 round_trippers.go:580]     X-Kubernetes-Pf-Flowschema-Uid: af0a188f-fc8b-4323-ae75-1dc2a930b79c
    I0324 16:47:40.943423 1522072 round_trippers.go:580]     X-Kubernetes-Pf-Prioritylevel-Uid: 249c1c1a-ab96-42e4-bd75-25fa3d93832f
    I0324 16:47:40.943432 1522072 round_trippers.go:580]     Date: Sun, 24 Mar 2024 08:47:40 GMT
    I0324 16:47:40.943662 1522072 request.go:1212] Response Body: {"kind":"Table","apiVersion":"meta.k8s.io/v1","metadata":{"resourceVersion":"1023944"},"columnDefinitions":[{"name":"Name","type":"string","format":"name","description":"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","priority":0},{"name":"Ready","type":"string","format":"","description":"Number> of the pod with ready state","priority":0},{"name":"Up-to-date","type":"string","format":"","description":"Total number of non-terminated pods targeted by this deployment that have the desired template spec.","priority":0},{"name":"Available","type":"string","format":"","description":"Total number of available pods (ready for at least minReadySeconds) targeted by this deployment.","priority":0},{ [truncated 5979 chars]
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    lister             1/1     1            1           23h
    nginx-deployment   3/3     3            3           21m

Kubernetes API和GroupVersionKind对应关系

https://127.0.0.1:46219/apis/apps/v1/namespaces/default/deployments?limit=500
    // The convention
https://{api-server-ip}/api(s)/{group}/{version}/namespaces/{namespace-value}/{resource-plural}?limit=500

我们可以通过RESTMapping将资源的GroupVersion信息转换为对应的resource信息

    // <https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/client-go/restmapper/discovery.go#L285>

    // RESTMapping identifies a preferred resource mapping for the
    // provided group kind.
    func (d *DeferredDiscoveryRESTMapper) RESTMapping(gk schema.GroupKind, versions ...string) (m *meta.RESTMapping, err error) {
    	del, err := d.getDelegate()
    	if err != nil {
    		return nil, err
    	}
    	m, err = del.RESTMapping(gk, versions...)
    	if err != nil && !d.cl.Fresh() {
    		d.Reset()
    		m, err = d.RESTMapping(gk, versions...)
    	}
    	return
    }

也可以通过resource信息转化为对应的GroupVersionKind

    // <https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/client-go/restmapper/discovery.go#L225>

    // KindFor takes a partial resource and returns back the single match.
    // It returns an error if there are multiple matches.
    func (d *DeferredDiscoveryRESTMapper) KindFor(resource schema.GroupVersionResource) (gvk schema.GroupVersionKind, err error) {
    	del, err := d.getDelegate()
    	if err != nil {
    		return schema.GroupVersionKind{}, err
    	}
    	gvk, err = del.KindFor(resource)
    	if err != nil && !d.cl.Fresh() {
    		d.Reset()
    		gvk, err = d.KindFor(resource)
    	}
    	return
    }

Scheme to convert Go type to HTTP url

    // <https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go#L46>
    // Scheme defines methods for serializing and deserializing API objects, a type
    // registry for converting group, version, and kind information to and from Go
    // schemas, and mappings between Go schemas of different versions. A scheme is the
    // foundation for a versioned API and versioned configuration over time.
    //
    // In a Scheme, a Type is a particular Go struct, a Version is a point-in-time
    // identifier for a particular representation of that Type (typically backwards
    // compatible), a Kind is the unique name for that Type within the Version, and a
    // Group identifies a set of Versions, Kinds, and Types that evolve over time. An
    // Unversioned Type is one that is not yet formally bound to a type and is promised
    // to be backwards compatible (effectively a "v1" of a Type that does not expect
    // to break in the future).
    //
    // Schemes are not expected to change at runtime and are only threadsafe after
    // registration is complete.
    type Scheme struct {
    	// gvkToType allows one to figure out the go type of an object with
    	// the given version and name.
    	gvkToType map[schema.GroupVersionKind]reflect.Type

    	// typeToGVK allows one to find metadata for a given go object.
    	// The reflect.Type we index by should *not* be a pointer.
    	typeToGVK map[reflect.Type][]schema.GroupVersionKind

    	// unversionedTypes are transformed without conversion in ConvertToVersion.
    	unversionedTypes map[reflect.Type]schema.GroupVersionKind

    	// unversionedKinds are the names of kinds that can be created in the context of any group
    	// or version
    	// TODO: resolve the status of unversioned types.
    	unversionedKinds map[string]reflect.Type

Kubernete对象的接口定义

    // <https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/interfaces.go#L323>
    // Object interface must be supported by all API types registered with Scheme. Since objects in a scheme are
    // expected to be serialized to the wire, the interface an Object must provide to the Scheme allows
    // serializers to set the kind, version, and group the object is represented as. An Object may choose
    // to return a no-op ObjectKindAccessor in cases where it is not expected to be serialized.
    type Object interface {
    	GetObjectKind() schema.ObjectKind
    	DeepCopyObject() Object
    }

添加Kubernetes对象到scheme

    // <https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go#L140>
    // AddKnownTypes registers all types passed in 'types' as being members of version 'version'.
    // All objects passed to types should be pointers to structs. The name that go reports for
    // the struct becomes the "kind" field when encoding. Version may not be empty - use the
    // APIVersionInternal constant if you have a type that does not have a formal version.
    func (s *Scheme) AddKnownTypes(gv schema.GroupVersion, types ...Object) {
    	s.addObservedVersion(gv)
    	for _, obj := range types {
    		t := reflect.TypeOf(obj)
    		if t.Kind() != reflect.Pointer {
    			panic("All types must be pointers to structs.")
    		}
    		t = t.Elem()
    		s.AddKnownTypeWithName(gv.WithKind(t.Name()), obj)
    	}
    }

通过传入Kubernetes对象获得其GroupVersionKind信息

    // <https://github1s.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/runtime/scheme.go#L243>
    // ObjectKinds returns all possible group,version,kind of the go object, true if the
    // object is considered unversioned, or an error if it's not a pointer or is unregistered.
    func (s *Scheme) ObjectKinds(obj Object) ([]schema.GroupVersionKind, bool, error) {
    	// Unstructured objects are always considered to have their declared GVK
    	if _, ok := obj.(Unstructured); ok {
    		// we require that the GVK be populated in order to recognize the object
    		gvk := obj.GetObjectKind().GroupVersionKind()
    		if len(gvk.Kind) == 0 {
    			return nil, false, NewMissingKindErr("unstructured object has no kind")
    		}
    		if len(gvk.Version) == 0 {
    			return nil, false, NewMissingVersionErr("unstructured object has no version")
    		}
    		return []schema.GroupVersionKind{gvk}, false, nil
    	}

    	v, err := conversion.EnforcePtr(obj)
    	if err != nil {
    		return nil, false, err
    	}
    	t := v.Type()

    	gvks, ok := s.typeToGVK[t]
    	if !ok {
    		return nil, false, NewNotRegisteredErrForType(s.schemeName, t)
    	}
    	_, unversionedType := s.unversionedTypes[t]

    	return gvks, unversionedType, nil
    }

In conclusion, the whole view of conversion from Go type to HTTP url goes like:

Untitled转存失败,建议直接上传图片文件