Need help with k9s?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

13.8K Stars 836 Forks Other 1.2K Commits 205 Opened issues


🐶 Kubernetes CLI To Manage Your Clusters In Style!

Services available


Need anything else?

Contributors list


K9s - Kubernetes CLI To Manage Your Clusters In Style!

K9s provides a terminal UI to interact with your Kubernetes clusters. The aim of this project is to make it easier to navigate, observe and manage your applications in the wild. K9s continually watches Kubernetes for changes and offers subsequent commands to interact with your observed resources.


As you may know k9s is not pimped out by a big corporation with deep pockets. It is a complex OSS project that demands a lot of my time to maintain and support. K9s will always remain OSS and therefore free! That said if you feel, k9s makes your day to day Kubernetes journey a tad brighter, please consider sponsoring us or purchase a K9sAlpha license. Your donations will go a long way in keeping our servers lights on and beers in our fridge!

Thank you!

Go Report Card golangci badge codebeat badge Build Status Docker Repository on Quay release License Releases


Please refer to our K9s documentation site for installation, usage, customization and tips.

Slack Channel

Wanna discuss K9s features with your fellow

or simply show your support for this tool?


K9s is available on Linux, macOS and Windows platforms.

  • Binaries for Linux, Windows and Mac are available as tarballs in the release page.

  • Via Homebrew for macOS or LinuxBrew for Linux

   brew install k9s
   sudo port install k9s
  • On Arch Linux
  pacman -S k9s
  • On OpenSUSE Linux distribution
  zypper install k9s
  scoop install k9s
  choco install k9s
  • Via a GO install
  # NOTE: The dev version will be in effect!
  go get -u
  • Via Webi for Linux and macOS
  curl -sS | bash
  • Via Webi for Windows
  curl.exe -A MS | powershell

Building From Source

K9s is currently using go v1.14 or above. In order to build K9s from source you must:

  1. Clone the repo
  2. Build and run the executable

      make build && ./execs/k9s

Running with Docker

Running the official Docker image

You can run k9s as a Docker container by mounting your

  docker run --rm -it -v $KUBECONFIG:/root/.kube/config

For default path it would be:

  docker run --rm -it -v ~/.kube/config:/root/.kube/config

Building your own Docker image

You can build your own Docker image of k9s from the Dockerfile with the following:

  docker build -t k9s-docker:0.1 .

You can get the latest stable

version and pass it to the
docker build
command with the
option. You can use the
option to pass any valid
version (like
  KUBECTL_VERSION=$(make kubectl-stable-version 2>/dev/null)
  docker build --build-arg KUBECTL_VERSION=${KUBECTL_VERSION} -t k9s-docker:0.1 .

Run your container:

  docker run --rm -it -v ~/.kube/config:/root/.kube/config k9s-docker:0.1

PreFlight Checks

  • K9s uses 256 colors terminal mode. On `Nix system make sure TERM is set accordingly.

    export TERM=xterm-256color
  • In order to issue manifest edit commands make sure your EDITOR env is set.

    # Kubectl edit command will use this env var.
    export EDITOR=my_fav_editor
    # Should your editor deals with streamed vs on disk files differently, also set...
    export K9S_EDITOR=my_fav_editor
  • K9s prefers recent kubernetes versions ie 1.16+

The Command Line

# List all available CLI options
k9s help
# To get info about K9s runtime (logs, configs, etc..)
k9s info
# To run K9s in a given namespace
k9s -n mycoolns
# Start K9s in an existing KubeConfig context
k9s --context coolCtx
# Start K9s in readonly mode - with all cluster modification commands disabled
k9s --readonly


Given the nature of the ui k9s does produce logs to a specific location. To view the logs and turn on debug mode, use the following commands:

k9s info
# Will produces something like this
#  ____  __.________
# |    |/ _/   __   \______
# |      < \____    /  ___/
# |    |  \   /    /\___ \
# |____|__ \ /____//____  >
#         \/            \/
# Configuration:   ~/Library/Preferences/k9s/config.yml
# Logs:            /var/folders/8c/hh6rqbgs5nx_c_8k9_17ghfh0000gn/T/k9s-fernand.log
# Screen Dumps:    /var/folders/8c/hh6rqbgs5nx_c_8k9_17ghfh0000gn/T/k9s-screens-fernand

To view k9s logs

tail -f /var/folders/8c/hh6rqbgs5nx_c_8k9_17ghfh0000gn/T/k9s-fernand.log

Start K9s in debug mode

k9s -l debug

Key Bindings

K9s uses aliases to navigate most K8s resources.

| Action | Command | Comment | |----------------------------------------------------------------|-------------------------------|------------------------------------------------------------------------| | Show active keyboard mnemonics and help |

| | | Show all available resource alias |
| | | To bail out of K9s |
| | | View a Kubernetes resource using singular/plural or short-name |
po⏎ | accepts singular, plural, short-name or alias ie pod or pods | | View a Kubernetes resource in a given namespace |
alias namespace⏎ | | | Filter out a resource view given a filter |
filter⏎ | Regex2 supported ie
to filter resources named fred or blee | | Inverse regex filter |
! filter⏎ | Keep everything that doesn't match. | | Filter resource view by labels |
-l label-selector⏎ | | | Fuzzy find a resource given a filter |
-f filter⏎ | | | Bails out of view/command/filter mode |
                       |                                                                        |
| Key mapping to describe, view, edit, view logs,...             | 
,... | | | To view and switch to another Kubernetes context |
ctx⏎ | | | To view and switch to another Kubernetes context |
ctx context-name⏎ | | | To view and switch to another Kubernetes namespace |
ns⏎ | | | To view all saved resources |
screendump or sd⏎ | | | To delete a resource (TAB and ENTER to confirm) |
| | | To kill a resource (no confirmation dialog!) |
| | | Launch pulses view |
pulses or pu⏎ | | | Launch XRay view |
xray RESOURCE [NAMESPACE]⏎ | RESOURCE can be one of po, svc, dp, rs, sts, ds, NAMESPACE is optional | | Launch Popeye view |
popeye or pop⏎ | See popeye |


  1. Pods
  2. Logs
  3. Deployments

Demo Videos/Recordings

K9s Configuration

K9s keeps its configurations inside of a

directory and the location depends on your operating system. K9s leverages XDG to load its various configurations files.

| Unix | macOS | Windows | |-----------------|-----------------------------|-----------------------| |


NOTE: This is still in flux and will change while in pre-release stage!

  # $XDG_CONFIG_HOME/k9s/config.yml
    # Represents ui poll intervals. Default 2secs
    refreshRate: 2
    # Number of retries once the connection to the api-server is lost. Default 15.
    maxConnRetry: 5
    # Enable mouse support. Default false
    enableMouse: true
    # Set to true to hide K9s header. Default false
    headless: false
    # Set to true to hide K9s crumbs. Default false
    crumbsless: false
    # Indicates whether modification commands like delete/kill/edit are disabled. Default is false
    readOnly: false
    # Toggles icons display as not all terminal support these chars.
    noIcons: false
    # Logs configuration
      # Defines the number of lines to return. Default 100
      tail: 200
      # Defines the total number of log lines to allow in the view. Default 1000
      buffer: 500
      # Represents how far to go back in the log timeline in seconds. Setting to -1 will show all available logs. Default is 5min.
      sinceSeconds: 300
      # Go full screen while displaying logs. Default false
      fullScreenLogs: false
      # Toggles log line wrap. Default false
      textWrap: false
      # Toggles log line timestamp info. Default false
      showTime: false
    # Indicates the current kube context. Defaults to current context
    currentContext: minikube
    # Indicates the current kube cluster. Defaults to current context cluster
    currentCluster: minikube
    # Persists per cluster preferences for favorite namespaces and view.
          active: coolio
          - cassandra
          - default
          active: po
          # Toggles NodeShell support. Allow K9s to shell into nodes if needed. Default false.
          nodeShell: false
        # Provide shell pod customization of feature gate is enabled
          # The shell pod image to use.
          image: killerAdmin
          # The namespace to launch to shell pod into.
          namespace: fred
          # The resource limit to set on the shell pod.
            cpu: 100m
            memory: 100Mi
        # The IP Address to use when launching a port-forward.
          active: all
          - all
          - kube-system
          - default
          active: dp

Popeye Configuration

K9s has integration with Popeye, which is a Kubernetes cluster sanitizer. Popeye itself uses a configuration called

, but when integrating with K9s the cluster-specific file should be name
. This allows you to have a different spinach config per cluster.

Node Shell

By enabling the nodeShell feature gate on a given cluster, K9s allows you to shell into your cluster nodes. Once enabled, you will have a new

menu option while in node view. K9s will launch a pod on the selected node using a special k9s_shell pod. Furthermore, you can refine your shell pod by using a custom docker image preloaded with the shell tools you love. By default k9s uses a BusyBox image, but you can configure it as follows:
# $XDG_CONFIG_HOME/k9s/config.yml
    # Configures node shell on cluster blee
        # You must enable the nodeShell feature gate to enable shelling into nodes
        nodeShell: true
      # You can also further tune the shell pod specification
        image: cool_kid_admin:42
        namespace: blee
          cpu: 100m
          memory: 100Mi

Command Aliases

In K9s, you can define your very own command aliases (shortnames) to access your resources. In your

define a file called
. A K9s alias defines pairs of alias:gvr. A gvr (Group/Version/Resource) represents a fully qualified Kubernetes resource identifier. Here is an example of an alias file:
# $XDG_CONFIG_HOME/k9s/alias.yml
  pp: v1/pods

Using this alias file, you can now type pp/crb to list pods or ClusterRoleBindings respectively.

HotKey Support

Entering the command mode and typing a resource name or alias, could be cumbersome for navigating thru often used resources. We're introducing hotkeys that allows a user to define their own hotkeys to activate their favorite resource views. In order to enable hotkeys please follow these steps:

  1. Create a file named
  2. Add the following to your

    . You can use resource name/short name to specify a command ie same as typing it while in command mode.
      # $XDG_CONFIG_HOME/k9s/hotkey.yml
        # Hitting Shift-0 navigates to your pod view
          shortCut:    Shift-0
          description: Viewing pods
          command:     pods
        # Hitting Shift-1 navigates to your deployments
          shortCut:    Shift-1
          description: View deployments
          command:     dp
        # Hitting Shift-2 navigates to your xray deployments
          shortCut:    Shift-2
          description: Xray Deployments
          command:     xray deploy

Not feeling so hot? Your custom hotkeys will be listed in the help view

. Also your hotkey file will be automatically reloaded so you can readily use your hotkeys as you define them.

You can choose any keyboard shortcuts that make sense to you, provided they are not part of the standard K9s shortcuts list.

NOTE: This feature/configuration might change in future releases!

Resource Custom Columns

SneakCast v0.17.0 on The Beach! - Yup! sound is sucking but what a setting!

You can change which columns shows up for a given resource via custom views. To surface this feature, you will need to create a new configuration file, namely

. This file leverages GVR (Group/Version/Resource) to configure the associated table view columns. If no GVR is found for a view the default rendering will take over (ie what we have now). Going wide will add all the remaining columns that are available on the given resource after your custom columns. To boot, you can edit your views config file and tune your resources views live!

NOTE: This is experimental and will most likely change as we iron this out!

Here is a sample views configuration that customize a pods and services views.

# $XDG_CONFIG_HOME/k9s/views.yml
        - AGE
        - NAMESPACE
        - NAME
        - IP
        - NODE
        - STATUS
        - READY
        - AGE
        - NAMESPACE
        - NAME
        - TYPE
        - CLUSTER-IP


K9s allows you to extend your command line and tooling by defining your very own cluster commands via plugins. K9s will look at

to locate all available plugins. A plugin is defined as follows:
  • Shortcut option represents the key combination a user would type to activate the plugin
  • Confirm option (when enabled) lets you see the command that is going to be executed and gives you an option to confirm or prevent execution
  • Description will be printed next to the shortcut in the k9s menu
  • Scopes defines a collection of resources names/short-names for the views associated with the plugin. You can specify
    to provide this shortcut for all views.
  • Command represents ad-hoc commands the plugin runs upon activation
  • Background specifies whether or not the command runs in the background
  • Args specifies the various arguments that should apply to the command above

K9s does provide additional environment variables for you to customize your plugins arguments. Currently, the available environment variables are as follows:

    -- the selected resource group
    -- the selected resource api version
    -- the selected resource name
    -- the selected resource namespace
  • $NAME
    -- the selected resource name
    -- the current container if applicable
    -- the current filter if any
    -- the KubeConfig location.
    the active cluster name
    the active context name
  • $USER
    the active user
    the active groups
  • $POD
    while in a container view
  • $COL-
    use a given column name for a viewed resource. Must be prefixed by


This defines a plugin for viewing logs on a selected pod using

for shortcut.
# $XDG_CONFIG_HOME/k9s/plugin.yml
  # Defines a plugin to provide a `ctrl-l` shortcut to tail the logs while in pod view.
    shortCut: Ctrl-L
    confirm: false
    description: Pod logs
    - pods
    command: kubectl
    background: false
    - logs
    - -f
    - $NAME
    - -n
    - --context
    - $CONTEXT

NOTE: This is an experimental feature! Options and layout may change in future K9s releases as this feature solidifies.

Benchmark Your Applications

K9s integrates Hey from the brilliant and super talented Jaana Dogan.

is a CLI tool to benchmark HTTP endpoints similar to AB bench. This preliminary feature currently supports benchmarking port-forwards and services (Read the paint on this is way fresh!).

To setup a port-forward, you will need to navigate to the PodView, select a pod and a container that exposes a given port. Using

a dialog comes up to allow you to specify a local port to forward. Once acknowledged, you can navigate to the PortForward view (alias
) listing out your active port-forwards. Selecting a port-forward and using
will run a benchmark on that HTTP endpoint. To view the results of your benchmark runs, go to the Benchmarks view (alias
). You should now be able to select a benchmark and view the run stats details by pressing
. NOTE: Port-forwards only last for the duration of the K9s session and will be terminated upon exit.

Initially, the benchmarks will run with the following defaults:

  • Concurrency Level: 1
  • Number of Requests: 200
  • HTTP Verb: GET
  • Path: /

The PortForward view is backed by a new K9s config file namely:

(note: extension is
and not
). Each cluster you connect to will have its own bench config file, containing the name of the K8s context for the cluster. Changes to this file should automatically update the PortForward view to indicate how you want to run your benchmarks.

Here is a sample benchmarks.yml configuration. Please keep in mind this file will likely change in subsequent releases!

# This file resides in $XDG_CONFIG_HOME/k9s/bench-mycontext.yml
  # Indicates the default concurrency and number of requests setting if a container or service rule does not match.
    # One concurrent connection
    concurrency: 1
    # Number of requests that will be sent to an endpoint
    requests: 500
    # Containers section allows you to configure your http container's endpoints and benchmarking settings.
    # NOTE: the container ID syntax uses namespace/pod-name:container-name
      # Benchmark a container named nginx using POST HTTP verb using http://localhost:port/bozo URL and headers.
      concurrency: 1
      requests: 10000
        path: /bozo
        method: POST
            - text/html
            - application/json
    # Similarly you can Benchmark an HTTP service exposed either via NodePort, LoadBalancer types.
    # Service ID is ns/svc-name
      # Set the concurrency level
      concurrency: 5
      # Number of requests to be sent
      requests: 500
        method: GET
        # This setting will depend on whether service is NodePort or LoadBalancer. NodePort may require vendor port tunneling setting.
        # Set this to a node if NodePort or LB if applicable. IP or dns name.
        host: A.B.C.D
        path: /bumblebeetuna
        user: jean-baptiste-emmanuel
        password: Zorg!


On RBAC enabled clusters, you would need to give your users/groups capabilities so that they can use K9s to explore their Kubernetes cluster. K9s needs minimally read privileges at both the cluster and namespace level to display resources and metrics.

These rules below are just suggestions. You will need to customize them based on your environment policies. If you need to edit/delete resources extra Fu will be necessary.

NOTE! Cluster/Namespace access may change in the future as K9s evolves. NOTE! We expect K9s to keep running even in atrophied clusters/namespaces. Please file issues if this is not the case!

Cluster RBAC scope

# K9s Reader ClusterRole
kind: ClusterRole
  name: k9s
  # Grants RO access to cluster resources node and namespace
  - apiGroups: [""]
    resources: ["nodes", "namespaces"]
    verbs: ["get", "list", "watch"]
  # Grants RO access to RBAC resources
  - apiGroups: [""]
    resources: ["clusterroles", "roles", "clusterrolebindings", "rolebindings"]
    verbs: ["get", "list", "watch"]
  # Grants RO access to CRD resources
  - apiGroups: [""]
    resources: ["customresourcedefinitions"]
    verbs: ["get", "list", "watch"]
  # Grants RO access to metric server (if present)
  - apiGroups: [""]
    resources: ["nodes", "pods"]
    verbs: ["get", "list", "watch"]

Sample K9s user ClusterRoleBinding

apiVersion: kind: ClusterRoleBinding metadata: name: k9s subjects:

  • kind: User name: fernand apiGroup: roleRef: kind: ClusterRole name: k9s apiGroup:

Namespace RBAC scope

If your users are constrained to certain namespaces, K9s will need to following role to enable read access to namespaced resources.

# K9s Reader Role (default namespace)
kind: Role
  name: k9s
  namespace: default
  # Grants RO access to most namespaced resources
  - apiGroups: ["", "apps", "autoscaling", "batch", "extensions"]
    resources: ["*"]
    verbs: ["get", "list", "watch"]
  # Grants RO access to metric server
  - apiGroups: [""]
    resources: ["pods", "nodes"]
      - get
      - list
      - watch

Sample K9s user RoleBinding

apiVersion: kind: RoleBinding metadata: name: k9s namespace: default subjects:

  • kind: User name: fernand apiGroup: roleRef: kind: Role name: k9s apiGroup:


Example: Dracula Skin ;)

Dracula Skin

You can style K9s based on your own sense of look and style. Skins are YAML files, that enable a user to change the K9s presentation layer. K9s skins are loaded from

. If a skin file is detected then the skin would be loaded if not the current stock skin remains in effect.

You can also change K9s skins based on the cluster you are connecting too. In this case, you can specify the skin file name as

Below is a sample skin file, more skins are available in the skins directory in this repo, just simply copy any of these in your user's home dir as

Colors can be defined by name or using a hex representation. Of recent, we've added a color named

to indicate a transparent background color to preserve your terminal background color settings if so desired.

NOTE: This is very much an experimental feature at this time, more will be added/modified if this feature has legs so thread accordingly!

NOTE: Please see K9s Skins for a list of available colors.

# Skin InTheNavy...
  # General K9s styles
    fgColor: dodgerblue
    bgColor: '#ffffff'
    logoColor: '#0000ff'
  # ClusterInfoView styles.
    fgColor: lightskyblue
    sectionColor: steelblue
  # Help panel styles
    fgColor: white
    bgColor: black
    keyColor: cyan
    numKeyColor: blue
    sectionColor: gray
    # Borders styles.
      fgColor: dodgerblue
      focusColor: aliceblue
    # MenuView attributes and styles.
      fgColor: darkblue
      keyColor: cornflowerblue
      # Used for favorite namespaces
      numKeyColor: cadetblue
    # CrumbView attributes for history navigation.
      fgColor: white
      bgColor: steelblue
      activeColor: skyblue
    # Resource status and update styles
      newColor: '#00ff00'
      modifyColor: powderblue
      addColor: lightskyblue
      errorColor: indianred
      highlightcolor: royalblue
      killColor: slategray
      completedColor: gray
    # Border title styles.
      fgColor: aqua
      bgColor: white
      highlightColor: skyblue
      counterColor: slateblue
      filterColor: slategray
    # TableView attributes.
      fgColor: blue
      bgColor: darkblue
      cursorColor: aqua
      # Header row styles.
        fgColor: white
        bgColor: darkblue
        sorterColor: orange
    # YAML info styles.
      keyColor: steelblue
      colonColor: blue
      valueColor: royalblue
    # Logs styles.
      fgColor: white
      bgColor: black


Without the contributions from these fine folks, this project would be a total dud!

Known Issues

This is still work in progress! If something is broken or there's a feature that you want, please file an issue and if so inclined submit a PR!

K9s will most likely blow up if...

  1. You're running older versions of Kubernetes. K9s works best on Kubernetes latest.
  2. You don't have enough RBAC fu to manage your cluster.

ATTA Girls/Boys!

K9s sits on top of many open source projects and libraries. Our sincere appreciations to all the OSS contributors that work nights and weekends to make this project a reality!

Meet The Core Team!

We always enjoy hearing from folks who benefit from our work!

Contributions Guideline

  • File an issue first prior to submitting a PR!
  • Ensure all exported items are properly commented
  • If applicable, submit a test suite against your PR

Imhotep  © 2020 Imhotep Software LLC. All materials licensed under Apache v2.0

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.