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。

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

相关推荐
炸炸鱼.10 小时前
Kubernetes高级调度02:Taint/Toleration、Cordon/Drain、亲和性与反亲和性完全指南
云原生·容器·kubernetes
wabs66612 小时前
关于贪心算法的一些自我总结【力扣45.跳跃游戏II】【灵感来源:代码随想录】
算法·贪心算法·复盘
geshifei15 小时前
K8s 容器运行 UnixBench — 代理机器执行记录
云原生·容器·kubernetes
Albert Edison17 小时前
【Docker】Ubuntu22.04 安装 Docker 教程
运维·docker·容器
codefan※18 小时前
一键部署私人 LLM:Ollama + Docker 极简指南
运维·docker·容器·大模型·llm·本地部署·ollama
李南想做条咸鱼20 小时前
k8s集群容器访问域名第一次不通,第二次必通如何解决
云原生·容器·kubernetes
FelixBitSoul20 小时前
K8s 调度器黑盒全拆解:拓扑约束数学陷阱 + Go 插件二开实战(避坑全记录)
容器·kubernetes
叶~小兮20 小时前
K8s常用组件学习笔记
笔记·学习·kubernetes
IT策士21 小时前
Docker 网络进阶:容器间通信与 DNS 解析
网络·docker·容器