理清Kubernetes Object, API的关系

232 阅读9分钟

APImachinery

用于Kubernetes对象行为接口定义、编解码、API约定的工具包,支持ubernetes和类Kubernetes API 对象的类型定义、类型申明、类型编解码、类型对象和类型对象API转换。

Kubernetes对象的编解码器:

提供Kubernetes Object和系列化数据之间的转换

// 
[interfaces.go - kubernetes/apimachinery - GitHub1s](https://github1s.com/kubernetes/apimachinery/blob/master/pkg/runtime/interfaces.go#L102-L107)
//提供Kubernetes Object和系列化数据之间的转换接口定义
type Serializer interface {
	Encoder
	Decoder
}
[interfaces.go - kubernetes/apimachinery - GitHub1s](https://github1s.com/kubernetes/apimachinery/blob/master/pkg/runtime/interfaces.go#L51-L70)
//序列化器提供Kubernetes Object到序列化数据的转换
type Encoder interface {
	Encode(obj Object, w io.Writer) error
	Identifier() Identifier
}
[interfaces.go - kubernetes/apimachinery - GitHub1s](https://github1s.com/kubernetes/apimachinery/blob/master/pkg/runtime/interfaces.go#L90-L101)
//序列化器提供序列化数据到Kubernetes Object的转换
type Decoder interface {
	Decode(data []byte, defaults *schema.GroupVersionKind, into Object) (Object, *schema.GroupVersionKind, error)
}

REST映射器:

RESTMapper 根据 runtime.Scheme 中的对象和 Kubernetes API 约定,实现从 Kind 和 APIVersion 到资源名称的映射关系,并且可以反向映射。

// [restmapper.go - kubernetes/apimachinery - GitHub1s](https://github1s.com/kubernetes/apimachinery/blob/master/pkg/api/meta/restmapper.go#L76-L98)
func NewDefaultRESTMapper(defaultGroupVersions []schema.GroupVersion) *DefaultRESTMapper {
	resourceToKind := make(map[schema.GroupVersionResource]schema.GroupVersionKind)
	kindToPluralResource := make(map[schema.GroupVersionKind]schema.GroupVersionResource)
	kindToScope := make(map[schema.GroupVersionKind]RESTScope)
	singularToPlural := make(map[schema.GroupVersionResource]schema.GroupVersionResource)
	pluralToSingular := make(map[schema.GroupVersionResource]schema.GroupVersionResource)
	// TODO: verify name mappings work correctly when versions differ

	return &DefaultRESTMapper{
		resourceToKind:       resourceToKind,
		kindToPluralResource: kindToPluralResource,
		kindToScope:          kindToScope,
		defaultGroupVersions: defaultGroupVersions,
		singularToPlural:     singularToPlural,
		pluralToSingular:     pluralToSingular,
	}
}

Kubernetes类型转化器: 负责Kubernetes Object之间的类型转换

// [converter.go - kubernetes/apimachinery - GitHub1s](https://github1s.com/kubernetes/apimachinery/blob/master/pkg/conversion/converter.go#L39-L48)
// Converter knows how to convert one type to another.
type Converter struct {
	// Map from the conversion pair to a function which can
	// do the conversion.
	conversionFuncs          ConversionFuncs
	generatedConversionFuncs ConversionFuncs

	// Set of conversions that should be treated as a no-op
	ignoredUntypedConversions map[typePair]struct{}
}

Kubernetes Object

在Kubernetes中实现了runtime.Object接口的Go结构体被视为Kubernetes资源对象

    //"k8s.io/apimachinery/pkg/runtime"
    type Object interface {
    	GetObjectKind() schema.ObjectKind
    	DeepCopyObject() Object
    }

GetObjectKind: 用于提供对象的所属类型Kind,其内部内嵌了SetGroupVersionKind和GroupVersionKind

type ObjectKind interface {
	SetGroupVersionKind(kind GroupVersionKind)
	GroupVersionKind() GroupVersionKind
}

DeepCopyObject: 提供对类型对象的深度拷贝,返回源对象的副本

// https://github1s.com/kubernetes/api/blob/v0.29.3/core/v1/zz_generated.deepcopy.go#L3502
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Pod) DeepCopyObject() runtime.Object {
	if c := in.DeepCopy(); c != nil {
		return c
	}
	return nil
}

以Pod为例,介绍Kubernetes资源定义

    //https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/types.go#L3995
    type Pod struct {
    	metav1.TypeMeta
    	metav1.ObjectMeta
    	// Spec defines the behavior of a pod.
    	// +optional
    	Spec PodSpec
    	// Status represents the current information about a pod. This data may not be up
    	// to date.
    	// +optional
    	Status PodStatus
    }
  • TypeMeta: 描述资源对象的类型源信息,包括资源类型Kind,分组版本APIVersion
  • ObjectMeta: 描述资源对象的基本信息,包括但不限于对象的名称,命名空间,标签,内部标签。
  • Spec: 描述资源对象的配置信息,包括容器的配置,容器重启策略,节点标签选择器,节点名称等
  • Status: 描述资源对象的状态信息,包括Pod的状态,IP,探测接口结果,容器运行状态等

metav1.TypeMeta

// https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L42
type TypeMeta struct {
	Kind string `json:"kind,omitempty" protobuf:"bytes,1,opt,name=kind"`
	APIVersion string `json:"apiVersion,omitempty" protobuf:"bytes,2,opt,name=apiVersion"`
}
  • Kind: 描述资源的类型
  • APIVersion: 描述资源的API版本信息,包括所属组和版本号

TypeMeta实现了runtime.Object接口的GetObjectKind方法

// https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/meta.go#L117
    func (obj *TypeMeta) GetObjectKind() schema.ObjectKind { return obj }

Pod指针对象实现了runtime.Object接口的DeepCopyObject方法

    // <https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/zz_generated.deepcopy.go#L3558>
    // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
    func (in *Pod) DeepCopyObject() runtime.Object {
    	if c := in.DeepCopy(); c != nil {
    		return c
    	}
    	return nil
    }

ObjectMeta

描述资源对象的基本信息

// <https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/types.go#L111>
// ObjectMeta is metadata that all persisted resources must have, which includes all objects
// users must create.
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"`
	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"`
	DeletionTimestamp *Time `json:"deletionTimestamp,omitempty" protobuf:"bytes,9,opt,name=deletionTimestamp"`
	DeletionGracePeriodSeconds *int64 `json:"deletionGracePeriodSeconds,omitempty" protobuf:"varint,10,opt,name=deletionGracePeriodSeconds"`
	Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,11,rep,name=labels"`
	Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,12,rep,name=annotations"`
	OwnerReferences []OwnerReference `json:"ownerReferences,omitempty" patchStrategy:"merge" patchMergeKey:"uid" protobuf:"bytes,13,rep,name=ownerReferences"`
	Finalizers []string `json:"finalizers,omitempty" patchStrategy:"merge" protobuf:"bytes,14,rep,name=finalizers"`
        ...
}
  • Name: 代表资源的名称
  • Namespace:代表资源所在命名空间
  • UID: 代表资源的唯一标识
  • ResourceVersion: 代表资源在当前状态的唯一版本号
  • CreationTimestamp:代表资源创建的时间
  • DeletionTimestamp:代表资源删除的时间
  • DeletionGracePeriodSeconds: 删除资源的优雅等待时间
  • DeletionGracePeriodSeconds
  • Labels:代表资源的标签
  • Annotations: 代表资源在Kubernetes内部的标签
  • OwnerReferences: 代表资源的拥有者列表
  • Finalizers: 代表资源的删除前需要执行的终止器列表

Spec

描述资源配置信息,包括但不限于运行容器的配置,容器重启策略,节点标签选择器,节点名称等。

// https://github1s.com/kubernetes/kubernetes/blob/master/pkg/apis/core/types.go#L3234-L3235
// PodSpec is a description of a pod
type PodSpec struct {
	Volumes []Volume
	InitContainers []Container
	Containers []Container
	NodeSelector map[string]string
	NodeName string
        ...
}
  • Volumes:代表要在Pod中挂载的卷的列表。
  • InitContainers:包含在主容器启动之前运行的初始化容器的列表。
  • Containers:代表在Pod中运行的容器的列表。
  • NodeSelector:指定用于匹配节点标签的键值对的映射。此字段用于将Pod调度到具有匹配标签的节点上。
  • NodeName:指定Pod应该调度到的节点的名称。
// https://github1s.com/kubernetes/kubernetes/blob/master/pkg/apis/core/types.go#L2447-L2542
type Container struct {
	Name string
	Image string
	Command []string
	Args []string
	WorkingDir string
	Ports []ContainerPort
	Env []EnvVar
        ...
	RestartPolicy *ContainerRestartPolicy
	VolumeMounts []VolumeMount
	LivenessProbe *Probe
}
  • Name: 描述容器的名称
  • Image: 描述容器镜像的名称
  • Command: 描述容器的启动命令,等同于docker compose的entrypoint
  • Args: 描述容器的启动命令的参数,等同于docker compose的command
  • WorkingDir: 描述容器的工作目录
  • Ports: 描述容器的对外提供的访问端口
  • Env: 描述容器运行时的环境变量
  • RestartPolicy: 描述容器异常退出后的重启策略
  • VolumeMounts: 描述容器内使用的卷挂载
  • LivenessProbe: 描述容器的存活探针

Status

描述资源在当前集群中的实际状态

    // <https://github1s.com/kubernetes/kubernetes/blob/master/pkg/apis/core/types.go#L3908>
    // PodStatus represents information about the status of a pod. Status may trail the actual
    // state of a system.
    type PodStatus struct {
    	Phase PodPhase
    	Conditions []PodCondition
    	Message string
    	Reason string
    	NominatedNodeName string
    	HostIP string
    	HostIPs []HostIP
    	PodIPs []PodIP
    	StartTime *metav1.Time
    	QOSClass PodQOSClass
    	InitContainerStatuses []ContainerStatus
    	ContainerStatuses []ContainerStatus
    	EphemeralContainerStatuses []ContainerStatus
    	Resize PodResizeStatus
    	ResourceClaimStatuses []PodResourceClaimStatus
    }
  • Phase:代表Pod的阶段或状态。
  • Conditions:代表一组描述Pod条件的结构。每个条件都表示Pod的某个方面或属性。
  • Message:提供有关Pod状态的额外信息,可用于诊断和排查问题。
  • Reason:提供有关Pod状态的原因或详细信息,可用于进一步分析问题。
  • NominatedNodeName:表示被提名运行该Pod的节点的名称。
  • HostIP:代表Pod所在主机的IP地址。
  • HostIPs:包含主机IP地址的列表,可能会有多个IP地址。
  • PodIPs:包含Pod IP地址的列表,可能会有多个IP地址。
  • StartTime:代表Pod的启动时间。
  • QOSClass:代表Pod的QoS(服务质量)类别。
  • InitContainerStatuses:包含init容器状态的列表。
  • ContainerStatuses:包含容器状态的列表。
  • EphemeralContainerStatuses:包含临时容器状态的列表。
  • Resize:代表Pod的调整大小状态。
  • ResourceClaimStatuses:包含资源声明状态的列表,表示Pod请求的资源声明的状态。

对照一个真实的pod实例

  OSW-4041 kg pod tunning -n dev -oyaml
// 对应Pod结构体的TypeMeta
apiVersion: v1
kind: Pod
// 对应Pod结构体的ObjectMeta
metadata:
  name: tunning
  namespace: dev
  resourceVersion: "24570303"
// 对应Pod结构体的Spec
spec:
  containers:
  - args:
    - -c
    - sleep infinity
    command:
    - sh
    image: busybox
    imagePullPolicy: Always
    name: tunning
    volumeMounts:
    - mountPath: /data
      name: persistent-storage
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-kc2cv
      readOnly: true
  nodeName: ip-192-1-12-199.ec2.internal
  restartPolicy: Always
  schedulerName: default-scheduler
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: efs-claim
// 对应Pod结构体的Status
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2023-12-08T06:43:07Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2023-12-08T06:43:09Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2023-12-08T06:43:09Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2023-12-08T06:43:07Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: containerd://04459ea9cf7888326d30f212e42938bab640759f13bca2fbb9ec39b7514ec1d5
    image: 500398181577.dkr.ecr.us-east-1.amazonaws.com/loadtestrunner-tools:latest
    imageID: 500398181577.dkr.ecr.us-east-1.amazonaws.com/loadtestrunner-tools@sha256:952e8323e37398ecd17b3f5c8770023ea7a65497ccf7e8949d36c6d9f393eecc
    lastState: {}
    name: tunning
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2023-12-08T06:43:09Z"
  hostIP: 192.1.12.199
  phase: Running
  podIP: 192.1.27.157
  podIPs:
  - ip: 192.1.27.157
  qosClass: BestEffort
  startTime: "2023-12-08T06:43:07Z"

Kubernetes API

Kubernetes API(Application Programming Interface)是一组定义了与Kubernetes集群进行交互的规范和接口。我们通过Kubernetes API提供的标准化的方式来对各种资源进行操作,如创建、更新和删除资源,以及监视集群状态和事件。通过使用Kubernetes API,我们可以通过编写代码或使用命令行工具与Kubernetes进行通信,而无需直接操作底层的集群组件。

Kubernetes API基于REST(Representational State Transfer)架构风格,支持HTTP协议,并使用JSON或YAML格式进行数据交换。它通过定义各种资源对象的规范和属性来描述集群中的状态和配置。典型资源对象包括Pods、Deployments、Services、ConfigMaps、Secrets等。

Kubernetes API提供详尽的文档和客户端库支持,可以用多种编程语言编写客户端代码来与Kubernetes集群进行交互。这使得开发人员可以根据自己的偏好和需求选择适合的工具和语言来操作和管理Kubernetes集群。

此外Kubernetes还用户自定义资源类型(CustomResourceDefinition),我们可以通过CRD实现自己的业务需求,并通过相应的控制器管理CRD及实现个性化业务功能,并且可以改CRD遵循Kubernetes API规范,提供相应的CRD API供外部访问。

Cluster级别的资源API:
https://{apiserver-address}/(api|apis)/{group}/{apiversion}/{resource-type-name}/{resource-instance-name}

Namespaced的资源API:
https://{apiserver-address}/(api|apis)/{group}/{apiversion}/namespaces/{namespace-value}/{resource-type-name}/{resource-instance-name}

Cluster级别的CRD资源API:
https://{apiserver-address}/(api|apis)/{group}/{apiversion}/{resource-type-name}/{resource-instance-name}

一个Pod实例

➜  OSW-4041 kg pod tunning -n dev -v 6       
I0411 08:55:12.224242 3643401 loader.go:395] Config loaded from file:  /root/.kube/config
I0411 08:55:14.211773 3643401 round_trippers.go:553] GET https://127.0.0.1:46219/api/api/v1/namespaces/dev/pods/tunning 200 OK in 1856 milliseconds
NAME      READY   STATUS    RESTARTS   AGE
tunning   1/1     Running   0          124d

一个Node实例

➜  onex git:(master) ✗ kg node test-control-plane -v6
I0411 09:07:51.556882 4078602 loader.go:395] Config loaded from file:  /home/going/.kube/config
I0411 09:07:51.581048 4078602 round_trippers.go:553] GET https://127.0.0.1:46219/api/v1/nodes/test-control-plane 200 OK in 14 milliseconds
NAME                 STATUS   ROLES           AGE   VERSION
test-control-plane   Ready    control-plane   27d   v1.29.2

一个名为PodAnalyzer的CRD实例

➜  onex git:(master) ✗ kg podanalyzer podanalyzer-sample -v6                 
I0411 09:10:25.967148 4079151 loader.go:395] Config loaded from file:  /home/going/.kube/config
I0411 09:10:25.989221 4079151 round_trippers.go:553] GET https://127.0.0.1:46219/apis/webapp.my.domain/v1/podanalyzers/podanalyzer-sample 200 OK in 13 milliseconds
NAME                 RESULTS
podanalyzer-sample   []

Kubernetes Object和Kubernetes API的映射关系

API约定
https://{api-server-ip}/api(s)/{group}/{version}/[namespaces/{namespace-value}]/{resource-plural}[?limit=500]
API实例
https://127.0.0.1:46219/apis/apps/v1/namespaces/default/deployments?limit=500