Add your own resource types without forking Kubernetes.
A CRD stores new object types in etcd and the API server serves them. An aggregated API proxies to a separate server and stores nothing in etcd.
CustomResourceDefinition
stored in etcd- Registered with a schema;
kubectl getworks like a built-in. - Served natively by
kube-apiserver. - Durable, declarative objects: the foundation of operators.
- Example:
Certificate(cert-manager),Application(Argo CD).
Aggregated API (APIService)
separate server- Requests are proxied to an independent API server.
- Data lives wherever that server keeps it, often not in etcd.
- Fits live, transient data, not durable intent.
- Example:
metrics-serverbehindkubectl topand the HPA.
see both on a cluster
$ kubectl get crd | head -3 # native, etcd-backed certificates.cert-manager.io 2026-01-12T09:02:11Z $ kubectl get apiservices | grep -v Local # aggregated v1beta1.metrics.k8s.io kube-system/metrics-server True
Reach for a CRD plus a controller when you want a new declarative resource; reach for an aggregated API only for data that must not live in etcd.