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: 100bash
# 操作自定义资源
kubectl get myapps
kubectl get ma # 使用短名称
kubectl describe myapp my-application
kubectl delete myapp my-applicationGo 类型定义(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