Kubernetes API扩展与自定义资源开发扩展集群功能一、API扩展概述Kubernetes API扩展允许用户自定义资源定义(CRD)和控制器扩展Kubernetes的核心功能。1.1 API扩展架构┌─────────────────────────────────────────────────────────────────┐ │ Kubernetes API Server │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ CustomResourceDefinition │ │ │ │ apiVersion: apiextensions.k8s.io/v1 │ │ │ │ kind: CustomResourceDefinition │ │ │ │ spec: group, names, scope, versions │ │ │ └────────────────────────────┬───────────────────────────┘ │ │ │ │ │ ┌────────────────────────────▼───────────────────────────┐ │ │ │ CustomResource │ │ │ │ apiVersion: example.com/v1 │ │ │ │ kind: MyResource │ │ │ │ metadata: name: my-resource │ │ │ │ spec: ... │ │ │ │ status: ... │ │ │ └────────────────────────────┬───────────────────────────┘ │ └───────────────────────────────┼─────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Controller │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Watcher │→│ Reconcile │→│ Actuator │→│ Status │ │ │ │ │ │ │ │ │ │ Update │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────────┘1.2 API扩展类型扩展类型说明CRD自定义资源定义Controller控制器逻辑Webhook验证和修改请求Admission Controller准入控制二、CRD定义2.1 基础CRD配置apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myresources.example.com spec: group: example.com names: kind: MyResource listKind: MyResourceList plural: myresources singular: myresource scope: Namespaced versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer minimum: 1 image: type: string resources: type: object properties: requests: type: object properties: cpu: type: string memory: type: string limits: type: object properties: cpu: type: string memory: type: string2.2 CR状态定义apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myresources.example.com spec: group: example.com names: kind: MyResource listKind: MyResourceList plural: myresources singular: myresource scope: Namespaced versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: status: type: object properties: readyReplicas: type: integer currentReplicas: type: integer subresources: status: {}三、CR使用3.1 创建CR实例apiVersion: example.com/v1 kind: MyResource metadata: name: my-resource spec: replicas: 3 image: my-app:latest resources: requests: cpu: 100m memory: 256Mi limits: cpu: 500m memory: 512Mi3.2 查询CRkubectl get myresources kubectl get myresource my-resource -o yaml kubectl describe myresource my-resource3.3 更新CRapiVersion: example.com/v1 kind: MyResource metadata: name: my-resource spec: replicas: 5 image: my-app:latest四、Controller开发4.1 Controller结构package main import ( context time appsv1 k8s.io/api/apps/v1 corev1 k8s.io/api/core/v1 k8s.io/apimachinery/pkg/api/errors metav1 k8s.io/apimachinery/pkg/apis/meta/v1 k8s.io/apimachinery/pkg/runtime k8s.io/client-go/tools/record sigs.k8s.io/controller-runtime/pkg/client sigs.k8s.io/controller-runtime/pkg/controller sigs.k8s.io/controller-runtime/pkg/handler sigs.k8s.io/controller-runtime/pkg/manager sigs.k8s.io/controller-runtime/pkg/reconcile sigs.k8s.io/controller-runtime/pkg/source examplev1 example.com/api/v1 ) type ReconcileMyResource struct { client.Client scheme *runtime.Scheme recorder record.EventRecorder } func (r *ReconcileMyResource) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { var resource examplev1.MyResource if err : r.Get(ctx, request.NamespacedName, resource); err ! nil { if errors.IsNotFound(err) { return reconcile.Result{}, nil } return reconcile.Result{}, err } deployment : appsv1.Deployment{} err : r.Get(ctx, client.ObjectKey{Name: resource.Name, Namespace: resource.Namespace}, deployment) if err ! nil errors.IsNotFound(err) { deployment r.createDeployment(resource) if err : r.Create(ctx, deployment); err ! nil { return reconcile.Result{}, err } r.recorder.Event(resource, corev1.EventTypeNormal, Created, Created Deployment) return reconcile.Result{RequeueAfter: time.Second * 5}, nil } else if err ! nil { return reconcile.Result{}, err } if deployment.Spec.Replicas ! resource.Spec.Replicas { deployment.Spec.Replicas resource.Spec.Replicas if err : r.Update(ctx, deployment); err ! nil { return reconcile.Result{}, err } r.recorder.Event(resource, corev1.EventTypeNormal, Updated, Updated Deployment) } return reconcile.Result{RequeueAfter: time.Minute}, nil } func (r *ReconcileMyResource) createDeployment(resource *examplev1.MyResource) *appsv1.Deployment { return appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ Name: resource.Name, Namespace: resource.Namespace, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(resource, examplev1.GroupVersion.WithKind(MyResource)), }, }, Spec: appsv1.DeploymentSpec{ Replicas: resource.Spec.Replicas, Selector: metav1.LabelSelector{ MatchLabels: map[string]string{ app: resource.Name, }, }, Template: corev1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ app: resource.Name, }, }, Spec: corev1.PodSpec{ Containers: []corev1.Container{ { Name: app, Image: resource.Spec.Image, Resources: resource.Spec.Resources, }, }, }, }, }, } }4.2 状态更新func (r *ReconcileMyResource) updateStatus(ctx context.Context, resource *examplev1.MyResource, deployment *appsv1.Deployment) error { resource.Status.CurrentReplicas deployment.Status.Replicas resource.Status.ReadyReplicas deployment.Status.ReadyReplicas if err : r.Status().Update(ctx, resource); err ! nil { return fmt.Errorf(failed to update status: %v, err) } return nil }五、Webhook配置5.1 Validating WebhookapiVersion: admissionregistration.k8s.io/v1 kind: ValidatingWebhookConfiguration metadata: name: my-resource-validation webhooks: - name: validate.myresource.example.com clientConfig: service: name: my-resource-webhook namespace: default path: /validate rules: - apiGroups: - example.com apiVersions: - v1 operations: - CREATE - UPDATE resources: - myresources failurePolicy: Fail5.2 Mutating WebhookapiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: name: my-resource-mutation webhooks: - name: mutate.myresource.example.com clientConfig: service: name: my-resource-webhook namespace: default path: /mutate rules: - apiGroups: - example.com apiVersions: - v1 operations: - CREATE - UPDATE resources: - myresources failurePolicy: Fail六、API扩展最佳实践6.1 CRD版本管理apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myresources.example.com spec: group: example.com names: kind: MyResource plural: myresources scope: Namespaced versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer image: type: string - name: v1beta1 served: true storage: false schema: openAPIV3Schema: type: object properties: spec: type: object properties: replicas: type: integer6.2 控制器部署apiVersion: apps/v1 kind: Deployment metadata: name: my-resource-controller spec: replicas: 1 selector: matchLabels: name: my-resource-controller template: spec: serviceAccountName: my-resource-controller containers: - name: controller image: my-resource-controller:latest command: - my-resource-controller env: - name: WATCH_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace七、总结API扩展实践包括CRD定义定义自定义资源结构Controller开发实现资源协调逻辑Webhook配置添加验证和修改逻辑版本管理支持多版本CRD部署控制器部署到集群运行建议使用Operator SDK简化开发流程遵循Kubernetes最佳实践。参考资料Kubernetes CRD文档Operator SDK文档Controller Runtime文档