K8S自定义API

第一步:编写 CRD 的"蓝图" (YAML 文件)

首先,我们需要告诉 Kubernetes 这个新资源长什么样。新建一个名为 myapp-crd.yaml 的文件,填入以下内容:

复制代码
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: mycomplexapps.example.com  # 命名格式:<复数名>.<组名>
spec:
  group: example.com               # API 组
  scope: Namespaced                # 作用域:Namespaced(命名空间级)或 Cluster(集群级)
  names:
    plural: mycomplexapps
    singular: mycomplexapp
    kind: MyComplexApp             # 资源类型名
    shortNames: [mca]              # 简写,比如可以用 kubectl get mca
  versions:
  - name: v1
    served: true
    storage: true
    schema:
      openAPIV3Schema:
        type: object
        properties:
          spec:
            type: object
            properties:
              
              # ================== 1. 副本与基础调度 ==================
              replicas:
                type: integer
                minimum: 0
                default: 1
                description: 期望的副本数量(对应 Deployment 的 replicas)
              podTemplate:
                type: object
                properties:
                  metadata:
                    type: object
                    description: Pod 的元数据(如 labels, annotations)
                  spec:
                    type: object
                    properties:
                      
                      # ================== 2. 容器与镜像模板 ==================
                      containers:
                        type: array
                        description: 容器定义列表(对应 Pod.spec.containers)
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                              description: 容器名称
                            image:
                              type: string
                              description: 容器镜像地址(如 nginx:1.25)
                            command:
                              type: array
                              items: { type: string }
                              description: 容器启动命令(覆盖 Dockerfile 的 ENTRYPOINT)
                            args:
                              type: array
                              items: { type: string }
                              description: 启动参数(覆盖 Dockerfile 的 CMD)
                            ports:
                              type: array
                              items:
                                type: object
                                properties:
                                  containerPort: { type: integer }
                                  name: { type: string }
                            # --- CPU、内存、GPU 等资源限制 ---
                            resources:
                              type: object
                              properties:
                                limits:
                                  type: object
                                  properties:
                                    cpu: { type: string, description: "CPU上限,如 '500m', '2'" }
                                    memory: { type: string, description: "内存上限,如 '512Mi', '2Gi'" }
                                    # GPU 资源通常以扩展资源形式存在,比如 nvidia.com/gpu
                                    nvidia.com/gpu: { type: string, description: "GPU数量,如 '1'" }
                                requests:
                                  type: object
                                  properties:
                                    cpu: { type: string, description: "CPU请求量" }
                                    memory: { type: string, description: "内存请求量" }
                                    nvidia.com/gpu: { type: string, description: "GPU请求量" }
                            # --- 环境变量 ---
                            env:
                              type: array
                              items:
                                type: object
                                properties:
                                  name: { type: string }
                                  value: { type: string }
                                  # 也可以从 ConfigMap 或 Secret 中引用值
                                  valueFrom:
                                    type: object
                                    properties:
                                      configMapKeyRef:
                                        type: object
                                        properties:
                                          name: { type: string }
                                          key: { type: string }
                                      secretKeyRef:
                                        type: object
                                        properties:
                                          name: { type: string }
                                          key: { type: string }
                            # --- 容器内的存储卷挂载点 ---
                            volumeMounts:
                              type: array
                              items:
                                type: object
                                properties

第二步:将 CRD 注册到 Kubernetes 集群

写好蓝图后,使用 kubectl 把它提交给集群:

复制代码
# 应用 CRD
kubectl apply -f myapp-crd.yaml

# 验证 CRD 是否创建成功
kubectl get crd | grep myapps
# 如果成功,你会看到类似 myapps.example.com 的输出

第三步:创建自定义资源实例 (CR)

CRD 注册成功后,Kubernetes 就认识 MyApp 这种新类型了。现在你可以像创建 Pod 一样,创建一个 MyApp 的实例。新建一个 myapp-sample.yaml 文件:

复制代码
apiVersion: example.com/v1  # 注意这里的 apiVersion 是 <组>/<版本>
kind: MyApp                 # 这里的 kind 对应 CRD 里定义的 names.kind
metadata:
  name: my-first-app
spec:
  replicas: 3
  image: nginx:latest

然后把它应用到集群中:

复制代码
# 创建自定义资源实例
kubectl apply -f myapp-sample.yaml

# 查看你创建的自定义资源(可以用复数,也可以用简写 ma)
kubectl get myapp
# 或者
kubectl get ma

补充

文件夹里存放多个独立的 YAML 文件
复制代码
my-k8s-app/
├── crd.yaml          # 你的"蓝图":定义 MyApp 这种新资源
├── my-app-config.yaml # 具体的"实例":包含 ConfigMap、Secret(密码卷)
└── my-app-instance.yaml # 具体的"实例":创建 MyApp,填写 CPU/GPU、副本数、挂载卷等

你只需要在文件夹的上一级目录,执行这条命令,K8s 就会自动把这个文件夹里所有的 YAML 文件全部应用

复制代码
kubectl apply -f my-k8s-app/

进阶提示:让 CRD 真正"动"起来

走到这一步,你已经成功在 K8s 里创建了一个可以存储的自定义对象。但你会发现,光有上面的配置,这个 MyApp 只是静静地躺在 etcd 数据库里,它不会自动帮你创建出 3 个 Nginx 容器。

如果你想让它像 Deployment 一样真正干活(比如自动创建 Pod、自动扩容),你就需要编写一个 自定义控制器(Controller)。

  • CRD 只是定义了"数据结构"(蓝图)。
  • Controller 才是"大脑和手脚",它负责监听你创建的 MyApp 实例,并根据 spec 里的要求,去真正创建底层的 Pod 和 Service。

在实际生产中,大家通常不会纯手写这些代码,而是使用 Kubebuilder 或 Operator SDK 这样的脚手架工具,它们能帮你自动生成 CRD 定义和控制器的基础代码框架,极大地提升开发效率。

相关推荐
键盘鼓手苏苏2 小时前
ESLint 规则渐进式升级:从 0 警告到全面开启的迁移策略(续篇)
云原生·kubernetes·k8
guo_wen_qiang2 小时前
云服务器elasticsearch环境搭建-单台
运维·elasticsearch·容器
江湖有缘5 小时前
Docker实战 | 使用Docker部署Bibliotheca阅读习惯管理工具
java·docker·容器
万联WANFLOW5 小时前
Docker Hub 镜像拉取慢、timeout 的排查方法
运维·docker·云原生·容器·eureka
bloglin9999916 小时前
vmware部署centos7启动docker容器后无法访问服务
运维·docker·容器
weixin_4445793016 小时前
Containerd
容器·k8s
AutumnWind042020 小时前
【Docker Compose 快速入门】
运维·docker·容器
如果'\'真能转义说1 天前
Docker Desktop | 本地化挂载 Postgresql
docker·postgresql·容器
谢亮_vipxieliang1 天前
从 Docker 到 Kubernetes:概念对照与迁移
docker·容器·kubernetes