Resource Example

This chapter walks through the definition of a new Resource call ContainerSet. ContainerSetcontains the image and replicas fields, and ensures a Deployment with matching image and replicasit running in the cluster.

Create the scaffolding for a new resource using the kubebuilder cli:

$ kubebuilder create api —group workloads —version v1beta1 —kind ContainerSet

This creates several files, including the Resource schema definition in:

pkg/apis/workloads/v1beta1/containerset_types.go

Type Definition

ContainerSet has 4 fields:

  • Spec contains the desired cluster state specified by the object. While much of the Spec isdefined by users, unspecified parts may be filled in with defaults or by Controllers such as autoscalers.
  • Status contains only observed cluster state and is only written by controllersStatus is not the source of truth for any information, but instead aggregates and publishes observed state.
  • TypeMeta contains metadata about the API itself - such as Group, Version, Kind.
  • ObjectMeta contains metadata about the specific object instance - such as the name, namespace,labels and annotations. ObjectMeta contains data common to most objects.
  1. // +genclient
  2. // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
  3. // ContainerSet creates a new Deployment running multiple replicas of a single container with the given
  4. // image.
  5. // +k8s:openapi-gen=true
  6. // +resource:path=containersets
  7. type ContainerSet struct {
  8. metav1.TypeMeta `json:",inline"`
  9. metav1.ObjectMeta `json:"metadata,omitempty"`
  10. // spec contains the desired behavior of the ContainerSet
  11. Spec ContainerSetSpec `json:"spec,omitempty"`
  12. // status contains the last observed state of the ContainerSet
  13. Status ContainerSetStatus `json:"status,omitempty"`
  14. }

Comment annotation directives

The definition contains several comment annotations of the form // +something. These areused to configure code generators to run against this code. The code generators will generate boilerplate functions and types to complete the Resource definition.

To learn more about how to use annotations in kubebuilder, refer to Generating CRD.

ContainerSetSpec

The ContainerSetSpec contains the container image and replica count, which should be read bythe controller and used to create and manage a new Deployment. The Spec field contains desiredstate defined by the user or, if unspecified, field defaults or Controllers set values.An example of an unspecified field that could be owned by a Controller would be the replicasfield, which may be set by autoscalers.

  1. // ContainerSetSpec defines the desired state of ContainerSet
  2. type ContainerSetSpec struct {
  3. // replicas is the number of replicas to maintain
  4. Replicas int32 `json:"replicas,omitempty"`
  5. // image is the container image to run. Image must have a tag.
  6. // +kubebuilder:validation:Pattern=.+:.+
  7. Image string `json:"image,omitempty"`
  8. }

ContainerSetStatus

The ContainerSetStatus contains the number of healthy replicas, and should be set by the controllereach time the ContainerSet is reconciled.

This field is propagated from the DeploymentStatus, and so the controller must watch for Deploymentevents to update the field.

  1. // ContainerSetStatus defines the observed state of ContainerSet
  2. type ContainerSetStatus struct {
  3. HealthyReplicas int32 `json:"healthyReplicas,omitempty"`
  4. }

Running Code Generators

While users don't directly modify generated code, the code must be regenerated after resources aremodified by adding or removing fields. This is automatically done when running make.

Scaffolded Boilerplate

Kubebuilder scaffolds boilerplate code to register resources with the runtime.Scheme used tomap go structs to GroupVersionKinds.

  • SchemeGroupVersion is the GroupVersion for the APIs in this package
  • SchemeBuilder should have every API in the package type added to it
  1. var (
  2. // SchemeGroupVersion is group version used to register these objects
  3. SchemeGroupVersion = schema.GroupVersion{Group: "workloads.k8s.io", Version: "v1beta1"}
  4. // SchemeBuilder is used to add go types to the GroupVersionKind scheme
  5. SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion})
  1. func init() {
  2. // Register the types with the SchemeBuilder
  3. SchemeBuilder.Register(&v1.ContainerSet{}, &v1.ContainerSetList{})
  4. }