Hello everybody,
In this post I want to go over a bit of my experience with Juju and ask some questions.
Brilliant!, Brilliant!, Brilliant!
I found Juju recently and have since been doing some experimentation with it and have started on writing a basic charm. The first thing that I will say is that the idea is brilliant. I have experience with Chef, Docker, Packer, Terraform, Rancher, and Docker Swarm and I’ve told my partner before that I felt like there still needed to be a tool that facilitates communication between the applications that are being provisioned. Juju is that tool. Juju allows for a level of orchestration that practically allows you to create your own “orchestrator” that manages your applications in a way that Kubernetes or Swarm would never let you. It is a GAME CHANGER.
The Problem
Anyway, as I started to test Juju a little bit, one of the first things that I noticed was that it seems to be somewhat unresponsive or slow when it comes to building out the application stacks. For instance, even with a simple app consisting of an app charm and a Postgresql Charm when I make a relation between that app and Postgres it can take a couple minutes before the app even responds to the new relation. Also, spinning up a Kubernetes cluster can take about an hour.
To clarify, I understand that the charms are doing a lot: they have to download, install, and configure the applications, but what seems to be taking a lot of time is not the installation or configuration of the apps, but the interaction between the apps over the relations. I’m not 100% sure this is the case yet, but I wanted to bring it up and see what other people’s experiences have been with it.
Initially, I just accepted the fact that things were going to be slower to spin up in Juju than they would be in something like Docker Swarm. It is a different environment and a different kind of way to have the apps interact. My problem came, though, when I started to try to write my own charm, and it started taking a long time to debug the charm because I would end up just waiting for the system to do something after I made a change, and I didn’t know what it was waiting for.
The charm I was trying to make was a super simple Docker charm that would run the CodiMD Docker container and connect to the Postgresql charm for the database. As I made deployments of my charm and looked at the juju debug-log
I noticed that most of the time that the Postgresql charm spent doing stuff was actually spent printing huge stacks of logs like this:
tracer: starting handler dispatch, 166 flags set
tracer: set flag apt.installed.postgresql-10
tracer: set flag apt.installed.postgresql-client-10
tracer: set flag apt.installed.postgresql-client-common
...
This seems to be where Juju is spending a lot of its time. To me it looks like the reactive framework is slowing Juju down, maybe even slowing it down drastically. My suspicion is that the hooks are firing relatively quickly, but the reactive framework is limiting the speed that the layers can actually do their work with all of the flags that it is setting.
I’m not sure if Python itself is the bottleneck, or if it is just an inefficient implementation of the Reactive framework, or if I’m missing the source of the delays entirely, but I’d love to get some feedback.
In order to test whether or not it is the reactive framework slowing things down, I’m going to do some testing with using just the normal hooks, skipping the reactive system, to see if there is a big difference in the responsiveness. I haven’t done any tests yet but I’ll post any further experience here once I do.
Idea!
As long as the Juju hooks do run in a timely fashion without delays I was entertaining the idea of creating a Rust framework for writing charms that would serve essentially the same purpose as the existing Python reactive framework except it would be written in Rust and use Cargo for package management instead of the existing charm layers.
If the reactive framework is the performance bottleneck, then writing the framework in efficient Rust code should solve that. A lot of people might not want to write Rust, which is totally understandable, but Rust is by far my favorite language and I think it could work well for me and my team. Also, because the way that you interact with relations in Juju stays the same, charms written with a Rust reactive framework would be 100% compatible with charms written with plain hooks or with the Python reactive framework. You could, if there was value in it, even create Python bindings to the Rust reactive framework to get the extra performance but still be able to use the familiar language.
What I love about Juju is the fact that I’m free to design my own charm building framework if I need/want to.
Summary
These are just my thoughts after starting out with Juju and I would like to get feedback on whether or not I’m completely misinterpreting what Juju is doing or whether or not that is just a limitation of the system somehow. My Rust idea is mostly brainstorming and may not may not make sense yet, but I figured I’d throw it out there in case anybody had any thoughts.
I’m really loving Juju so far and I think that me and my team will be able to do some pretty awesome stuff with it. Can’t wait to see what we can accomplish.