Create a Kubernetes explainer video
The output is an MP4 for a lecture: graphical, animated, almost no text, no subtitles.
Argument voiceover=on|off (default on). on narrates with the local Kokoro TTS voice; off makes a silent video and never installs or loads Kokoro.
Argument setup: install only, no video. Do the "Check the environment" step below, then stop.
Two folders. SKILL is the skill's base directory (the folder holding this file). It holds .venv/, icons/, references/ and scripts/. OUT is <the user's working directory>/<topic>, created per video. Scene file, media/ and the final MP4 live in OUT, never in SKILL (updating or removing the skill deletes SKILL). Use absolute paths; do not rely on the current directory.
What ships with this skill
icons/: the official Kubernetes community icons (labelled set, CC-BY-4.0). Use only these icons for Kubernetes components and resources. Never redraw, recolor into something else, or substitute a generic shape for a component that has an icon here. For concepts with no icon (CSR, certificate, packet, iptables rules), use simple shapes likeDocandPacketin the reference.references/node_join.py: a complete, approved example (kubeadm node join). Copy its style, palette and helper classes.references/kokoro_service.py: Kokoro-82M plugged into manim-voiceover.references/kit.py: shared palette, helpers and theExplainerbase scene plusvoiced(Scene). New scenes import from it.scripts/setup.sh [voiceover=on|off] [--yes]: reports what is missing and prints the install plan (macOS, Arch, Debian/Ubuntu); installs only with--yes.
| file | component | file | component | file | component |
|---|---|---|---|---|---|
| api | kube-apiserver | pod | Pod | cm | ConfigMap |
| etcd | etcd | rs | ReplicaSet | secret | Secret |
| sched | kube-scheduler | deploy | Deployment | pv | PersistentVolume |
| c-m | kube-controller-manager | sts | StatefulSet | pvc | PersistentVolumeClaim |
| c-c-m | cloud-controller-manager | ds | DaemonSet | sc | StorageClass |
| kubelet | kubelet | job | Job | ns | Namespace |
| k-proxy | kube-proxy | cronjob | CronJob | sa | ServiceAccount |
| control-plane | control plane node | svc | Service | role / c-role | Role / ClusterRole |
| node | worker node | ep | Endpoints | rb / crb | RoleBinding / ClusterRoleBinding |
| hpa | HorizontalPodAutoscaler | ing | Ingress | quota | ResourceQuota |
| crd | CustomResourceDefinition | netpol | NetworkPolicy | limits | LimitRange |
Manim drops the text baked into these SVGs, and api, c-m, sched, kubelet, k-proxy share the same gear glyph. Always label icons with the Icon(name, label) helper.
Workflow
1. Check the environment
Run bash SKILL/scripts/setup.sh voiceover=<on|off>. If it prints Ready., continue. Otherwise it printed what is missing and the plan (first run on this machine): show the plan to the user and ask before installing.
- On confirmation run it again with
--yes. It is slow (torch, system packages), so run it in the background or with a long timeout. - If the plan has a
sudoline you cannot type the password: give the user the command to run themselves (! bash SKILL/scripts/setup.sh voiceover=<on|off> --yes). - Kokoro is free, Apache-2.0 (fine for paid courses), offline and near-commercial quality; if the user does not want it, suggest
voiceover=off.
2. Agree the storyboard
Ask for the topic if it wasn't given. Then propose a storyboard in chat and wait for approval, because rendering takes minutes:
- 6–12 beats, each with: a 1–3 word step label, what moves on screen, one spoken sentence.
- Story told through motion: icons in boxes, packets on arcs, color changes for state. Only short labels on screen.
- Facts must be correct for the current Kubernetes version. If unsure about a detail, say so instead of guessing.
3. Write the scene
Model it on references/node_join.py:
- One
NARRATIONdict (beat → sentence) as a class attribute, one method per beat;Explainer.constructloops them insidewith self.voice(line). - Write
OUT/<topic>.pywithfrom references.kit import *, subclassExplainer, and add<Name>Voiced = voiced(<Name>)at the bottom. Beats aredef beat(self, i). The silent<Name>and the narrated<Name>Voicedcome from the same code. - Never name the scene file after a stdlib module (
operator.pybreaks Python's imports). - Reuse the palette (dark
#0b1220, k8s blue#326ce5, gold token, teal network, amber NotReady, green Ready) and the helpersIcon,Packet,Doc,Step,Pill,send. - Small classes, minimal code.
- Spell terms the way they're spoken in the narration: kubeadm → "kube admin", etcd → "et-cee-dee", kubectl → "kube control".
4. Preview, then render
Run manim as PYTHONPATH=SKILL SKILL/.venv/bin/manim --media_dir OUT/media ... from OUT.
- Preview:
... -ql <topic>.py <Name>, then extract ~8 frames with ffmpeg into one contact sheet and look at it once. Fix overlaps, clipped labels, and dim or unreadable text. - Render final:
... -qh <topic>.py <Name>whenvoiceover=off, or<Name>Voicedwhenvoiceover=on. CopyOUT/media/videos/<topic>/1080p60/<Name>.mp4toOUT/<topic>.mp4. - With
voiceover=on, confirm the MP4 has an audio stream (ffprobe). - Open the MP4 when you finish (
openon macOS;xdg-openon Linux, or if there is no display just print the path).
Report the absolute MP4 path, the duration, anything to listen for (pronunciation of unusual terms) and remind the user the icons need the credit "Kubernetes community icons, CC BY 4.0" (the outro already shows it). Voice options: af_heart (default), am_michael, am_fenrir; pass one as voiced(<Name>, voice="am_michael").