Kubernetes Series — CRD

Pirix Technologies
3 min readJun 11, 2019
Kubernetes Custom Resource Definition

What exactly is CRD

CRD stands for Custom Resource Definition, with Kubernetes gaining popularity, the requirement to make it modular and extensible is gaining traction, in 1.7 release, Kubernetes introduced this powerful feature in an attempt to allow each developer be able to customize the platform to their unique needs.

Why do we need it (what if we don’t have it)

Kubernetes is turning into the de-facto computing platform rather than just container orchestration it started with. CRD provides flexibility and extensibility. Without the extensibility of CRD, when you have a new feature idea or an API to extend, first you’ll have to submit feature request and consult/discuss with community to determine if it will be accepted, this can sometimes get into a contentious divided viewpoint argument. Then once you have submitted a pull request back to feature branch, code review and improvement back and forth takes time as well. Therefore, have the ability to develop a “plugin” for Kubernetes can save a lot of resources (most importantly time) if the need is unique and/or specific.

The good side of CRD (when should you use it)

It provides a framework for developers to conveniently extend functionality of Kubernetes to their or their company’s needs, with little overhead. Like all frameworks it has its rules and standards to follow, and complying with those rules can leverage a lot of powerful features comes with core product and save valuable development time. Like AirBnB, you have to follow the rules of the host, whereas if you travel to a place and book a room in a fancy hotel, you can do pretty much whatever you want, stay as late as you want, but the cost can rack up pretty quickly.

The ugly side of CRD (when NOT to use it)

Its strength is also its “weakness“. By setting the ground rules, it doesn’t provide much flexibility in terms of how you want to control the behaviour of your resource and deployment strategy. If the use case doesn’t require Kubernetes support (e.g. kubectl, ui, namespace, api support etc.) and a fine control of resources and REST API path is required, then developing a standalone API is better suited.

An Example of using it

In general, add a CRD to your Kubernetes environment requires two steps:

  • Define a custom resource definition
  • Define an object to use that custom resource definition

With these two it’s still not declarative API, to achieve that, we need a custom controller to keep the current state and desired state in sync

To scaffold a Kubernetes API, Kubebuilder can be used to scaffold and bootstrap the effort, detailed documentation can be found in https://book.kubebuilder.io/introduction.html

Create a custom resource definition:

formula1-crd.yaml

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: cars.stable.pirix.io
spec:
# group name to use for REST API: /apis/<group>/<version>
group: stable.pirix.io
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: cars
# singular name to be used as an alias on the CLI and for display
singular: car
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: F1
# shortNames allow shorter string to match your resource on the CLI
shortNames:
- f1
subresources:
status: {}
# Kubernetes starts using server side printing since 1.11, i.e. server decides what
# to show when `Kubectl get` issued
additionalPrinterColumns:
- name: Age
type: date
JSONPath: .metadata.creationTimestamp
- name: Replicas
type: integer
description: The number of jobs launched by the F1
JSONPath: .spec.replicas
- name: EngineClass
type: string
description: The engine class spec defining how powerful engine is
JSONPath: .spec.engineClass
- name: Image
type: string
description: The image being running
JSONPath: .spec.image

Create a custom resource object:

formula1.yaml

apiVersion: "stable.pirix.io/v1"
kind: F1
metadata:
name: f1-car
spec:
powerRanking: 1
engineClass: v10
engineProvider: FiA
chassisProviderNumber: 10
image: formula1

Full code can be found at https://github.com/PXMYH/kubernetes-series

--

--

Pirix Technologies

We provide cloud computing and software development services to our clients