kubeplay
kubeplay copied to clipboard
kubeplay – a new way to interact with Kubernetes API from your terminal
kubeplay – a new way to interact with Kubernetes
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.
Usage example: easy REPL with Ruby syntax
> ./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 :)
Resource Verbs
Currently implemented verbs are the following:
podsservicesreplicasetsdaemonsets
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 "*".
Resource Arguments
A verb may take up two arguments in any order - a glob string and a block or hash.
TL;DR
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" ; }
Glob Expressions
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 "*/".
Label & Field Selectors
Another argument a resource verb understand is a block specifying label and field selectors using special syntax outlined below.
Label Selector Syntax
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.
Field Selector Syntax
This syntax is different, yet somewhat simpler.
Here is a selector mathing all running pods:
{ status.phase != :Running }
Using Slectors
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)"
Inspecting the Logs
To get grep logs for any pod matching given selector
pods{ @name =~ "launch-generator" ; }.any.logs.grep ".*INFO:.*", ".*user-agent:.*"
Usage example: object generator with minimal input
> ./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
>
TODOs
Here are some TODO items and ideas.
- [x]
pod.delete! - [x]
pod.create! - [x]
pod.logs&pod.logs.grep - [x]
pods.logs&pods.logs.grep - [ ]
pod.logs.pagerandpod.logs.grep.pager - [ ] grep logs in any set of resources
- [ ] more fluent behaviour of set resources, e.g.
replicasets.podsand notreplicasets.any.pods - [ ] reverse lookup, e.g. given
@rs = replicasets.any,@rs.pods.any.ownershould be the same as@rs - [ ] way to run scripts and not just REPL
- [ ] extend resource generator functionality
- [ ]
ReplicaSet+Service - [ ]
KubefileDSL
- [ ]
Ideas
- 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"
Building
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 .
Credits
The mruby integration was inspired by @erikh's box, and some of the code was initially copied from there.