Earlier we have seen about Kubernetes Custom Resources Definition, In this article will see most basics about the custom resource definitions to understand more about “How to Create Kubernetes Custom Resources Definition using kubectl”.
What is a Kubernetes Resource
A Kubernetes resource is an endpoint in the Kubernetes API that stores a collection of API objects of a certain kind. For example, the built-in Pods resource contains a collection of Pod objects.
In Kubernetes, there are many built-in resources available. For example: Deployment, Pods, Services, and ConfigMap, etc.
What is a Custom Resource (CR)
A Custom Resource is an object that extends the Kubernetes API that is not available by default, which means it allows you to introduce your own API into Kubernetes cluster.
Custom resources can appear and disappear in a running cluster through dynamic registration, and cluster admins can update custom resources independently of the cluster itself. Once a custom resource is installed, users can create and access its objects using kubectl, just as they do for built-in resources like Pods.
What is a Custom Resource Definition (CRD)
As we mentioned above in the Kubernetes API, a resource is an endpoint that stores a collection of API objects of a certain kind. The standard Kubernetes distribution comes with lot of inbuilt API objects/resources. For example, the built-in pods’ resource contains a collection of Pod objects. CRD comes when we want to introduce our own object into the Kubernetes cluster to fulfil our custom requirements. Once we create a CRD in Kubernetes we can use it like any other native Kubernetes object thus leveraging all the features of Kubernetes like its CLI, security, API services, RBAC etc.
The custom resource created is also stored in the etcd cluster with proper replication and lifecycle management. This is a powerful way to extend Kubernetes capabilities beyond the default installation. Also, it allows us to extend Kubernetes capabilities by adding any kind of API object useful for our application. This is a powerful way to extend Kubernetes capabilities beyond the default installation.
When you create a new CRD, the Kubernetes API Server creates a new RESTful resource path to serve and handle the storage of your custom resource.
Create a CustomResourceDefinition
Let’s create a simple CRD. Here is the YAML manifest we’ll use. You can save the following CRD to crd.yaml
:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# name must be in the form: <plural>.<group>
name: myapps.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
group: example.com
scope: Namespaced
names:
# kind is normally the CamelCased singular type.
kind: MyApp
# singular name to be used as an alias on the CLI
singular: myapp
# plural name in the URL: /apis/<group>/<version>/<plural>
plural: myapps
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
x-kubernetes-preserve-unknown-fields: true
The next step is to create the CRD using kubectl:
# kubectl apply -f crd.yaml
customresourcedefinition.apiextensions.k8s.io/myapps.example.com created
Now you can verify it using following command,
# kubectl api-resources | grep myapp
NAME APIVERSION NAMESPACED KIND
myapps example.com/v1 true MyApp
Create a Custom Object
After the CRD object has been created, you can create custom objects. Custom objects can contain custom fields. These fields can contain arbitrary JSON.
To create the custom object, you’ll use the following YAML manifest:
apiVersion: example.com/v1
kind: MyApp
metadata:
name: test-app
spec:
replicas: 3
environment: dev
version: release-1.0.0
creator: foxutech
You can save the above YAML manifest to test-app.yaml, and create the custom object:
# kubectl apply -f test-app.yaml
You can then manage your MyApp objects using kubectl. For example:
# kubectl get myapp
NAME AGE
test-app 6s
Resource names are not case-sensitive when using kubectl, and you can use either the singular or plural forms defined in the CRD, as well as any short names.
You can also view the raw YAML data for a custom resource:
# kubectl get myapp test-app -o yaml
apiVersion: example.com/v1
kind: MyApp
metadata:
creationTimestamp: "2022-10-29T05:26:29Z"
generation: 1
name: test-app
namespace: test
resourceVersion: "2342342"
spec:
environment: dev
creator: foxutech
replicas: 3
version: release-1.0.0
Delete a CustomResourceDefinition
When you delete a CustomResourceDefinition, the server will uninstall the RESTful API endpoint and delete all custom objects stored in it.
# kubectl delete -f crd.yaml
Add Additional Printer Columns
The kubectl
tool relies on server-side output formatting. Your cluster’s API server decides which columns are shown by the kubectl get
command. You can customize these columns for a CustomResourceDefinition
via the additionalPrinterColumns
field. The following example adds the REPLICAS, VERSION
and Age
columns. You can save the following manifest to crd.yaml
.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: myapps.example.com
spec:
group: example.com
scope: Namespaced
names:
kind: MyApp
singular: myapp
plural: myapps
versions:
- name: v1
served: true
storage: true
additionalPrinterColumns:
- name: Replicas
type: integer
description: The number of pods launched by the MyApp
jsonPath: .spec.replicas
- name: Version
type: string
jsonPath: .spec.version
- name: Age
type: date
jsonPath: .metadata.creationTimestamp
schema:
openAPIV3Schema:
type: object
properties:
spec:
x-kubernetes-preserve-unknown-fields: true
Create the CustomResourceDefinition:
# kubectl apply -f crd.yaml
Create an instance using the test-app.yaml
from the previous section. Invoke the server-side printing:
# kubectl get myapp test-app
Notice the NAME, REPLICAS, VERSION
and AGE
columns in the output:
NAME REPLICAS VERSION AGE
test-app 3 release-1.0.0 4s
Well, hope this give some idea about custom resource definition (CRD), you can expand this with multiple use cases. We will be seeing more about this in coming posts.