The Boundary God for Kubernetes Ephemeral Storage.
Terminus is a cloud-native storage governance system designed to secure Kubernetes nodes from Rootfs/Overlayfs exhaustion.
In standard Kubernetes, ephemeral storage limits (requests.ephemeral-storage) are soft limits enforced by periodic Kubelet scanning (du). This mechanism is IO-intensive, slow to react, and ineffective against rapid disk consumption, often leading to node instability ("Noisy Neighbor" problems).
Terminus solves this by enforcing Hard Limits at the Linux kernel level using Project Quota. It also introduces a Disk-Aware Scheduler to balance I/O pressure based on real disk usage, ensuring node stability under high load.
"Terminus, the Roman god of boundaries, yields to no one."
-
π‘οΈ Kernel-Level Isolation (Terminus-Enforcer) Enforce strict disk usage limits on container Rootfs using XFS/Ext4 Project Quota via NRI (Node Resource Interface). Zero overhead, immediate enforcement.
-
π§ Disk-Aware Scheduling (Terminus-Scheduler) A scheduler plugin that filters and scores nodes based on Real Physical Usage and configurable Over-provisioning Rates. It prevents scheduling pods to nodes that are physically dangerously full, regardless of their allocation status.
-
β‘ Active Protection (Terminus-Exporter) An efficient node agent that monitors Project ID usage and triggers graceful
-
π§ Nexus AI Scheduling Brain (v0.2 New!) A revolutionary Disk-Aware Scheduler powered by an asynchronous LLM routine. It performs Dual-Plane Risk Control, contrasting
Physical Disk UsageagainstVirtual Quota Use. It proactively suppresses scores for nodes that are "physical safe but virtually bankrupt", effectively defusing time bombs and preventing data bank runs. -
π‘οΈ Native kubernetes resource yaml configure support Support native Kubernetes YAML parameter configuration for ephemeral-storage and emptydir temporary storage configurations, and enforce hard quotas based on quota
Terminus consists of three micro-components working in harmony:
graph TD
User((User)) -->|resource.limits.ephemeral-storage: '10Gi'| API[K8s API Server]
subgraph Control Plane
API -->|Watch| Scheduler[Kube-Scheduler]
Scheduler -- Filter/Score --> Plugin[<b>Terminus-Scheduler</b>]
API -.->|Watch Nodes & Pods<br/>Informer Cache| Nexus[<b>Nexus AI Goroutine</b>]
Nexus -- "Dual-Plane Eval<br/>(Async)" --> LLM((LLM API))
LLM -- "Local Score Cache<br/>O(1) Lookup" --> Plugin
end
subgraph Worker Node
API -->|Schedule| Kubelet
Kubelet --> CRI[Containerd]
CRI -- Hook --> NRI[<b>Terminus-Enforcer</b>]
NRI -- Set Quota --> Kernel[Linux Kernel<br/>Project Quota]
Kernel -.-> Pod[Container Rootfs]
Agent[<b>Terminus-Exporter</b>] -- Watch Usage --> Kernel
end
classDef component fill:#f9f,stroke:#333,stroke-width:2px;
classDef ai fill:#ffe4e1,stroke:#ff69b4,stroke-width:2px;
class NRI,Plugin,Agent component;
class Nexus ai;
Before installing Terminus, ensure your environment meets the following requirements:
- Kubernetes: v1.24+ (Requires Containerd with NRI support enabled).
- Container Runtime: Containerd v1.7+.
- Filesystem: The backend filesystem for
/var/lib/containerdmust be XFS or Ext4 with Project Quota enabled (prjquotamount option).
Edit your /etc/containerd/config.toml to enable the NRI plugin:
[plugins."io.containerd.nri.v1.nri"]
disable = false
disable_connections = false
plugin_config_path = "/etc/nri/conf.d"
plugin_path = "/opt/nri/plugins"
socket_path = "/var/run/nri/nri.sock"
Restart containerd after editing.
helm repo add terminus https://terminus-io.github.io/Terminus
helm install terminus terminus/terminus --set scheduler.enable=true,scheduler.useAI=false,replaceEphemeralStorage.enabled=true --version 1.0.0 -n terminus --create-namespacehelm install terminus ./charts/terminus --set scheduler.enable=true,scheduler.useAI=true,scheduler.aiWeightRatio=50,scheduler.modelType=OPENAI,scheduler.modelName=gpt-3.5-turbo,scheduler.openAIAPIKey="sk-12345678123123123",scheduler.openAIAPIURL="https://api.openai.com/v1",replaceEphemeralStorage.enabled=true -n terminus --create-namespace# Install the RBAC
kubectl apply -f deploy/manifests/rbac.yaml
# Install the Scheduler Configmap
kubectl create cm -n terminus --from-file=deploy/manifests/terminus-scheduler-config.yaml
# Install the Node Agent (Enforcer & Exporter)
kubectl apply -f deploy/manifests/terminus-enforcer.yaml
# Install the Scheduler Plugin
kubectl apply -f deploy/manifests/terminus-scheduler.yaml
Simply add the storage.terminus.io/size or storage.terminus.io/size.${containerName} annotation to your Pod Or A specific container within a Pod. Terminus will automatically inject the Project Quota limit.
apiVersion: v1
kind: Pod
metadata:
name: my-app
annotations:
# Limit the Rootfs (Overlayfs) to 10Gi (Hard Limit)
storage.terminus.io/size: "10Gi"
storage.terminus.io/size.nginx: "5Gi"
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: 10m
ephemeral-storage: 10Gi
You can configure the Terminus-Scheduler via ConfigMap to set the over-provisioning strategy.
apiVersion: v1
kind: ConfigMap
metadata:
name: terminus-scheduler-config
namespace: terminus
data:
terminus-scheduler-config.yaml: |
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
leaderElection:
leaderElect: true
resourceName: terminus-scheduler
resourceNamespace: terminus
profiles:
- schedulerName: terminus-scheduler
plugins:
filter:
enabled:
- name: terminus-scheduler
score:
enabled:
- name: terminus-scheduler
weight: 1
pluginConfig:
- name: terminus-scheduler
args:
useAI: true
aiWeightRatio: 30 (default 30)
modelType: OPENAI
modelName: gpt-5
openAIAPIKey: ""
openAIAPIURL: https://api.openai.com/v1
oversubscriptionRatio: 1.5
-
v0.1 (MVP):
- NRI plugin implementation for XFS Project Quota.
- Prometheus Exporter & Grafana Dashboard integration.
- Scheduler Plugin with "Real Usage" awareness.
-
v0.2 (AI Scheduling Featrue):
- Enforcer Native Kernel Syscall via terminus-io/quota for zero-overhead enforcement.
- Nexus AI Scheduling Brain (Dual-Plane Risk Control).
-
v1.0 (Official Version):
- Supports native Kubernetes YAML configuration for ephemeral-storage limits (zero changes required, no additional annotations needed)
- Webhook automatically injects per-container quota
- Dual hard limits on rootfs + emptyDir (full coverage of temporary storage)
- Write operations exceeding quota trigger immediate ENOSPC β only the Pod dies, the node remains stable and never crashes
We welcome contributions! Please see CONTRIBUTING.md for details on how to submit a PR.
- Fork the repo.
- Create your feature branch (
git checkout -b feature/amazing-feature). - Commit your changes.
- Push to the branch.
- Open a Pull Request.
Distributed under the Apache 2.0 License. See LICENSE for more information.
