π¦ Kubernetes Installed PackagesΒΆ
Muppy makes deploying Helm packages into Kubernetes clusters straightforward, through an intuitive graphical interface. Users manage all of their packages directly from the Muppy interface.
π§© Muppy Meta Package (m2p)ΒΆ
Muppy also offers the Muppy Meta Packages (m2p).
An m2p is a tool that simplifies deploying complex applications on Kubernetes, by
grouping several Docker containers and their configuration into a single package, called a
metapackage.
That metapackage is made of parts β modular sub-components representing services, their dependencies and their parameters. Thanks to this structure, even users with little Kubernetes experience can deploy advanced applications smoothly and quickly.
π§± The components of a deploymentΒΆ
Deploying a package relies on the following elements:
-
π¦ K8s Package: the definition of the package to deploy (a Helm chart, or Kubernetes files applied with
kubectl)
β for Helm, it includes the default values (values.yaml) -
π§Ύ K8s Package Profile: for metapackages, the profiles define:
- the parts the package is made of
- the default resources (limits, replicas)
- the dashboards used for configuration
-
the available versions and the upgrade strategies
-
π Installed Package: an instance of a K8s Package deployed in a Kubernetes cluster, with the parameters defined in a K8s Package Profile
-
π Config Journal: the log of the Helm operations performed on a package (deployment history, upgrades, diffs, β¦)
π A package's life cycleΒΆ
- π Creation (to be documented)
- π οΈ Installation / Modification
- βοΈ Edit (Update)
- π Upgrade (version bump)
- β Deletion (to be documented)
βοΈ ModificationΒΆ
Two kinds of modification are possible:
1. Edit / UpdateΒΆ
Changes handled directly by Helm:
- changes to the values
- part configuration
- network or dashboard settings
Muppy automatically detects the differences between the current configuration and the desired one, and displays the "Drifted values" indicator.
These changes are applied on the next helm upgrade.
Every helm upgrade is recorded in the Config Journal, with:
- the values used
- the diff against the previous version
2. π Package UpgradeΒΆ
For the cases where an update affects the databases, or requires stopping the application, Muppy offers an advanced version-bump mechanism: Package Release Upgrade.
Available through:
- π§ the βPackage Release Upgradeβ wizard
- βοΈ the CI/CD API
Based on SEMVER version management, it can:
- identify the version profiles
- run migration scripts
- apply the changes safely
π Version profilesΒΆ
A profile holds:
- π§ the definition of the parts
- π the associated dashboards
- π§ͺ a migration script (if needed)
- π the criteria for applying it
π§ββοΈ How the Package Release Upgrade worksΒΆ
Unlike a plain helm upgrade, the version upgrade wizard expects:
- π― the K8s Profile to apply
- β»οΈ Reload Values (boolean): reload the default values from the profile
- π§Ή Reset Values Overload (boolean): reset, or merge, the customised values
π The upgrade, step by stepΒΆ
If the profile to deploy differs from the one currently in place, the version bump follows these steps:
-
β Profile change
The new K8s Package Profile is assigned to the instance. -
βοΈ Execution of
onchange__k8s_package_profile_id()
This method does the following:-
calls
reload_mpy_meta_config_yaml()to reload the parts configuration:- from the profile, or
- failing that, from the package
-
updates the fields:
default_pathdefault_path_debughealthcheck_pathfqdn_hostname_smart_config_id(if present in the new profile)
-
-
π§© Applying the dashboards
The dashboards defined in the new profile are put in place.β οΈ Existing values are preserved
The values previously entered in the dashboards are preserved by default. -
β»οΈ Reload Values (if enabled)
- reloads the dashboard's values from the profile
- reloads the content of the
valuesfile from the package
-
π§Ή Reset Values Overload (if enabled)
- if enabled: the Values Overload section is replaced by the new values
- otherwise: the new values are merged with the existing ones
-
𧬠Computing the final values
The combined result (default values + overloads) is injected into Final Values. -
π Deployment
Thehelm upgradecommand runs with the Final Values.
𧬠The Upgrade Job, and what decides whether it runs¢
When a version change needs the database migrated, the upgrade does not simply swap the image. It runs an Upgrade Job: a Kubernetes Job that executes the profile's migration command in a pod carrying the new image, before the application comes back.
The sequence around it:
- πΎ Backup β if the profile has Backup before upgrade, a
pg_dumpof the Release's databases is taken first. A Release with no database logs it and carries on. - βΈοΈ Stop β the parts that hold a connection to the database go to 0 replica while the Job runs (a cronjob part is suspended instead). Which parts those are is declared per part in the Parts Config: the default is to stop, and a part can opt out β a Tailscale sidecar, for instance, keeps its pod throughout.
- 𧬠The Job β it runs, and the upgrade waits for it, up to Upgrade Job Timeout.
- βΆοΈ Restart β a second
helm upgraderestores the replicas and moves the images.
A failed Job leaves the parts stopped, on purpose
If the Job fails or times out, the stopped parts are not restarted: the database may be half migrated, and starting the application on it is the very thing the stop exists to prevent. The Release then carries Parts stopped for the upgrade, and Resume after stop is what brings them back β once you have dealt with the database.
ποΈ Upgrade Job TriggerΒΆ
Whether the Job runs at all is the profile's Upgrade Job Trigger. It compares the version currently deployed against the profile's App Version:
| Trigger | The Job runs when⦠|
|---|---|
| Disabled | never |
| SEMVER Major change | the major number differs. The pre-release suffix is not looked at |
| SEMVER Minor change | the major or the minor differs. The pre-release suffix is not looked at |
| Any SEMVER change | the two versions differ at all β the patch number and the pre-release suffix included |
| Always | every time, even onto the same version |
Pre-release suffixes: Major and Minor do not see them
18.5.0-beta.1 and 18.5.0-beta.2 share their major, their minor and their patch.
A profile set to SEMVER Major change or SEMVER Minor change therefore sees no
change between them and skips the migration entirely β silently, since skipping is
a normal outcome.
A profile that deploys branch builds needs Any SEMVER change or Always.
π§± Upgrading a Pack8sΒΆ
A Pack8s is the same application deployed on several clusters: one primary Release that serves the traffic, and followers sitting at 0 replica ready to take over. They share one database β the primary's cluster accepts writes, the followers are wired to standbys that replay it and refuse every write.
Two consequences, and both bite:
- every member carries the same name, so searching Releases by name returns several rows on several clusters. There is no the Release β there is the pack;
- upgrading one member alone leaves the pack on two versions, which is exactly the state a failover turns into an incident: the application comes back on the old image, over a database the other member already migrated.
So a Pack8s is upgraded as a pack, not member by member. One gesture carries every member onto the target profile, primary first, and the members are serialised β a member starts only once the previous one has finished, not merely started.
Only the primary migrates the database
The pack has a single database, so the Upgrade Job runs on the primary and on it alone. A follower is wired to a standby that refuses every write; its own Job would fail and leave that member stopped for nothing.
A failed primary stops the pack there
If the primary's upgrade fails, the followers do not start. That is deliberate: nothing should run over a database that may be half migrated. Deal with the database, then release the remaining members by hand.
π§ͺ Development ModeΒΆ
A checkbox on the Release (Dashboard tab) that mounts a persistent volume holding the application code, so a fix made inside a running pod survives a restart. Commit it, and CI/CD rebuilds the image for the parts that do not carry the volume.
It is not Debug Mode:
| Debug Mode | Development Mode | |
|---|---|---|
| Scope | one part | the whole Release |
| What runs | debug_config.command (code-server, sleep) |
the application, normally |
| Purpose | get a shell or an IDE inside a part | keep the code across restarts |
They combine: a Release in Development Mode serves from the volume, and you can additionally put one part in Debug Mode to edit through code-server. With Development Mode off, the Release provisions no development storage at all.
Requires mpy-metapackage β₯ 3.1.0, and a Parts Config declaring the volume β see the m2p documentation for the declaration itself.
Changing the volume declaration is not a simple edit
A Parts Config lives in three places, and each keeps its own copy. After editing the reference template you must walk the whole chain, in this order:
- Sync Package from Registry on the Package β only if the chart itself changed
- Reload from Template on the Package Profile
- Reload Parts Config, then Sync Parts Config, on the Release
Skip a step and the deployment silently keeps the previous definition.
And a PVC's accessModes and storageClassName are immutable: changing them on a
deployed Release makes the next upgrade fail with "spec is immutable after creation".
The only way out is deleting the claim by hand, which destroys its contents.
β DeletionΒΆ
To be documented later