This repo was created from my desire to better understand how to create an operator using the Operator SDK. The Hello Operator is able to scale the number of hello-go image containers to the value specified in the Hello Custom Resource (CR). The work shown here is heavily influenced by the Memcached Operator Sample.
- Have the OpenShift CLI installed
- Have an OpenShift cluster up and running.
- Be logged into the OpenShift cluster as a user with the Cluster Admin role.
- Have the Operator SDK installed
- Create the hello-operator project and move into it.
$ operator-sdk new hello-operator --api-version=github.awgreene.com/v1alpha1 --kind=Hello \
&& cd hello-operator
- Modify the spec and status of the Hello CR at
pkg/apis/cache/v1alpha1/types.go
.
...
type HelloSpec struct {
// Size is the size of the hello deployment
Size int32 `json:"size"`
// World is an Environment variable passed into the containers
World string `json:"world"`
}
type HelloStatus struct {
// Nodes are the names of the hello pods
Nodes []string `json:"nodes"`
}
- Update the generated code for the CR:
$ operator-sdk generate k8s
- Define where you will store your hello-operator image.
$ export REGISTRY=<SOME_REGISTRY> \
&& export NAMESPACE=<SOME_NAMESPACE> \
&& export REPOSITORY=<SOME_REPOSITORY> \
&& export TAG=<SOME_TAG>
-
Update the controller logic by changing the
pkg/stub/handler.go
file to match the same file in this repo. Make sure not to replace your hello-operator project import.NOTE: Notice that we watch for new values for each field defined in the
HelloSpec
strcuture found inpkg/apis/cache/v1alpha1/types.go
as shown on line 51.NOTE: Notice that the Deployment yaml is defined within the deploymentForHello function on line 79
-
Build and push the hello-operator image to a public registry such as quay.io.
$ operator-sdk build $REGISTRY/$NAMESPACE/$REPOSITORY:$TAG \
&& docker push $REGISTRY/$NAMESPACE/$REPOSITORY:$TAG
- Update the
deploy/operator.yaml
file to deploy the image you just pushed.
$ sed -i "s|REPLACE_IMAGE|${REGISTRY}/${NAMESPACE}/${REPOSITORY}:${TAG}|g" deploy/operator.yaml
- Deploy the hello-operator.
$ oc apply -f deploy/sa.yaml \
&& oc apply -f deploy/crd.yaml \
&& oc apply -f deploy/rbac.yaml \
&& oc apply -f deploy/operator.yaml
- View your hello-operator.
$ oc get pods
// Expected output
NAME READY STATUS RESTARTS AGE
hello-operator-5bb798cd5-5rrjx 1/1 Running 0 9m
- Modify
deploy/cr.yaml
as shown.
apiVersion: "github.awgreene.com/v1alpha1"
kind: "Hello"
metadata:
name: "hello-go"
spec:
size: 2
world: "Go Programmer"
- Create a Hello CR. The hello-operator will deploy two hello-go pods in response.
$ oc apply -f deploy/cr.yaml
- View your deployment. The number of example pods should match the
Size
field defined in thedeploy/cr.yaml
file.
$ oc get pods
// Expected output
NAME READY STATUS RESTARTS AGE
hello-go-69d74f6f56-jx27j 1/1 Running 0 8m
hello-go-69d74f6f56-qq7d9 1/1 Running 0 8m
hello-operator-5bb798cd5-5rrjx 1/1 Running 0 9m
- Run a cURL command from within a container to view your message. The recipient of the hello should match the
WORLD
field defined in `deploy/cr.yaml:
$ kubectl exec -it $(kubectl get pods -o go-template -l app=hello -o jsonpath='{.items[0].metadata.name}') curl localhost:8000/env
// Expected output
Hello, Go Programmer!
With that, you have successfully create the Hello Operator. Try changing the size of the deployment and the message!
It's possible to use the Operator SDK for end-to-end testing. In this example, our tests will deploy two clusters in ephemeral namespaces that will scale four hello-go images.
-
Copy the
tests
directory from this repo to your project. -
Make sure all dependencies are in your project.
$ dep ensure
- Run the tests using the operator sdk.
$ operator-sdk test --test-location ./tests/e2e