Exercise 6: Custom Resource Definitions (CRDs)
Task 1 - Understanding Custom Resource Definitions
Custom Resource Definitions (CRDs) allow you to extend the Kubernetes API with your own custom resources.
CRDs define:
- The structure of your custom resource (schema)
- The validation rules for the resource
- How the resource is presented in the API
Create a CRD manifest:
$applicationCrd = @" apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: applications.workshop-example.io spec: group: workshop-example.io versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: deploymentName: type: string replicas: type: integer minimum: 1 maximum: 10 image: type: string containerPort: type: integer resources: type: object properties: memoryRequest: type: string cpuRequest: type: string memoryLimit: type: string cpuLimit: type: string required: - deploymentName - replicas - image scope: Namespaced names: plural: applications singular: application kind: Application shortNames: - app "@ # Output the CRD to review it $applicationCrd
cat <<EOF > application-crd.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: applications.workshop-example.io spec: group: workshop-example.io versions: - name: v1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: deploymentName: type: string replicas: type: integer minimum: 1 maximum: 10 image: type: string containerPort: type: integer resources: type: object properties: memoryRequest: type: string cpuRequest: type: string memoryLimit: type: string cpuLimit: type: string required: - deploymentName - replicas - image scope: Namespaced names: plural: applications singular: application kind: Application shortNames: - app EOF # Output the CRD to review it cat application-crd.yaml
This manifest defines an
Application
resource with properties likedeploymentName
,replicas
,image
, etc.
Task 2 - Create a Custom Resource Definition
First, check if any previous version of the CRD exists and delete it if needed:
kubectl delete crd applications.workshop-example.io --ignore-not-found
kubectl delete crd applications.workshop-example.io --ignore-not-found
Apply the Application CRD:
$applicationCrd | kubectl apply -f -
kubectl apply -f application-crd.yaml
Verify the CRD was created:
kubectl get crd applications.workshop-example.io
kubectl get crd applications.workshop-example.io
Examine the CRD details:
kubectl describe crd applications.workshop-example.io
kubectl describe crd applications.workshop-example.io
Notice the schema validation rules and the API versions available.
Task 3 - Create a Custom Resource
Create the Application custom resource:
$applicationCr = @" apiVersion: workshop-example.io/v1 kind: Application metadata: name: example-app spec: deploymentName: example-app replicas: 3 image: k8sonazureworkshoppublic.azurecr.io/nginx:latest containerPort: 80 resources: memoryRequest: "64Mi" cpuRequest: "100m" memoryLimit: "128Mi" cpuLimit: "200m" "@ # Output the custom resource to review it $applicationCr
cat <<EOF > application-cr.yaml apiVersion: workshop-example.io/v1 kind: Application metadata: name: example-app spec: deploymentName: example-app replicas: 3 image: k8sonazureworkshoppublic.azurecr.io/nginx:latest containerPort: 80 resources: memoryRequest: "64Mi" cpuRequest: "100m" memoryLimit: "128Mi" cpuLimit: "200m" EOF # Output the custom resource to review it cat application-cr.yaml
This is an instance of the
Application
custom resource type we just defined.Create the Custom Resource:
$applicationCr | kubectl apply -f -
kubectl apply -f application-cr.yaml
Verify the Custom Resource was created:
kubectl get applications
kubectl get applications
View the details of the Custom Resource:
kubectl describe application example-app
kubectl describe application example-app
Task 4 - Test Validation Rules
Try to create an invalid Custom Resource (with too many replicas):
$invalidApp = @" apiVersion: workshop-example.io/v1 kind: Application metadata: name: invalid-app spec: deploymentName: invalid-app replicas: 20 image: k8sonazureworkshoppublic.azurecr.io/nginx:latest containerPort: 80 "@ $invalidApp | kubectl apply -f -
cat <<EOF | kubectl apply -f - apiVersion: workshop-example.io/v1 kind: Application metadata: name: invalid-app spec: deploymentName: invalid-app replicas: 20 image: k8sonazureworkshoppublic.azurecr.io/nginx:latest containerPort: 80 EOF
You should get an error because the
replicas
field has amaximum
value of 10 in our CRD.Fix the invalid resource and apply again:
$validApp = @" apiVersion: workshop-example.io/v1 kind: Application metadata: name: valid-app spec: deploymentName: valid-app replicas: 5 image: k8sonazureworkshoppublic.azurecr.io/nginx:latest containerPort: 80 resources: memoryRequest: "64Mi" cpuRequest: "100m" memoryLimit: "128Mi" cpuLimit: "200m" "@ $validApp | kubectl apply -f -
cat <<EOF | kubectl apply -f - apiVersion: workshop-example.io/v1 kind: Application metadata: name: valid-app spec: deploymentName: valid-app replicas: 5 image: k8sonazureworkshoppublic.azurecr.io/nginx:latest containerPort: 80 resources: memoryRequest: "64Mi" cpuRequest: "100m" memoryLimit: "128Mi" cpuLimit: "200m" EOF
Verify the resource was created:
kubectl get applications
kubectl get applications
Task 5 - Using Kubectl for Custom Resources
Try kubectl commands with your custom resource:
# List all applications kubectl get applications # Get output in YAML format kubectl get application example-app -o yaml # Get specific fields using jsonpath kubectl get application example-app -o jsonpath='{.spec.replicas}'
# List all applications kubectl get applications # Get output in YAML format kubectl get application example-app -o yaml # Get specific fields using jsonpath kubectl get application example-app -o jsonpath='{.spec.replicas}'
Edit a Custom Resource:
kubectl edit application example-app
kubectl edit application example-app
Change the number of replicas to 4 and save the file.
Verify the change:
kubectl get application example-app -o jsonpath='{.spec.replicas}'
kubectl get application example-app -o jsonpath='{.spec.replicas}'
Task 6 - Clean up
Remove the Custom Resources:
kubectl delete application example-app valid-app
kubectl delete application example-app valid-app
Remove the Custom Resource Definition:
kubectl delete crd applications.workshop-example.io
kubectl delete crd applications.workshop-example.io