kubed-sh

GitHub release GitHub issues Go Report Card

Welcome to kubed-sh, the Kubernetes distributed shell for the casual cluster user. In a nutshell, kubed-sh lets you execute a program in a Kubernetes cluster without having to create a container image or learn new concepts. For example, let’s say you have a Node.js script called test.js and you want to launch it as a containerized app in your Kubernetes cluster, here’s what you’d need to do in kubed-sh:

[minikube::default]$ node test.js &
[minikube::default]$ ps
DPID                          SOURCE      URL
kubed-sh-1517679562543558000  test.js     test

Looks familiar to what you do in your local shell? That’s the point of kubed-sh :)

See it in action, below or try it out in your browser using this Katacoda scenario:

Introducing kubed-sh kubed-sh hot-reload feature demo
Introducing kubed-sh (5 min) kubed-sh hot-reload feature demo (3 min)

In addition to launching (Linux ELF) binaries directly, the following interpreted environments are currently supported:

Note that kubed-sh is a proper shell environment. This means you can expect features such as auto-complete of built-in commands, history operations (CTRL+R), or clearing the screen (CTRL+L) to work as per usual.

Use cases

If you have access to a Kubernetes cluster and you have kubectl installed, you’re good to go. You might want to consider using kubed-sh, for example for:

Also, you may be interested in my motivation for writing kubed-sh?

Install it

No matter if you’re using the binaries below or if you build it from source, the following two prerequisites must be met:

  1. kubectl must be installed, tested with client version 1.9.1 so far.
  2. Access to a Kubernetes cluster must be configured (tested with 1.7 and 1.8 clusters so far). To verify this, you can use the following two steps:
    • if you do ls ~/.kube/config > /dev/null && echo $? and you see a 0 as a result, you’re good, and further
    • if you do kubectl config get-contexts | wc -l and see a number greater than 0, then that’s super dope.

Download binaries

Currently, only binaries for Linux and macOS are provided. Do the following to install kubed-sh on your machine.

For Linux:

$ curl -s -L https://github.com/mhausenblas/kubed-sh/releases/download/0.5.1/kubed-sh-linux -o kubed-sh
$ chmod +x kubed-sh
$ sudo mv kubed-sh /usr/local/bin

For macOS:

$ curl -s -L https://github.com/mhausenblas/kubed-sh/releases/download/0.5.1/kubed-sh-macos -o kubed-sh
$ chmod +x kubed-sh
$ sudo mv kubed-sh /usr/local/bin

Build from source

You need Go in order to build kubed-sh. I’m using go1.9.2 darwin/amd64 on my machine. To build kubed-sh from source, do the following:

$ go get github.com/mhausenblas/kubed-sh

Note that if your $GOPATH/bin is in your $PATH then now you can use kubed-sh from everywhere. If not, you can:

Use it

Once you’ve kubed-sh installed, launch it and you should find yourself in an interactive shell:

$ kubed-sh
Note: It seems you're running kubed-sh in a non-Linux environment (detected: darwin),
so make sure the binaries you launch are Linux binaries in ELF format.

Detected Kubernetes client in version v1.9.1 and server in version v1.8.0

[minikube::default]$

Above, you notice that on start-up kubed-sh will tell you which client and server version of Kubernetes it has detected and at any point in time you are able to tell in which context (minikube here) and namespace (default here) you’re operating.

Built-in commands

Supported built-in commands (see also help) are as follows:

cat (local):
                        output content of file to terminal
cd (local):
                        change working directory
curl (cluster):
                        execute a curl operation in the cluster
contexts (local):
                        list available Kubernetes contexts (cluster, namespace, user tuples)
echo (local):
                        print a value or environment variable
env (local):
                        list all environment variables currently defined
exit (local):
                        leave shell
help (local):
                        list built-in commands; use help command for more details
kill (cluster):
                        stop a distributed process
literally (local):
                        execute what follows as a kubectl command
                        note that you can also prefix a line with ` to achieve the same
ls (local):
                        lists content of directory
ps (cluster):
                        list all distributed (long-running) processes in current context
pwd (local):
                        print current working directory
sleep (local):
                        sleep for specified time interval (NOP)
use (local):
                        select a certain context to work with

Modes

You can use kubed-sh either interactively or in script mode. In script mode, you provide kubed-sh a script file to interpret or make it executable (for example using chmod 755 thescript along with a hashbang header). The following example illustrates using kubed-sh in script mode:

Imagine you have a script file called test.kbdsh with the following content:

#!/usr/bin/env kubed-sh
use minikube
# This line is a comment that will be ignored
node ../thescript.js &
ps

Then, you can make it executable and execute it like so:

$ chmod 755 test.kbdsh
$ ./test.kbdsh

Alternatively you can provide a script via stdin:

$ cat tc/script.kbdsh | kubed-sh

… or as a command line argument:

$ kubed-sh tc/script.kbdsh

Note that all three ways shown above are equivalent.

Environments

kubed-sh supports environments and within it variables—akin to what your local shell (bash, zsh, fish) does. There are some pre-defined environment variables which influence the creation of the cluster processes you create by either specifying a binary or interpreter and script:

TIP

You can overwrite at any time any of the above environment variables to change the runtime behaviour of the cluster processes you create. All changes are valid for the runtime of kubed-sh. That is, when you quit kubed-sh all pre-defined environment variables are reset to their default values.

Useful for scripting and advanced users: with the 0.5 release there are now four sub-commands to env (which itself simply lists the defined variables):

If no environment is selected, you are operating in the global environment. See also the design as well as Issue #6 for what environments are and how to work with them. Note that when you do an env delete ENVNAME, this environment is reaped and goes back into the global.

Configuration

The following environment variables, defined in the parent shell (such as bash), influence the runtime behavior of kubed-sh. On start-up, kubed-sh evaluates these environment variables and enables or changes its behavior:

env var default set for
KUBEDSH_DEBUG false print detailed messages for debug purposes
KUBEDSH_NOPREPULL false disable image pre-pull
KUBECTL_BINARY which kubectl is used to determine the binary if set, rather than using auto-discovery, use this binary for kubectl commands

TIP

If you are in an environment (such as OpenShift Online) where you can’t create a DaemonSet, launch kubed-sh like so: $ KUBEDSH_NOPREPULL=true kubed-sh

If you want to use the OpenShift CLI tool oc launch it with KUBECTL_BINARY=$(which oc) kubed-sh

FAQ

Q: For whom is kubed-sh? When to use it?
A: I suppose it’s mainly useful in a prototyping, development, or testing phase, although for low-level interactions you might find it handy in prod environments as well since it provides an interactive, context-aware version of kubectl. See also use cases.

Q: How is kubed-sh pronounced?
A: Glad you asked. Well, I pronounce it /ku:bˈdæʃ/ as in ‘kube dash’ ;)

Q: Why another Kubernetes shell? There are already some, such as cloudnativelabs/kube-shell, errordeveloper/kubeplay, and c-bata/kube-prompt.
A: True, there is previous art, though these shells more or less aim at making kubectl interactive, exposing the commands such as get or apply to the user. In a sense kubed-sh is more like technosophos/kubeshell, trying to provide an environment a typical *nix user is comfortable with. For example, rather than providing a create or apply command to run a program, the user would simply enter the name of the executable, as she would do, for example, in the bash shell. See also the motivation.

Q: How does this actually work?
A: Good question. Essentially a glorified kubectl wrapper on steroids. See also the design.