HariKube
What is this?
Normally, Kubernetes uses a database called ETCD. Kine (the origin of this project) is a tool that allows Kubernetes to use other databases (like SQLite or PostgreSQL) instead.
This specific version of Kine is unique because it handles filtering adirectly at the database level, which can make your cluster much faster and more efficient.
Why this fork exists?
Both ETCD and Kine are limited by Kubernetes API server itself and how it filters data. API server manages an O(n) cache in memory, and filters data at client side, because both ETCD and Kine are lacking on data filtering. The only real option is vertical scaling of all (API, ETCD, Kine). An average cluster dies at 50-100k records. Of course, you can add more ram, more iops, but these are just postponing the problem.
By changing a few lines of Kubernetes and a few lines of Kine, this project is able to send filtering to the database level. With these changes it is able to disable watch cache in Kubernetes API, and consumes O(1) memory during operation.
Here are some benchmark results on Ultra 7 165H 18 Core 4G, single VM ran everything including the k6 benchmark itself. 120 vus, each vu created a custom resource (6 different type) and read it back via label selector:
- Vanilla Kubernetes with 3 node ETCD cluster:
checks_succeeded...: 100.00% 51236 out of 51236
checks_failed......: 0.00% 0 out of 51236
http_req_duration..............: avg=799.54ms min=3.87ms med=82.39ms max=4.17s p(90)=2.47s p(95)=2.82s
http_req_failed................: 0.00% 0 out of 51236
http_reqs......................: 51236 24.976013/s
time="2026-02-14T19:07:26Z" level=error msg="test run was aborted because k6 received a 'interrupt' signal" make: *** [Makefile:589: k6s-start] Error 105
OOM Killed, thanks API server
- HariKube OSS with Postgres:
checks_succeeded...: 100.00% 101772 out of 101772
checks_failed......: 0.00% 0 out of 101772
http_req_duration..............: avg=708.33ms min=6.4ms med=300.67ms max=6.2s p(90)=1.99s p(95)=2.48s
http_req_failed................: 0.00% 0 out of 101772
http_reqs......................: 101772 28.188433/s
The numbers are talking for themselves
| Metric | HariKube OSS | Vanilla K8s |
|---|---|---|
| Throughput | 28 req/s ✅ | 25 req/s ❌ |
| Success Rate | 100% ✅ | 100% (OOM) ❌ |
| Latency average | 708ms ✅ | 799ms ❌ |
| Latency p95 | 2480ms ✅ | 2820ms ❌ |
| Latency p90 | 1990ms ✅ | 2470ms ❌ |
| Test Duration | 60m ✅ | ~34m (OOM) ❌ |
| Stability | Completed ✅ | KILLED ❌ |
| Objects Handled | 50k ✅ | ~26k (OOM) ❌ |
HariKube on steroids with 6 Postgres
checks_succeeded...: 100.00% 429180 out of 429180
checks_failed......: 0.00% 0 out of 429180
http_req_duration..............: avg=167.17ms min=7.75ms med=71.06ms max=3.71s p(90)=398ms p(95)=543.76ms
http_req_failed................: 0.00% 0 out of 429180
http_reqs......................: 429180 119.106435/s
| Metric | HariKube AE | Vanilla K8s | Gain |
|---|---|---|---|
| Throughput | 119 req/s ✅ | 25 req/s ❌ | 4.8x |
| Success Rate | 100% ✅ | 100% (then OOM) ❌ | not comparable |
| Latency average | 167ms ✅ | 799ms ❌ | 4.8x |
| Latency p95 | 543ms ✅ | 2820ms ❌ | 5.2x |
| Latency p90 | 398ms ✅ | 2470ms ❌ | 6.2x |
| Test Duration | 60m ✅ | ~34m (OOM) ❌ | not comparable |
| Stability | Completed ✅ | KILLED ❌ | not comparable |
| Objects Handled | 200k+ ✅ | ~26k (crashed) ❌ | 4x |
Open-Source edition is designed to interface with a single backend database instance at a time, which can become a performance bottleneck as your cluster grows. To address this, our business editions introduce various data routing capabilities. This allows you to distribute workloads across multiple database backends simultaneously, ensuring horizontal scalability for even the most demanding environments. Check out which edition fit's to your use-case.
Installation
Prerequisets
- Kubernetes cluster; supported versions Vanilla, EKS, AKS, GKE, RKE2, OpenShift >=1.34.0
- Cert-manager
helm install harikube oci://quay.io/harikube/harikube \
--version 0.16.3 \
--dependency-update \
--create-namespace \
--namespace harikube
kubectl wait -n harikube --for=jsonpath='{.status.readyReplicas}'=1 statefulset/harikube --timeout=5mIf you change namespace, please
--set vcluster.exportKubeConfigserver=https://harikube.<NAMESPACE>:443
You can enable network policies. You have to create namespace manually, label the namespace and skip --create-namespace flag.
--set middleware.networkPolicy.create=true # kubectl label namespace harikube harikube.info/<NAMESPACE>-middleware=enabled --overwriteYou can enable ServiceMonitors per service.
--set middleware.monitoring.create=trueYou can enable the MutatingAdmissionPolicy to label non core resources with skip-controller-manager-metadata-caching.
--set mutatingAdmissionPolicy.create=trueYou can enable a scalable contorl plane extension.
--set apiServer.create=true
--set controllerManager.create=true # By default all controllers are disabled, enable controllers you want to run.You can enable network policies for control plane.
--set apiServer.networkPolicy.create=true # kubectl label namespace harikube harikube.info/<NAMESPACE>-apiserver=enabled --overwrite
--set controllerManager.networkPolicy.create=true # kubectl label namespace harikube harikube.info/<NAMESPACE>-controllermanager=enabled --overwriteYou can enable ServiceMonitors per service.
--set apiServer.monitoring.create=true
--set controllerManager.monitoring.create=truevCluster connection
Connect via vCluster CLI.
vcluster connect harikubeConnect via vCluster KUBECONFIG.
kubectl get secret -n harikube vc-harikube -o yaml🔓 vCluster simplifies the operational workflow by automatically updating your local environment. For more details how to disable this behaviour, or how to get config by service account for example please wisit the official docs` Access and expose vCluster section.
🔓 For service access from host, the vCluster setup keeps things simple: Create your ServiceAccount, create a secret annotated with
kubernetes.io/service-account.name(example below), and vCluster will sync the secret to the host cluster.
apiVersion: v1
kind: Secret
metadata:
name: remote-your-service-account-name
annotations:
kubernetes.io/service-account.name: "your-service-account-name"
type: kubernetes.io/service-account-tokenOn the host cluster, you can fetch the connection details.
KUBE_API_URL=harikube.harikube.svc.cluster.local
TOKEN=$(kubectl get secret -n harikube remote-your-service-account-name-x-default-x-harikube -o jsonpath='{.data.token}' | base64 -d)
CA_CERT=$(kubectl get secret -n harikube remote-your-service-account-name-x-default-x-harikube -o jsonpath='{.data.ca\.crt}' | base64 -d)Important Requirement
To use these features to their full potential, you cannot use "standard" Kubernetes. You must use the patched images provided by us These patches allow the Kubernetes API to understand the special storage instructions Kine is waiting for.