As an alternative to CustomResourceDefinitions, you can use a custom API server. Custom API servers can serve API groups with resources the same way the main Kubernetes API server does. In contrast to CRDs, there are hardly any limits to what you can do with a custom API server.
This chapter begins by listing a number of reasons why CRDs might not be the right solution for your use case. It describes the aggregation pattern that makes it possible to extend the Kubernetes API surface with a custom API server. Finally, you’ll learn to actually implement a custom API server using Golang.
A custom API server can be used in place of CRDs. It can do everything that CRDs can do and offers nearly infinite flexibility. Of course, this comes at a cost: complexity of both development and operation.
Let’s look at some limits of CRDs as of the time of this writing (when Kubernetes 1.14 was the stable release). CRDs:
etcd as their storage medium (or whatever the Kubernetes API server uses).
Do not support protobuf, only JSON.
Support only two kinds of subresources: /status and /scale (see “Subresources”).
Do not support graceful deletion.1 Finalizers can simulate this but do not allow a custom graceful deletion time.
Add significantly to the Kubernetes API server’s CPU load, because all algorithms are implemented in a generic way (for example, validation).
Implement only standard CRUD semantics for the API endpoints. ...