
Kubernetes 是一个高度可扩展的"系统"，比如常见的自定义资源，控制器，准入控制及调度器进行扩展开发等。

Operator 是一种包装、运行和管理 K8S 应用的一种方式。它涵盖了 CRD（CustomResourceDefinition） + AdmissionWebhook + Controller，并以 Deployment 的形式部署到 K8S 中。

- CRD 用来定义声明式 API（yaml），程序会通过该定义一直让最小调度单元（POD）趋向该状态。
- AdmissionWebhook 用来拦截请求做 mutate（修改）提交的声明（yaml）和 validate（校验）声明式的字段。
- Controller 主要的控制器，监视资源的 创建 / 更新 / 删除 事件，并触发 Reconcile 函数作为响应。整个调整过程被称作 Reconcile Loop（协调一致的循环），其实就是让 POD 趋向 CRD 定义所需的状态。

operator 可以做什么？

- 自动化部署应用
- 自动修复服务，比如资源被别人删除了或者修改了错误的配置，operator 可以自动修复他们

Groups、Versions、Kinds、resources 是什么？

比如现在有一个 calico 的 ippool 资源 `ippools.crd.projectcalico.org`

```yaml
# kubectl get ippools.crd.projectcalico.org default-pool -o yaml
apiVersion: crd.projectcalico.org/v1
kind: IPPool
metadata:
  annotations:
    projectcalico.org/metadata: '{"creationTimestamp":"2025-07-26T10:49:29Z"}'
  creationTimestamp: "2025-07-26T10:49:29Z"
  generation: 1
  name: default-pool
  resourceVersion: "472"
  uid: 1e88652d-bded-4ede-91e1-53b427f4aebe
spec:
  allowedUses:
  - Workload
  - Tunnel
  blockSize: 26
  cidr: 10.233.64.0/18
  ipipMode: Never
  natOutgoing: true
  nodeSelector: all()
  vxlanMode: Always
```

其中 crd.projectcalico.org 是 API Group，v1 是 API Version，IPPool 是 Kind，default-pool 是 Name，ippools.crd.projectcalico.org 是 Resource。

在 crd.projectcalico.org 中还有很多其他 Kind。

```bash
# kubectl api-resources | grep crd.projectcalico.org
bgpconfigurations                                crd.projectcalico.org/v1            false        BGPConfiguration
bgpfilters                                       crd.projectcalico.org/v1            false        BGPFilter
bgppeers                                         crd.projectcalico.org/v1            false        BGPPeer
blockaffinities                                  crd.projectcalico.org/v1            false        BlockAffinity
caliconodestatuses                               crd.projectcalico.org/v1            false        CalicoNodeStatus
clusterinformations                              crd.projectcalico.org/v1            false        ClusterInformation
felixconfigurations                              crd.projectcalico.org/v1            false        FelixConfiguration
globalnetworkpolicies                            crd.projectcalico.org/v1            false        GlobalNetworkPolicy
globalnetworksets                                crd.projectcalico.org/v1            false        GlobalNetworkSet
hostendpoints                                    crd.projectcalico.org/v1            false        HostEndpoint
ipamblocks                                       crd.projectcalico.org/v1            false        IPAMBlock
ipamconfigs                                      crd.projectcalico.org/v1            false        IPAMConfig
ipamhandles                                      crd.projectcalico.org/v1            false        IPAMHandle
ippools                                          crd.projectcalico.org/v1            false        IPPool
ipreservations                                   crd.projectcalico.org/v1            false        IPReservation
kubecontrollersconfigurations                    crd.projectcalico.org/v1            false        KubeControllersConfiguration
networkpolicies                                  crd.projectcalico.org/v1            true         NetworkPolicy
networksets                                      crd.projectcalico.org/v1            true         NetworkSet
tiers                                            crd.projectcalico.org/v1            false        Tier
```

API Group 是相关功能的集合，每一个 group 都有一个或者多个版本。不同的版本的行为可能不一样。

每一个 API group-version 都包含一个或者多个 API 的类型称为 Kinds。虽然 Kind 在不同 API Version 中可能会有不同的字段或者结构，但是每个版本必须能表达所有版本的数据。新版本增加的字段，旧版本没有，必须有办法保存起来（放到 annotation 中或者一些保留字段中）。这样即使客户端使用旧版本 API（如 v1beta1），也不会丢失用新版本 API 创建的额外信息。

Resources 是 api 中某个 Kind 的使用。Kind 描述了这个资源是什么。而 resource 是这个 Kind 的实现。通常情况下 kind 和 resource 是一一对应的关系。例如 pods 资源对应的是 Pod Kind。
有时候多个 Resource 会返回同一个 Kind。比如 deployments/scale 和 replicasets/scale 资源都返回 Scale Kind。

```yaml
# kubectl get deployment -n kube-system calico-kube-controllers   --subresource=scale -o yaml

apiVersion: autoscaling/v1
kind: Scale
metadata:
  creationTimestamp: "2025-07-26T10:49:42Z"
  name: calico-kube-controllers
  namespace: kube-system
  resourceVersion: "100288"
  uid: 6b53a108-627e-4cf1-aa60-6fda4b32f290
spec:
  replicas: 1
status:
  replicas: 1
  selector: k8s-app=calico-kube-controllers

```

```yaml
# kubectl get replicasets.apps -n kube-system calico-kube-controllers-5d8f654785   --subresource=scale  -o yaml

apiVersion: autoscaling/v1
kind: Scale
metadata:
  creationTimestamp: "2025-07-26T10:49:42Z"
  name: calico-kube-controllers-5d8f654785
  namespace: kube-system
  resourceVersion: "100287"
  uid: d9833008-f78e-4c1c-90c9-c0215d8a3ddb
spec:
  replicas: 1
status:
  replicas: 1
  selector: k8s-app=calico-kube-controllers,pod-template-hash=5d8f654785
```

但是使用 CRD 时，每一个 Kind 都对应一个 resource。并且 resource 名称始终都是小写的，按照惯例都是 Kind 的小写形式。

Kubernetes 的资源对象（如 Deployment、ReplicaSet、StatefulSet）有复杂的 spec 和 status 字段：

- spec.replicas：期望副本数
- status.replicas、status.availableReplicas：当前副本数

如果每次扩容/缩容都直接更新主资源（如 Deployment 的 spec.replicas），会有两个问题：

- 权限问题：扩容/缩容操作只需要改副本数，不应该有权修改 Deployment 其他字段。
- 接口解耦：HPA 等自动伸缩组件不需要关心 Deployment 的完整结构，只要能读/写副本数即可。

所以 Kubernetes 提供了 subresource 来解决这个问题。除了 scale 之外，还有 status 和 log 等。

以上只是描述 CR 和 CRD，那么 k8s 要知道拿到这个 CR 或者 CRD 后改如何操作呢？

需要实现一个 controller 来监听 CR 或者 CRD 的变化，然后根据变化来更新主资源。

