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
[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
- Use cases
See it in action, below or try it out in your browser using this Katacoda scenario:
|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:
- When you enter
node script.js, a Node.js (default version: 9.4) environment is provided and
- When you enter
python script.py, a Python (default version: 3.6) environment is provided and the
- When you enter
ruby script.rb, a Ruby (default version: 2.5) environment is provided and the
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.
- Prototyping—Let's say you quickly want to try out a Python script or, in the context of microservices, see how a Go program and a Node.js script play together.
- Developing—Imagine you're developing a program in Ruby and want to launch it in a Kubernetes cluster, without having to build an image and pushing it to a registry. In this case, the experimental hot-reload feature (using
HOTRELOAD=true) is useful for you. Whenever you save the file locally, it gets updated in the Kubernetes cluster, if hot-reload is enabled.
- Learning Kubernetes—You're new to Kubernetes and want to learn how to interact with it? Tip: if you issue the
debugcommand you can see which
kubed-shlaunches in the background.
Also, you may be interested in my motivation for writing
kubectlmust be installed, tested with client version
- 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
0as a result, you're good, and further
- if you do
kubectl config get-contexts | wc -land see a number greater than
0, then that's super dope.
$ 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
$ 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:
- Do a
cd $GOPATH/src/github.com/mhausenblas/kubed-shfollowed by a
go buildand use it from this directory.
- Run it like so:
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.
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
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
$ 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.
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:
alpine:3.7) … used for executing binaries
node:9.4-alpine) … used for executing Node.js scripts
python:3.6-alpine3.7) … used for executing Python scripts
ruby:2.5-alpine3.7) … used for executing Ruby scripts
80) … used to expose long-running processes within the cluster
"") … used to overwrite the URL for long-running processes within the cluster
false) … used for enabling a watch on local files to trigger automatic updates on modification (EXPERIMENTAL)
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-shall 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):
env list… list all defined environments in current context
env create ENVNAME… create a new environment called
env select ENVNAME… make environment called
ENVNAMEthe active one
env delete ENVNAME… delete environment called
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.
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|
||print detailed messages for debug purposes|
||disable image pre-pull|
||if set, rather than using auto-discovery, use this binary for
If you are in an environment (such as OpenShift Online) where you can't create a DaemonSet, launch
$ KUBEDSH_NOPREPULL=true kubed-sh
If you want to use the OpenShift CLI tool oc launch it with
KUBECTL_BINARY=$(which oc) kubed-sh
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
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
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
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.