NOTE: this project is still in an early stage
If you like this project, please checkout TODOs and open an issue if you'd like to contribute or discuss anything in particular.
> ./kubeplay
kubeplay (namespace="*")> pods # list pods in the cluster
<list-of-pods>
kubeplay (namespace="*")> @pod = _.any # pick a random pod from the list
kubeplay (namespace="*")> puts @pod.to_json # output the pod definition in JSON
{
"metadata": {
...
},
"spec": {
...
"containers": [
{
...
}
],
},
"status": {
...
}
}
kubeplay (namespace="*")> puts @pod.to_ruby # output the same as a Ruby hash
{ ... }
kubeplay (namespace="*")> @pod.delete! # I am a chaos monkey :)
Currently implemented verbs are the following:
pods
services
replicasets
daemonsets
Each of these can be used with index operator, e.g. services[10]
, as well as first
, last
and any
methonds.
Any resource object can be converted to a JSON string with to_json
method, or a Ruby object with to_ruby
.
With a Ruby object reprsentation you can do things like this:
@metadata = replicasets("*/").to_ruby.items.map do |k,v|
v.metadata
end
@metadata.each do |i|
puts "Name:\t#{i.name}"
puts "Labels:\t#{i.labels}"
puts
end
You can define a verb aliases with def_alias
, e.g. to create an rs
verb alias for replicasets
use
def_alias :rs, :replicasets
By default a verb operates on all namespaces, hence (namespace="*")
is shown in the prompt.
You can switch current namespaces with namespace
verb, e.g.
kubeplay (namespace="*")> namespace "kube-system"
kubeplay (namespace="kube-system")>
To go back to all-namespaces mode, use namespace "*"
.
A verb may take up two arguments in any order - a glob string and a block or hash.
To get all replica sets in default
namespaces which have label app
not matching foo
or bar
and label version
matching 0.1
or 0.2
use
replicasets "default/", labels: -> { @app !~ %w(foo bar) ; @version =~ %w(0.1 0.2) ; }
To get all running pods with label app
matching foo
or bar
use
pods { @app =~ %w(foo bar) ; status.phase == "Running" ; }
Here are some examples illustrating the types of glob expressions that kubeplay
understands.
Get all pods in kube-systems
namespace:
pods "kube-system/"
Get all pods in all namespace:
pods "*/"
Get all pods in current namespace with name matching *foo*
:
pods "*foo*"
More specifically, this enables getting pods in a namespace other then current like this:
kubeplay (namespace="default")> pods "kube-system/foo-*"
Or, gettin pods with name matching "bar-*
in all namespace like this:
kubeplay (namespace="default")> pods "*/bar-*"
NOTE: if current namespace is
"*"
,pods "*"
is the same aspods
;pods "*/*"
is always the same aspods "*/"
.
Another argument a resource verb understand is a block specifying label and field selectors using special syntax outlined below.
To match a label agains a set of values, use label("name") =~ %w(foo bar)
, or !~
.
If you want to just get resources with a certain label to set anything, use label("baz").defined?
This
{
label("name") =~ %w(foo bar)
label("baz").defined?
}
will compile a selector string name in (foo, bar),myapp
.
And this
{
label("name") !~ %w(foo bar)
label("baz").defined?
}
will compile a selector string name notin (foo, bar),myapp
.
Some well-known labels have shortuct, e.g.
{
@app !~ %w(foo bar)
@version =~ %w(0.1 0.2)
@tier =~ %w(frontend backend)
}
Simply pass a block like this:
replicasets { @app !~ %w(foo bar); @version =~ %w(0.1 0.2); @tier =~ %w(frontend backend); }
You can also use make_label_selector
verb to construct these expressions and save those to variabels etc.
This syntax is different, yet somewhat simpler.
Here is a selector mathing all running pods:
{ status.phase != :Running }
To get all running pods with label tier
mathcing backend
:
pods { status.phase != :Running ; @tier =~ "backend" ; }
Alternatively, if you prefer to be more explicit, you can use a hash:
pods fields: -> { status.phase != :Running }, labels: -> { @tier =~ "backend" }
You can also use compose selector expressions diretly as strings, if you prefer:
pods fields: "status.phase != Running", labels: "tier in (backend)"
To get grep logs for any pod matching given selector
pods{ @name =~ "launch-generator" ; }.any.logs.grep ".*INFO:.*", ".*user-agent:.*"
> ./kubeplay -kubeconfig ~/.kube/config
kubeplay (namespace="*")> @pod = make_pod(image: "errordeveloper/foo:latest")
kubeplay (namespace="*")> puts _.to_json
{
"metadata": {
"creationTimestamp": null,
"labels": {
"name": "foo"
}
},
"spec": {
"containers": [
{
"name": "foo",
"image": "errordeveloper/foo:latest",
"resources": {}
}
]
},
"status": {}
}
kubeplay (namespace="*")> @pod.create!
kubeplay (namespace="*")> @pod.delete!
kubeplay (namespace="*")> ^D
>
Here are some TODO items and ideas.
-
pod.delete!
-
pod.create!
-
pod.logs
&pod.logs.grep
-
pods.logs
&pods.logs.grep
-
pod.logs.pager
andpod.logs.grep.pager
- grep logs in any set of resources
- more fluent behaviour of set resources, e.g.
replicasets.pods
and notreplicasets.any.pods
- reverse lookup, e.g. given
@rs = replicasets.any
,@rs.pods.any.owner
should be the same as@rs
- way to run scripts and not just REPL
- extend resource generator functionality
-
ReplicaSet
+Service
-
Kubefile
DSL
-
- simple framework for controllers and 3rd-party resource (e.g. chaos monkey of sorts, or use terraform to create an exteranl resource and store URL in a secret, custom policy controller made easy)
- multi-cluster support
- resource diff
- network policy tester framework
- eval/exec code in a pod
- test framework for apps, e.g. "Here is my app, it has a configmap and a secrete, and I want to test if it works"
Get the source code and build the dependencies:
go get github.com/Masterminds/glide
go get -d github.com/errordeveloper/kubeplay
cd $GOPATH/src/github.com/errordeveloper/kubeplay
$GOPATH/bin/glide up -v
make -C vendor/github.com/mitchellh/go-mruby libmruby.a
go install ./rubykube
Build kubeplay
:
go build .
The mruby integration was inspired by @erikh's box, and some of the code was initially copied from there.