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 $applicationCrdcat <<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.yamlThis manifest defines an
Applicationresource 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-foundkubectl delete crd applications.workshop-example.io --ignore-not-foundApply the Application CRD:
$applicationCrd | kubectl apply -f -kubectl apply -f application-crd.yamlVerify the CRD was created:
kubectl get crd applications.workshop-example.iokubectl get crd applications.workshop-example.ioExamine the CRD details:
kubectl describe crd applications.workshop-example.iokubectl describe crd applications.workshop-example.ioNotice 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 $applicationCrcat <<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.yamlThis is an instance of the
Applicationcustom resource type we just defined.Create the Custom Resource:
$applicationCr | kubectl apply -f -kubectl apply -f application-cr.yamlVerify the Custom Resource was created:
kubectl get applicationskubectl get applicationsView the details of the Custom Resource:
kubectl describe application example-appkubectl 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 EOFYou should get an error because the
replicasfield has amaximumvalue 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" EOFVerify the resource was created:
kubectl get applicationskubectl 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-appkubectl edit application example-appChange 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-appkubectl delete application example-app valid-appRemove the Custom Resource Definition:
kubectl delete crd applications.workshop-example.iokubectl delete crd applications.workshop-example.io