Runboat is a Kubernetes operator. It deploys, monitors and undeploys resources necessary to run live Odoo instances. It is written in Python. Here is an overview of the technologies I used to create it - with a screencast at the end. 1/10 🧵👇. github.com/sbidoul/runboat.
First is #kubernetes itself. It provides an ubiquitous API to manage deployment resources. Runboat sets custom labels and annotations to store metadata. Using the powerful k8s watch mechanism, it can react to events happening in the cluster. The perfect tool for the job. 2/10
Then there is #python, 3.10. Using type annotations to improve code readability and catch occasional bugs. asyncio provides robust, lightweight concurrency. It is amazing how far modern Python has gone while still being recognizable as the same language it was 25 years ago. 3/10
Flit is used to package the project and declare dependencies using modern python packaging standards (PEP 621 pyproject.toml, PEP 660 and more). 4/10
Using the official Python Kubernetes client, with a touch of async wrapper, it is fairly easy to write a Kubernetes operator in Python. A future improvement will be to use an asyncio-native client lib with type annotations. lightkube looks promising. 5/10
Runboat needs to query, sort, and dig through deployments. Using sqlite3 as an in-memory database makes it easy and fast. Python still has a lot of useful batteries included! 6/10
Exposing a REST API is super easy and fun using #FastAPI and #Starlette. 7/10
Then there is the web UI. With HTML Custom Elements (via #lit), frontend code can be lightweight and readable at the same time. The modern web is cool again. 8/10
Using Server Side Events, and an EventSource in the browser, the frontend reacts to events in the cluster. It is quite fascinating to see a git push being noticed by the runboat webhook, triggering a k8s deployment which in turn creates a new build card in the frontend. 9/10
That's all for today folks. Here is the promised screen cast! 10/10
• • •
Missing some Tweet in this thread? You can try to
force a refresh