目 录CONTENT

文章目录

Kubernetes自定义资源(CRD)实战入门指南

Administrator
2025-09-10 / 0 评论 / 1 点赞 / 17 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Kubernetes自定义资源(CRD)实战入门指南

在Kubernetes生态系统中,虽然内置资源如Deployment、Service等能满足大部分需求,但在实际应用中,我们经常需要定义自己的资源类型来管理特定的应用或服务。CustomResourceDefinition(CRD)正是为此而生,它允许我们扩展Kubernetes API,定义自己的资源类型。本文将通过一个完整的示例,带你从零开始掌握CRD的创建和使用。

一、CRD概述与应用场景

CustomResourceDefinition(CRD)是Kubernetes中一种强大的扩展机制,允许用户定义自己的资源类型,而无需修改Kubernetes核心代码。通过CRD,我们可以:

  1. 扩展Kubernetes API,添加自定义资源类型
  2. 与自定义控制器配合,实现自动化运维
  3. 构建Operator,管理复杂应用的生命周期

CRD的典型应用场景包括:

  • 数据库管理:如MySQL、PostgreSQL等数据库的自动部署和管理
  • 服务网格配置:如Istio中的VirtualService、DestinationRule等
  • 监控系统配置:如Prometheus Operator中的ServiceMonitor
  • CI/CD流水线:如Tekton中的PipelineRun、TaskRun等

二、CRD基础概念

在深入实践之前,我们需要了解几个核心概念:

1. CustomResourceDefinition (CRD)

CRD是Custom Resource Definition的缩写,它是自定义资源的定义模板,描述了自定义资源的结构和属性。

2. Custom Resource (CR)

CR是Custom Resource的缩写,它是CRD的具体实例,就像Pod是Deployment的具体实例一样。

3. Controller

控制器负责监听自定义资源的变化,并根据资源的期望状态执行相应的操作。

三、创建第一个CRD

让我们通过一个实际的例子来学习CRD的创建。我们将创建一个名为Website的自定义资源,用于管理网站部署。

1. 定义CRD

首先,创建一个名为website-crd.yaml的文件:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  # 名称必须与下面的spec字段匹配,格式为<plural>.<group>
  name: websites.web.example.com
spec:
  # 组名,用于REST API: /apis/<group>/<version>
  group: web.example.com
  # CRD可以支持多个版本
  versions:
  - name: v1
    # 每个版本都可以通过served标志来独立启用或禁止
    served: true
    # 其中一个且只有一个版本必须被标记为存储版本
    storage: true
    # 定义自定义资源的结构
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              domain:
                type: string
                description: 网站域名
              image:
                type: string
                description: 网站使用的镜像
              replicas:
                type: integer
                description: 网站副本数
                minimum: 1
              port:
                type: integer
                description: 网站服务端口
                minimum: 1
                maximum: 65535
          status:
            type: object
            properties:
              availableReplicas:
                type: integer
                description: 可用副本数
  # 可以是Namespaced或Cluster
  scope: Namespaced
  names:
    # 名称的复数形式,用于URL:/apis/<group>/<version>/<plural>
    plural: websites
    # 名称的单数形式,作为命令行使用时和显示时的别名
    singular: website
    # kind通常是单数形式的驼峰编码(CamelCased)形式
    kind: Website
    # CLI中使用的资源简称
    shortNames:
    - ws

2. 应用CRD

使用kubectl将CRD应用到集群中:

kubectl apply -f website-crd.yaml

验证CRD是否创建成功:

kubectl get crd websites.web.example.com

查看CRD详细信息:

kubectl describe crd websites.web.example.com

四、创建自定义资源实例

CRD创建成功后,我们就可以创建自定义资源实例了。

1. 定义自定义资源

创建一个名为my-website.yaml的文件:

apiVersion: web.example.com/v1
kind: Website
metadata:
  name: my-website
  namespace: default
spec:
  domain: "mywebsite.example.com"
  image: "nginx:1.20"
  replicas: 3
  port: 80

2. 应用自定义资源

kubectl apply -f my-website.yaml

3. 查看自定义资源

kubectl get websites
kubectl get ws  # 使用简称
kubectl describe website my-website

五、CRD验证规则

为了确保自定义资源的数据质量,我们可以为CRD添加验证规则。

修改website-crd.yaml,添加验证规则:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: websites.web.example.com
spec:
  group: web.example.com
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              domain:
                type: string
                description: 网站域名
                pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$'
              image:
                type: string
                description: 网站使用的镜像
              replicas:
                type: integer
                description: 网站副本数
                minimum: 1
                maximum: 10
              port:
                type: integer
                description: 网站服务端口
                minimum: 1
                maximum: 65535
            required: ["domain", "image", "replicas", "port"]
          status:
            type: object
            properties:
              availableReplicas:
                type: integer
    # 添加验证规则
    additionalPrinterColumns:
    - name: Domain
      type: string
      description: 网站域名
      jsonPath: .spec.domain
    - name: Replicas
      type: integer
      description: 副本数
      jsonPath: .spec.replicas
    - name: Age
      type: date
      jsonPath: .metadata.creationTimestamp
  scope: Namespaced
  names:
    plural: websites
    singular: website
    kind: Website
    shortNames:
    - ws

重新应用CRD:

kubectl apply -f website-crd.yaml

现在当我们查看websites资源时,会显示额外的列:

kubectl get websites

六、CRD版本管理

随着应用的发展,我们可能需要升级CRD以支持新的字段或功能。Kubernetes支持CRD的多版本管理。

1. 添加新版本

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: websites.web.example.com
spec:
  group: web.example.com
  versions:
  - name: v1
    served: true
    storage: false
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              domain:
                type: string
              image:
                type: string
              replicas:
                type: integer
                minimum: 1
                maximum: 10
              port:
                type: integer
                minimum: 1
                maximum: 65535
          status:
            type: object
            properties:
              availableReplicas:
                type: integer
  - name: v2
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              domain:
                type: string
              image:
                type: string
              replicas:
                type: integer
                minimum: 1
                maximum: 100
              port:
                type: integer
                minimum: 1
                maximum: 65535
              # 新增字段
              tls:
                type: object
                properties:
                  enabled:
                    type: boolean
                  secretName:
                    type: string
          status:
            type: object
            properties:
              availableReplicas:
                type: integer
              phase:
                type: string
  scope: Namespaced
  names:
    plural: websites
    singular: website
    kind: Website
    shortNames:
    - ws

七、实际应用示例

让我们通过一个完整的示例来展示CRD的实际应用。我们将创建一个简单的控制器,用于根据Website资源自动创建Deployment和Service。

1. 创建Website资源

apiVersion: web.example.com/v1
kind: Website
metadata:
  name: nginx-website
  namespace: default
spec:
  domain: "nginx.example.com"
  image: "nginx:1.20"
  replicas: 2
  port: 80

2. 控制器工作原理

虽然编写完整的控制器超出了本文的范围,但一个简单的控制器需要执行以下操作:

  1. 监听Website资源的变化
  2. 根据Website的spec创建Deployment
  3. 根据Website的spec创建Service
  4. 更新Website的status字段

3. 生成的Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-website
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-website
  template:
    metadata:
      labels:
        app: nginx-website
    spec:
      containers:
      - name: website
        image: nginx:1.20
        ports:
        - containerPort: 80

4. 生成的Service

apiVersion: v1
kind: Service
metadata:
  name: nginx-website
  namespace: default
spec:
  selector:
    app: nginx-website
  ports:
  - port: 80
    targetPort: 80
  type: ClusterIP

八、最佳实践

在使用CRD时,应遵循以下最佳实践:

1. 命名规范

  • Group名称应该是一个有效的域名(如web.example.com)
  • 资源名称应该是复数形式(如websites)
  • Kind名称应该是单数形式的驼峰命名(如Website)

2. 版本管理

  • 为CRD提供多个版本支持
  • 使用served标记启用版本
  • 使用storage标记存储版本
  • 提供版本转换机制

3. 验证规则

  • 使用OpenAPI v3 schema定义资源结构
  • 添加必要的字段验证规则
  • 设置必填字段

4. 状态管理

  • 在status子资源中维护资源状态
  • 提供丰富的状态信息
  • 定期更新状态

5. 打印列定义

  • 定义additionalPrinterColumns以改善CLI体验
  • 包含关键信息的列
  • 使用合适的列类型

九、故障排除

在使用CRD时,可能会遇到以下常见问题:

1. CRD创建失败

检查YAML文件语法是否正确,字段是否符合要求。

2. 自定义资源验证失败

检查自定义资源是否符合CRD定义的schema。

3. 控制器无法识别新资源

确保控制器已正确配置并具有访问CRD的权限。

十、总结

CRD是Kubernetes生态系统中一个强大的扩展机制,它允许我们定义自己的资源类型,从而更好地管理复杂的应用和服务。通过本文的学习,你应该已经掌握了:

  1. CRD的基本概念和应用场景
  2. 如何定义和创建CRD
  3. 如何创建自定义资源实例
  4. 如何添加验证规则和打印列
  5. 如何管理CRD版本
  6. CRD的最佳实践

通过合理使用CRD,我们可以将复杂的业务逻辑封装成简单的Kubernetes资源,实现基础设施即代码和声明式API的理想状态。

参考文档

  1. Kubernetes官方文档 - Custom Resources
  2. Kubernetes官方文档 - Extend the Kubernetes API with CustomResourceDefinitions
  3. Kubebuilder - 用于构建Kubernetes API的框架
  4. Operator SDK - 用于构建Operator的工具包
  5. Kubernetes API Conventions
1
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区