Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<div align="center">

# KERNO

Check warning on line 3 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (KERNO)

### The production incident diagnosis engine for Kubernetes

**Your cluster broke. Your dashboards are green. Users are paging.**
**Run `kerno doctor`. 30 seconds. Root cause. Plain English.**

Check warning on line 8 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (kerno)

<sub>Same single binary runs on bare metal, VMs, EC2, GCE - wherever Linux lives.</sub>

Expand All @@ -18,30 +18,30 @@

[**Quick Start**](#quick-start) · [**How It Works**](#how-it-works) · [**Features**](#features) · [**Kubernetes**](#kubernetes-deployment) · [**Docs**](docs/architecture.md)

<img src="demo.gif" alt="kerno doctor demo" width="900" />

Check warning on line 21 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (kerno)

</div>

---

## What is Kerno?

Check warning on line 27 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (Kerno)

Kerno is a **Kubernetes-native incident diagnosis engine** built on eBPF.

Check warning on line 29 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (Kerno)
It runs as a DaemonSet on every node, watches the kernel - not your app - and answers a single question on demand:

> *Why is production broken right now?*

```bash
kubectl -n kerno-system exec ds/kerno -- kerno doctor

Check warning on line 35 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (kerno)

Check warning on line 35 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (kerno)

Check warning on line 35 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (kerno)
```

30 seconds later you get a ranked diagnostic report with **plain-English causes, evidence, ETAs, and copy-paste fix steps** - no dashboards to wire, no query language to learn, no agents in your app.

The kernel knows minutes before your APM. Hours before your users. Kerno makes that visible.

Check warning on line 40 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (Kerno)

**Same binary outside Kubernetes too.** `curl | bash` it onto any bare-metal box, EC2 instance, or systemd VM and `sudo kerno doctor` works exactly the same.

## Why Kerno?

Check warning on line 44 in README.md

View workflow job for this annotation

GitHub Actions / Spell check

Unknown word (Kerno)

It's 3am. PagerDuty fires. Latency is up, error budget is burning, and every dashboard you own is **green**.

Expand Down Expand Up @@ -233,6 +233,7 @@
- Runs with the **minimum capabilities needed** - `CAP_BPF`, `CAP_PERFMON`, `CAP_SYS_PTRACE`, `CAP_NET_ADMIN`, `CAP_DAC_READ_SEARCH` (not `CAP_SYS_ADMIN` for the hot path).
- Read-only root filesystem, `ProtectSystem=strict` via systemd on bare metal.
- No outbound network calls. AI integration is opt-in and goes through your configured provider only.
- **Opt-in NetworkPolicy**: Limit metrics ingress to Prometheus pods, and allow DNS, K8s API server, and Kubelet egress. (Note: Since Kerno runs with `hostNetwork: true`, standard `NetworkPolicy` resources do not enforce restrictions on it in most mainstream CNIs without host-firewall configuration). See [Helm README](deploy/helm/kerno/README.md).

### Helm values

Expand All @@ -253,6 +254,9 @@
enabled: true
interval: 15s

networkPolicy:
enabled: false

nodeSelector:
monitoring: "true"
```
Expand Down
19 changes: 19 additions & 0 deletions deploy/helm/kerno/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Kerno Helm Chart

Deploys Kerno as a DaemonSet.

## Installation

```bash
helm install kerno ./deploy/helm/kerno -n kerno-system --create-namespace
```

## Hardening

Set `networkPolicy.enabled=true` to enable the NetworkPolicy.

> [!WARNING]
> Since Kerno runs with `hostNetwork: true`, standard Kubernetes `NetworkPolicy` resources are not enforced on it by most mainstream CNIs (like Cilium or Calico) without host-endpoint or host-firewall configuration.
>
> If `networkPolicy.enabled` is set to `true`, egress to the Kubernetes API server and Kubelet is blocked by default unless their specific IP CIDR blocks are configured via `networkPolicy.k8sApiServer.cidrs` and `networkPolicy.kubelet.cidrs` respectively.

77 changes: 77 additions & 0 deletions deploy/helm/kerno/templates/networkpolicy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
{{- if .Values.networkPolicy.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: kerno
namespace: {{ .Release.Namespace }}
labels:
{{- include "kerno.labels" . | nindent 4 }}
spec:
podSelector:
Comment thread
bhavyanjain3004 marked this conversation as resolved.
matchLabels:
{{- include "kerno.selectorLabels" . | nindent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
- ports:
- protocol: TCP
port: {{ .Values.prometheus.port }}
{{- if or .Values.networkPolicy.prometheus.namespaceSelector .Values.networkPolicy.prometheus.podSelector }}
from:
{{- if .Values.networkPolicy.prometheus.namespaceSelector }}
- namespaceSelector:
{{- toYaml .Values.networkPolicy.prometheus.namespaceSelector | nindent 12 }}
{{- if .Values.networkPolicy.prometheus.podSelector }}
podSelector:
{{- toYaml .Values.networkPolicy.prometheus.podSelector | nindent 12 }}
{{- end }}
{{- else if .Values.networkPolicy.prometheus.podSelector }}
- podSelector:
{{- toYaml .Values.networkPolicy.prometheus.podSelector | nindent 12 }}
{{- end }}
{{- end }}
{{- if .Values.networkPolicy.additionalIngress }}
{{- toYaml .Values.networkPolicy.additionalIngress | nindent 4 }}
{{- end }}
egress:
- ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
{{- if .Values.networkPolicy.k8sApiServer.cidrs }}
- ports:
{{- range .Values.networkPolicy.k8sApiServer.ports }}
- protocol: TCP
port: {{ . }}
{{- end }}
to:
{{- range .Values.networkPolicy.k8sApiServer.cidrs }}
- ipBlock:
cidr: {{ . }}
{{- end }}
{{- end }}
{{- if .Values.networkPolicy.kubelet.cidrs }}
- ports:
{{- range .Values.networkPolicy.kubelet.ports }}
- protocol: TCP
port: {{ . }}
{{- end }}
to:
{{- range .Values.networkPolicy.kubelet.cidrs }}
- ipBlock:
cidr: {{ . }}
{{- end }}
{{- end }}
{{- if .Values.networkPolicy.additionalEgress }}
{{- toYaml .Values.networkPolicy.additionalEgress | nindent 4 }}
{{- end }}
{{- end }}
28 changes: 28 additions & 0 deletions deploy/helm/kerno/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,31 @@ securityContext:
# Host path prefix — Kerno mounts host paths under /host/ to avoid conflicts.
# All pollers read from /host/proc, /host/sys/fs/cgroup, etc.
hostPathPrefix: /host

# NetworkPolicy configuration.
# NOTE: Since Kerno runs with 'hostNetwork: true', standard NetworkPolicies
# do not restrict its traffic in most CNIs without host-firewall configuration.
networkPolicy:
enabled: false
prometheus:
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app.kubernetes.io/name: prometheus
k8sApiServer:
ports:
- 443
- 6443
# Target API server CIDRs. If empty, egress is blocked by default.
cidrs: []
kubelet:
ports:
- 10250
- 10255
# Target Kubelet CIDRs. If empty, egress is blocked by default.
cidrs: []
additionalIngress: []
additionalEgress: []

Loading