1. 项目概述最近在准备CKA认证考试时发现2025年新版题库中增加了不少关于CRD(Custom Resource Definition)的实操题目。作为一个在K8S领域摸爬滚打多年的老手我决定搭建一个专门的练习环境来攻克这个考点。CRD作为Kubernetes扩展机制的核心组件在实际生产环境和认证考试中都占据着重要位置。这个练习环境需要满足几个关键需求首先它必须能够快速创建和销毁方便反复练习其次要能模拟真实考试场景中的CRD操作最后还需要包含验证机制确保配置的正确性。基于这些考虑我设计了一套完整的解决方案下面就把搭建过程和关键技巧分享给大家。2. 环境准备与基础配置2.1 最小化K8S集群搭建对于CRD练习环境我推荐使用轻量级的k3s或者minikube。这里以k3s为例它的安装非常简单curl -sfL https://get.k3s.io | sh -安装完成后检查集群状态kubectl cluster-info kubectl get nodes注意如果是在本地开发机上练习建议使用--docker参数安装k3s这样可以避免与现有docker环境冲突。2.2 必要工具准备除了基础的kubectl还需要准备以下工具yq用于处理yaml文件jq用于处理json输出k9s可选提供更友好的交互界面安装命令# 在Ubuntu/Debian上 sudo apt install -y jq yq # 在CentOS/RHEL上 sudo yum install -y jq yq3. CRD核心概念解析3.1 CRD基础架构CRD允许用户在Kubernetes中定义自己的资源类型它由几个关键部分组成GroupAPI组名如example.comVersionAPI版本如v1alpha1Kind资源类型名称Scope资源作用域Namespaced或Cluster一个典型的CRD定义如下apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myresources.example.com spec: group: example.com versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: size: type: integer image: type: string scope: Namespaced names: plural: myresources singular: myresource kind: MyResource shortNames: - mr3.2 CRD验证机制Kubernetes提供了强大的验证机制来确保CRD实例的合规性。主要有两种验证方式结构验证通过OpenAPI v3 schema定义字段类型和格式准入控制通过Webhook实现更复杂的业务逻辑验证在考试环境中我们主要关注结构验证。下面是一个带验证的CRD示例apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: validatedresources.example.com spec: # ...其他字段同上... validation: openAPIV3Schema: type: object properties: spec: type: object required: [size, image] properties: size: type: integer minimum: 1 maximum: 10 image: type: string pattern: ^[a-z0-9-]$4. CRD实操练习4.1 创建和验证CRD首先创建CRD定义kubectl apply -f my-crd.yaml验证CRD是否创建成功kubectl get crd kubectl describe crd myresources.example.com创建CR实例apiVersion: example.com/v1 kind: MyResource metadata: name: my-resource-example spec: size: 5 image: nginx应用实例并验证kubectl apply -f my-resource.yaml kubectl get myresource kubectl describe myresource my-resource-example4.2 常见错误排查在练习过程中我遇到了几个典型错误Schema验证失败The CustomResourceDefinition myresources.example.com is invalid: spec.validation.openAPIV3Schema.type: Required value: must not be empty at the root解决方法确保在validation.openAPIV3Schema中指定了type字段。名称冲突customresourcedefinitions.apiextensions.k8s.io myresources.example.com already exists解决方法删除现有CRD或使用不同名称。版本不匹配no matches for kind MyResource in version example.com/v1beta1解决方法检查CRD中定义的版本与实例中使用的版本是否一致。5. 高级CRD特性练习5.1 多版本支持在实际生产环境中CRD可能需要支持多个版本。下面是一个支持多版本的CRD示例apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: multiversion.example.com spec: group: example.com versions: - name: v1alpha1 served: true storage: false schema: {...} - name: v1beta1 served: true storage: false schema: {...} - name: v1 served: true storage: true schema: {...} conversion: strategy: None # ...其他字段...5.2 子资源启用CRD可以启用status和scale子资源这在operator开发中很常见apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: subresources.example.com spec: # ...其他字段... subresources: status: {} scale: specReplicasPath: .spec.replicas statusReplicasPath: .status.replicas labelSelectorPath: .status.labelSelector6. CKA考试重点练习6.1 考试常见题型分析根据最新考试大纲CRD相关题目主要考察以下能力根据要求创建CRD定义为CRD添加验证规则创建符合规范的CR实例排查CRD相关问题6.2 模拟试题练习题目1创建一个名为apps.example.com的CRD要求资源类型名为App作用域为Namespaced包含size(整数1-10)和image(字符串)字段image字段必须符合DNS子域名规则解答apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: apps.example.com spec: group: example.com versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object required: [size, image] properties: size: type: integer minimum: 1 maximum: 10 image: type: string pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ scope: Namespaced names: plural: apps singular: app kind: App题目2为上述CRD创建一个实例要求名称为nginx-appsize为3image为nginx:latest解答apiVersion: example.com/v1 kind: App metadata: name: nginx-app spec: size: 3 image: nginx:latest7. 环境优化与技巧分享7.1 快速重置技巧在反复练习时可以快速删除所有CRD和CR实例kubectl delete crd --all kubectl delete all --all --all-namespaces7.2 验证技巧使用kubectl的--dry-run和--validate选项可以在实际创建前验证配置kubectl create -f my-crd.yaml --dry-runclient --validatetrue7.3 调试技巧当CRD验证失败时可以使用以下命令查看详细错误kubectl get crd myresources.example.com -o yaml查看API服务器日志也能获取有用信息journalctl -u k3s -f8. 生产环境注意事项虽然这是练习环境但了解生产环境中的注意事项也很重要版本兼容性不同K8S版本对CRD的支持有差异特别是1.16版本使用apiextensions.k8s.io/v1性能考虑大量CRD会影响API服务器性能建议合并相关资源命名规范使用公司域名作为group避免冲突验证严格性生产环境应该启用更严格的验证规则文档完整性为自定义资源编写详细的文档和使用示例9. 常见问题解答Q1CRD创建后为什么不能立即使用A1API服务器需要一些时间来处理新的CRD通常几秒钟后就可以使用。可以通过kubectl get crd查看状态。Q2如何更新已有的CRDA2直接修改CRD定义并重新apply。但要注意某些字段如scope不能修改。Q3CRD和Operator有什么关系A3Operator通常会使用CRD来定义它管理的自定义资源然后通过控制器来管理这些资源的生命周期。Q4为什么我的CR实例创建成功了但字段被修改了A4可能是默认值或准入控制器修改了你的资源。使用kubectl get -o yaml查看实际存储的内容。Q5如何备份CRD和CR实例A5可以使用kubectl get crd -o yaml crds.yaml备份CRD对CR实例也是类似操作。10. 个人经验分享在实际操作中我发现几个特别有用的技巧使用kubectl explain创建CRD后可以像内置资源一样使用kubectl explain查看字段说明kubectl explain app.specyq工具处理yaml当需要频繁修改CRD定义时yq工具可以大大简化操作yq eval .spec.versions[0].schema.openAPIV3Schema.properties.spec.properties.size.minimum 1 -i my-crd.yaml模板化创建为常用CRD创建模板文件使用时只需替换关键字段#!/bin/bash CRD_NAME$1 GROUP$2 KIND$3 sed s/{{NAME}}/$CRD_NAME/g; s/{{GROUP}}/$GROUP/g; s/{{KIND}}/$KIND/g template.yaml output.yaml日志监控在测试复杂CRD时实时监控API服务器日志可以快速发现问题tail -f /var/log/k3s.log | grep -i customresource渐进式验证先创建最简单的CRD验证通过后再逐步添加复杂验证规则避免一次性调试太多问题。