Please enable Javascript to view the contents

K8s Custom Resources(CR)

 ·  ☕ 2 åˆ†é’Ÿ

Custom Resource 的入口

请求是这样分发到 api 扩展点的:

image-20210327224709520

例如我们有 (Custom Resource)CR

1
2
3
4
5
6
7
8
apiVersion: cnat.programming-kubernetes.info/v1alpha1
kind: At
metadata:
  name: example-at
spec:
  schedule: "2019-07-03T02:00:00Z"
status:
  phase: "pending"

相应的 CustomResourceDefinition (CRD) 会是这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ats.cnat.programming-kubernetes.info
spec:
  group: cnat.programming-kubernetes.info
  names:
    kind: At
    listKind: AtList
    plural: ats
    singular: at
  scope: Namespaced
  subresources:
    status: {}
  version: v1alpha1
  versions:
  - name: v1alpha1
    served: true
    storage: true

可以在命令行中访问 Resource:

1
2
3
$ kubectl get ats
NAME                                         CREATED AT
ats.cnat.programming-kubernetes.info         2019-04-01T14:03:33Z

入场和校验

image-20210327225800617

格式上的校验,是借助 CRD 中定义的,基于 OpenAPI 的 Schema。此外,还可以调用的一个外置的 Webhook API 进行程序化的高级校验。

短名和分类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$ kubectl api-resources
NAME                   SHORTNAMES  APIGROUP NAMESPACED  KIND
bindings                                    true        Binding
componentstatuses      cs                   false       ComponentStatus
configmaps             cm                   true        ConfigMap
endpoints              ep                   true        Endpoints
events                 ev                   true        Event
limitranges            limits               true        LimitRange
namespaces             ns                   false       Namespace
nodes                  no                   false       Node
persistentvolumeclaims pvc                  true       PersistentVolumeClaim
persistentvolumes      pv                   false       PersistentVolume
pods                   po                   true        Pod
statefulsets           sts         apps     true        StatefulSet

Subresources

如:

/api/v1/namespace/namespace/pods/name/logs
/api/v1/namespace/namespace/pods/name/portforward
/api/v1/namespace/namespace/pods/name/exec
/api/v1/namespace/namespace/pods/name/status

Controller 开发者

和 kubernetes 的程序,有几种编码方式:

  • 使用client-go的 dynamic client
  • 使用强类型的方式

Dynamic client

非强类型的,它不管 GVK。

Typed Clients

强类型的类型定义一般和 GVK 对应,常见 pattern 为:

pkg/apis/group/version

每个 Golang 数据结构嵌入了 TypeMeta

1
2
3
4
5
6
type TypeMeta struct {
    // +optional
    APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
    // +optional
    Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
}

一般对象均有以下属性:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
type ObjectMeta struct {
    Name string `json:"name,omitempty"`
    Namespace string `json:"namespace,omitempty"`
    UID types.UID `json:"uid,omitempty"`
    ResourceVersion string `json:"resourceVersion,omitempty"`
    CreationTimestamp Time `json:"creationTimestamp,omitempty"`
    DeletionTimestamp *Time `json:"deletionTimestamp,omitempty"`
    Labels map[string]string `json:"labels,omitempty"`
    Annotations map[string]string `json:"annotations,omitempty"`
    ...
}
Golang 的 package 结构

数据结构的定义,一般放在pkg/apis/group/version下的types.go。

doc.go文件记录了API 的功能和生成用的 tag。

1
2
3
4
5
// Package v1alpha1 contains the cnat v1alpha1 API group
//
// +k8s:deepcopy-gen=package
// +groupName=cnat.programming-kubernetes.info
package v1alpha1

register.go 包含了一些 Helper 和 注册点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package version

import (
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/runtime"
    "k8s.io/apimachinery/pkg/runtime/schema"

    group "repo/pkg/apis/group"
)

// SchemeGroupVersion is group version used to register these objects
var SchemeGroupVersion = schema.GroupVersion{
    Group: group.GroupName,
    Version: "version",
}

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
    return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Resource takes an unqualified resource and returns a Group
// qualified GroupResource
func Resource(resource string) schema.GroupResource {
    return SchemeGroupVersion.WithResource(resource).GroupResource()
}

var (
    SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
    AddToScheme   = SchemeBuilder.AddToScheme
)

// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
    scheme.AddKnownTypes(SchemeGroupVersion,
        &SomeKind{},
        &SomeKindList{},
    )
    metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
    return nil
}

参考

[Programming Kubernetes]

分享

Mark Zhu
作者
Mark Zhu
Old Developer