Much has been said about micro-services over the last year and I wanted to find out for myself what the fuss was all about. At Molecule, we needed a way to augment our main application with supporting functions and services, and I figured it was time to give micro-services a shot. I looked at several open source technologies that promised to provide an easy-to-use micro-services platform. We ultimately landed on Knative given the strong community support around the technology and how the technology met our needs.
I used the following as guiding principles for evaluating the various micro-services technologies:
- Strong community support
- Integrates with our GitLab and Kubernetes Continuous Integration(CI)/Continuous Delivery(CD) tooling
- Supports our primary use cases
- Extends to our customers
Strong Community Support
As with any open source technology, strong community support is a must-have. Even if it's great tech, but does not have a good developer community supporting the technology, best to look for something else. In Knative's case, there is active community support on GitHub and a thriving Slack community. And of course, Google is behind the technology.
Integrates With Our Existing CI/CD Tooling
It was important for me to not add yet another tool to our engineering workflow and to ensure we can leverage our existing CI/CD tooling. We were already heavy users of GitLab for our source code management and Docker image registry as well as AWS EKS (Kubernetes) to run the Molecule app. Our chosen micro-services platform needed to work within our current infrastructure.
To run our Knative instance, I ended up creating a separate AWS EKS cluster from our main production cluster to allow us to more easily upgrade our Knative cluster as needed and to avoid any unintended consequences to our production cluster. The following components are installed in the EKS Knative cluster:
- Knative Serving and Eventing
- Kafka (as a messaging provider)
The Knative cluster consists of two primary namespaces, molecule-functions-dev for services under development and testing and molecule-functions that are serving production workloads. In GitLab, each function is a separate project with an accompanying
.gitlab-ci.yml file to manage the build of the service and the auto-deployment to the appropriate namespace in the K8s cluster. When a change to a function is merged to the master code branch, the Knative service is built and auto-deployed to the molecule-functions-dev namespace. When a tag is applied to a function, the Knative service is auto-deployed to the molecule-functions namespace. Included in the build and deployment is the K8s
service.yaml file which describes the service and any supporting deployments such as a
cronjob.yaml, if one is required for scheduled services.
With this approach, our developers as well as our customer success team can live in their favorite IDE, and easily develop, maintain, and deploy scalable Knative services simply by committing and tagging code in GitLab.
Supports Our Primary Use-Cases
At Molecule, our chosen micro-services platform needed to support the following use-cases:
- Can it run on a schedule?
- Can it be executed on-demand?
- Does it support messaging?
- Can it scale?
On a Schedule
We have multiple instances where we need to run a function on a schedule to allow our customer success team or our development team to execute routine functions that allow us to maintain the health of the Molecule app. Knative's CronJobSource provides a straight forward mechanism to schedule these routine functions. Examples of routine scheduled functions include data integrity checks, cleaning up obsolete log data, and nightly resetting our alerting system.
To help extend the core Molecule application, our services needed to be reachable from the Molecule app that would allow us to execute custom services that we develop on behalf of our customers or services that we want to run outside of our production cluster. For example, our asset valuation module can call external services either hosted by our customers or hosted by us that returns custom valuation data to Molecule. These services can now run in our Knative cluster allowing us to scale these services as needed.
Guaranteed and reliable messaging is critical to any enterprise system, particularly commodity trading and risk management systems like Molecule. We reliably utilize messaging today within our core Molecule app to scale our back-end processes; however, we also have a need to utilize messaging outside of our core app to support business critical functions on behalf our customers. For example, our batch reporting functionality relies on messaging to distribute the creation and publication of batch reports (e.g. trade confirms) to our customers. In our Knative cluster, we utilize Kafka as a guaranteed message transport to ensure a message reaches its destination and performs the intended function.
Scalability is another critical component of a good micro-services architecture that supports the scaling of services to meet demand as well as scaling to zero for non-critical services that can tolerate a cold start. Knative supports this requirements nicely by allowing us to set scaling parameters at a per service level supporting scaling to 0, setting a default number of always-on service replicas to respond to normal demand, and setting max scaling levels to control the workload in peek demand.
Extends to Our Customers
A primary reason for adding a micro-services based approach to our ecosystem is to better support our customers and to provide them with the functionality that is required to do their business without having to resort to core application changes. As stated above, our Knative cluster allows us to quickly and easily develop, deploy, and scale business critical services to augment our core application and also enables us to better serve our customers. This platform also positions us to provide future services to our customers such as our customers running their own developed and managed services in our managed Knative cluster to further extend their use of Molecule.
With all the benefits and capabilities of a micro-services platform outlined above, we have embraced micro-services as an extension to our platform and we are now referring to this collected set of capabilities as Molecule's m.functions.