Skip to content

CRD 自定义资源定义

CRD 概述

CRD(CustomResourceDefinition)允许用户向 K8s API 注册自定义资源类型,扩展 K8s 的能力。

定义 CRD

yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: myapps.apps.mycompany.io  # <plural>.<group>
spec:
  group: apps.mycompany.io
  names:
    kind: MyApp
    listKind: MyAppList
    plural: myapps
    singular: myapp
    shortNames:
    - ma
  scope: Namespaced  # Namespaced | Cluster

  versions:
  - name: v1alpha1
    served: true
    storage: true  # 只有一个版本可以是 storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            required: [image, replicas]
            properties:
              image:
                type: string
                description: "应用镜像"
              replicas:
                type: integer
                minimum: 1
                maximum: 100
                default: 1
              config:
                type: object
                x-kubernetes-preserve-unknown-fields: true
          status:
            type: object
            properties:
              phase:
                type: string
                enum: [Pending, Running, Failed]
              readyReplicas:
                type: integer
              conditions:
                type: array
                items:
                  type: object
                  properties:
                    type:
                      type: string
                    status:
                      type: string
                    message:
                      type: string

    # 子资源
    subresources:
      status: {}  # 启用 status 子资源(独立更新 status)
      scale:      # 启用 scale 子资源(支持 kubectl scale)
        specReplicasPath: .spec.replicas
        statusReplicasPath: .status.readyReplicas

    # 额外打印列(kubectl get 时显示)
    additionalPrinterColumns:
    - name: Image
      type: string
      jsonPath: .spec.image
    - name: Replicas
      type: integer
      jsonPath: .spec.replicas
    - name: Phase
      type: string
      jsonPath: .status.phase
    - name: Age
      type: date
      jsonPath: .metadata.creationTimestamp

使用 CRD

yaml
# 创建自定义资源实例(CR)
apiVersion: apps.mycompany.io/v1alpha1
kind: MyApp
metadata:
  name: my-application
  namespace: production
spec:
  image: my-app:v1.0
  replicas: 3
  config:
    logLevel: info
    maxConnections: 100
bash
# 操作自定义资源
kubectl get myapps
kubectl get ma  # 使用短名称
kubectl describe myapp my-application
kubectl delete myapp my-application

Go 类型定义(kubebuilder)

go
// api/v1alpha1/myapp_types.go

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:subresource:scale:specpath=.spec.replicas,statuspath=.status.readyReplicas
// +kubebuilder:printcolumn:name="Image",type=string,JSONPath=`.spec.image`
// +kubebuilder:printcolumn:name="Replicas",type=integer,JSONPath=`.spec.replicas`
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

type MyApp struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   MyAppSpec   `json:"spec,omitempty"`
    Status MyAppStatus `json:"status,omitempty"`
}

type MyAppSpec struct {
    // +kubebuilder:validation:Required
    Image string `json:"image"`

    // +kubebuilder:validation:Minimum=1
    // +kubebuilder:validation:Maximum=100
    // +kubebuilder:default=1
    Replicas int32 `json:"replicas,omitempty"`

    Config map[string]string `json:"config,omitempty"`
}

type MyAppStatus struct {
    // +kubebuilder:validation:Enum=Pending;Running;Failed
    Phase         string             `json:"phase,omitempty"`
    ReadyReplicas int32              `json:"readyReplicas,omitempty"`
    Conditions    []metav1.Condition `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
type MyAppList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata,omitempty"`
    Items           []MyApp `json:"items"`
}

CRD 版本转换

yaml
# 多版本 CRD,通过 Webhook 转换
spec:
  conversion:
    strategy: Webhook
    webhook:
      conversionReviewVersions: ["v1", "v1beta1"]
      clientConfig:
        service:
          name: my-operator-webhook
          namespace: my-operator-system
          path: /convert

本站内容由 褚成志 整理编写,仅供学习参考