A simple quick-start introduction on how to build an operator from scratch
This project assumes you have knowledge of golang and at least some level of understanding of operators
The Operator SDK is a framework that uses the controller-runtime library to make writing Operators easier by providing:
High level APIs and abstractions to write the operational logic more intuitively. Tools for scaffolding and code generation to bootstrap a new project fast. Extensions to cover common Operator use cases.
The following is the workflow for a new Go-based Operator with the Operator SDK:
- Create a new Operator project using the SDK CLI.
- Create a new Custom Resource Definition API Type using the SDK CLI.
- Add your Custom Resource Definition (CRD) to your live Kubernetes cluster.
- Define your Custom Resource Spec and Status.
- Create a new Controller for your Custom Resource Definition API.
- Write the reconciling logic for your Controller.
- Run the Operator locally to test your code against your live Kubernetes cluster.
- Add your Custom Resource (CR) to your live Kubernetes cluster and watch your Operator in action!
- After you are satisifed with your work, run some Makefile commands to build and generate the Operator Deployment manifests.
- Optionally add additional APIs and Controllers using the SDK CLI.
- Use the okd-operator-pipeline to build, bundle and create a catalog for you new operator
To start you will neeed the following software packages
- golang
- golangci-lint
- operator-sdk
- opm
- kustomize
- go tools (controller-gen,setup-envtest)
There is a script in this repo to assist in getting the packages for linux only, please contribute to get brew install etc for mac
Clone the repo
git clone https://github.com/okd-project/okd-sample-operator
cd okd-sample-operator
Execute the script
sudo ./operator-software-util.sh
Once all the packages have been installed we are ready to start with the scaffolding of the operator
NB A complete solution is provided in this repository as a reference.
Create a new directory in your main projects folder.
as an example
mkdir mysample-operator
cd mysample-operator
We have provided an opinionated Makefile (it's been tailored to use in the okd-operator-pipeline).
Create and initialize the project
N.B. The operator-sdk init expects the base directory to be empty (i.e no files etc).
operator-sdk init --domain okd.io --repo github.com/<github-user-id>/mysample-operator
Create a simple SampleOperator API
operator-sdk create api --group=app --version=v1alpha1 --kind=SampleOperator --resource --controller
In the file sampleoperator_types.go inside of operator/api/v1aplpha1 change the following code:
// SampleOperatorSpec defines the desired state of SampleOperator
type SampleOperatorSpec struct {
// +kubebuilder:validation:Minimum=1
// +kubebuilder:validation:Maximum=5
Replicas int32 `json:"replicas,omitempty"`
}
// SampleOperatorStatus defines the observed state of SampleOperator
type SampleOperatorStatus struct {
PodNames []string `json:"podNames"`
AvailableReplicas int32 `json:"availableReplicas"`
}
If you are editing the API definitions (as in Step 3), generate the manifests such as CustomResource's or CustomResourceDefinition's by executing the following
N.B. Make a backup of the current Makefile
# we are in mysample-operator directory
mv Makefile Makefile-bak
Copy the Makefile (from the solution we provided) to your working directory (mysample-operator)
cp ../Makefile .
N.B. Change the variables at the top of the Makefile
PROJECT ?= mysample-operator
REGISTRY ?= <your-registry>
NAMESPACE ?= <your-namespace>
Execute ther following commands
make generate
make manifests
Edit the controllers/sampleoperator_controller.go file
Refer to the solution folder (to copy the sampleoperator_controler.go worked out example)
For more detailed information in what is being done in the controller please read the inline comments in the code
As we have updated the sampleoperator_controller.go file and added dependencies execute the following
go mod tidy
To deploy and execute the controller (run locally so that we can verify/debug) execute the following
export KUBECONFIG=<path-to-kubeconfig>
make deploy
# scale down the manager (so we can run locally)
kubectl scale deployment.apps/operator-controller-manager -n operator-system --replicas=0
make run
Edit the file config/samples/app_v1alpha1_sampleoperator.yaml to show the following
apiVersion: app.okd.io/v1alpha1
kind: SampleOperator
metadata:
labels:
app.kubernetes.io/name: sampleoperator
app.kubernetes.io/instance: sampleoperator-instance
app.kubernetes.io/part-of: operator
app.kubernetes.io/managed-by: kustomize
app.kubernetes.io/created-by: operator
name: sampleoperator-instance
spec:
replicas: 2
Apply the changes
Open a new terminal to execute the following commands
kubectl apply -f config/samples/app_v1alpha1_sampleoperator.yaml
kubectl get pods
Check the status of the controller
kubectl get sampleoperators.app.okd.io sample-instance -n operator-system -o yaml
You can also see the ouptut of the terminal (where you launched make run)
Once you are satisfied with all your changes you can go ahead and create a bundle (this will be used in the pipeline)
# a command line prompt is used to input relevant info
make bundle
This is an extremely simple solution, you may want to add other types of objects to watch/deploy
Use the makefile to build and push your specific version to a registry.
Commit your final changes to git.
The project okd-operator-pipeline can now be utilized to build, deploy and create a catalog for this operator. using your git repo.
For the okd-operator-pipeline to work on this repo consider using the makefile we have provided) as it has the correct recipes for the pipeline.
For more information on how to use and deploy the okd-operator-pipeline refer to the repository here okd-operator-pipeline
For more information about developing an operator please refer to the documentation for Operator SDK