# Katalyst-core: a QoS model and agents for a shared Kubernetes cluster

> Katalyst-core is the implementation half of the Katalyst system, a set of agents and centralized components that add a QoS resource model, elastic scaling, NUMA and device aware scheduling, and fine-grained over-commitment to a Kubernetes cluster. It is written in Go, ships as Helm charts, and expects to run on a KubeWharf enhanced Kubernetes rather than upstream.

**kubewharf/katalyst-core** — Katalyst aims to provide a universal solution to help improve resource utilization and optimize the overall costs in the cloud. This is the core components in Katalyst system, including multiple agents and centralized components

- Repository: https://github.com/kubewharf/katalyst-core
- Stars: 565 · Forks: 130
- Language: Go
- License: Apache-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/kubewharf-katalyst-core

## A QoS model where vanilla Kubernetes has only two tiers

The problem Katalyst addresses is stated in the repository description: improving resource utilization and reducing overall costs in the cloud. The mechanism is a pre-defined QoS model, and the README lists that as the first main feature, with multiple enhancements to meet the QoS requirements of various workloads.

That first feature is the load bearing one. Upstream Kubernetes gives you a Guaranteed request and limit or a BestEffort request and limit, and nothing in between. A cluster that co-locates a latency sensitive service with a batch job has no way to express that the batch job should be allowed to use spare cycles but must never delay the service, because the request and limit model has no vocabulary for that. Katalyst adds named QoS levels, and the example manifests show a range of them: dedicated, shared, reclaimed and shared-unlimited, each with its own resource semantics.

The second feature is elastic resource management, with both horizontal and vertical scaling implementations and an extensible mechanism for out-of-tree algorithms. The third is topology-aware scheduling and allocation, where Katalyst extends the native scheduler and kubelet to be aware of NUMA and device topology when scheduling pods and allocating resources to them. The fourth is fine-grained resource isolation, with real-time over-commitment, allocation and isolation strategies for each QoS, driven by auto-tuned workload profiling.

The unit of work throughout is the QoS level rather than the pod, and that is what makes the pieces fit together: the scheduler places a pod into a QoS, the QoS decides what that pod may claim, and the reclaim logic decides what happens when the node is over its committed capacity.

## Scheduler policies: binpack, spread and a custom extension point

The clearest way to see how the system works is through the example manifests, and the scheduler policy files are the most concrete of them.

There are three examples in the repository, and their names describe three different scheduling intents. There is a binpack policy, which is the opposite of what the default Kubernetes scheduler does, since the default spreads pods to fill nodes evenly. There is a spread policy, which reproduces or extends the default behaviour. And there is a custom policy, which is the one that shows the extension point.

The custom policy example is what makes the design legible. Rather than hard-coding a scheduling algorithm, Katalyst exposes it as a plugin that the scheduler consults, so an organisation can express its own binpacking or spreading rule without forking the scheduler. The README's third main feature calls this out as an extensible mechanism, and the third example file is the concrete artifact.

Alongside the scheduler there is a kubelet-side story, and the repository includes a shell script in the examples directory that prints the cpuset a pod is running in. That is a small but telling inclusion: a QoS model that allocates CPU from a NUMA topology is only meaningful if you can see the cpuset it chose, and the example is there so you can check it.

The reclaimed examples complete the picture. A reclaimed deployment and reclaimed pod files describe a workload that is allowed to consume resources beyond its reservation when the node has capacity to spare, which is the over-commitment mechanism, and there are two eviction configuration files alongside them, one for memory system config and one for reclaimed resource config. So the reclaim behaviour is configurable rather than a single fixed policy.

## Shared and dedicated: the QoS ladder in the example manifests

The pod examples make the QoS model concrete, and reading them together tells you what the levels mean in practice.

There is a dedicated-normal-pod.yaml, which is the closest thing to a conventional workload: it reserves what it needs and does not share. There is a shared-normal-pod.yaml and a shared-large-pod.yaml, where a shared pod can run alongside others on the same node and can be given more than it reserved. There is a shared-unlimited-pod.yaml, which is the extreme of that: no ceiling on what it may consume while capacity allows. And there is a reclaimed-normal-pod.yaml and a reclaimed-large-pod.yaml for the case where a pod explicitly opts into being reclaimed, meaning it gives resources back when the node needs them for work with a higher claim.

The normal and large suffix in the file names indicates a second axis, presumably a size or a resource class within the QoS level, and the tutorial document linked from the README, docs/tutorial/colocation.md, is where the colocation semantics are meant to be explained.

That colocation story is the practical heart of the project. The point of a QoS ladder is to let a cluster operator say that some pods are latency sensitive and must not be disturbed, that others are background work and may be preempted, and that some in between may share with the sensitive ones as long as the sensitive ones still get what they reserved. A node running all three levels at once is the interesting case, and the examples directory is built around exactly that.

## The Go module, and what the dependency list says about the scope

The module path is github.com/kubewharf/katalyst-core and the go directive is 1.18, which is a useful detail: this is a codebase that still targets a Go version from before the current ones, so it can be built in older CI images.

The dependency list is where the scope of the project becomes clear, because the list reads as a description of what a resource management agent has to touch. The Kubernetes client libraries are there, obviously, along with the katalyst-api module pinned at a pseudo-version that tracks a specific commit. Prometheus client_golang and the OpenTelemetry packages with a Prometheus metric exporter cover observability, and robfig/cron is the scheduler behind the periodic reconciliation the agents need to do.

Then there are the low-level dependencies, and they are the interesting ones. The eBPF library cilium/ebpf is present, and the NRI plugin containerd/nri is too, which are the mechanisms through which an agent can observe and influence what a container is actually doing rather than only what the API server says about it. The containerd cgroups package and moby/sys/mountinfo are the cgroup and mount introspection pieces. vishvananda/netlink and vishvananda/netns are the netlink and network namespace libraries, which is what you need to move a network interface or read namespace state. google/cadvisor is the container metrics source, and klauspost/cpuid is there for CPU feature detection, which fits the NUMA and topology awareness claim.

There is also a cluster of testing libraries, gomonkey and bytedance/mockey for monkey patching at test time, smartystreets/goconvey and stretchr/testify for assertions, and h2non/gock for HTTP mocking. The presence of two separate monkey patching libraries is a small signal about the testing style: these are unit tests that patch functions in place rather than integration tests against a real cluster.

## Deploying: Helm charts and an enhanced Kubernetes, not upstream

This is the constraint that decides whether the project is usable for you, and the README does not hide it. Katalyst runs on a KubeWharf enhanced Kubernetes cluster, and the detailed deployment instructions live in docs/install-enhanced-k8s.md in the repository. The components themselves are installed with Helm charts, and the charts live in a separate repository, github.com/kubewharf/charts, which also carries charts for all projects in KubeWharf.

So the install path has two parts: get an enhanced Kubernetes, then install the charts. There is no path that takes an upstream vanilla cluster and adds Katalyst to it, and the README is explicit that the enhanced distribution is developed based on specific versions of upstream Kubernetes and maintains API compatibility with the corresponding versions.

That last sentence carries a warning for anyone running other components. If you want to run an operator alongside Katalyst, you need to check that the operator is compatible with the corresponding Kubernetes API version that your enhanced cluster corresponds to. An enhanced distribution that tracks a specific upstream version and patches it is fine as long as everything else in the cluster agrees about which version that is.

For trying it out, the repository provides example yaml files demonstrating the common use cases, and the README points at the colocation tutorial for the walkthrough. That combination, examples plus a tutorial, is the intended first-run experience, and it assumes you already have the enhanced cluster underneath.

## The build: generated protocols, image tags derived from git

The Makefile shows how the code is generated and how images are named, and the first target is generation rather than compilation.

The default target is generate, which calls generate-pb, which in turn calls generate-sys-advisor-cpu-plugin, generate-advisor-svc and generate-borwein-inference-svc. So the protocol buffers for several services are produced from a temporary repository that the make rules clone into a directory structure mirroring their import paths, under github.com/kubewharf and github.com/gogo, and then clean up afterwards. The dependency on gogo/protobuf for the generated code explains that second path.

The image naming is derived from git rather than from a file, and that is worth noting because it tells you how a build is identified. The commit is read with git rev-parse HEAD, and if no tag points at that commit the version falls back to the first seven characters of the hash. Otherwise the version is the nearest tag, read with git describe. The registry defaults to docker.io and the namespace to kubewharf, and the credentials come from REGISTRY_USER and REGISTRY_PWD, with the image tag set to the derived version.

The image name and tag are assembled from those pieces:

```make
IMAGE_TAG = ${GIT_VERSION}
REGISTRY ?= docker.io
REGISTRY_NAMESPACE ?= kubewharf
```

The practical consequence is that a build from a tagged commit produces the tag as the image tag, and a build from an untagged commit produces a short hash, so you can tell from the tag which tree a running image came from.

The repository also carries a .golangci.yml for linting, a codecov.yml, a CODEOWNERS file, a GOVERNANCE.md and a MAINTAINERS.md, plus a .licenseignore file, which is there because parts of the tree are derived from Kubernetes itself and therefore already carry a different licence header.

## Governance, cadence and where the project actually lives

Katalyst is a ByteDance-adjacent project run under the KubeWharf organisation, and the community structure is documented rather than implied.

There is a tentative bi-weekly meeting, on Thursday at 19:30 UTC+8, with a Lark meeting link and a published agenda document, and its stated purpose is to discuss proposals, review milestones and do question and answer sessions. The word tentative is doing some work in that sentence, since a project that has just moved to a regular slot and calls it tentative is still settling into the rhythm. Communication runs through GitHub issues and pull requests, with email through the MAINTAINERS file, a Lark channel for Chinese speakers and a Slack channel for English speakers.

The release history shows a steady monthly cadence on a 0.5 line. The recent tags are v0.5.52 on 2026-09-02, v0.5.51 on 2026-08-04 and v0.5.50 on 2026-07-06, and the last push to the repository was on 2026-10-16. The high patch number on a 0.5 version is a pattern worth reading carefully: the API is still moving, and the version number is a signal that the interfaces in katalyst-api and the core implementations are expected to shift.

The licence is Apache 2.0, with the file at the root of the repository, and the README adds a specific note: certain implementations rely on existing code from Kubernetes, and the credits go to the original Kubernetes authors. That is why the .licenseignore file exists, and it is the point to raise in a legal review of a codebase that vendors parts of the Kubernetes codebase.

The project spans three repositories, and knowing which one to look at saves time. katalyst-api holds the API definitions including the CRDs, protocols and the QoS model itself, katalyst-core is this implementation, and the charts repository holds the Helm charts for all projects in KubeWharf. The QoS model you read about lives in the first of those, not in this one.

## Conclusion

Adopt Katalyst-core if you run a large multi-tenant Kubernetes cluster where pods share nodes and you need a QoS tier system, binpack or spread scheduling policies, and memory reclaim with eviction, and you are willing to run a KubeWharf enhanced cluster. Do not adopt it as a drop-in for an upstream Kubernetes cluster, because the prerequisite is an enhanced distribution that maintains API compatibility with specific upstream versions. Verify first which Kubernetes version your cluster corresponds to, since the README warns that other components such as operators must be checked for compatibility with that API version, that the qos CRDs from katalyst-api are applied before the agents start, and that the scheduler policy plugin configuration in the example manifests matches the policy you intend to enforce.

## FAQ

### What does Katalyst do in a Kubernetes cluster?

Katalyst provides a pre-defined QoS resource model with multiple levels, elastic horizontal and vertical scaling with an extensible out-of-tree mechanism, topology-aware scheduling and allocation that extends the native scheduler and kubelet to be NUMA and device aware, and fine-grained over-commitment, allocation and isolation per QoS level driven by auto-tuned workload profiling.

### How do I deploy Katalyst?

The README states that Katalyst runs on a KubeWharf enhanced Kubernetes cluster, with deployment instructions in docs/install-enhanced-k8s.md, and that the components are installed with Helm charts from the separate github.com/kubewharf/charts repository. Example yaml files and the colocation tutorial are provided for the common use cases.

### Which QoS levels does Katalyst support?

The example manifests in the repository show dedicated, shared, shared-unlimited and reclaimed levels, with normal and large pod variants for shared and reclaimed. The tutorial at docs/tutorial/colocation.md is where the colocation semantics for those levels are documented.

### What are the three repositories that make up Katalyst?

Katalyst-API holds the API definitions including the CRDs, protocols and the QoS model, Katalyst-Core holds the core implementations, and the charts repository holds Helm charts for all projects in KubeWharf. This repository is the implementation half.

### How are Katalyst images versioned?

The Makefile derives the version from git: if no tag points at the current commit it uses the first seven characters of the commit hash, otherwise the nearest tag via git describe. The registry defaults to docker.io and the namespace to kubewharf, and the image tag is set to that derived version.

## Sources

- [Issues](https://github.com/kubewharf/katalyst-core/issues)
- [kubewharf/katalyst-core on GitHub](https://github.com/kubewharf/katalyst-core)
- [License: Apache-2.0](https://github.com/kubewharf/katalyst-core/blob/main/LICENSE)
- [README](https://github.com/kubewharf/katalyst-core/blob/main/README.md)
- [Releases](https://github.com/kubewharf/katalyst-core/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/kubewharf-katalyst-core
