JSONPath range not working when using kubectl - kubernetes

I'm accessing Kubernetes through the CLI tool kubectl and I'm trying to get a list of all context names, one per line.
I know that JSONPath can be used to extract and format specific output. I get really close to what I want with
kubectl config view -o=jsonpath="{.contexts[*].name}"
but this puts all the names on the same line. I'm trying to use range to list all names separated by newlines:
kubectl config view -o=jsonpath='{range .contexts[*]}{.name}{"\n"}{end}'
But this just gives me an error:
error: unexpected arguments: [.contexts[*]}{.name}{"\n"}{end}]
See 'kubectl config view -h' for help and examples.
I've reviewed the kubectl documentation and what I'm doing is really similar to https://kubernetes.io/docs/tasks/access-application-cluster/list-all-running-container-images/#list-containers-by-pod, where the command is
kubectl get pods --all-namespaces -o=jsonpath='{range .items[*]}{"\n"}{.metadata.name}{":\t"}{range .spec.containers[*]}{.image}{", "}{end}{end}' |\
sort
but I can't see where I'm going wrong.

Your command works for me in kubectl 1.9.2
If it still doesn't work, you can use tr in bash to replace spaces with new lines:
kubectl config view -o=jsonpath="{.contexts[*].name}" | tr " " "\n"

I figured it out. I had been using #ahmetb's kubectl-aliases script, which works fine with no problem, but one of the suggestions in the README was:
Print the full command before running it: Add this to your .bashrc or .zshrc file:
function kubectl() { echo "+ kubectl $#"; command kubectl $#; }
I had that function declaration in my .bashrc and it was stripping off the quotes for my jsonpath argument. As soon as I commented out that declaration and opened a new shell, the command worked correctly.

Related

Kubectl Namespace script to filter only name

I'm trying to use Kubectl get namespaces command it is fetching the data.
kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-node-lease Active 1d
kube-public Active 1d
kube-system Active 1d
but I want to filter it with name only. So when u run the script it should show like this.
kubectl get namespace
NAME
default
kube-node-lease
kube-public
kube-system
I've tried some powershell command but it is not working out for me.
Try any one of the command
kubectl get namespace --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}'
kubectl get namespace | awk '{print $1}'
kubectl get namespace --no-headers -o custom-columns=":metadata.name"
kubectl get namespace -o=name | sed "s/^.\{10\}//"
I presume the output of kubectrl is pure text so to manipulate it you will need to either do text parsing (error-prone and not fun) or you need to get the data into a PowerShell object.
ConvertFrom-SourceTable
This will allow you to read and parse the text/string data into a PowerShell object. Then you can simply Select-Object name to get the Name column only.
The second option is to use text/string parsing but for that, you will have to use length detections to extract the columns. An example of that can be found here.
This code works for me:
kubectl get ns | awk '{print $1}'

Kubernetes - show help for a command but only show examples

Is it possible to get the help for a k8s command but only show the Examples section of the help?
For example, if I run:
kubectl run --help
It outputs different sections, but I only want to see examples on the screen.
This command only show line 2 to line 30
kubectl run --help | head -n30 | tail -n28
Like many other help pages, K8s help docs come in this order:
Description
Examples
Options
Usage
you could use sed to cut out the part you need:
kubectl run --help | sed -n "/Examples:/,/Options:/p"
or better:
kubectl run --help | sed -n "/Examples:/,/Options:/p" | grep -v "Options:"

How to delete multiple Kubernetes pods having the same name expression except the latest one?

I have multiple pods running as below. I want to delete them all except the one having minimum age. How to do it?
Something like this? Perhaps also add -l app=value to filter for a specific app
kubectl get pods --sort-by=.metadata.creationTimestamp -o name | head -n -1 | xargs echo kubectl delete
(Remove echo to do it for realz)
You could just use PowerShell and pipe the output to the Foreach-Object, which then loops over each line:
kubectl get pods -n default -o name | ForEach-Object { kubectl delete $_ }

Multiple mongo commands in kubernetes not working

I am attempting to automate the following series of commands which work correctly into a BASH script:
kubectl exec -it mongo-pod -- bash
mongo DBNAME
db.auth("theUser", "thePw")
db.theCollection.find()
The script I am using is as follows:
#!/bin/bash
kubectl exec -it mongo-pod -- bash -c "mongo DBNAME && /
db.auth("theUser", "thePw") && /
db.theCollection.find()"
I have tried the following:
Executing multiple commands( or from a shell script) in a kubernetes pod
but any commands that are added after the first using & or && are not executed. For example just using "mongo DBNAME" correctly opens the prompt and sets it to the correct db, but adding any other command with && causes all commands to fail with the following:
bash: -c line 0: syntax error near unexpected token 'theUser'
All of the comments are spot on, but at least two things I have the highest confidence I have the answer to:
First, you have the line continuation character wrong; it should be \ and not /. It actually wouldn't even be required if you switched bash into "exit on error" mode, with
kubectl exec -it mongo-pod -- bash -ec "mongo DBNAME
echo 'this command only runs if mongo exits a-ok'
exit 1
and this never will run
"
However, the other mistake is around the quoting characters used: if you have bash -c " then you must either use the single-quote for the interior string literals, or escape them with \". You can actually see what I'm talking about by looking at the syntax highlighting of the shell snippet in your question. Observe that the string literal is red, but then the text theUser as well as thePw are both black -- that's because they are outside the string literal since the string stopped at the first " it encountered -- the one present in db.auth("
It is almost always the case that you'll want to use single quotes when invoking bash remotely like that, for several reasons but the most relevant is that you can then use db.auth("something") without having to unnecessarily escape the double quotes.
Since mongo (like many interpreters such a node and python) wants you to either type in it interactively, provide the input on its "standard input", or give it a local file containing commands, you will want to change the invocation to one of those strategies depending on your needs.
A very convenient way of redirecting standard input without having to use echo or printf and its associated quoting hell is to use what are called "here documents" (abbreviated "heredocs") in bash:
kubectl exec -it mongo-pod -- bash -ec 'mongo DBNAME<<"FOO"
db.auth("theUser", "thePw")
printjson(db.theCollection.find())
FOO
'
That causes bash to transmit almost all characters between the two "heredoc delimiters" to the standard input of the command. If you quote the delimiter, as I have with the [arbitrary] word FOO, then the contents are not subject to variable expansion, command interpolation, etc, which can be one more mechanism to avoid backtick and dollarsign weirdness.

Comma in kubectl used as a pipe

Have you seen a comma in a kubectl command?
Like the following command:
kubectl get deployments,ing -n my-system
Is it like a pipe grap or?
It is just a separator between k8s resources, that you would like to do something with (get/describe/etc...). Your command will output the list of Ingress resources next to the list of Deployments