π A modern, pretty TUI for Kubernetes, tuned for AI Hyperscaler clusters.
Built with Go + Bubble Tea.
- Drill-Down Navigation: Press
Enteron any pod to view its containers, then drill into container logs with full text wrapping and search - Paginated Tables: Browse pods, nodes, and namespaces with configurable page sizes
- Vim Keybindings: Navigate efficiently with
j/k,h/l,g/G, and command mode with: - Command Mode: Type
:to enter command mode, then use commands likepods,nodes,ns, orquit - Log Viewing: View container logs with timestamps, text wrapping (
w), autoscroll (s), and fullscreen mode (f) - Customizable: Configure page sizes and UI elements via
~/.k10s.conf - Fast & Lightweight: Built in Go with minimal dependencies
git clone https://github.com/shvbsle/k10s.git
cd k10s
make buildThe binary will be available at bin/k10s.
Once releases are published:
brew tap shvbsle/tap
brew install k10sgo install github.com/shvbsle/k10s/cmd/k10s@latest
k10s# Run directly
bin/k10s
# Or use make
make runjorβ: Move down in the tablekorβ: Move up in the tablehorβorPgUp: Previous pagelorβorPgDown: Next pageg: Jump to top of tableG: Jump to bottom of tableEnter: Drill down into selected resource (pod β containers β logs)Esc: Go back to previous view:: Enter command mode:quitor:q: Quit k10s
When viewing container logs:
w: Toggle text wrappingt: Toggle timestampss: Toggle autoscrollf: Toggle fullscreen modeEsc: Go back to container list
- Type a command and press
Enterto execute - Press
Escto cancel and return to normal mode
When in command mode (press :), you can use:
podsorpo: Show all pods across all namespacespods <namespace>: Show pods in specific namespacenodesorno: Show all nodes in the clusternamespacesorns: Show all namespacesservicesorsvc: Show all servicesquitorq: Exit k10s
k10s reads configuration from ~/.k10s.conf. On first run, a default config file is created automatically.
# k10s configuration file
# Number of items per page in table views
page_size=20
# Pagination style: "bubbles" (dots) or "verbose" (text like "Page 1/10")
# Default: bubbles
pagination_style=bubbles
# ASCII logo (between logo_start and logo_end)
logo_start
/\_/\
( o.o )
> Y <
logo_end
page_size: Number of rows to display per page (default: 20)pagination_style: Pagination display style -bubblesfor dot-based paginator orverbosefor text like "Page 1/10" (default: bubbles)logo_start/logo_end: Custom ASCII art logo to display
k10s features a built-in extensible plugin system that allows adding custom functionality like games, tools, or utilities. The plugin architecture is a core k10s feature designed to enable seamless integration of additional commands while maintaining isolation between plugins and the core system.
A fun infinite runner platformer game! Try typing :play, :game, or :kitten to launch it.
Features:
- Infinite procedural platform generation
- Pattern-based fish collectibles with combo system
- High score persistence (stored in
~/.k10s/plugins/kitten/highscores.json) - Space theme with stars
- Progressive difficulty scaling
Plugins are compiled into k10s and implement a simple interface. Here's how to create one:
mkdir -p internal/plugins/mypluginCreate internal/plugins/myplugin/myplugin.go:
package myplugin
import "github.com/shvbsle/k10s/internal/plugins"
type MyPlugin struct{}
func (p *MyPlugin) Name() string {
return "my-plugin"
}
func (p *MyPlugin) Description() string {
return "A description of what my plugin does"
}
func (p *MyPlugin) Commands() []string {
return []string{"myplugin", "mp"} // Command aliases
}
func (p *MyPlugin) Launch() error {
// Your plugin logic here
fmt.Println("Hello from my plugin!")
return nil
}
func New() *MyPlugin {
return &MyPlugin{}
}In cmd/k10s/main.go, import and register your plugin:
import (
// ... existing imports ...
"github.com/shvbsle/k10s/internal/plugins/myplugin"
)
func main() {
// ... existing setup ...
// Initialize plugin registry
pluginRegistry := plugins.NewRegistry()
pluginRegistry.Register(kitten.New())
pluginRegistry.Register(myplugin.New()) // Add your plugin
// ... rest of main ...
}make build
./bin/k10s
# Type :myplugin to launch your pluginSee the Plugin interface definition for the complete API with documentation.
Plugins implement:
Name()- Unique identifier (kebab-case)Description()- Shown in help textCommands()- Command aliases (e.g., ["play", "game"])Launch()- Execute plugin, returns to k10s on exit
- Commands: Use short, memorable command aliases (e.g.,
play,debug,tool) - Error Handling: Handle errors gracefully within your plugin
- Dependencies: Add any required dependencies to
go.mod - Data Storage: Store plugin data in isolated directories to avoid cross-contamination
- Use
config.GetPluginDataDir(pluginName)to get your plugin's data directory - Path format:
~/.k10s/plugins/{plugin-name}/ - Each plugin gets its own isolated directory automatically created
- Example: High scores for kitten are stored in
~/.k10s/plugins/kitten/highscores.json
- Use
For TUI-based plugins using Bubble Tea:
func (p *MyPlugin) Launch() error {
program := tea.NewProgram(myModel{})
if _, err := program.Run(); err != nil {
return fmt.Errorf("error running plugin: %w", err)
}
return nil // Return to k10s after plugin exits
}For more details, see internal/plugins/README.md.
- Go 1.24 or later
- Access to a Kubernetes cluster (via
~/.kube/configor in-cluster config)
make buildmake runmake testmake lintmake fmtContributions are welcome! Please feel free to submit a Pull Request.
See RELEASING.md for detailed instructions on creating releases.
Apache 2.0 - see LICENSE file for details
