Learning Path
Get started using Kubernetes Operators
- Overview
- Intro to Kubernetes Operators
- Deep dive into Kubernetes operators
- Develop and deploy a Level I JanusGraph Operator using BerkeleyDB
- Develop and deploy a Level I JanusGraph operator using Apache Cassandra
- The Operator Cookbook: How to make an operator
- Seamlessly upgrade a JanusGraph operator
- Certify a JanusGraph image and operator for publishing to the Red Hat Marketplace
- Summary
This tutorial shows you how to develop and deploy a Level II operator on the OpenShift Container Platform. This is the continuation of the Level I operator tutorial series where it has the functionality to upgrade the version of your operand -- in this case, the operand is JanusGraph.
When you have completed this tutorial, you will understand how to:
- Build and push the latest version of the JanusGraph image
- Upgrade the version of the operand (JanusGraph application)
Prerequisites
To complete this tutorial, we assume that you:
- have some experience developing operators
- have some knowledge of Kubernetes Operators concepts
- have created the Level I operator
Estimated time
It should take you about 30 minutes to complete this tutorial.
What is Operators Level II capability?
Operators Level II capability is what's referred to as a seamless upgrade. The operator should support a seamless upgrade of the operator and the operand. An upgrade to the operator means that the custom resource (CR) instances are in a new desired state and would upgrade the operand. The upgrade can also mean upgrading the application that the operator manages along with other internals such as schema migrations. It's important to clearly state what is and isn't upgraded in the process.
To upgrade the current version of the operand (JanusGraph) to the desired version using go, you need to:
- Check for the current version of the container image.
- Compare the current version of the CR instance with the container image.
- If the current version is not the same and is lower than the one in the CR, then you should update the container image. If the current version is higher than the one in the CR, ignore the version upgrade.
Steps
1. Implement the version upgrade in the operator controller
The operator should be capable of upgrading the current version to a higher one. To do this, the following cases should be implemented in the operator's controller:
- Get the desired version from the CR.
- Get the current version from the container specification.
- Check to see if the container image needs to be upgraded.
- Upgrade the container image if the current version is less than the desired version.
Let's look at the code implementation (note the comments to see what the code is doing):
// version upgrade/downgrade
//1. Get the desired version from the CR
desiredVersion := janusgraph.Spec.Version
crImage := fmt.Sprintf("%s:%s", JANUS_IMAGE, desiredVersion)
//2. Get the current version from the container specification
manifestImage := *&found.Spec.Template.Spec.Containers[0].Image
versionSplit := strings.Split(manifestImage, ":")
currentVersion := versionSplit[1]
log.Info("Current version is", ":", currentVersion)
//3. Check to see if the container image needs to be upgraded
// only version with x.x.x format will work
// ex: 1.1.1 or 1.1 or 2
vA, err := semver.NewVersion(desiredVersion)
if err != nil {
fmt.Println(err.Error())
}
log.Info("Desired Version ", ":", vA.String())
vB, err := semver.NewVersion(currentVersion)
if err != nil {
fmt.Println(err.Error())
}
//4. Upgrade the container image if the current version is less than the desired version
if vB.LessThan(*vA) {
log.Info("Upgrading to new version", ":", vA.String())
found.Spec.Template.Spec.Containers[0].Image = crImage
err = r.Update(ctx, found)
if err != nil {
log.Error(err, "Failed to update version")
return ctrl.Result{}, err
}
// Spec updated - return and requeue
return ctrl.Result{Requeue: true}, nil
} else {
log.Info("Not Upgrading : ", "Already at latest version", currentVersion)
}
2. Deploy the operator
After the code has been changed, you can deploy the operator to your cluster using the steps described in the previous tutorial, "Develop and deploy a Level I JanusGraph operator using Apache Cassandra."
3. Update the CR version and apply
To upgrade the version, the CR instance should contain the version that you are upgrading to. Modify the version attribute in the spec:
apiVersion: graph.example.com/v1alpha1
kind: Janusgraph
metadata:
name: janusgraph-sample
spec:
# Add fields here
size: 3
version: 1.0.1
After you've updated it to the desired version, you can apply the CR to your cluster:
oc apply -f config/samples/graph_v1alpha1_janusgraph.yaml
4. Test the version upgrade
There are multiple ways to test if the version of the operand has changed:
- Test your application to make sure the feature changes have been applied.
- Check your pods to see if the container image has the latest version. You can do that describing the pods and check
Containers.janusgraph.Imageto make sure it has the right image and version:
oc describe <pod name>
Containers:
janusgraph:
Container ID: cri-o://f6d4584e850308d988f13cfdf76ab89b4da77687763c64e6640b50b0bcc8ae4b
Image: sanjeevghimire/janusgraph:1.0.1
Image ID: docker.io/sanjeevghimire/janusgraph@sha256:609ed2aa1c802f4ea377855f0add33e024572c0ddfa728dcded24f0f1164eaa8
Port: 8182/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 09 Jun 2021 12:04:17 -0700
Conclusion
You have now successfully implemented Level II operator for JanusGraph -- well done!
The next tutorial in this series shows you how to certify a JanusGraph image.