### Custom Resources
Kubernetes allows for the dynamic addition of new resources, known as Custom Resources. Once added, these resources can be created and accessed using standard commands like `kubectl`. This functionality enables the creation of new structured data stored in the `etcd` database and accessed via the `kube-apiserver`.
To make a new custom resource part of a declarative API, a controller is needed to manage the resource. This controller, or operator, is an agent that creates and manages instances of a specific stateful application, ensuring the declared state matches the actual state. Built-in controllers, such as Deployments and DaemonSets, operate similarly.
Custom resources can be added to your Kubernetes cluster in two ways:
1. **Custom Resource Definitions (CRD)**: The easier but less flexible method.
2. **Aggregated APIs (AA)**: A more flexible method that requires adding a new API server to the cluster.
### Custom Resource Definitions
CRDs are the simplest way to add new resources to your Kubernetes cluster. They allow you to extend the Kubernetes API by defining a new type of object. Once defined, these objects can be managed using standard Kubernetes tools.
A CRD adds a new endpoint to the Kubernetes API, which the `kube-apiserver` can then use to manage the new resource. The CRD specification must follow a predefined structure, ensuring the resource can be managed like any built-in resource.
#### Example Configuration
Here's an example of a CRD configuration:
```yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: backups.stable.linux.com
spec:
group: stable.linux.com
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: backups
singular: backup
shortNames:
- bks
kind: BackUp
```
**Explanation:**
- **apiVersion**: Indicates the version of the CRD API.
- **kind**: Specifies that this is a CustomResourceDefinition.
- **metadata.name**: The name of the CRD, following the pattern `<plural>.<group>`.
- **spec.group**: The API group under which this resource will be served.
- **spec.versions**: Lists the versions of this resource, with one version being marked as storage and served.
- **spec.scope**: Defines whether the resource is Namespaced or Cluster-scoped.
- **spec.names**: Contains the naming conventions for the resource, including plural, singular, short names, and kind.
#### Deploying a Custom Resource
After defining a CRD, you can create instances of the new resource. Here's an example of deploying a custom resource using the defined CRD:
```yaml
apiVersion: stable.linux.com/v1
kind: BackUp
metadata:
name: a-backup-object
spec:
timeSpec: "* * * * */5"
image: linux-backup-image
replicas: 5
```
### Optional Hooks and Validation
CRDs support optional hooks and validation rules to ensure data integrity and facilitate custom behaviors.
**Finalizer:**
A finalizer is a hook that ensures certain cleanup actions are performed before an object is deleted.
```yaml
metadata:
finalizers:
- finalizer.stable.linux.com
```
**Validation:**
Validation ensures that the resource meets specific criteria before being accepted by the API server.
```yaml
validation:
openAPIV3Schema:
properties:
spec:
properties:
timeSpec:
type: string
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}