Article

The remarkable simplicity of Mamluk's enterprise offering

Meezaan-ud-Din Abdu Dhil-Jalali Wal-Ikram · · 16 min read
The remarkable simplicity of Mamluk's enterprise offering

Mamluk’s enterprise offering is a stack of five layers. Debian is the operating system. The Bahriya Kubernetes Engine (BKE) turns a group of Debian machines into a Kubernetes cluster and keeps a fleet of clusters on the same tested versions. Bahriya Tersane is a catalogue of Helm charts that turns a cluster into a platform: databases, caches, identity, a registry, continuous integration and the shapes in which applications are deployed. Kipchak is the framework in which the APIs and applications above it are written. Bahriya Cloud, a public cloud, is built from all four.

Each layer has one responsibility, and each is small enough to be described completely. This article does so: what each layer decides, what it leaves to the organisation, how it is configured, how it is upgraded, and how the layers fit together. It closes with where each layer came from, and with the ways an enterprise can take one layer or the whole stack.

Five layers stacked from the bottom: Debian since 2016, one operating system on every node; the Bahriya Kubernetes Engine, on Kubernetes since 2021 and as a distribution since 2022, deciding the network fabric and the exact Kubernetes version; Bahriya Tersane since 2022, the services applications need; Kipchak since 2023, the framework the APIs and applications are written in; and Bahriya Cloud since 2026, a public cloud. Above them are the workloads: Islamic Network's APIs and applications, and customers' containers.

What simplicity means here

Simplicity in this stack is not a short feature list. It is four properties, held at every layer.

Each layer makes as few decisions as it can. A layer decides only what the layer above cannot work without, and leaves every other decision to the organisation that runs it.

Each layer is built from parts that can be named. Debian, Kubernetes, Calico, Kong, Longhorn, MySQL, Valkey and Keycloak are upstream projects with their own documentation, communities and security advisories. Where Mamluk has written something of its own, such as Kipchak or the workload charts, it is published and its source is available to the organisation that uses it.

Each layer is configured in files the organisation keeps. A cluster is described by its config.yaml and one values file per component. A chart release is described by its values file. A Kipchak service is described by its own source and configuration. All of them belong in the organisation’s source control, and an auditor can read them without logging in to anything.

Each layer stands on its own. A layer depends on the interface of the one beneath it, not on its brand. Kipchak runs wherever a container runs. The Tersane charts install on any conformant Kubernetes distribution. BKE installs on Debian, which anyone may run without a licence.

Debian: one operating system

Every node in the stack runs Debian. It was chosen for three reasons. Its stable releases change slowly and predictably, so a node that has been patched behaves the same way the next day. Its security support is long and its timetable is published in advance. It is maintained by an independent community project rather than a vendor, so the operating system carries no subscription and no commercial roadmap that the estate must follow.

The decision is kept narrow on purpose. BKE checks every node before it installs anything, and refuses a node that does not run Debian or whose operating system it cannot identify. One operating system is one set of package versions, one kernel lineage and one security feed to test against, and every BKE release is tested on that base alone.

BKE also changes as little of the machine as it can. It installs the packages a node needs to run Kubernetes, such as the kubelet, kubeadm, kubectl and containerd, and leaves the SSH configuration untouched unless the administrator asks it to manage SSH. Its scripts are read from the network and run without being written to disk, and anything they fetch, Helm included, goes to a private temporary directory that is removed when the script exits, whether it succeeded or not. The organisation’s own Helm, if it has one, is never replaced.

The Bahriya Kubernetes Engine: a fleet of clusters

One Kubernetes cluster can be installed and maintained by hand. Several cannot, not without the clusters drifting apart. The Bahriya Kubernetes Engine exists to keep a fleet of clusters on versions that have been tested together.

Two decisions

BKE is upstream Kubernetes, installed with kubeadm, with exactly two decisions made for every cluster: the network fabric, which is Calico with WireGuard encryption between nodes, and the Kubernetes version, pinned to the exact patch. Everything else is a component the organisation enables or leaves out, with one line per component in config.yaml:

Component What it provides
Kong Ingress and API gateway, run without a database, so that an upgrade is a replacement of pods
cert-manager Certificates, from whichever issuer the organisation configures
Longhorn Replicated block storage
Kuma A service mesh, enabled one namespace at a time
Fluent Bit Log shipping to the organisation’s log platform
netdata Monitoring, including Prometheus-format metrics
metrics-server The resource metrics that autoscaling depends on

A component that is not enabled is not installed. A component the organisation already runs can be adopted in place, by naming its existing Helm release.

A handful of commands

A cluster is created, changed and upgraded with a small number of scripts, each with one job:

Command What it does
check.sh Checks a node before anything is installed or upgraded on it
register.sh Registers the cluster’s licence, once
install.sh Prepares a node; on the first control-plane node, creates the cluster
apply.sh Installs or changes the enabled components to match config.yaml
upgrade.sh Moves a node to a newer BKE version
version.sh Reports what a node is running

Nothing changes unless the administrator says so. A script that would change the cluster first reports what it will do, and does it only when it is run again with --commit.

Configuration without secrets

config.yaml never contains a secret. Each credential a component needs is named in config.yaml and held on the node as a file under /etc/bke/secrets.d/, from which BKE creates the Kubernetes Secret; an organisation that already uses an external secrets manager can supply the Secret itself instead. Because the file holds no secret, it can be sent to Mamluk’s API, which renders the values file for each component from it and refuses an invalid configuration with a diagnostic before anything is installed. The node parses nothing.

The rendered values files belong to the organisation, which may edit them. At the next upgrade, BKE shows the difference between the organisation’s edited file and the new release’s file, and waits for the administrator to agree.

Upgrades by their effect

One BKE version pins the whole set: Kubernetes, Calico and every component, each to an exact patch release. Every image and chart is mirrored by Mamluk, and a published tag is never pushed again, so two installations of one BKE version are the same cluster. Releases are classified by what they do to a running cluster. A patch release changes component patches only and never drains a node. A jump across Kubernetes minor versions that are not adjacent is refused, because Kubernetes itself does not support it.

Login and independence

People log in to a cluster with their organisation’s own identity provider, through OIDC. BKE installs nothing for this: the API server is configured to trust the provider directly.

No management plane of Mamluk’s sits in the path of the cluster’s traffic. If the licence lapses, or Mamluk cannot be reached, the cluster continues to serve its workloads; only installation and upgrade pause. The full documentation is on the BKE website, and the case for this design is set out in Kubernetes built from parts.

Bahriya Tersane: from cluster to platform

A cluster is not yet a platform. Applications need databases, caches, an identity provider, a registry, source control and a way to build and deploy, and each of those needs replication, backups and an upgrade path that someone has decided. Bahriya Tersane holds those decisions in a catalogue of Helm charts, organised by function:

Group Charts
Data MySQL, Valkey, Memcached
Identity Keycloak
Registry and CI Harbor, OneDev, Concourse
Workloads safeena for web services, khadim for workers, saat for scheduled jobs
Security ClamAV, as a shared malware scanner

Upstream software keeps its upstream name. The three workload charts are Mamluk’s own, and carry Arabic and Turkish names: safeena is a ship, khadim a servant and saat an hour.

What a chart decides

A generic chart installs the software and leaves its operation to the reader. A Tersane chart carries the operational decisions as well: resource limits, disruption budgets, anti-affinity, RBAC, network policies and backups. Three examples show the depth.

MySQL has two modes. Standard mode runs a single primary with optional read replicas. HA Cluster mode runs Group Replication with automatic failover. The chart seeds a new member by cloning an existing one. A replica that has fallen so far behind that the primary no longer holds the logs it needs detects the condition and clones itself again, without an operator’s intervention. The chart also supports point-in-time recovery.

Valkey has three topologies behind a single mode setting: a standalone instance, a primary with replicas and Sentinel for failover, or a sharded cluster. Each ships with TLS, access control lists, persistence, backups to S3-compatible storage, a metrics exporter and a network policy. It follows the conventions of the MySQL chart, so an engineer who has operated one can read the other.

safeena, khadim and saat are the three shapes in which an application is deployed: a web service behind Kong with TLS, plugins, autoscaling and health probes; a worker with no public ingress; and a job on a schedule. An application team states its image and its requirements, and the chart supplies the rest.

Delivery and scope

The charts are delivered from a private chart repository, and the images from a private registry, with a separate credential for each. Each release is installed with a values file that the organisation keeps. The data each service holds stays in that project’s own format, so it can be read without Tersane.

Industry-specific additions, called Convoys, are installed on top of the functional groups; the first is for banking. Tersane is sold with or without BKE. Its defaults assume a BKE cluster, so an organisation running another distribution supplies the equivalent ingress, storage and certificate services itself, or engages Mamluk to do so.

Kipchak: one framework for every API

Kipchak is a PHP API framework built on Slim and optimised for FrankenPHP in worker mode, in which the application is loaded once and serves many requests rather than being started for each one. It serves Mamluk’s own production traffic at over 3,000 requests per second, using substantially fewer resources than an equivalent Symfony or Laravel service.

A small core

The core is deliberately small: a bootstrap, base classes, request and response helpers, and two interfaces, one for drivers and one for middleware. A Kipchak service has three folders that the core loads in order: drivers/, which registers connections to data stores and services; middlewares/, which registers what runs around every request; and routes/, which registers the API itself. A new service starts from the starter project and is a working API before its first route is written.

Drivers and middleware as packages

Everything beyond the core is a separate package, installed only where it is used. There are more than twenty drivers, covering Valkey, Memcached, Doctrine, CouchDB, Kafka, RabbitMQ, OpenSearch, S3-compatible storage, SFTP and others, and middleware for JWT, JWKS, HMAC and API-key authentication, usage metering, quotas and the Subashi web application firewall. A service carries the packages it uses and nothing else, which keeps its dependencies, its image and its audit as small as the service itself.

The core is open source and free. Kipchak Enterprise adds enterprise drivers and middleware, delivered as source through an authenticated Composer repository, and support from the people who maintain the framework. An expired licence never interferes with software that is already running.

Kipchak does not depend on the layers beneath it. A Kipchak service is a container image, and it runs wherever a container runs.

Bahriya Cloud: the stack in use

Bahriya Cloud reached general availability on 31 August 2026. It is a public cloud, used in the same way as AWS, Azure or DigitalOcean: customers sign up, deploy containers and managed data stores through a console, a CLI, a Terraform provider or an API, and pay for what they use. It is not sold as an enterprise product.

It is, however, the most complete demonstration of the four layers beneath it. Its API is written in Kipchak. Its managed services are Tersane charts. It runs on BKE clusters, and those clusters run on Debian. An enterprise considering the stack can see every layer of it in operation, under public load, before it licenses any part of it.

Where each layer came from

None of the layers was designed in advance as part of a product range. Each was added when the workload above it required it. That workload was Islamic Network’s APIs and applications, which began with the AlAdhan prayer times API in 2013.

A timeline from 2013 to 2026. In 2013 the AlAdhan API starts on shared hosting, written in CodeIgniter. In 2014 it moves to CentOS virtual private servers. In 2016 Debian becomes the operating system, with Docker Swarm. In 2021 Kubernetes is adopted. In 2022 the Bahriya Kubernetes Engine and the Helm charts now named Bahriya Tersane begin. In 2023 Kipchak replaces Slim. In 2026 Bahriya Cloud reaches general availability.

The services moved from shared hosting to CentOS servers in 2014, to containers on Debian under Docker Swarm in 2016, and to Kubernetes in 2021. The installation and upgrade of those clusters became BKE in 2022, and the charts for the services they ran began the same year. The application code moved from CodeIgniter to Slim, first under Apache and then under Nginx Unit; by 2023 Islamic Network ran more than a dozen APIs, processing over a billion queries a month, and what they had in common became Kipchak.

Each layer has carried that workload in production since:

Layer In production since Workload
Debian 2016 Every Mamluk service and node
Kubernetes, then BKE 2021, then 2022 Every Mamluk cluster
Bahriya Tersane 2022 Mamluk’s data stores, identity, registry and deployments
Kipchak 2023 Islamic Network’s APIs, and Bahriya Cloud’s API
Bahriya Cloud 2026 Customers’ containers and data stores

At the end of 2024 Islamic Network served up to 60 million requests a day to more than 1,500 developers, and the volume has grown since.

A toolkit, or the whole

Because each layer stands on its own, an organisation can take as much or as little of the stack as it needs.

Three ways to use the stack, drawn as three stacks side by side. In the first, the organisation takes one layer, here Bahriya Tersane, and keeps its own applications, framework, Kubernetes and operating system. In the second, it takes the whole stack on premise: BKE, Tersane and Kipchak Enterprise from Mamluk, on Debian on its own servers, beneath its own applications. In the third, it uses Bahriya Cloud, which Mamluk operates, and supplies only its containers.

One layer. An organisation with an established Kubernetes estate can take Tersane for its data stores, registry and CI. A development team that already has a platform can take Kipchak Enterprise for its APIs. An organisation that wants its own clusters, and has its own services above them, can take BKE. Each is licensed separately, and none requires the others.

The whole stack, on premise. BKE, Tersane and Kipchak together, on Debian, on the organisation’s own servers, provide the ground that an integrated platform such as OpenShift occupies: clusters, the services applications need, and a framework to write the applications in. The difference is that every part is upstream or published, every part is named and versioned, and every part can be replaced without replacing the others. What that difference costs and saves is worked through in What three clusters cost a bank and on the BKE cost-of-ownership page.

Bahriya Cloud. An organisation that wants none of the operation can deploy its containers on Bahriya Cloud and use the stack as a service, with Mamluk running every layer.

What the approach asks of the organisation

A stack that makes few decisions leaves the remaining decisions with the organisation. An organisation that takes the whole stack on premise chooses which BKE components each cluster carries, which Tersane charts each application uses, and how its own services connect to them. Mamluk’s consulting and support can inform those choices, but they remain the organisation’s own, as they should for the people accountable for the estate.

In return, the organisation receives a stack in which every layer has run production traffic for years, can be read in full, and can be changed one layer at a time. The products page lists each layer, a 14-day BKE trial is self-service at console.maml.uk, and every other conversation begins on the contact page.

Share
← Back to the Journal

More from the Journal